diff -rubwBEN 3.4/configure.ac 3.4-mm/configure.ac --- 3.4/configure.ac 2013-09-10 23:09:23.110467000 +0100 +++ 3.4-mm/configure.ac 2013-09-21 21:20:13.189998613 +0100 @@ -1907,6 +1907,10 @@ AC_DEFINE(HAVE_KRB5_GET_ERROR_MESSAGE,1, [Define to 1 if you have krb5_get_error_message]),) AC_CHECK_DECLS(krb5_kt_free_entry,,,[#include ]) + AC_CHECK_TYPE(krb5_pac, + AC_DEFINE(HAVE_KRB5_PAC,1, + [Define to 1 if you have krb5_pac]),, + [#include ]) AC_CHECK_LIB(krb5,krb5_kt_free_entry, AC_DEFINE(HAVE_KRB5_KT_FREE_ENTRY,1, [Define to 1 if you have krb5_kt_free_entry]),) @@ -1925,6 +1929,33 @@ AC_CHECK_LIB(krb5,profile_release, AC_DEFINE(HAVE_PROFILE_RELEASE,1, [Define to 1 if you have profile_release]),) + AC_CHECK_LIB(krb5,krb5_get_renewed_creds, + AC_DEFINE(HAVE_KRB5_GET_RENEWED_CREDS,1, + [Define to 1 if you have krb5_get_renewed_creds]),) + AC_CHECK_LIB(krb5,krb5_principal_get_realm, + AC_DEFINE(HAVE_KRB5_PRINCIPAL_GET_REALM,1, + [Define to 1 if you have krb5_principal_get_realm]),) + AC_CHECK_LIB(krb5, krb5_get_init_creds_opt_alloc, + AC_DEFINE(HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC,1, + [Define to 1 if you have krb5_get_init_creds_opt_alloc]),) + AC_MSG_CHECKING([for krb5_get_init_creds_free requires krb5_context]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + ]],[[krb5_context context; + krb5_get_init_creds_opt *options; + krb5_get_init_creds_opt_free(context, options)]])],[ + AC_DEFINE(HAVE_KRB5_GET_INIT_CREDS_FREE_CONTEXT,1, + [Define to 1 if you krb5_get_init_creds_free requires krb5_context]) + AC_MSG_RESULT(yes) + ],[AC_MSG_RESULT(no)],[AC_MSG_RESULT(no)]) + + + AC_CHECK_FUNCS(gss_map_name_to_any, + AC_DEFINE(HAVE_GSS_MAP_ANY_TO_ANY,1, + [Define to 1 if you have gss_map_name_to_any]),) + AC_CHECK_FUNCS(gsskrb5_extract_authz_data_from_sec_context, + AC_DEFINE(HAVE_GSSKRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT,1, + [Define to 1 if you have gsskrb5_extract_authz_data_from_sec_context]),) SQUID_CHECK_KRB5_CONTEXT_MEMORY_CACHE SQUID_DEFINE_BOOL(HAVE_KRB5_MEMORY_CACHE,$squid_cv_memory_cache, diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc --- 3.4/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc 2013-09-22 00:47:09.658819098 +0100 @@ -65,7 +65,7 @@ void clean_gd(struct gdstruct *gdsp); void clean_nd(struct ndstruct *ndsp); -void clean_ls(struct ndstruct *lssp); +void clean_ls(struct lsstruct *lssp); void clean_gd(struct gdstruct *gdsp) @@ -78,22 +78,12 @@ pp = p; p = p->next; } - if (p->group) { - xfree(p->group); - p->group = NULL; - } - if (p->domain) { - xfree(p->domain); - p->domain = NULL; - } - if (pp && pp->next) { - xfree(pp->next); - pp->next = NULL; - } - if (p == gdsp) { - xfree(gdsp); - gdsp = NULL; - } + safe_free(p->group); + safe_free(p->domain); + if (pp) + safe_free(pp->next); + if (p == gdsp) + safe_free(gdsp); p = gdsp; } } @@ -109,22 +99,12 @@ pp = p; p = p->next; } - if (p->netbios) { - xfree(p->netbios); - p->netbios = NULL; - } - if (p->domain) { - xfree(p->domain); - p->domain = NULL; - } - if (pp && pp->next) { - xfree(pp->next); - pp->next = NULL; - } - if (p == ndsp) { - xfree(ndsp); - ndsp = NULL; - } + safe_free(p->netbios); + safe_free(p->domain); + if (pp) + safe_free(pp->next); + if (p == ndsp) + safe_free(ndsp); p = ndsp; } } @@ -140,22 +120,12 @@ pp = p; p = p->next; } - if (p->lserver) { - xfree(p->lserver); - p->lserver = NULL; - } - if (p->domain) { - xfree(p->domain); - p->domain = NULL; - } - if (pp && pp->next) { - xfree(pp->next); - pp->next = NULL; - } - if (p == lssp) { - xfree(lssp); - lssp = NULL; - } + safe_free(p->lserver); + safe_free(p->domain); + if (pp) + safe_free(pp->next); + if (p == lssp) + safe_free(lssp); p = lssp; } } @@ -163,50 +133,17 @@ void clean_args(struct main_args *margs) { - if (margs->glist) { - xfree(margs->glist); - margs->glist = NULL; - } - if (margs->ulist) { - xfree(margs->ulist); - margs->ulist = NULL; - } - if (margs->tlist) { - xfree(margs->tlist); - margs->tlist = NULL; - } - if (margs->nlist) { - xfree(margs->nlist); - margs->nlist = NULL; - } - if (margs->llist) { - xfree(margs->llist); - margs->llist = NULL; - } - if (margs->luser) { - xfree(margs->luser); - margs->luser = NULL; - } - if (margs->lpass) { - xfree(margs->lpass); - margs->lpass = NULL; - } - if (margs->lbind) { - xfree(margs->lbind); - margs->lbind = NULL; - } - if (margs->lurl) { - xfree(margs->lurl); - margs->lurl = NULL; - } - if (margs->ssl) { - xfree(margs->ssl); - margs->ssl = NULL; - } - if (margs->ddomain) { - xfree(margs->ddomain); - margs->ddomain = NULL; - } + safe_free(margs->glist); + safe_free(margs->ulist); + safe_free(margs->tlist); + safe_free(margs->nlist); + safe_free(margs->llist); + safe_free(margs->luser); + safe_free(margs->lpass); + safe_free(margs->lbind); + safe_free(margs->lurl); + safe_free(margs->ssl); + safe_free(margs->ddomain); if (margs->groups) { clean_gd(margs->groups); margs->groups = NULL; @@ -413,8 +350,8 @@ log((char *) "%s| %s: INFO: Got User: %s Netbios Name: %s\n", LogTime(), PROGRAM, up, np); domain = get_netbios_name(&margs, netbios); user = nuser; - xfree(up); - xfree(np); + safe_free(up); + safe_free(np); } else if (domain) { strup(domain); *domain = '\0'; @@ -436,8 +373,8 @@ else log((char *) "%s| %s: INFO: Got User: %s Domain: %s\n", LogTime(), PROGRAM, up, domain ? dp : "NULL"); - xfree(up); - xfree(dp); + safe_free(up); + safe_free(dp); if (!strcmp(user, "QQ") && domain && !strcmp(domain, "QQ")) { clean_args(&margs); exit(-1); @@ -477,7 +414,7 @@ strup(char *s) { while (*s) { - *s = toupper((unsigned char) *s); + *s = (char)toupper((unsigned char) *s); ++s; } } diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_group.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_group.cc --- 3.4/helpers/external_acl/kerberos_ldap_group/support_group.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_group.cc 2013-09-22 01:01:05.906874358 +0100 @@ -31,6 +31,7 @@ #include "support.h" struct gdstruct *init_gd(void); +void free_gd(struct gdstruct *gdsp); struct gdstruct * init_gd(void) { @@ -59,7 +60,8 @@ char * utf8dup(struct main_args *margs) { - int c = 0, s; + size_t c = 0; + unsigned char s; size_t n; char *src; unsigned char *p, *dupp; @@ -79,7 +81,7 @@ *p = 194; ++p; *p = s; - } else if (s > 191 && s < 256) { + } else if (s > 191) { *p = 195; ++p; *p = s - 64; @@ -121,7 +123,7 @@ return NULL; char *upd = strrchr(up, '@'); - size_t a = (upd ? (upd - up) : strlen(up) ); + size_t a = (upd ? (size_t)(upd - up) : strlen(up) ); char *ul = (char *) xmalloc(strlen(up)+1); size_t n = 0; @@ -174,17 +176,17 @@ if (iUTF2) { if (iUTF2 == 0xC2 && ichar > 0x7F && ichar < 0xC0) { iUTF2 = 0; - ul[nl - 1] = ichar; + ul[nl - 1] = (char)ichar; } else if (iUTF2 == 0xC3 && ichar > 0x7F && ichar < 0xC0) { iUTF2 = 0; - ul[nl - 1] = ichar + 64; + ul[nl - 1] = (char)(ichar + 64); } else if (iUTF2 > 0xC3 && iUTF2 < 0xE0 && ichar > 0x7F && ichar < 0xC0) { iUTF2 = 0; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else { iUTF2 = 0; - ul[nl] = ichar; + ul[nl] = (char)ichar; ul[nl + 1] = '\0'; debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul); xfree(ul); @@ -193,27 +195,27 @@ } else if (iUTF3) { if (iUTF3 == 0xE0 && ichar > 0x9F && ichar < 0xC0) { iUTF3 = 1; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else if (iUTF3 > 0xE0 && iUTF3 < 0xED && ichar > 0x7F && ichar < 0xC0) { iUTF3 = 2; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else if (iUTF3 == 0xED && ichar > 0x7F && ichar < 0xA0) { iUTF3 = 3; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else if (iUTF3 > 0xED && iUTF3 < 0xF0 && ichar > 0x7F && ichar < 0xC0) { iUTF3 = 4; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else if (iUTF3 > 0 && iUTF3 < 5 && ichar > 0x7F && ichar < 0xC0) { iUTF3 = 0; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else { iUTF3 = 0; - ul[nl] = ichar; + ul[nl] = (char)ichar; ul[nl + 1] = '\0'; debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul); xfree(ul); @@ -222,26 +224,26 @@ } else if (iUTF4) { if (iUTF4 == 0xF0 && ichar > 0x8F && ichar < 0xC0) { iUTF4 = 1; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else if (iUTF4 > 0xF0 && iUTF3 < 0xF4 && ichar > 0x7F && ichar < 0xC0) { iUTF4 = 2; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else if (iUTF4 == 0xF4 && ichar > 0x7F && ichar < 0x90) { iUTF4 = 3; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else if (iUTF4 > 0 && iUTF4 < 5 && ichar > 0x7F && ichar < 0xC0) { if (iUTF4 == 4) iUTF4 = 0; else iUTF4 = 4; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else { iUTF4 = 0; - ul[nl] = ichar; + ul[nl] = (char)ichar; ul[nl + 1] = '\0'; debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul); xfree(ul); @@ -249,25 +251,25 @@ } } else if (ichar < 0x80) { /* UTF1 */ - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else if (ichar > 0xC1 && ichar < 0xE0) { /* UTF2 (Latin) */ iUTF2 = ichar; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else if (ichar > 0xDF && ichar < 0xF0) { /* UTF3 */ iUTF3 = ichar; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else if (ichar > 0xEF && ichar < 0xF5) { /* UTF4 */ iUTF4 = ichar; - ul[nl] = ichar; + ul[nl] = (char)ichar; ++nl; } else { - ul[nl] = ichar; + ul[nl] = (char)ichar; ul[nl + 1] = '\0'; debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul); xfree(ul); diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support.h 3.4-mm/helpers/external_acl/kerberos_ldap_group/support.h --- 3.4/helpers/external_acl/kerberos_ldap_group/support.h 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support.h 2013-09-22 12:42:55.834656998 +0100 @@ -156,13 +156,13 @@ int create_ls(struct main_args *margs); #ifdef HAVE_KRB5 -int krb5_create_cache(struct main_args *margs, char *domain); +int krb5_create_cache(char *domain); void krb5_cleanup(void); #endif -int get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, int nhosts, char *domain); -int get_hostname_list(struct main_args *margs, struct hstruct **hlist, int nhosts, char *name); -int free_hostname_list(struct hstruct **hlist, int nhosts); +size_t get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, size_t nhosts, char *domain); +size_t get_hostname_list(struct hstruct **hlist, size_t nhosts, char *name); +size_t free_hostname_list(struct hstruct **hlist, size_t nhosts); #if defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H) || defined(HAVE_SASL_DARWIN) int tool_sasl_bind(LDAP * ld, char *binddn, char *ssl); diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_krb5.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_krb5.cc --- 3.4/helpers/external_acl/kerberos_ldap_group/support_krb5.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_krb5.cc 2013-09-22 13:53:30.148936803 +0100 @@ -33,7 +33,9 @@ krb5_context context; char *mem_cache_env; krb5_ccache cc; -} kparam; +}; + +static struct kstruct kparam; #define KT_PATH_MAX 256 @@ -50,23 +52,20 @@ * create Kerberos memory cache */ int -krb5_create_cache(struct main_args *margs, char *domain) +krb5_create_cache(char *domain) { krb5_keytab keytab = 0; krb5_keytab_entry entry; krb5_kt_cursor cursor; krb5_creds *creds = NULL; - krb5_creds *tgt_creds = NULL; krb5_principal *principal_list = NULL; krb5_principal principal = NULL; char *service; char *keytab_name = NULL, *principal_name = NULL, *mem_cache = NULL; char buf[KT_PATH_MAX], *p; - int nprinc = 0; - int i; + size_t j,nprinc = 0; int retval = 0; - int found = 0; krb5_error_code code = 0; kparam.context = NULL; @@ -112,6 +111,7 @@ nprinc = 0; while ((code = krb5_kt_next_entry(kparam.context, keytab, &entry, &cursor)) == 0) { + int found = 0; principal_list = (krb5_principal *) xrealloc(principal_list, sizeof(krb5_principal) * (nprinc + 1)); krb5_copy_principal(kparam.context, entry.principal, &principal_list[nprinc++]); @@ -182,12 +182,14 @@ * if no principal name found in keytab for domain use the prinipal name which can get a TGT */ if (!principal_name) { + size_t i; debug((char *) "%s| %s: DEBUG: Did not find a principal in keytab for domain %s.\n", LogTime(), PROGRAM, domain); debug((char *) "%s| %s: DEBUG: Try to get principal of trusted domain.\n", LogTime(), PROGRAM); - creds = (krb5_creds *) xmalloc(sizeof(*creds)); - memset(creds, 0, sizeof(*creds)); for (i = 0; i < nprinc; ++i) { + krb5_creds *tgt_creds = NULL; + creds = (krb5_creds *) xmalloc(sizeof(*creds)); + memset(creds, 0, sizeof(*creds)); /* * get credentials */ @@ -205,7 +207,6 @@ snprintf(service, strlen("krbtgt") + 2 * strlen(domain) + 3, "krbtgt/%s@%s", domain, domain); creds->client = principal_list[i]; code = krb5_parse_name(kparam.context, service, &creds->server); - if (service) xfree(service); code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0); #endif @@ -233,7 +234,6 @@ snprintf(service, strlen("krbtgt") + strlen(domain) + strlen(krb5_princ_realm(kparam.context, principal_list[i])->data) + 3, "krbtgt/%s@%s", domain, krb5_princ_realm(kparam.context, principal_list[i])->data); #endif code = krb5_parse_name(kparam.context, service, &creds->server); - if (service) xfree(service); if (code) { error((char *) "%s| %s: ERROR: Error while initialising TGT credentials : %s\n", LogTime(), PROGRAM, error_message(code)); @@ -245,19 +245,22 @@ goto loop_end; } else { debug((char *) "%s| %s: DEBUG: Found trusted principal name: %s\n", LogTime(), PROGRAM, principal_name); - found = 1; break; } loop_end: - if (principal_name) - xfree(principal_name); - principal_name = NULL; - } - - if (tgt_creds) + safe_free(principal_name); + if (tgt_creds) { krb5_free_creds(kparam.context, tgt_creds); tgt_creds = NULL; + } + if (creds) + krb5_free_creds(kparam.context, creds); + creds = NULL; + + } + + safe_free(principal_name); if (creds) krb5_free_creds(kparam.context, creds); creds = NULL; @@ -287,7 +290,6 @@ snprintf(service, strlen("krbtgt") + 2 * strlen(domain) + 3, "krbtgt/%s@%s", domain, domain); creds->client = principal; code = krb5_parse_name(kparam.context, service, &creds->server); - if (service) xfree(service); code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0); #endif @@ -316,19 +318,15 @@ cleanup: if (keytab) krb5_kt_close(kparam.context, keytab); - if (keytab_name) xfree(keytab_name); - if (principal_name) xfree(principal_name); - if (mem_cache) xfree(mem_cache); if (principal) krb5_free_principal(kparam.context, principal); - for (i = 0; i < nprinc; ++i) { - if (principal_list[i]) - krb5_free_principal(kparam.context, principal_list[i]); + for (j = 0; j < nprinc; ++j) { + if (principal_list[j]) + krb5_free_principal(kparam.context, principal_list[j]); } - if (principal_list) xfree(principal_list); if (creds) krb5_free_creds(kparam.context, creds); diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_ldap.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_ldap.cc --- 3.4/helpers/external_acl/kerberos_ldap_group/support_ldap.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_ldap.cc 2013-09-22 13:42:10.642891901 +0100 @@ -35,7 +35,7 @@ char *convert_domain_to_bind_path(char *domain); char *escape_filter(char *filter); int check_AD(struct main_args *margs, LDAP * ld); -int ldap_set_defaults(struct main_args *margs, LDAP * ld); +int ldap_set_defaults(LDAP * ld); int ldap_set_ssl_defaults(struct main_args *margs); LDAP *tool_ldap_open(struct main_args *margs, char *host, int port, char *ssl); @@ -51,7 +51,7 @@ #define FILTER_AD "(samaccountname=%s)" #define ATTRIBUTE_AD "memberof" -int get_attributes(struct main_args *margs, LDAP * ld, LDAPMessage * res, const char *attribute /* IN */ , char ***out_val /* OUT (caller frees) */ ); +size_t get_attributes(LDAP * ld, LDAPMessage * res, const char *attribute /* IN */ , char ***out_val /* OUT (caller frees) */ ); int search_group_tree(struct main_args *margs, LDAP * ld, char *bindp, char *ldap_group, char *group, int depth); #if defined(HAVE_SUN_LDAP_SDK) || defined(HAVE_MOZILLA_LDAP_SDK) @@ -210,7 +210,7 @@ convert_domain_to_bind_path(char *domain) { char *dp, *bindp = NULL, *bp = NULL; - int i = 0; + size_t i = 0; if (!domain) return NULL; @@ -243,8 +243,8 @@ char * escape_filter(char *filter) { - int i; char *ldap_filter_esc, *ldf; + size_t i; i = 0; for (ldap_filter_esc = filter; *ldap_filter_esc; ++ldap_filter_esc) { @@ -278,7 +278,7 @@ *ldf = '\0'; return ldap_filter_esc; -}; +} int check_AD(struct main_args *margs, LDAP * ld) @@ -286,8 +286,8 @@ LDAPMessage *res; char **attr_value = NULL; struct timeval searchtime; - int max_attr = 0; - int j, rc = 0; + size_t max_attr = 0; + int rc = 0; #define FILTER_SCHEMA "(objectclass=*)" #define ATTRIBUTE_SCHEMA "schemaNamingContext" @@ -301,7 +301,7 @@ NULL, NULL, &searchtime, 0, &res); if (rc == LDAP_SUCCESS) - max_attr = get_attributes(margs, ld, res, ATTRIBUTE_SCHEMA, &attr_value); + max_attr = get_attributes(ld, res, ATTRIBUTE_SCHEMA, &attr_value); if (max_attr == 1) { ldap_msgfree(res); @@ -318,11 +318,11 @@ * Cleanup */ if (attr_value) { + size_t j; for (j = 0; j < max_attr; ++j) { xfree(attr_value[j]); } - xfree(attr_value); - attr_value = NULL; + safe_free(attr_value); } ldap_msgfree(res); return rc; @@ -332,11 +332,11 @@ { LDAPMessage *res = NULL; char **attr_value = NULL; - int max_attr = 0; + size_t max_attr = 0; char *filter = NULL; char *search_exp = NULL; - int j, rc = 0, retval = 0; - char *av = NULL, *avp = NULL; + size_t j; + int rc = 0, retval = 0; int ldepth; char *ldap_filter_esc = NULL; struct timeval searchtime; @@ -378,9 +378,9 @@ debug((char *) "%s| %s: DEBUG: Found %d ldap entr%s\n", LogTime(), PROGRAM, ldap_count_entries(ld, res), ldap_count_entries(ld, res) > 1 || ldap_count_entries(ld, res) == 0 ? "ies" : "y"); if (margs->AD) - max_attr = get_attributes(margs, ld, res, ATTRIBUTE_AD, &attr_value); + max_attr = get_attributes(ld, res, ATTRIBUTE_AD, &attr_value); else - max_attr = get_attributes(margs, ld, res, ATTRIBUTE, &attr_value); + max_attr = get_attributes(ld, res, ATTRIBUTE, &attr_value); /* * Compare group names @@ -388,10 +388,12 @@ retval = 0; ldepth = depth + 1; for (j = 0; j < max_attr; ++j) { + char *av = NULL; /* Compare first CN= value assuming it is the same as the group name itself */ av = attr_value[j]; if (!strncasecmp("CN=", av, 3)) { + char *avp = NULL; av += 3; if ((avp = strchr(av, ','))) { *avp = '\0'; @@ -399,17 +401,17 @@ } if (debug_enabled) { int n; - debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" in hex UTF-8 is ", LogTime(), PROGRAM, j + 1, av); + debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" in hex UTF-8 is ", LogTime(), PROGRAM, j + 1, av); for (n = 0; av[n] != '\0'; ++n) fprintf(stderr, "%02x", (unsigned char) av[n]); fprintf(stderr, "\n"); } if (!strcasecmp(group, av)) { retval = 1; - debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" matches group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group); + debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" matches group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group); break; } else - debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" does not match group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group); + debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" does not match group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group); /* * Do recursive group search */ @@ -418,13 +420,14 @@ if (search_group_tree(margs, ld, bindp, av, group, ldepth)) { retval = 1; if (!strncasecmp("CN=", av, 3)) { + char *avp = NULL; av += 3; if ((avp = strchr(av, ','))) { *avp = '\0'; } } if (debug_enabled) - debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" is member of group named \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group); + debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" is member of group named \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group); else break; @@ -438,8 +441,7 @@ for (j = 0; j < max_attr; ++j) { xfree(attr_value[j]); } - xfree(attr_value); - attr_value = NULL; + safe_free(attr_value); } ldap_msgfree(res); @@ -447,7 +449,7 @@ } int -ldap_set_defaults(struct main_args *margs, LDAP * ld) +ldap_set_defaults(LDAP * ld) { int val, rc = 0; #ifdef LDAP_OPT_NETWORK_TIMEOUT @@ -484,14 +486,14 @@ #endif #ifdef HAVE_OPENLDAP int val; - char *ssl_cacertfile = NULL; - int free_path; #elif defined(HAVE_LDAPSSL_CLIENT_INIT) char *ssl_certdbpath = NULL; #endif #ifdef HAVE_OPENLDAP if (!margs->rc_allow) { + char *ssl_cacertfile = NULL; + int free_path; debug((char *) "%s| %s: DEBUG: Enable server certificate check for ldap server.\n", LogTime(), PROGRAM); val = LDAP_OPT_X_TLS_DEMAND; rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &val); @@ -509,7 +511,6 @@ rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ssl_cacertfile); if (ssl_cacertfile && free_path) { xfree(ssl_cacertfile); - ssl_cacertfile = NULL; } if (rc != LDAP_OPT_SUCCESS) { error((char *) "%s| %s: ERROR: Error while setting LDAP_OPT_X_TLS_CACERTFILE for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); @@ -543,10 +544,7 @@ rc = ldapssl_advclientauth_init(ssl_certdbpath, NULL, 0, NULL, NULL, 0, NULL, 0); debug((char *) "%s| %s: DEBUG: Disable server certificate check for ldap server.\n", LogTime(), PROGRAM); } - if (ssl_certdbpath) { xfree(ssl_certdbpath); - ssl_certdbpath = NULL; - } if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while setting SSL for ldap server: %s\n", LogTime(), PROGRAM, ldapssl_err2string(rc)); return rc; @@ -557,13 +555,13 @@ return LDAP_SUCCESS; } -int -get_attributes(struct main_args *margs, LDAP * ld, LDAPMessage * res, const char *attribute, char ***ret_value) +size_t +get_attributes(LDAP * ld, LDAPMessage * res, const char *attribute, char ***ret_value) { LDAPMessage *msg; char **attr_value = NULL; - int max_attr = 0; + size_t max_attr = 0; attr_value = *ret_value; /* @@ -588,15 +586,15 @@ if ((values = ldap_get_values_len(ld, msg, attr)) != NULL) { for (il = 0; values[il] != NULL; ++il) { - attr_value = (char **) xrealloc(attr_value, (il + 1) * sizeof(char *)); + attr_value = (char **) xrealloc(attr_value, (max_attr + 1) * sizeof(char *)); if (!attr_value) break; - attr_value[il] = (char *) xmalloc(values[il]->bv_len + 1); - memcpy(attr_value[il], values[il]->bv_val, values[il]->bv_len); - attr_value[il][values[il]->bv_len] = 0; + attr_value[max_attr] = (char *) xmalloc(values[il]->bv_len + 1); + memcpy(attr_value[max_attr], values[il]->bv_val, values[il]->bv_len); + attr_value[max_attr][values[il]->bv_len] = 0; + max_attr++; } - max_attr = il; } ber_bvecfree(values); } @@ -615,7 +613,7 @@ } } - debug((char *) "%s| %s: DEBUG: %d ldap entr%s found with attribute : %s\n", LogTime(), PROGRAM, max_attr, max_attr > 1 || max_attr == 0 ? "ies" : "y", attribute); + debug((char *) "%s| %s: DEBUG: %ld ldap entr%s found with attribute : %s\n", LogTime(), PROGRAM, max_attr, max_attr > 1 || max_attr == 0 ? "ies" : "y", attribute); *ret_value = attr_value; return max_attr; @@ -661,13 +659,13 @@ if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while parsing url: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); xfree(ldapuri); - xfree(url); + ldap_free_urldesc(url); return NULL; } #else #error "No URL parsing function" #endif - safe_free(url); + ldap_free_urldesc(url); rc = ldap_initialize(&ld, ldapuri); xfree(ldapuri); if (rc != LDAP_SUCCESS) { @@ -679,7 +677,7 @@ #else ld = ldap_init(host, port); #endif - rc = ldap_set_defaults(margs, ld); + rc = ldap_set_defaults(ld); if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while setting default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); ldap_unbind(ld); @@ -726,13 +724,13 @@ if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while parsing url: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); xfree(ldapuri); - xfree(url); + ldap_free_urldesc(url); return NULL; } #else #error "No URL parsing function" #endif - safe_free(url); + ldap_free_urldesc(url); rc = ldap_initialize(&ld, ldapuri); xfree(ldapuri); if (rc != LDAP_SUCCESS) { @@ -741,7 +739,7 @@ ld = NULL; return NULL; } - rc = ldap_set_defaults(margs, ld); + rc = ldap_set_defaults(ld); if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while setting default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); ldap_unbind(ld); @@ -757,7 +755,7 @@ ld = NULL; return NULL; } - rc = ldap_set_defaults(margs, ld); + rc = ldap_set_defaults(ld); if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while setting default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); ldap_unbind(ld); @@ -787,18 +785,12 @@ char *filter = NULL; char *search_exp; struct timeval searchtime; - int i, j, rc = 0, kc = 1; + int rc = 0, kc = 1; int retval; char **attr_value = NULL; - char *av = NULL, *avp = NULL; - int max_attr = 0; + size_t max_attr = 0; struct hstruct *hlist = NULL; - int nhosts = 0; - char *hostname; - char *host; - int port; - char *ssl = NULL; - char *p; + size_t nhosts = 0; char *ldap_filter_esc = NULL; searchtime.tv_sec = SEARCH_TIMEOUT; @@ -810,7 +802,7 @@ debug((char *) "%s| %s: DEBUG: Setup Kerberos credential cache\n", LogTime(), PROGRAM); #ifdef HAVE_KRB5 - kc = krb5_create_cache(margs, domain); + kc = krb5_create_cache(domain); if (kc) { error((char *) "%s| %s: ERROR: Error during setup of Kerberos credential cache\n", LogTime(), PROGRAM); } @@ -839,6 +831,7 @@ debug((char *) "%s| %s: DEBUG: Initialise ldap connection\n", LogTime(), PROGRAM); if (domain && !kc) { + size_t i; if (margs->ssl) { debug((char *) "%s| %s: DEBUG: Enable SSL to ldap servers\n", LogTime(), PROGRAM); } @@ -848,7 +841,7 @@ */ nhosts = get_ldap_hostname_list(margs, &hlist, 0, domain); for (i = 0; i < nhosts; ++i) { - port = 389; + int port = 389; if (hlist[i].port != -1) port = hlist[i].port; debug((char *) "%s| %s: DEBUG: Setting up connection to ldap server %s:%d\n", LogTime(), PROGRAM, hlist[i].host, port); @@ -893,6 +886,12 @@ bindp = convert_domain_to_bind_path(domain); } if ((!domain || !ld) && margs->lurl && strstr(margs->lurl, "://")) { + char *hostname; + char *host; + int port; + char *ssl = NULL; + char *p; + size_t i; /* * If username does not contain a domain and a url was given then try it */ @@ -912,8 +911,8 @@ ++p; port = atoi(p); } - nhosts = get_hostname_list(margs, &hlist, 0, host); - safe_free(host); + nhosts = get_hostname_list(&hlist, 0, host); + xfree(host); for (i = 0; i < nhosts; ++i) { ld = tool_ldap_open(margs, hlist[i].host, port, ssl); @@ -995,22 +994,25 @@ debug((char *) "%s| %s: DEBUG: Found %d ldap entr%s\n", LogTime(), PROGRAM, ldap_count_entries(ld, res), ldap_count_entries(ld, res) > 1 || ldap_count_entries(ld, res) == 0 ? "ies" : "y"); if (ldap_count_entries(ld, res) != 0) { + size_t k; if (margs->AD) - max_attr = get_attributes(margs, ld, res, ATTRIBUTE_AD, &attr_value); + max_attr = get_attributes(ld, res, ATTRIBUTE_AD, &attr_value); else { - max_attr = get_attributes(margs, ld, res, ATTRIBUTE, &attr_value); + max_attr = get_attributes(ld, res, ATTRIBUTE, &attr_value); } /* * Compare group names */ retval = 0; - for (j = 0; j < max_attr; ++j) { + for (k = 0; k < max_attr; ++k) { + char *av = NULL; /* Compare first CN= value assuming it is the same as the group name itself */ - av = attr_value[j]; + av = attr_value[k]; if (!strncasecmp("CN=", av, 3)) { + char *avp = NULL; av += 3; if ((avp = strchr(av, ','))) { *avp = '\0'; @@ -1018,7 +1020,7 @@ } if (debug_enabled) { int n; - debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" in hex UTF-8 is ", LogTime(), PROGRAM, j + 1, av); + debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" in hex UTF-8 is ", LogTime(), PROGRAM, k + 1, av); for (n = 0; av[n] != '\0'; ++n) fprintf(stderr, "%02x", (unsigned char) av[n]); fprintf(stderr, "\n"); @@ -1026,32 +1028,35 @@ if (!strcasecmp(group, av)) { retval = 1; if (debug_enabled) - debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" matches group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group); + debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" matches group name \"%s\"\n", LogTime(), PROGRAM, k + 1, av, group); else break; } else - debug((char *) "%s| %s: DEBUG: Entry %d \"%s\" does not match group name \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group); + debug((char *) "%s| %s: DEBUG: Entry %ld \"%s\" does not match group name \"%s\"\n", LogTime(), PROGRAM, k + 1, av, group); } /* * Do recursive group search for AD only since posixgroups can not contain other groups */ if (!retval && margs->AD) { + size_t j; if (debug_enabled && max_attr > 0) { debug((char *) "%s| %s: DEBUG: Perform recursive group search\n", LogTime(), PROGRAM); } for (j = 0; j < max_attr; ++j) { + char *av = NULL; av = attr_value[j]; if (search_group_tree(margs, ld, bindp, av, group, 1)) { retval = 1; if (!strncasecmp("CN=", av, 3)) { + char *avp = NULL; av += 3; if ((avp = strchr(av, ','))) { *avp = '\0'; } } if (debug_enabled) - debug((char *) "%s| %s: DEBUG: Entry %d group \"%s\" is (in)direct member of group \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group); + debug((char *) "%s| %s: DEBUG: Entry %ld group \"%s\" is (in)direct member of group \"%s\"\n", LogTime(), PROGRAM, j + 1, av, group); else break; } @@ -1061,11 +1066,11 @@ * Cleanup */ if (attr_value) { + size_t j; for (j = 0; j < max_attr; ++j) { xfree(attr_value[j]); } - xfree(attr_value); - attr_value = NULL; + safe_free(attr_value); } ldap_msgfree(res); } else if (ldap_count_entries(ld, res) == 0 && margs->AD) { @@ -1101,11 +1106,11 @@ debug((char *) "%s| %s: DEBUG: Found %d ldap entr%s\n", LogTime(), PROGRAM, ldap_count_entries(ld, res), ldap_count_entries(ld, res) > 1 || ldap_count_entries(ld, res) == 0 ? "ies" : "y"); - max_attr = get_attributes(margs, ld, res, ATTRIBUTE_GID, &attr_value); + max_attr = get_attributes(ld, res, ATTRIBUTE_GID, &attr_value); if (max_attr == 1) { char **attr_value_2 = NULL; - int max_attr_2 = 0; + size_t max_attr_2 = 0; ldap_msgfree(res); filter = (char *) FILTER_GID; @@ -1123,7 +1128,7 @@ NULL, NULL, &searchtime, 0, &res); xfree(search_exp); - max_attr_2 = get_attributes(margs, ld, res, ATTRIBUTE, &attr_value_2); + max_attr_2 = get_attributes(ld, res, ATTRIBUTE, &attr_value_2); /* * Compare group names */ @@ -1129,9 +1134,8 @@ */ retval = 0; if (max_attr_2 == 1) { - /* Compare first CN= value assuming it is the same as the group name itself */ - av = attr_value_2[0]; + char *av = attr_value_2[0]; if (!strcasecmp(group, av)) { retval = 1; debug((char *) "%s| %s: DEBUG: \"%s\" matches group name \"%s\"\n", LogTime(), PROGRAM, av, group); @@ -1143,11 +1147,11 @@ * Cleanup */ if (attr_value_2) { + size_t j; for (j = 0; j < max_attr_2; ++j) { xfree(attr_value_2[j]); } - xfree(attr_value_2); - attr_value_2 = NULL; + safe_free(attr_value_2); } ldap_msgfree(res); @@ -1161,11 +1165,11 @@ * Cleanup */ if (attr_value) { + size_t j; for (j = 0; j < max_attr; ++j) { xfree(attr_value[j]); } - xfree(attr_value); - attr_value = NULL; + safe_free(attr_value); } } rc = ldap_unbind(ld); diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_log.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_log.cc --- 3.4/helpers/external_acl/kerberos_ldap_group/support_log.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_log.cc 2013-09-22 12:56:14.502709775 +0100 @@ -34,13 +34,13 @@ const char * LogTime() { - struct tm *tm; - struct timeval now; static time_t last_t = 0; + struct timeval now; static char buf[128]; gettimeofday(&now, NULL); if (now.tv_sec != last_t) { + struct tm *tm; time_t tmp = now.tv_sec; tm = localtime(&tmp); strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm); diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_lserver.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_lserver.cc --- 3.4/helpers/external_acl/kerberos_ldap_group/support_lserver.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_lserver.cc 2013-09-22 01:34:06.390005229 +0100 @@ -29,6 +29,7 @@ #include "support.h" struct lsstruct *init_ls(void); +void free_ls(struct lsstruct *lssp); struct lsstruct * init_ls(void) { diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_netbios.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_netbios.cc --- 3.4/helpers/external_acl/kerberos_ldap_group/support_netbios.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_netbios.cc 2013-09-22 01:01:46.521877042 +0100 @@ -30,6 +30,7 @@ #include "support.h" struct ndstruct *init_nd(void); +void free_nd(struct ndstruct *ndsp); struct ndstruct * init_nd(void) { diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_resolv.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_resolv.cc --- 3.4/helpers/external_acl/kerberos_ldap_group/support_resolv.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_resolv.cc 2013-09-22 13:11:12.079769087 +0100 @@ -95,10 +95,10 @@ sort(struct hstruct *array, int nitems, int (*cmp) (struct hstruct *, struct hstruct *), int begin, int end) { if (end > begin) { - int pivot = begin; int l = begin + 1; int r = end; while (l < r) { + int pivot = begin; if (cmp(&array[l], &array[pivot]) <= 0) { l += 1; } else { @@ -116,7 +116,7 @@ static void msort(struct hstruct *array, size_t nitems, int (*cmp) (struct hstruct *, struct hstruct *)) { - sort(array, nitems, cmp, 0, nitems - 1); + sort(array, (int)nitems, cmp, 0, (int)(nitems - 1)); } static int @@ -145,33 +145,25 @@ return 0; } -int -free_hostname_list(struct hstruct **hlist, int nhosts) +size_t +free_hostname_list(struct hstruct **hlist, size_t nhosts) { struct hstruct *hp = NULL; - int i; + size_t i; hp = *hlist; for (i = 0; i < nhosts; ++i) { - if (hp[i].host) xfree(hp[i].host); - hp[i].host = NULL; } - if (hp) - xfree(hp); - hp = NULL; + safe_free(hp); *hlist = hp; return 0; } -int -get_hostname_list(struct main_args *margs, struct hstruct **hlist, int nhosts, char *name) +size_t +get_hostname_list(struct hstruct **hlist, size_t nhosts, char *name) { - /* - * char host[sysconf(_SC_HOST_NAME_MAX)]; - */ - char host[1024]; struct addrinfo *hres = NULL, *hres_list; int rc, count; struct hstruct *hp = NULL; @@ -194,6 +186,10 @@ hres_list = hres; count = 0; while (hres_list) { + /* + * char host[sysconf(_SC_HOST_NAME_MAX)]; + */ + char host[1024]; rc = getnameinfo(hres_list->ai_addr, hres_list->ai_addrlen, host, sizeof(host), NULL, 0, 0); if (rc != 0) { error((char *) "%s| %s: ERROR: Error while resolving ip address with getnameinfo: %s\n", LogTime(), PROGRAM, gai_strerror(rc)); @@ -219,24 +215,21 @@ return (nhosts); } -int -get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, int nh, char *domain) +size_t +get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, size_t nh, char *domain) { /* * char name[sysconf(_SC_HOST_NAME_MAX)]; */ char name[1024]; - char host[NS_MAXDNAME]; char *service = NULL; struct hstruct *hp = NULL; struct lsstruct *ls = NULL; - int nhosts = 0; + size_t nhosts = 0; int size; - int type, rdlength; - int priority, weight, port; int len, olen; - int i, j, k; + size_t i, j, k; u_char *buffer = NULL; u_char *p; @@ -305,7 +298,7 @@ } if (len > PACKETSZ_MULT * NS_PACKETSZ) { olen = len; - buffer = (u_char *) xrealloc(buffer, len); + buffer = (u_char *) xrealloc(buffer, (size_t)len); if ((len = res_search(service, ns_c_in, ns_t_srv, (u_char *) buffer, len)) < 0) { error((char *) "%s| %s: ERROR: Error while resolving service record %s with res_search\n", LogTime(), PROGRAM, service); nsError(h_errno, service); @@ -322,7 +315,7 @@ error((char *) "%s| %s: ERROR: Message to small: %d < header size\n", LogTime(), PROGRAM, len); goto finalise; } - if ((size = dn_expand(buffer, buffer + len, p, name, sysconf(_SC_HOST_NAME_MAX))) < 0) { + if ((size = dn_expand(buffer, buffer + len, p, name, sizeof(name))) < 0) { error((char *) "%s| %s: ERROR: Error while expanding query name with dn_expand: %s\n", LogTime(), PROGRAM, strerror(errno)); goto finalise; } @@ -333,7 +326,8 @@ goto finalise; } while (p < buffer + len) { - if ((size = dn_expand(buffer, buffer + len, p, name, sysconf(_SC_HOST_NAME_MAX))) < 0) { + int type, rdlength; + if ((size = dn_expand(buffer, buffer + len, p, name, sizeof(name))) < 0) { error((char *) "%s| %s: ERROR: Error while expanding answer name with dn_expand: %s\n", LogTime(), PROGRAM, strerror(errno)); goto finalise; } @@ -351,6 +345,8 @@ NS_GET16(rdlength, p); /* RR data length (16bit) */ if (type == ns_t_srv) { /* SRV record */ + int priority, weight, port; + char host[NS_MAXDNAME]; if (p > buffer + len) { error((char *) "%s| %s: ERROR: Message to small: %d < header + query name,type,class + answer name + RR type,class,ttl + RR data length\n", LogTime(), PROGRAM, len); goto finalise; @@ -400,7 +396,7 @@ } finalise: - nhosts = get_hostname_list(margs, &hp, nh, domain); + nhosts = get_hostname_list(&hp, nh, domain); debug("%s| %s: DEBUG: Adding %s to list\n", LogTime(), PROGRAM, domain); @@ -435,7 +431,7 @@ } /* Sort by Priority / Weight */ - msort(hp, nhosts, compare_hosts); + msort(hp, (size_t)nhosts, compare_hosts); if (debug_enabled) { debug((char *) "%s| %s: DEBUG: Sorted ldap server names for domain %s:\n", LogTime(), PROGRAM, domain); @@ -443,9 +439,7 @@ debug((char *) "%s| %s: DEBUG: Host: %s Port: %d Priority: %d Weight: %d\n", LogTime(), PROGRAM, hp[i].host, hp[i].port, hp[i].priority, hp[i].weight); } } - if (buffer) xfree(buffer); - if (service) xfree(service); *hlist = hp; return (nhosts); diff -rubwBEN 3.4/helpers/external_acl/kerberos_ldap_group/support_sasl.cc 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_sasl.cc --- 3.4/helpers/external_acl/kerberos_ldap_group/support_sasl.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/external_acl/kerberos_ldap_group/support_sasl.cc 2013-09-21 21:22:39.146008258 +0100 @@ -196,17 +196,11 @@ { lutilSASLdefaults *defs = (lutilSASLdefaults *) defaults; - if (defs->mech) xfree(defs->mech); - if (defs->realm) xfree(defs->realm); - if (defs->authcid) xfree(defs->authcid); - if (defs->passwd) xfree(defs->passwd); - if (defs->authzid) xfree(defs->authzid); - if (defs->resps) xfree(defs->resps); xfree(defs); diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/Makefile.am 3.4-mm/helpers/negotiate_auth/kerberos/Makefile.am --- 3.4/helpers/negotiate_auth/kerberos/Makefile.am 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/negotiate_auth/kerberos/Makefile.am 2013-09-21 21:21:03.306001925 +0100 @@ -7,7 +7,7 @@ AM_CPPFLAGS = $(INCLUDES) -I$(srcdir) -negotiate_kerberos_auth_SOURCES = negotiate_kerberos_auth.cc +negotiate_kerberos_auth_SOURCES = negotiate_kerberos_auth.cc negotiate_kerberos_pac.cc negotiate_kerberos_auth_LDFLAGS = negotiate_kerberos_auth_LDADD = \ $(top_builddir)/lib/libmiscencoding.la \ diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc --- 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc 2013-09-22 00:39:08.281787289 +0100 @@ -36,79 +36,7 @@ #if HAVE_GSSAPI -#if HAVE_STRING_H -#include -#endif -#if HAVE_STDOI_H -#include -#endif -#if HAVE_NETDB_H -#include -#endif -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_TIME_H -#include -#endif - -#include "util.h" -#include "base64.h" - -#if HAVE_GSSAPI_GSSAPI_H -#include -#elif HAVE_GSSAPI_H -#include -#endif - -#if !HAVE_HEIMDAL_KERBEROS -#if HAVE_GSSAPI_GSSAPI_KRB5_H -#include -#endif -#if HAVE_GSSAPI_GSSAPI_GENERIC_H -#include -#endif -#if HAVE_GSSAPI_GSSAPI_EXT_H -#include -#endif -#endif - -#ifndef gss_nt_service_name -#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE -#endif - -#define PROGRAM "negotiate_kerberos_auth" - -#ifndef MAX_AUTHTOKEN_LEN -#define MAX_AUTHTOKEN_LEN 65535 -#endif -#ifndef SQUID_KERB_AUTH_VERSION -#define SQUID_KERB_AUTH_VERSION "3.0.4sq" -#endif - -int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, - const char *function, int log); -char *gethost_name(void); -static const char *LogTime(void); - -static const unsigned char ntlmProtocol[] = {'N', 'T', 'L', 'M', 'S', 'S', 'P', 0}; - -static const char * -LogTime() -{ - struct tm *tm; - struct timeval now; - static time_t last_t = 0; - static char buf[128]; - - gettimeofday(&now, NULL); - if (now.tv_sec != last_t) { - tm = localtime((time_t *) & now.tv_sec); - strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm); - last_t = now.tv_sec; - } - return buf; -} +#include "negotiate_kerberos.h" char * gethost_name(void) @@ -155,7 +83,7 @@ int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, - const char *function, int log) + const char *function, int log, int sout) { if (GSS_ERROR(major_status)) { OM_uint32 maj_stat, min_stat; @@ -198,6 +126,7 @@ gss_release_buffer(&min_stat, &status_string); } while (msg_ctx); debug((char *) "%s| %s: ERROR: %s failed: %s\n", LogTime(), PROGRAM, function, buf); + if (sout) fprintf(stdout, "BH %s failed: %s\n", function, buf); if (log) fprintf(stderr, "%s| %s: INFO: User not authenticated\n", LogTime(), @@ -213,7 +142,20 @@ char buf[MAX_AUTHTOKEN_LEN]; char *c, *p; char *user = NULL; - int length = 0; + char *rfc_user = NULL; +#if HAVE_PAC_SUPPORT + char ad_groups[MAX_PAC_GROUP_SIZE]; + char *ag=NULL; + krb5_context context = NULL; + krb5_error_code ret; + krb5_pac pac; +#if HAVE_HEIMDAL_KERBEROS + gss_buffer_desc data_set = GSS_C_EMPTY_BUFFER; +#else + gss_buffer_desc type_id = GSS_C_EMPTY_BUFFER; +#endif +#endif + long length = 0; static int err = 0; int opt, log = 0, norealm = 0; OM_uint32 ret_flags = 0, spnego_flag = 0; @@ -284,6 +226,7 @@ snprintf((char *) service.value, strlen(service_name) + strlen(host_name) + 2, "%s@%s", service_name, host_name); service.length = strlen((char *) service.value); + xfree(host_name); } while (1) { @@ -312,7 +255,7 @@ err = 0; continue; } - debug((char *) "%s| %s: DEBUG: Got '%s' from squid (length: %d).\n", LogTime(), PROGRAM, buf, length); + debug((char *) "%s| %s: DEBUG: Got '%s' from squid (length: %ld).\n", LogTime(), PROGRAM, buf, length); if (buf[0] == '\0') { debug((char *) "%s| %s: ERROR: Invalid request\n", LogTime(), PROGRAM); @@ -338,23 +281,14 @@ if (kerberosToken) { /* Allocated by parseNegTokenInit, but no matching free function exists.. */ if (!spnego_flag) - xfree((char *) kerberosToken); - kerberosToken = NULL; + xfree(kerberosToken); } if (spnego_flag) { /* Allocated by makeNegTokenTarg, but no matching free function exists.. */ if (spnegoToken) - xfree((char *) spnegoToken); - spnegoToken = NULL; + xfree(spnegoToken); } - if (token) { xfree(token); - token = NULL; - } - if (host_name) { - xfree(host_name); - host_name = NULL; - } fprintf(stdout, "BH quit command\n"); exit(0); } @@ -373,12 +307,12 @@ fprintf(stdout, "BH Invalid negotiate request\n"); continue; } - input_token.length = base64_decode_len(buf+3); + input_token.length = (size_t)base64_decode_len(buf+3); debug((char *) "%s| %s: DEBUG: Decode '%s' (decoded length: %d).\n", LogTime(), PROGRAM, buf + 3, (int) input_token.length); input_token.value = xmalloc(input_token.length); - input_token.length = base64_decode((char *) input_token.value, input_token.length, buf+3); + input_token.length = (size_t)base64_decode((char *) input_token.value, (unsigned int)input_token.length, buf+3); if ((input_token.length >= sizeof ntlmProtocol + 1) && (!memcmp(input_token.value, ntlmProtocol, sizeof ntlmProtocol))) { @@ -399,19 +333,20 @@ } else { server_name = GSS_C_NO_NAME; major_status = GSS_S_COMPLETE; + minor_status = 0; } } else { major_status = gss_import_name(&minor_status, &service, gss_nt_service_name, &server_name); } - if (check_gss_err(major_status, minor_status, "gss_import_name()", log)) + if (check_gss_err(major_status, minor_status, "gss_import_name()", log, 1)) goto cleanup; major_status = gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_ACCEPT, &server_creds, NULL, NULL); - if (check_gss_err(major_status, minor_status, "gss_acquire_cred()", log)) + if (check_gss_err(major_status, minor_status, "gss_acquire_cred()", log, 1)) goto cleanup; major_status = gss_accept_sec_context(&minor_status, @@ -424,16 +359,16 @@ if (output_token.length) { spnegoToken = (const unsigned char *) output_token.value; spnegoTokenLength = output_token.length; - token = (char *) xmalloc(base64_encode_len(spnegoTokenLength)); + token = (char *) xmalloc((size_t)base64_encode_len((int)spnegoTokenLength)); if (token == NULL) { debug((char *) "%s| %s: ERROR: Not enough memory\n", LogTime(), PROGRAM); fprintf(stdout, "BH Not enough memory\n"); goto cleanup; } - base64_encode_str(token, base64_encode_len(spnegoTokenLength), - (const char *) spnegoToken, spnegoTokenLength); + base64_encode_str(token, base64_encode_len((int)spnegoTokenLength), + (const char *) spnegoToken, (int)spnegoTokenLength); - if (check_gss_err(major_status, minor_status, "gss_accept_sec_context()", log)) + if (check_gss_err(major_status, minor_status, "gss_accept_sec_context()", log, 1)) goto cleanup; if (major_status & GSS_S_CONTINUE_NEEDED) { debug((char *) "%s| %s: INFO: continuation needed\n", LogTime(), PROGRAM); @@ -445,7 +380,7 @@ gss_display_name(&minor_status, client_name, &output_token, NULL); - if (check_gss_err(major_status, minor_status, "gss_display_name()", log)) + if (check_gss_err(major_status, minor_status, "gss_display_name()", log, 1)) goto cleanup; user = (char *) xmalloc(output_token.length + 1); if (user == NULL) { @@ -458,14 +393,49 @@ if (norealm && (p = strchr(user, '@')) != NULL) { *p = '\0'; } + +#if HAVE_PAC_SUPPORT + ret = krb5_init_context(&context); + if (!check_k5_err(context, "krb5_init_context", ret)) { +#if HAVE_HEIMDAL_KERBEROS +#define ADWIN2KPAC 128 + major_status = gsskrb5_extract_authz_data_from_sec_context(&minor_status, + gss_context, ADWIN2KPAC, &data_set); + if (!check_gss_err(major_status, minor_status, + "gsskrb5_extract_authz_data_from_sec_context()", log, 0)) { + ret = krb5_pac_parse(context, data_set.value, data_set.length, &pac); + gss_release_buffer(&minor_status, &data_set); + if (!check_k5_err(context, "krb5_pac_parse", ret)) { + ag = get_ad_groups((char *)&ad_groups, context, pac); + krb5_pac_free(context, pac); + } + krb5_free_context(context); + } +#else + type_id.value = (void *)"mspac"; + type_id.length = strlen((char *)type_id.value); +#define KRB5PACLOGONINFO 1 + major_status = gss_map_name_to_any(&minor_status, client_name, KRB5PACLOGONINFO, &type_id, (gss_any_t *)&pac); + if (!check_gss_err(major_status, minor_status, "gss_map_name_to_any()", log, 0)) { + ag = get_ad_groups((char *)&ad_groups,context, pac); + } + (void)gss_release_any_name_mapping(&minor_status, client_name, &type_id, (gss_any_t *)&pac); + krb5_free_context(context); +#endif + } + if (ag) { + debug((char *) "%s| %s: DEBUG: Groups %s\n", LogTime(), PROGRAM, ag); + } +#endif fprintf(stdout, "AF %s %s\n", token, user); - debug((char *) "%s| %s: DEBUG: AF %s %s\n", LogTime(), PROGRAM, token, rfc1738_escape(user)); + rfc_user = rfc1738_escape(user); + debug((char *) "%s| %s: DEBUG: AF %s %s\n", LogTime(), PROGRAM, token, rfc_user); if (log) fprintf(stderr, "%s| %s: INFO: User %s authenticated\n", LogTime(), PROGRAM, rfc1738_escape(user)); goto cleanup; } else { - if (check_gss_err(major_status, minor_status, "gss_accept_sec_context()", log)) + if (check_gss_err(major_status, minor_status, "gss_accept_sec_context()", log, 1)) goto cleanup; if (major_status & GSS_S_CONTINUE_NEEDED) { debug((char *) "%s| %s: INFO: continuation needed\n", LogTime(), PROGRAM); @@ -477,7 +447,7 @@ gss_display_name(&minor_status, client_name, &output_token, NULL); - if (check_gss_err(major_status, minor_status, "gss_display_name()", log)) + if (check_gss_err(major_status, minor_status, "gss_display_name()", log, 1)) goto cleanup; /* * Return dummy token AA. May need an extra return tag then AF @@ -511,23 +481,15 @@ if (kerberosToken) { /* Allocated by parseNegTokenInit, but no matching free function exists.. */ if (!spnego_flag) - xfree((char *) kerberosToken); - kerberosToken = NULL; + safe_free(kerberosToken); } if (spnego_flag) { /* Allocated by makeNegTokenTarg, but no matching free function exists.. */ if (spnegoToken) - xfree((char *) spnegoToken); - spnegoToken = NULL; - } - if (token) { - xfree(token); - token = NULL; - } - if (user) { - xfree(user); - user = NULL; + safe_free(spnegoToken); } + safe_free(token); + safe_free(user); continue; } } diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc --- 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc 2013-09-22 00:39:15.520787767 +0100 @@ -196,9 +196,9 @@ goto cleanup; if (output_token.length) { - token = (char *) xmalloc(base64_encode_len(output_token.length)); - base64_encode_str(token, base64_encode_len(output_token.length), - (const char *) output_token.value, output_token.length); + token = (char *) xmalloc((size_t)base64_encode_len((int)output_token.length)); + base64_encode_str(token, base64_encode_len((int)output_token.length), + (const char *) output_token.value, (int)output_token.length); } cleanup: gss_delete_sec_context(&minor_status, &gss_context, NULL); diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos.h 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos.h --- 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos.h 1970-01-01 01:00:00.000000000 +0100 +++ 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos.h 2013-09-22 00:38:53.197786292 +0100 @@ -0,0 +1,156 @@ +/* + * ----------------------------------------------------------------------------- + * + * Author: Markus Moeller (markus_moeller at compuserve.com) + * + * Copyright (C) 2013 Markus Moeller. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exemption, M Moeller gives permission to link this program + * with MIT, Heimdal or other GSS/Kerberos libraries, and distribute + * the resulting executable, without including the source code for + * the Libraries in the source distribution. + * + * ----------------------------------------------------------------------------- + */ + +#if HAVE_STRING_H +#include +#endif +#if HAVE_STDIO_H +#include +#endif +#if HAVE_NETDB_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_TIME_H +#include +#endif + +#include "util.h" +#include "base64.h" + +#if HAVE_KRB5_H +#if HAVE_BROKEN_SOLARIS_KRB5_H +#warn "Warning! You have a broken Solaris system header" +#warn "http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6837512" +#if defined(__cplusplus) +#define KRB5INT_BEGIN_DECLS extern "C" { +#define KRB5INT_END_DECLS +KRB5INT_BEGIN_DECLS +#endif +#endif /* HAVE_BROKEN_SOLARIS_KRB5_H */ +#if HAVE_BROKEN_HEIMDAL_KRB5_H +extern "C" { +#include +} +#else +#include +#endif +#endif /* HAVE_KRB5_H */ + +#if HAVE_GSSAPI_GSSAPI_H +#include +#elif HAVE_GSSAPI_H +#include +#endif + +#if !HAVE_HEIMDAL_KERBEROS +#if HAVE_GSSAPI_GSSAPI_KRB5_H +#include +#endif +#if HAVE_GSSAPI_GSSAPI_GENERIC_H +#include +#endif +#if HAVE_GSSAPI_GSSAPI_EXT_H +#include +#endif +#else +#if HAVE_GSSAPI_GSSAPI_KRB5_H +#include +#endif +#endif + +#ifndef gss_nt_service_name +#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE +#endif + +#define PROGRAM "negotiate_kerberos_auth" + +#ifndef MAX_AUTHTOKEN_LEN +#define MAX_AUTHTOKEN_LEN 65535 +#endif +#ifndef SQUID_KERB_AUTH_VERSION +#define SQUID_KERB_AUTH_VERSION "3.0.4sq" +#endif + +char *gethost_name(void); + +static const char *LogTime(void); + +static const unsigned char ntlmProtocol[] = {'N', 'T', 'L', 'M', 'S', 'S', 'P', 0}; + +static const char * +LogTime() +{ + struct tm *tm; + struct timeval now; + static time_t last_t = 0; + static char buf[128]; + + gettimeofday(&now, NULL); + if (now.tv_sec != last_t) { + tm = localtime((time_t *) & now.tv_sec); + strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm); + last_t = now.tv_sec; + } + return buf; +} + +int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, + const char *function, int log, int sout); + +char *gethost_name(void); + +#if (defined(HAVE_GSSKRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT) || defined(HAVE_GSS_MAP_NAME_TO_ANY)) && HAVE_KRB5_PAC +#define HAVE_PAC_SUPPORT 1 +#define MAX_PAC_GROUP_SIZE 200*60 +typedef struct { + uint16_t length; + uint16_t maxlength; + uint32_t pointer; +} RPC_UNICODE_STRING; + +int check_k5_err(krb5_context context, const char *msg, krb5_error_code code); +void align(int n); +void getustr(RPC_UNICODE_STRING *string); +char **getgids(char **Rids, uint32_t GroupIds, uint32_t GroupCount); +char *getdomaingids(char *ad_groups, uint32_t DomainLogonId, char **Rids, uint32_t GroupCount); +char *getextrasids(char *ad_groups, uint32_t ExtraSids, uint32_t SidCount); +uint64_t get6byt_be(void); +uint32_t get4byt(void); +uint16_t get2byt(void); +uint8_t get1byt(void); +char *xstrcpy( char *src, const char*dst); +char *xstrcat( char *src, const char*dst); +int checkustr(RPC_UNICODE_STRING *string); +char *get_ad_groups(char *ad_groups, krb5_context context, krb5_pac pac); +#else +#define HAVE_PAC_SUPPORT 0 +#endif diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc --- 3.4/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc 1970-01-01 01:00:00.000000000 +0100 +++ 3.4-mm/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc 2013-09-22 00:39:23.494788294 +0100 @@ -0,0 +1,455 @@ +/* + * ----------------------------------------------------------------------------- + * + * Author: Markus Moeller (markus_moeller at compuserve.com) + * + * Copyright (C) 2007 Markus Moeller. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exemption, M Moeller gives permission to link this program + * with MIT, Heimdal or other GSS/Kerberos libraries, and distribute + * the resulting executable, without including the source code for + * the Libraries in the source distribution. + * + * ----------------------------------------------------------------------------- + */ + +#include "squid.h" +#include "rfc1738.h" +#include "compat/getaddrinfo.h" +#include "compat/getnameinfo.h" + +#include "negotiate_kerberos.h" + +#if HAVE_PAC_SUPPORT + +static int bpos; +static krb5_data *ad_data; +static unsigned char *p; + +int +check_k5_err(krb5_context context, const char *function, krb5_error_code code) +{ + const char *errmsg; + + if (code) { + errmsg = krb5_get_error_message(context, code); + debug((char *) "%s| %s: ERROR: %s failed: %s\n", LogTime(), PROGRAM, function, errmsg); + fprintf(stderr, "%s| %s: ERROR: %s: %s\n", LogTime(), PROGRAM, function, errmsg); + krb5_free_error_message(context, errmsg); + } + return code; +} + +void +align(int n){ + if ( bpos % n != 0 ) { + int al; + al = (bpos/n); + bpos = bpos+(bpos-n*al); + } +} + +void +getustr(RPC_UNICODE_STRING *string) { + + string->length = (uint16_t)((p[bpos]<<0) | (p[bpos+1]<<8)); + string->maxlength = (uint16_t)((p[bpos+2]<<0) | (p[bpos+2+1]<<8)); + string->pointer = (uint32_t)((p[bpos+4]<<0) | (p[bpos+4+1]<<8) | (p[bpos+4+2]<<16) | (p[bpos+4+3]<<24)); + bpos = bpos+8; + +} + +uint64_t +get6byt_be(void) { + uint64_t var; + + var = ((uint64_t)p[bpos+5]<<0) | ((uint64_t)p[bpos+4]<<8) | ((uint64_t)p[bpos+3]<<16) | ((uint64_t)p[bpos+2]<<24) | ((uint64_t)p[bpos+1]<<32) | ((uint64_t)p[bpos]<<40); + bpos = bpos+6; + + return var; +} + +uint32_t +get4byt(void) { + uint32_t var; + + var=(uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24)); + bpos = bpos+4; + + return var; +} + +uint16_t +get2byt(void) { + uint16_t var; + + var=(uint16_t)((p[bpos]<<0) | (p[bpos+1]<<8)); + bpos = bpos+2; + + return var; +} + +uint8_t +get1byt(void) { + uint8_t var; + + var=(uint8_t)((p[bpos]<<0)); + bpos = bpos+1; + + return var; +} + +char * +xstrcpy( char *src, const char *dst) { + if (dst) { + if (strlen(dst)>MAX_PAC_GROUP_SIZE) + return NULL; + else + return strcpy(src,dst); + } else + return src; +} + +char * +xstrcat( char *src, const char *dst) { + if (dst) { + if (strlen(src)+strlen(dst)+1>MAX_PAC_GROUP_SIZE) + return NULL; + else + return strcat(src,dst); + } else + return src; +} + + +int +checkustr(RPC_UNICODE_STRING *string) { + uint32_t size,off,len; + + if (string->pointer != 0){ + align(4); + size = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24)); + bpos = bpos+4; + off = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24)); + bpos = bpos+4; + len = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24)); + bpos = bpos+4; + if (len > size || off != 0 || + string->length > string->maxlength || len != string->length/2) { + debug((char *) "%s| %s: ERROR: RPC_UNICODE_STRING encoding error => size: %d len: %d/%d maxlength: %d offset: %d\n", + LogTime(), PROGRAM, size, len, string->length, string->maxlength, off); + return -1; + } + /* UNICODE string */ + bpos = bpos+string->length; + } + return 0; +} + +char ** +getgids(char **Rids, uint32_t GroupIds, uint32_t GroupCount) { + if (GroupIds!= 0){ + uint32_t ngroup; + uint32_t sauth; + int l; + + align(4); + ngroup = get4byt(); + if ( ngroup != GroupCount) { + debug((char *) "%s| %s: ERROR: Group encoding error => GroupCount: %d Array size: %d\n", + LogTime(), PROGRAM, GroupCount, ngroup); + return NULL; + } + debug((char *) "%s| %s: INFO: Found %d rids\n", LogTime(), PROGRAM, GroupCount); + + Rids=(char **)xcalloc(GroupCount*sizeof(char*),1); + for ( l=0; l<(int)GroupCount; l++) { + Rids[l]=(char *)xcalloc(4*sizeof(char),1); + memcpy((void *)Rids[l],(void *)&p[bpos],4); + sauth = get4byt(); + debug((char *) "%s| %s: Info: Got rid: %u\n", LogTime(), PROGRAM, sauth); + /* attribute */ + bpos = bpos+4; + } + } + return Rids; +} + +char * +getdomaingids(char *ad_groups, uint32_t DomainLogonId, char **Rids, uint32_t GroupCount) { + if (DomainLogonId!= 0) { + uint32_t nauth; + uint8_t rev; + uint64_t idauth; + uint32_t sauth; + char dli[256]; + char *ag; + size_t length; + int l; + + align(4); + + nauth = get4byt(); + + /* prepend rids with DomainID */ + length=1+1+6+nauth*4; + for (l=0; l<(int)GroupCount;l++){ + ag=(char *)xcalloc((length+4)*sizeof(char),1); + memcpy((void *)ag,(const void*)&p[bpos],1); + memcpy((void *)&ag[1],(const void*)&p[bpos+1],1); + ag[1] = ag[1]+1; + memcpy((void *)&ag[2],(const void*)&p[bpos+2],6+nauth*4); + memcpy((void *)&ag[length],(const void*)Rids[l],4); + if (l==0) { + if (!xstrcpy(ad_groups,"group=")) { + debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", + LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups); + } + } else { + if (!xstrcat(ad_groups," group=")) { + debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", + LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups); + } + } + if (!xstrcat(ad_groups,base64_encode_bin(ag, (int)(length+4)))) { + debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", + LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups); + } + xfree(ag); + } + + /* mainly for debug only */ + rev = get1byt(); + bpos = bpos + 1; /*nsub*/ + idauth = get6byt_be(); + + snprintf(dli,sizeof(dli),"S-%d-%lu",rev,(long unsigned int)idauth); + for ( l=0;l<(int)nauth;l++ ) { + sauth = get4byt(); + snprintf((char *)&dli[strlen(dli)],sizeof(dli)-strlen(dli),"-%u",sauth); + } + debug((char *) "%s| %s: INFO: Got DomainLogonId %s\n", LogTime(), PROGRAM, dli); + } + return ad_groups; +} + +char * +getextrasids(char *ad_groups, uint32_t ExtraSids, uint32_t SidCount) { + if (ExtraSids!= 0){ + uint32_t ngroup; + uint32_t *pa; + char *ag; + size_t length; + int l; + + align(4); + ngroup = get4byt(); + if ( ngroup != SidCount) { + debug((char *) "%s| %s: ERROR: Group encoding error => SidCount: %d Array size: %d\n", + LogTime(), PROGRAM, SidCount, ngroup); + return NULL; + } + debug((char *) "%s| %s: INFO: Found %d ExtraSIDs\n", LogTime(), PROGRAM, SidCount); + + pa=(uint32_t *)xmalloc(SidCount*sizeof(uint32_t)); + for ( l=0; l < (int)SidCount; l++ ){ + pa[l] = get4byt(); + bpos = bpos+4; /* attr */ + } + + for ( l=0; l<(int)SidCount; l++ ){ + char es[256]; + uint32_t nauth; + uint8_t rev; + uint64_t idauth; + uint32_t sauth; + int k; + + if (pa[l] != 0){ + nauth = get4byt(); + + length = 1+1+6+nauth*4; + ag = (char *)xcalloc((length)*sizeof(char),1); + memcpy((void *)ag,(const void*)&p[bpos],length); + if (!ad_groups) { + if (!xstrcpy(ad_groups,"group=")) { + debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", + LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups); + } + } else { + if (!xstrcat(ad_groups," group=")) { + debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", + LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups); + } + } + if (!xstrcat(ad_groups,base64_encode_bin(ag, (int)length))) { + debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", + LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups); + } + xfree(ag); + + rev = get1byt(); + bpos = bpos + 1; /* nsub */ + idauth = get6byt_be(); + + snprintf(es,sizeof(es),"S-%d-%lu",rev,(long unsigned int)idauth); + for ( k=0;k<(int)nauth;k++ ) { + sauth = get4byt(); + snprintf((char *)&es[strlen(es)],sizeof(es)-strlen(es),"-%u",sauth); + } + debug((char *) "%s| %s: INFO: Got ExtraSid %s\n", LogTime(), PROGRAM, es); + } + } + xfree(pa); + } + return ad_groups; +} + +char * +get_ad_groups(char *ad_groups, krb5_context context, krb5_pac pac){ + krb5_error_code ret; + RPC_UNICODE_STRING EffectiveName; + RPC_UNICODE_STRING FullName; + RPC_UNICODE_STRING LogonScript; + RPC_UNICODE_STRING ProfilePath; + RPC_UNICODE_STRING HomeDirectory; + RPC_UNICODE_STRING HomeDirectoryDrive; + RPC_UNICODE_STRING LogonServer; + RPC_UNICODE_STRING LogonDomainName; + uint32_t GroupCount=0; + uint32_t GroupIds=0; + uint32_t LogonDomainId=0; + uint32_t SidCount=0; + uint32_t ExtraSids=0; + /* + uint32_t ResourceGroupDomainSid=0; + uint32_t ResourceGroupCount=0; + uint32_t ResourceGroupIds=0; + */ + char **Rids=NULL; + int l=0; + + ad_data = (krb5_data *)xmalloc(sizeof(krb5_data)); + +#define KERB_LOGON_INFO 1 + ret = krb5_pac_get_buffer(context, pac, KERB_LOGON_INFO, ad_data); + if (check_k5_err(context, "krb5_pac_get_buffer", ret)) + goto k5clean; + + p = (unsigned char *)ad_data->data; + + debug((char *) "%s| %s: INFO: Got PAC data of lengh %d\n", + LogTime(), PROGRAM, (int)ad_data->length); + + /* Skip 16 bytes icommon RPC header + * Skip 4 bytes RPC unique pointer referent + * http://msdn.microsoft.com/en-gb/library/cc237933.aspx + */ + /* Some data are pointers to data which follows the main KRB5 LOGON structure => + * So need to read the data + * some logical consistency checks are done when analysineg the pointer data + */ + bpos = 20; + /* 8 bytes LogonTime + * 8 bytes LogoffTime + * 8 bytes KickOffTime + * 8 bytes PasswordLastSet + * 8 bytes PasswordCanChange + * 8 bytes PasswordMustChange + */ + bpos = bpos+48; + getustr(&EffectiveName); + getustr(&FullName); + getustr(&LogonScript); + getustr(&ProfilePath); + getustr(&HomeDirectory); + getustr(&HomeDirectoryDrive); + /* 2 bytes LogonCount + * 2 bytes BadPasswordCount + * 4 bytes UserID + * 4 bytes PrimaryGroupId + */ + bpos = bpos+12; + GroupCount = get4byt(); + GroupIds = get4byt(); + /* 4 bytes UserFlags + * 16 bytes UserSessionKey + */ + bpos = bpos+20; + getustr(&LogonServer); + getustr(&LogonDomainName); + LogonDomainId = get4byt(); + /* 8 bytes Reserved1 + * 4 bytes UserAccountControl + * 4 bytes SubAuthStatus + * 8 bytes LastSuccessfullLogon + * 8 bytes LastFailedLogon + * 4 bytes FailedLogonCount + * 4 bytes Reserved2 + */ + bpos = bpos+40; + SidCount = get4byt(); + ExtraSids = get4byt(); + /* 4 bytes ResourceGroupDomainSid + * 4 bytes ResourceGroupCount + * 4 bytes ResourceGroupIds + */ + bpos = bpos+12; + /* + * Read all data from structure => Now check pointers + */ + if (checkustr(&EffectiveName)<0) + goto k5clean; + if (checkustr(&FullName)<0) + goto k5clean; + if (checkustr(&LogonScript)<0) + goto k5clean; + if (checkustr(&ProfilePath)<0) + goto k5clean; + if (checkustr(&HomeDirectory)<0) + goto k5clean; + if (checkustr(&HomeDirectoryDrive)<0) + goto k5clean; + Rids = getgids(Rids,GroupIds,GroupCount); + if (checkustr(&LogonServer)<0) + goto k5clean; + if (checkustr(&LogonDomainName)<0) + goto k5clean; + ad_groups = getdomaingids(ad_groups,LogonDomainId,Rids,GroupCount); + if ((ad_groups = getextrasids(ad_groups,ExtraSids,SidCount))==NULL) + goto k5clean; + + debug((char *) "%s| %s: INFO: Read %d of %d bytes \n", LogTime(), PROGRAM, bpos, (int)ad_data->length); + if (Rids) { + for ( l=0; l<(int)GroupCount; l++) { + xfree(Rids[l]); + } + xfree(Rids); + } + krb5_free_data(context, ad_data); + return ad_groups; +k5clean: + if (Rids) { + for ( l=0; l<(int)GroupCount; l++) { + xfree(Rids[l]); + } + xfree(Rids); + } + krb5_free_data(context, ad_data); + return NULL; +} +#endif diff -rubwBEN 3.4/helpers/negotiate_auth/kerberos/test_negotiate_auth.sh 3.4-mm/helpers/negotiate_auth/kerberos/test_negotiate_auth.sh --- 3.4/helpers/negotiate_auth/kerberos/test_negotiate_auth.sh 1970-01-01 01:00:00.000000000 +0100 +++ 3.4-mm/helpers/negotiate_auth/kerberos/test_negotiate_auth.sh 2013-09-21 21:23:25.897011347 +0100 @@ -0,0 +1,7 @@ +#!/bin/bash +if [[ -z "$1" ]]; then + echo "Need squid hostname" + exit 0 +fi +dir=`dirname $0` +$dir/negotiate_kerberos_auth_test $1 | awk '{sub(/Token:/,"YR"); print $0}END{print "QQ"}' | $dir/negotiate_kerberos_auth -d diff -rubwBEN 3.4/src/peer_proxy_negotiate_auth.cc 3.4-mm/src/peer_proxy_negotiate_auth.cc --- 3.4/src/peer_proxy_negotiate_auth.cc 2013-08-26 22:02:02.226038000 +0100 +++ 3.4-mm/src/peer_proxy_negotiate_auth.cc 2013-09-21 21:20:41.093000457 +0100 @@ -210,21 +210,29 @@ static krb5_keytab_entry entry; static krb5_kt_cursor cursor; static krb5_creds *creds = NULL; -#if HAVE_HEIMDAL_KERBEROS +#if defined(HAVE_HEIMDAL_KERBEROS) && !defined(HAVE_KRB5_GET_RENEWED_CREDS) static krb5_creds creds2; #endif static krb5_principal principal = NULL; static krb5_deltat skew; +#if HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC + krb5_get_init_creds_opt *options; +#else krb5_get_init_creds_opt options; +#endif krb5_error_code code = 0; krb5_deltat rlife; #if HAVE_PROFILE_H && HAVE_KRB5_GET_PROFILE && HAVE_PROFILE_GET_INTEGER && HAVE_PROFILE_RELEASE profile_t profile; #endif -#if HAVE_HEIMDAL_KERBEROS +#if defined(HAVE_HEIMDAL_KERBEROS) && !defined(HAVE_KRB5_GET_RENEWED_CREDS) krb5_kdc_flags flags; - krb5_realm *client_realm; +#if HAVE_KRB5_PRINCIPAL_GET_REALM + const char *client_realm; +#else + krb5_realm client_realm; +#endif #endif char *mem_cache; @@ -236,7 +244,7 @@ (creds->times.endtime - time(0) > skew) && (creds->times.renew_till - time(0) > 2 * skew)) { if (creds->times.endtime - time(0) < 2 * skew) { -#if !HAVE_HEIMDAL_KERBEROS +#if HAVE_KRB5_GET_RENEWED_CREDS /* renew ticket */ code = krb5_get_renewed_creds(kparam.context, creds, principal, @@ -256,10 +264,15 @@ << error_message(code)); return (1); } +#if HAVE_KRB5_PRINCIPAL_GET_REALM + client_realm = krb5_principal_get_realm(kparam.context, principal); +#else client_realm = krb5_princ_realm(kparam.context, creds2.client); +#endif code = krb5_make_principal(kparam.context, &creds2.server, - *client_realm, KRB5_TGS_NAME, *client_realm, NULL); + (krb5_const_realm)&client_realm, KRB5_TGS_NAME, + (krb5_const_realm)&client_realm, NULL); if (code) { debugs(11, 5, HERE << "Error while getting krbtgt principal : " << @@ -400,7 +413,11 @@ creds = (krb5_creds *) xmalloc(sizeof(*creds)); memset(creds, 0, sizeof(*creds)); +#if HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC + krb5_get_init_creds_opt_alloc(kparam.context, &options); +#else krb5_get_init_creds_opt_init(&options); +#endif code = krb5_string_to_deltat((char *) MAX_RENEW_TIME, &rlife); if (code != 0 || rlife == 0) { debugs(11, 5, @@ -408,8 +425,18 @@ " : " << error_message(code)); return (1); } +#if HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC + krb5_get_init_creds_opt_set_renew_life(options, rlife); + code = + krb5_get_init_creds_keytab(kparam.context, creds, principal, + keytab, 0, NULL, options); +#if HAVE_KRB5_GET_INIT_CREDS_FREE_CONTEXT + krb5_get_init_creds_opt_free(kparam.context, options); +#else + krb5_get_init_creds_opt_free(options); +#endif +#else krb5_get_init_creds_opt_set_renew_life(&options, rlife); - code = krb5_get_init_creds_keytab(kparam.context, creds, principal, keytab, 0, NULL, &options); @@ -413,6 +440,7 @@ code = krb5_get_init_creds_keytab(kparam.context, creds, principal, keytab, 0, NULL, &options); +#endif if (code) { debugs(11, 5, HERE <<