From 75f3c557e5647d80a5f9b5dc1c322f34a8617f12 Mon Sep 17 00:00:00 2001 From: Markus Moeller Date: Mon, 20 Apr 2015 21:50:22 -0700 Subject: [PATCH] Add Kerberos support for MAC OS X 10.x --- acinclude/krb5.m4 | 21 ++++++ configure.ac | 19 +++-- .../kerberos_ldap_group/required.m4 | 5 ++ .../kerberos_ldap_group/support.h | 4 ++ .../kerberos_ldap_group/support_ldap.cc | 70 +++++++++++++------ .../kerberos/negotiate_kerberos.h | 8 ++- .../kerberos/negotiate_kerberos_auth.cc | 2 - .../kerberos/negotiate_kerberos_auth_test.cc | 3 + src/peer_proxy_negotiate_auth.cc | 4 ++ tools/squidclient/gssapi_support.h | 3 + 10 files changed, 108 insertions(+), 31 deletions(-) diff --git a/acinclude/krb5.m4 b/acinclude/krb5.m4 index 8f15b9a215..e7611109a2 100644 --- a/acinclude/krb5.m4 +++ b/acinclude/krb5.m4 @@ -79,6 +79,9 @@ AC_DEFUN([SQUID_CHECK_MAX_SKEW_IN_KRB5_CONTEXT],[ KRB5INT_BEGIN_DECLS #endif #endif +#if USE_APPLE_KRB5 +#define KERBEROS_APPLE_DEPRECATED(x) +#endif #include krb5_context kc; kc->max_skew = 1; ]]) @@ -100,6 +103,9 @@ AC_DEFUN([SQUID_CHECK_KRB5_CONTEXT_MEMORY_CACHE],[ KRB5INT_BEGIN_DECLS #endif #endif +#if USE_APPLE_KRB5 +#define KERBEROS_APPLE_DEPRECATED(x) +#endif #include int main(int argc, char *argv[]) { @@ -127,6 +133,9 @@ AC_DEFUN([SQUID_CHECK_KRB5_CONTEXT_MEMORY_KEYTAB],[ KRB5INT_BEGIN_DECLS #endif #endif +#if USE_APPLE_KRB5 +#define KERBEROS_APPLE_DEPRECATED(x) +#endif #include int main(int argc, char *argv[]) { @@ -157,6 +166,9 @@ AC_DEFUN([SQUID_CHECK_WORKING_GSSAPI], [ #include #endif #else +#if USE_APPLE_KRB5 +#define GSSKRB_APPLE_DEPRECATED(x) +#endif #if HAVE_GSSAPI_GSSAPI_H #include #elif HAVE_GSSAPI_H @@ -200,6 +212,9 @@ AC_DEFUN([SQUID_CHECK_SPNEGO_SUPPORT], [ #include #endif #else +#if USE_APPLE_KRB5 +#define GSSKRB_APPLE_DEPRECATED(x) +#endif #if HAVE_GSSAPI_GSSAPI_H #include #elif HAVE_GSSAPI_H @@ -239,6 +254,9 @@ dnl checks that krb5 is functional. Sets squid_cv_working_krb5 AC_DEFUN([SQUID_CHECK_WORKING_KRB5],[ AC_CACHE_CHECK([for working krb5], squid_cv_working_krb5, [ AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#if USE_APPLE_KRB5 +#define KERBEROS_APPLE_DEPRECATED(x) +#endif #if HAVE_KRB5_H #if HAVE_BROKEN_SOLARIS_KRB5_H #if defined(__cplusplus) @@ -338,6 +356,9 @@ AC_DEFUN([SQUID_CHECK_KRB5_FUNCS],[ [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([[ + #if USE_APPLE_KRB5 + #define KERBEROS_APPLE_DEPRECATED(x) + #endif #include ]],[[krb5_context context; krb5_get_init_creds_opt *options; diff --git a/configure.ac b/configure.ac index 076623db65..acd0817437 100644 --- a/configure.ac +++ b/configure.ac @@ -1411,6 +1411,7 @@ case "$with_mit_krb5" in with_mit_krb5=yes esac ]) +AH_TEMPLATE(USE_APPLE_KRB5,[Apple Kerberos support is available]) AH_TEMPLATE(USE_MIT_KRB5,[MIT Kerberos support is available]) AH_TEMPLATE(USE_SOLARIS_KRB5,[Solaris Kerberos support is available]) @@ -1501,6 +1502,7 @@ elif test $ac_with_krb5_count -eq 0 ; then krb5confpath="`dirname $ac_cv_path_krb5_config`" ac_heimdal="`$ac_cv_path_krb5_config --version 2>/dev/null | grep -c -i heimdal`" ac_solaris="`$ac_cv_path_krb5_config --version 2>/dev/null | grep -c -i solaris`" + ac_apple="`$ac_cv_path_krb5_config --vendor 2>/dev/null | grep -c -i apple`" if test $ac_heimdal -gt 0 ; then with_heimdal_krb5=yes ac_with_krb5_count=1 @@ -1509,7 +1511,11 @@ elif test $ac_with_krb5_count -eq 0 ; then with_solaris_krb5=yes ac_with_krb5_count=1 fi - if test $ac_heimdal -eq 0 && test $ac_solaris -eq 0 ; then + if test $ac_apple -gt 0 ; then + with_apple_krb5=yes + ac_with_krb5_count=1 + fi + if test $ac_heimdal -eq 0 && test $ac_solaris -eq 0 && test $ac_apple -eq 0; then with_mit_krb5=yes ac_with_krb5_count=1 fi @@ -1519,7 +1525,7 @@ elif test $ac_with_krb5_count -eq 0 ; then fi fi -if test "x$with_mit_krb5" = "xyes"; then +if test "x$with_mit_krb5" = "xyes" || test "x$with_apple_krb5" = "xyes" ; then SQUID_STATE_SAVE([squid_krb5_save]) LIBS="$LIBS $LIB_KRB5_PATH" @@ -1570,10 +1576,15 @@ if test "x$with_mit_krb5" = "xyes"; then ]) if test "x$LIB_KRB5_LIBS" != "x"; then + if test "x$with_apple_krb5" = "xyes" ; then + AC_DEFINE(USE_APPLE_KRB5,1,[Apple Kerberos support is available]) + KRB5_FLAVOUR="Apple" + else + AC_DEFINE(USE_MIT_KRB5,1,[MIT Kerberos support is available]) + KRB5_FLAVOUR="MIT" + fi KRB5LIBS="$LIB_KRB5_PATH $LIB_KRB5_LIBS $KRB5LIBS" KRB5INCS="$LIB_KRB5_CFLAGS" - AC_DEFINE(USE_MIT_KRB5,1,[MIT Kerberos support is available]) - KRB5_FLAVOUR="MIT" # check for other specific broken implementations CXXFLAGS="$CXXFLAGS $KRB5INCS" diff --git a/helpers/external_acl/kerberos_ldap_group/required.m4 b/helpers/external_acl/kerberos_ldap_group/required.m4 index c7e64096ec..f3297c5c1b 100644 --- a/helpers/external_acl/kerberos_ldap_group/required.m4 +++ b/helpers/external_acl/kerberos_ldap_group/required.m4 @@ -7,5 +7,10 @@ if test "x$with_krb5" == "xyes"; then BUILD_HELPER="kerberos_ldap_group" + if test "x$with_apple_krb5" = "xyes" ; then + AC_CHECK_LIB(resolv, [main], [XTRA_LIBS="$XTRA_LIBS -lresolv"],[ + AC_MSG_ERROR([library 'resolv' is required for Apple Kerberos]) + ]) + fi SQUID_CHECK_SASL fi diff --git a/helpers/external_acl/kerberos_ldap_group/support.h b/helpers/external_acl/kerberos_ldap_group/support.h index 41cab4e758..db49836df7 100644 --- a/helpers/external_acl/kerberos_ldap_group/support.h +++ b/helpers/external_acl/kerberos_ldap_group/support.h @@ -34,6 +34,10 @@ #include +#if USE_APPLE_KRB5 +#define KERBEROS_APPLE_DEPRECATED(x) +#endif + #if HAVE_KRB5_H #if HAVE_BROKEN_SOLARIS_KRB5_H #warn "Warning! You have a broken Solaris system header" diff --git a/helpers/external_acl/kerberos_ldap_group/support_ldap.cc b/helpers/external_acl/kerberos_ldap_group/support_ldap.cc index f6869b6835..27d7a4efd8 100644 --- a/helpers/external_acl/kerberos_ldap_group/support_ldap.cc +++ b/helpers/external_acl/kerberos_ldap_group/support_ldap.cc @@ -114,11 +114,16 @@ ldap_simple_rebind( void *params) { struct ldap_creds *cp = (struct ldap_creds *) params; + struct berval cred; + if (cp->pw) { + cred.bv_val=cp->pw; + cred.bv_len=strlen(cp->pw); + } whop = whop; credp = credp; methodp = methodp; freeit = freeit; - return ldap_bind_s(ld, cp->dn, cp->pw, LDAP_AUTH_SIMPLE); + return ldap_sasl_bind_s(ld, cp->dn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); } #elif HAVE_LDAP_REBIND_PROC #if HAVE_SASL_H || HAVE_SASL_SASL_H || HAVE_SASL_DARWIN @@ -148,7 +153,12 @@ ldap_simple_rebind( void *params) { struct ldap_creds *cp = (struct ldap_creds *) params; - return ldap_bind_s(ld, cp->dn, cp->pw, LDAP_AUTH_SIMPLE); + struct berval cred; + if (cp->pw) { + cred.bv_val=cp->pw; + cred.bv_len=strlen(cp->pw); + } + return ldap_sasl_bind_s(ld, cp->dn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); } #elif HAVE_LDAP_REBIND_FUNCTION @@ -188,11 +198,16 @@ ldap_simple_rebind( void *params) { struct ldap_creds *cp = (struct ldap_creds *) params; + struct berval cred; + if (cp->pw) { + cred.bv_val=cp->pw; + cred.bv_len=strlen(cp->pw); + } whop = whop; credp = credp; methodp = methodp; freeit = freeit; - return ldap_bind_s(ld, cp->dn, cp->pw, LDAP_AUTH_SIMPLE); + return ldap_sasl_bind_s(ld, cp->dn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); } #else #error "No rebind functione defined" @@ -202,7 +217,7 @@ ldap_simple_rebind( static LDAP_REBIND_PROC ldap_sasl_rebind; static int -ldap_sasl_rebind(LDAP *ld, LDAP_CONST char *, ber_tag_t, ber_int_t, void *params) +ldap_sasl_rebind(LDAP *ld, LDAP_CONST char *, ber_tag_t request, ber_int_t msgid, void *params) { struct ldap_creds *cp = (struct ldap_creds *) params; return tool_sasl_bind(ld, cp->dn, cp->pw); @@ -212,11 +227,16 @@ ldap_sasl_rebind(LDAP *ld, LDAP_CONST char *, ber_tag_t, ber_int_t, void *params static LDAP_REBIND_PROC ldap_simple_rebind; static int -ldap_simple_rebind(LDAP * ld, LDAP_CONST char *, ber_tag_t, ber_int_t, void *params) +ldap_simple_rebind(LDAP *ld, LDAP_CONST char *, ber_tag_t request, ber_int_t msgid, void *params) { struct ldap_creds *cp = (struct ldap_creds *) params; - return ldap_bind_s(ld, cp->dn, cp->pw, LDAP_AUTH_SIMPLE); + struct berval cred; + if (cp->pw) { + cred.bv_val=cp->pw; + cred.bv_len=strlen(cp->pw); + } + return ldap_sasl_bind_s(ld, cp->dn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); } #endif @@ -745,7 +765,7 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl) xfree(ldapuri); if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while initialising connection to ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); - ldap_unbind(ld); + ldap_unbind_ext(ld,NULL,NULL); ld = NULL; return NULL; } @@ -755,7 +775,7 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl) 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); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; return NULL; } @@ -767,7 +787,7 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl) rc = ldap_set_ssl_defaults(margs); if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while setting SSL default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); - ldap_unbind(ld); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; return NULL; } @@ -778,7 +798,7 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl) rc = ldap_start_tls_s(ld, NULL, NULL); if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while setting start_tls for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); - ldap_unbind(ld); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; url = (LDAPURLDesc *) xmalloc(sizeof(*url)); memset(url, 0, sizeof(*url)); @@ -810,14 +830,14 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl) xfree(ldapuri); if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while initialising connection to ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); - ldap_unbind(ld); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; return NULL; } 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); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; return NULL; } @@ -826,14 +846,14 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl) ld = ldapssl_init(host, port, 1); if (!ld) { error((char *) "%s| %s: ERROR: Error while setting SSL for ldap server: %s\n", LogTime(), PROGRAM, ldapssl_err2string(rc)); - ldap_unbind(ld); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; return NULL; } 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); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; return NULL; } @@ -940,7 +960,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group) rc = tool_sasl_bind(ld, bindp, margs->ssl); if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while binding to ldap server with SASL/GSSAPI: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); - ldap_unbind(ld); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; continue; } @@ -953,7 +973,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group) break; } #else - ldap_unbind(ld); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; error((char *) "%s| %s: ERROR: SASL not supported on system\n", LogTime(), PROGRAM); continue; @@ -993,7 +1013,11 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group) nhosts = get_hostname_list(&hlist, 0, host); xfree(host); for (size_t i = 0; i < nhosts; ++i) { - + struct berval cred; + if (margs->lpass) { + cred.bv_val=margs->lpass; + cred.bv_len=strlen(margs->lpass); + } ld = tool_ldap_open(margs, hlist[i].host, port, ssl); if (!ld) continue; @@ -1002,10 +1026,10 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group) */ debug((char *) "%s| %s: DEBUG: Bind to ldap server with Username/Password\n", LogTime(), PROGRAM); - rc = ldap_simple_bind_s(ld, margs->luser, margs->lpass); + rc = ldap_sasl_bind_s(ld, margs->luser, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error while binding to ldap server with Username/Password: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); - ldap_unbind(ld); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; continue; } @@ -1040,7 +1064,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group) rc = check_AD(margs, ld); if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error determining ldap server type: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); - ldap_unbind(ld); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; retval = 0; goto cleanup; @@ -1066,7 +1090,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group) if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error searching ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); - ldap_unbind(ld); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; retval = 0; goto cleanup; @@ -1151,7 +1175,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group) ldap_msgfree(res); } else if (ldap_count_entries(ld, res) == 0 && margs->AD) { ldap_msgfree(res); - ldap_unbind(ld); + ldap_unbind_ext(ld, NULL, NULL); ld = NULL; retval = 0; goto cleanup; @@ -1363,7 +1387,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group) safe_free(attr_value); } } - rc = ldap_unbind(ld); + rc = ldap_unbind_ext(ld, NULL, NULL); ld = NULL; if (rc != LDAP_SUCCESS) { error((char *) "%s| %s: ERROR: Error unbind ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc)); diff --git a/helpers/negotiate_auth/kerberos/negotiate_kerberos.h b/helpers/negotiate_auth/kerberos/negotiate_kerberos.h index 48a9ac893a..f32a592a89 100644 --- a/helpers/negotiate_auth/kerberos/negotiate_kerberos.h +++ b/helpers/negotiate_auth/kerberos/negotiate_kerberos.h @@ -47,6 +47,11 @@ #include "base64.h" #include "util.h" +#if USE_APPLE_KRB5 +#define KERBEROS_APPLE_DEPRECATED(x) +#define GSSKRB_APPLE_DEPRECATED(x) +#endif + #if HAVE_KRB5_H #if HAVE_BROKEN_SOLARIS_KRB5_H #warn "Warning! You have a broken Solaris system header" @@ -144,7 +149,6 @@ typedef struct { 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); @@ -161,4 +165,4 @@ char *get_ad_groups(char *ad_groups, krb5_context context, krb5_pac pac); #else #define HAVE_PAC_SUPPORT 0 #endif - +int check_k5_err(krb5_context context, const char *msg, krb5_error_code code); diff --git a/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc b/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc index c8de3eaea6..a251c82a20 100644 --- a/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc +++ b/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc @@ -65,7 +65,6 @@ krb5_error_code krb5_read_keytab(krb5_context context, krb5_kt_list *kt_list); #endif /* HAVE_KRB5_MEMORY_KEYTAB */ -#if HAVE_PAC_SUPPORT || HAVE_KRB5_MEMORY_KEYTAB int check_k5_err(krb5_context context, const char *function, krb5_error_code code) { @@ -85,7 +84,6 @@ check_k5_err(krb5_context context, const char *function, krb5_error_code code) } return code; } -#endif char * gethost_name(void) diff --git a/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc b/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc index 467a234432..1ac8b6da09 100644 --- a/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc +++ b/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc @@ -33,6 +33,9 @@ #include "squid.h" #if HAVE_GSSAPI +#if USE_APPLE_KRB5 +#define GSSKRB_APPLE_DEPRECATED(x) +#endif #include #include diff --git a/src/peer_proxy_negotiate_auth.cc b/src/peer_proxy_negotiate_auth.cc index 08a7a4704a..64a7cb6359 100644 --- a/src/peer_proxy_negotiate_auth.cc +++ b/src/peer_proxy_negotiate_auth.cc @@ -13,6 +13,10 @@ #include "squid.h" #if HAVE_KRB5 && HAVE_GSSAPI +#if USE_APPLE_KRB5 +#define KERBEROS_APPLE_DEPRECATED(x) +#define GSSKRB_APPLE_DEPRECATED(x) +#endif #include "base64.h" #include "Debug.h" diff --git a/tools/squidclient/gssapi_support.h b/tools/squidclient/gssapi_support.h index 7b1529c1c2..70fd121d27 100644 --- a/tools/squidclient/gssapi_support.h +++ b/tools/squidclient/gssapi_support.h @@ -10,6 +10,9 @@ #define _SQUID_TOOLS_SQUIDCLIENT_GSSAPI_H #if HAVE_GSSAPI +#if USE_APPLE_KRB5 +#define GSSKRB_APPLE_DEPRECATED(x) +#endif #if USE_HEIMDAL_KRB5 #if HAVE_GSSAPI_GSSAPI_H -- 2.47.2