------------------------------------------------------------ revno: 13595 revision-id: squid3@treenet.co.nz-20140917132107-qegw7ryzw84878bk parent: squid3@treenet.co.nz-20140915132934-d92d9900538htbq5 author: Markus Moeller committer: Amos Jeffries branch nick: trunk timestamp: Wed 2014-09-17 06:21:07 -0700 message: Fix various Kerberos issues * Fix error_message detection and use. * Fix library detection * Fix spelling typo * Change handling of principals in keytab for kerberos_ldap_group. ------------------------------------------------------------ # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: squid3@treenet.co.nz-20140917132107-qegw7ryzw84878bk # target_branch: http://bzr.squid-cache.org/bzr/squid3/trunk/ # testament_sha1: 41754fd30973c91bd1c48dc22f996b7612a67d0b # timestamp: 2014-09-17 13:27:15 +0000 # source_branch: http://bzr.squid-cache.org/bzr/squid3/trunk/ # base_revision_id: squid3@treenet.co.nz-20140915132934-\ # d92d9900538htbq5 # # Begin patch === modified file 'acinclude/krb5.m4' --- acinclude/krb5.m4 2014-09-02 01:08:58 +0000 +++ acinclude/krb5.m4 2014-09-17 13:21:07 +0000 @@ -248,12 +248,35 @@ dnl checks for existence of krb5 functions AC_DEFUN([SQUID_CHECK_KRB5_FUNCS],[ + ac_com_error_message=no + if test "x$ac_cv_header_com_err_h" = "xyes" ; then + AC_EGREP_HEADER(error_message,com_err.h,ac_com_error_message=yes) + elif test "x$ac_cv_header_et_com_err_h" = "xyes" ; then + AC_EGREP_HEADER(error_message,et/com_err.h,ac_com_error_message=yes) + fi + + if test `echo $KRB5LIBS | grep -c com_err` -ne 0 -a "x$ac_com_error_message" = "xyes" ; then + AC_CHECK_LIB(com_err,error_message, + AC_DEFINE(HAVE_ERROR_MESSAGE,1, + [Define to 1 if you have error_message]),) + elif test "x$ac_com_error_message" = "xyes" ; then + AC_CHECK_LIB(krb5,error_message, + AC_DEFINE(HAVE_ERROR_MESSAGE,1, + [Define to 1 if you have error_message]),) + fi + AC_CHECK_LIB(krb5,krb5_get_err_text, AC_DEFINE(HAVE_KRB5_GET_ERR_TEXT,1, [Define to 1 if you have krb5_get_err_text]),) AC_CHECK_LIB(krb5,krb5_get_error_message, AC_DEFINE(HAVE_KRB5_GET_ERROR_MESSAGE,1, [Define to 1 if you have krb5_get_error_message]),) + AC_CHECK_LIB(krb5,krb5_free_error_message, + AC_DEFINE(HAVE_KRB5_FREE_ERROR_MESSAGE,1, + [Define to 1 if you have krb5_free_error_message]),) + AC_CHECK_LIB(krb5,krb5_free_error_string, + AC_DEFINE(HAVE_KRB5_FREE_ERROR_STRING,1, + [Define to 1 if you have krb5_free_error_string]),) AC_CHECK_DECLS(krb5_kt_free_entry,,,[#include ]) AC_CHECK_TYPE(krb5_pac, AC_DEFINE(HAVE_KRB5_PAC,1, @@ -297,7 +320,6 @@ 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]),) === modified file 'configure.ac' --- configure.ac 2014-09-14 14:15:01 +0000 +++ configure.ac 2014-09-17 13:21:07 +0000 @@ -1513,19 +1513,24 @@ ## For some OS pkg-config is broken or unavailable. ## Detect libraries the hard way. + SQUID_STATE_SAVE([squid_mit_save]) AC_MSG_NOTICE([Try to find Kerberos libraries in given path]) AC_CHECK_LIB(com_err, [main], [LIB_KRB5_LIBS="-lcom_err $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'com_err' is required for MIT Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(k5crypto, [main], [LIB_KRB5_LIBS="-lk5crypto $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'k5crypto' is required for MIT Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(krb5, [main], [LIB_KRB5_LIBS="-lkrb5 $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'krb5' is required for MIT Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(gssapi_krb5, [main], [LIB_KRB5_LIBS="-lgssapi_krb5 $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'gssapi_krb5' is required for MIT Kerberos]) ]) + SQUID_STATE_ROLLBACK([squid_mit_save]) fi ]) @@ -1546,16 +1551,6 @@ AC_CHECK_HEADERS(krb5.h com_err.h et/com_err.h) AC_CHECK_HEADERS(profile.h) - if test `echo $KRB5LIBS | grep -c com_err` -ne 0 -a "x$ac_com_error_message" = "xyes" ; then - AC_CHECK_LIB(com_err,error_message, - AC_DEFINE(HAVE_ERROR_MESSAGE,1, - [Define to 1 if you have error_message]),) - elif test "x$ac_com_error_message" = "xyes" ; then - AC_CHECK_LIB(krb5,error_message, - AC_DEFINE(HAVE_ERROR_MESSAGE,1, - [Define to 1 if you have error_message]),) - fi - SQUID_CHECK_KRB5_FUNCS fi @@ -1596,13 +1591,16 @@ CXXFLAGS="-I/usr/include/kerberosv5 $CXXFLAGS" + SQUID_STATE_SAVE([squid_solaris_save]) AC_MSG_NOTICE([Try to find Kerberos libraries in given path]) AC_CHECK_LIB(krb5, [main], [LIB_KRB5_LIBS="-lkrb5 $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'krb5' is required for Solaris Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(gss, [main], [LIB_KRB5_LIBS="-lgss $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'gss' is required for Solaris Kerberos]) ]) + SQUID_STATE_ROLLBACK([squid_solaris_save]) fi if test "x$LIB_KRB5_LIBS" != "x"; then @@ -1666,44 +1664,57 @@ else ## For some OS pkg-config is broken or unavailable. ## Detect libraries the hard way. + SQUID_STATE_SAVE([squid_heimdal_save]) AC_MSG_NOTICE([Try to find Kerberos libraries in given path]) AC_CHECK_LIB(resolv, [main], [LIB_KRB5_LIBS="-lresolv $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'resolv' is required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(crypt, [main], [LIB_KRB5_LIBS="-lcrypt $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'crypt' is required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(roken, [main], [LIB_KRB5_LIBS="-lroken $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'roken' is required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(heimbase, [main], [LIB_KRB5_LIBS="-lheimbase $LIB_KRB5_LIBS"],[ AC_MSG_WARN([library 'heimbase' may be required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(wind, [main], [LIB_KRB5_LIBS="-lwind $LIB_KRB5_LIBS"],[ AC_MSG_WARN([library 'wind' may be required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(crypto, [main], [LIB_KRB5_LIBS="-lcrypto $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'crypto' is required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(com_err, [main], [LIB_KRB5_LIBS="-lcom_err $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'com_err' is required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(hx509, [main], [LIB_KRB5_LIBS="-lhx509 $LIB_KRB5_LIBS"],[ AC_MSG_WARN([library 'hx509' may be required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(asn1, [main], [LIB_KRB5_LIBS="-lasn1 $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'asn1' is required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(krb5, [main], [LIB_KRB5_LIBS="-lkrb5 $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'krb5' is required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(heimntlm, [main], [LIB_KRB5_LIBS="-lheimntlm $LIB_KRB5_LIBS"],[ AC_MSG_WARN([library 'heimntlm' may be required for Heimdal Kerberos]) ]) + LIBS=$LIB_KRB5_LIBS AC_CHECK_LIB(gssapi, [main], [LIB_KRB5_LIBS="-lgssapi $LIB_KRB5_LIBS"],[ AC_MSG_ERROR([library 'gssapi' is required for Heimdal Kerberos]) ]) + SQUID_STATE_ROLLBACK([squid_heimdal_save]) fi ]) @@ -1726,16 +1737,6 @@ AC_DEFINE(HAVE_BROKEN_HEIMDAL_KRB5_H, 1, [Define to 1 if Heimdal krb5.h is broken for C++]) fi - if test `echo $KRB5LIBS | grep -c com_err` -ne 0 -a "x$ac_com_error_message" = "xyes" ; then - AC_CHECK_LIB(com_err,error_message, - AC_DEFINE(HAVE_ERROR_MESSAGE,1, - [Define to 1 if you have error_message]),) - elif test "x$ac_com_error_message" = "xyes" ; then - AC_CHECK_LIB(krb5,error_message, - AC_DEFINE(HAVE_ERROR_MESSAGE,1, - [Define to 1 if you have error_message]),) - fi - SQUID_CHECK_KRB5_FUNCS fi === modified file 'helpers/external_acl/kerberos_ldap_group/support_krb5.cc' --- helpers/external_acl/kerberos_ldap_group/support_krb5.cc 2014-09-13 13:31:49 +0000 +++ helpers/external_acl/kerberos_ldap_group/support_krb5.cc 2014-09-17 13:21:07 +0000 @@ -91,6 +91,25 @@ goto cleanup; } /* + * prepare memory credential cache + */ +#if !HAVE_KRB5_MEMORY_CACHE || HAVE_SUN_LDAP_SDK + mem_cache = (char *) xmalloc(strlen("FILE:/tmp/squid_ldap_") + 16); + snprintf(mem_cache, strlen("FILE:/tmp/squid_ldap_") + 16, "FILE:/tmp/squid_ldap_%d", (int) getpid()); +#else + mem_cache = (char *) xmalloc(strlen("MEMORY:squid_ldap_") + 16); + snprintf(mem_cache, strlen("MEMORY:squid_ldap_") + 16, "MEMORY:squid_ldap_%d", (int) getpid()); +#endif + + setenv("KRB5CCNAME", mem_cache, 1); + debug((char *) "%s| %s: DEBUG: Set credential cache to %s\n", LogTime(), PROGRAM, mem_cache); + code = krb5_cc_resolve(kparam.context, mem_cache, &kparam.cc); + if (code) { + error((char *) "%s| %s: ERROR: Error while resolving memory ccache : %s\n", LogTime(), PROGRAM, error_message(code)); + retval = 1; + goto cleanup; + } + /* * getting default keytab name */ @@ -151,8 +170,74 @@ retval = 1; break; } - if (found) + if (found) { + debug((char *) "%s| %s: DEBUG: Got principal name %s\n", LogTime(), PROGRAM, principal_name); + /* + * build principal + */ + code = krb5_parse_name(kparam.context, principal_name, &principal); + if (code) { + error((char *) "%s| %s: ERROR: Error while parsing name %s : %s\n", LogTime(), PROGRAM, principal_name, error_message(code)); + safe_free(principal_name); + if (principal) + krb5_free_principal(kparam.context, principal); + found = 0; + continue; + } + creds = (krb5_creds *) xcalloc(1,sizeof(*creds)); + + /* + * get credentials + */ +#if HAVE_GET_INIT_CREDS_KEYTAB + code = krb5_get_init_creds_keytab(kparam.context, creds, principal, keytab, 0, NULL, NULL); +#else + service = (char *) xmalloc(strlen("krbtgt") + 2 * strlen(domain) + 3); + 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); + xfree(service); + code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0); +#endif + + if (code) { + error((char *) "%s| %s: ERROR: Error while initialising credentials from keytab : %s\n", LogTime(), PROGRAM, error_message(code)); + safe_free(principal_name); + if (principal) + krb5_free_principal(kparam.context, principal); + if (creds) + krb5_free_creds(kparam.context, creds); + creds = NULL; + found = 0; + continue; + } + code = krb5_cc_initialize(kparam.context, kparam.cc, principal); + if (code) { + error((char *) "%s| %s: ERROR: Error while initializing memory caches : %s\n", LogTime(), PROGRAM, error_message(code)); + safe_free(principal_name); + if (principal) + krb5_free_principal(kparam.context, principal); + if (creds) + krb5_free_creds(kparam.context, creds); + creds = NULL; + found = 0; + continue; + } + code = krb5_cc_store_cred(kparam.context, kparam.cc, creds); + if (code) { + error((char *) "%s| %s: ERROR: Error while storing credentials : %s\n", LogTime(), PROGRAM, error_message(code)); + if (principal) + krb5_free_principal(kparam.context, principal); + safe_free(principal_name); + if (creds) + krb5_free_creds(kparam.context, creds); + creds = NULL; + found = 0; + continue; + } + debug((char *) "%s| %s: DEBUG: Stored credentials\n", LogTime(), PROGRAM); break; + } } if (code && code != KRB5_KT_END) { @@ -166,25 +251,7 @@ retval = 1; goto cleanup; } - /* - * prepare memory credential cache - */ -#if !HAVE_KRB5_MEMORY_CACHE || HAVE_SUN_LDAP_SDK - mem_cache = (char *) xmalloc(strlen("FILE:/tmp/squid_ldap_") + 16); - snprintf(mem_cache, strlen("FILE:/tmp/squid_ldap_") + 16, "FILE:/tmp/squid_ldap_%d", (int) getpid()); -#else - mem_cache = (char *) xmalloc(strlen("MEMORY:squid_ldap_") + 16); - snprintf(mem_cache, strlen("MEMORY:squid_ldap_") + 16, "MEMORY:squid_ldap_%d", (int) getpid()); -#endif - setenv("KRB5CCNAME", mem_cache, 1); - debug((char *) "%s| %s: DEBUG: Set credential cache to %s\n", LogTime(), PROGRAM, mem_cache); - code = krb5_cc_resolve(kparam.context, mem_cache, &kparam.cc); - if (code) { - error((char *) "%s| %s: ERROR: Error while resolving memory ccache : %s\n", LogTime(), PROGRAM, error_message(code)); - retval = 1; - goto cleanup; - } /* * if no principal name found in keytab for domain use the prinipal name which can get a TGT */ @@ -252,15 +319,17 @@ goto loop_end; } else { debug((char *) "%s| %s: DEBUG: Found trusted principal name: %s\n", LogTime(), PROGRAM, principal_name); + if (tgt_creds) + krb5_free_creds(kparam.context, tgt_creds); + tgt_creds = NULL; break; } loop_end: safe_free(principal_name); - if (tgt_creds) { + if (tgt_creds) krb5_free_creds(kparam.context, tgt_creds); - tgt_creds = NULL; - } + tgt_creds = NULL; if (creds) krb5_free_creds(kparam.context, creds); creds = NULL; @@ -271,53 +340,7 @@ krb5_free_creds(kparam.context, creds); creds = NULL; } - if (principal_name) { - - debug((char *) "%s| %s: DEBUG: Got principal name %s\n", LogTime(), PROGRAM, principal_name); - /* - * build principal - */ - code = krb5_parse_name(kparam.context, principal_name, &principal); - if (code) { - error((char *) "%s| %s: ERROR: Error while parsing name %s : %s\n", LogTime(), PROGRAM, principal_name, error_message(code)); - retval = 1; - goto cleanup; - } - creds = (krb5_creds *) xmalloc(sizeof(*creds)); - memset(creds, 0, sizeof(*creds)); - - /* - * get credentials - */ -#if HAVE_GET_INIT_CREDS_KEYTAB - code = krb5_get_init_creds_keytab(kparam.context, creds, principal, keytab, 0, NULL, NULL); -#else - service = (char *) xmalloc(strlen("krbtgt") + 2 * strlen(domain) + 3); - 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); - xfree(service); - code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0); -#endif - if (code) { - error((char *) "%s| %s: ERROR: Error while initialising credentials from keytab : %s\n", LogTime(), PROGRAM, error_message(code)); - retval = 1; - goto cleanup; - } - code = krb5_cc_initialize(kparam.context, kparam.cc, principal); - if (code) { - error((char *) "%s| %s: ERROR: Error while initializing memory caches : %s\n", LogTime(), PROGRAM, error_message(code)); - retval = 1; - goto cleanup; - } - code = krb5_cc_store_cred(kparam.context, kparam.cc, creds); - if (code) { - error((char *) "%s| %s: ERROR: Error while storing credentials : %s\n", LogTime(), PROGRAM, error_message(code)); - retval = 1; - goto cleanup; - } - debug((char *) "%s| %s: DEBUG: Stored credentials\n", LogTime(), PROGRAM); - } else { + if (!principal_name) { debug((char *) "%s| %s: DEBUG: Got no principal name\n", LogTime(), PROGRAM); retval = 1; } === modified file 'helpers/external_acl/kerberos_ldap_group/support_ldap.cc' --- helpers/external_acl/kerberos_ldap_group/support_ldap.cc 2014-09-14 03:11:33 +0000 +++ helpers/external_acl/kerberos_ldap_group/support_ldap.cc 2014-09-17 13:21:07 +0000 @@ -894,7 +894,7 @@ } #else kc = 1; - debug((char *) "%s| %s: DEBUG: Kerberos is not supported. Use username/passwaord with ldap url instead\n", LogTime(), PROGRAM); + debug((char *) "%s| %s: DEBUG: Kerberos is not supported. Use username/password with ldap url instead\n", LogTime(), PROGRAM); #endif } === modified file 'helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc' --- helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc 2014-09-13 13:31:49 +0000 +++ helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc 2014-09-17 13:21:07 +0000 @@ -57,7 +57,13 @@ 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); +#if HAVE_KRB5_FREE_ERROR_MESSAGE krb5_free_error_message(context, errmsg); +#elif HAVE_KRB5_FREE_ERROR_STRING + krb5_free_error_string(context, (char *)errmsg); +#else + xfree(errmsg); +#endif } return code; } === modified file 'src/peer_proxy_negotiate_auth.cc' --- src/peer_proxy_negotiate_auth.cc 2014-09-02 01:08:58 +0000 +++ src/peer_proxy_negotiate_auth.cc 2014-09-17 13:21:07 +0000 @@ -62,13 +62,13 @@ #define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE #endif -#if !HAVE_ERROR_MESSAGE && HAVE_KRB5_GET_ERR_MESSAGE +#if !HAVE_ERROR_MESSAGE && HAVE_KRB5_GET_ERROR_MESSAGE #define error_message(code) krb5_get_error_message(kparam.context,code) -#elif !HAVE_ERROR_MESSAGE && HAVE_KRB5_GET_ERROR_TEXT +#elif !HAVE_ERROR_MESSAGE && HAVE_KRB5_GET_ERR_TEXT #define error_message(code) krb5_get_err_text(kparam.context,code) #elif !HAVE_ERROR_MESSAGE static char err_code[17]; - const char *KRB5_CALLCONV + const char *KRB5_CALLCONV error_message(long code) { snprintf(err_code,16,"%ld",code); return err_code;