]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fix various Kerberos issues
authorMarkus Moeller <huaraz@moeller.plus.com>
Wed, 17 Sep 2014 13:21:07 +0000 (06:21 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Wed, 17 Sep 2014 13:21:07 +0000 (06:21 -0700)
* Fix error_message detection and use.

* Fix library detection

* Fix spelling typo

* Change handling of principals in keytab for kerberos_ldap_group.

acinclude/krb5.m4
configure.ac
helpers/external_acl/kerberos_ldap_group/support_krb5.cc
helpers/external_acl/kerberos_ldap_group/support_ldap.cc
helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc
src/peer_proxy_negotiate_auth.cc

index e8545f9e71e02f564e98bb7735de70b8e8e0fce0..5aa8a99d54423c3000a9cadacca05b0efd084dd7 100644 (file)
@@ -248,12 +248,35 @@ fi
 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 <krb5.h>])
   AC_CHECK_TYPE(krb5_pac,
     AC_DEFINE(HAVE_KRB5_PAC,1,
@@ -297,7 +320,6 @@ AC_DEFUN([SQUID_CHECK_KRB5_FUNCS],[
        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]),)
index 8144e5f071ba39b5def1d5df07e875a0c16f2a50..9479f510f421d99dc12001b6204b69d7a3e02cd5 100644 (file)
@@ -1513,19 +1513,24 @@ if test "x$with_mit_krb5" = "xyes"; then
       ## 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 @@ if test "x$with_mit_krb5" = "xyes"; then
     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 @@ if test "x$with_solaris_krb5" = "xyes"; then
 
     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 @@ if test "x$with_heimdal_krb5" = "xyes"; then
     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 @@ if test "x$with_heimdal_krb5" = "xyes"; then
       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
index 92bb895eafa2d7b0cba489f76a5300c5c92e6a65..be9ab3df1eda3817f3e628051ec154e0a502a9ac 100644 (file)
@@ -90,6 +90,25 @@ krb5_create_cache(char *domain)
         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;
+    }
     /*
      * getting default keytab name
      */
@@ -151,8 +170,74 @@ krb5_create_cache(char *domain)
             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 @@ krb5_create_cache(char *domain)
         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 @@ krb5_create_cache(char *domain)
                 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 @@ loop_end:
             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;
     }
index 7d02913b0720c93642289fc60bab99240c7e9c44..1f3d50f8eb85d8ad6923b3886e9ffcda415cc42a 100644 (file)
@@ -894,7 +894,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group)
         }
 #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
     }
 
index 0fc05355bafa5821706717425b080b2a2023ecd9..31f22114a6bdcb59b6b277d7bfee568cf2bf835f 100644 (file)
@@ -57,7 +57,13 @@ check_k5_err(krb5_context context, const char *function, krb5_error_code 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);
+#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;
 }
index fdbc604b0e033e672670c19a32790a63070b683d..94d8af960bde30e76513f162f45a1706503b5763 100644 (file)
@@ -62,13 +62,13 @@ extern "C" {
 #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;