This patch add support for SASL GSSAPI to squid_ldap_group, feature required if you want check group membership from a W2003 Active Directory or openldap with kerberos authentication.
Patch created from squid 2.5-STABLE7. To Compile with GSSAPI support: cd helpers/external_acl/ldap_group make LDFLAGS='-lkrb5 -lsasl2' CFLAGS='-DCYRUS_SASL' this requieres cyrus-sasl 2.x.x, openldap 2.x.x and krb5 1.3.x libraries. see krb5 documentation about howto configure kerberos client. -- DiegoWS LANUX
diff -Nur squid-2.5.STABLE7/helpers/external_acl/ldap_group/README squid-2.5.STABLE7-krb5/helpers/external_acl/ldap_group/README --- squid-2.5.STABLE7/helpers/external_acl/ldap_group/README 2003-11-19 21:41:37.000000000 -0300 +++ squid-2.5.STABLE7-krb5/helpers/external_acl/ldap_group/README 2004-10-20 21:06:41.000000000 -0300 @@ -8,3 +8,10 @@ The latest version of this program can always be found from MARA Systems at http://marasystems.com/download/LDAP_Group/ + +If you want compile with GSSAPI support: + +cd helpers/external_acl/ldap_group +make LDFLAGS='-lkrb5 -lsasl2' CFLAGS='-DCYRUS_SASL' + +this requieres cyrus-sasl 2.x.x, openldap 2.x.x and krb5 1.3.x libraries. diff -Nur squid-2.5.STABLE7/helpers/external_acl/ldap_group/squid_ldap_group.c squid-2.5.STABLE7-krb5/helpers/external_acl/ldap_group/squid_ldap_group.c --- squid-2.5.STABLE7/helpers/external_acl/ldap_group/squid_ldap_group.c 2004-03-02 06:13:29.000000000 -0300 +++ squid-2.5.STABLE7-krb5/helpers/external_acl/ldap_group/squid_ldap_group.c 2004-10-20 21:03:01.000000000 -0300 @@ -39,6 +39,9 @@ #include <ctype.h> #include <lber.h> #include <ldap.h> +#if defined (CYRUS_SASL) +#include <sasl/sasl.h> +#endif #if defined(LDAP_OPT_NETWORK_TIMEOUT) #include <sys/time.h> #endif @@ -76,34 +79,38 @@ static int readSecret(char *filename); +#if defined (CYRUS_SASL) +static int do_sasl_interact(LDAP * ld, unsigned flags, void *defaults, void *_interact); +#endif + /* Yuck.. we need to glue to different versions of the API */ #if defined(LDAP_API_VERSION) && LDAP_API_VERSION > 1823 -static int +static int squid_ldap_errno(LDAP * ld) { int err = 0; ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err); return err; } -static void +static void squid_ldap_set_aliasderef(LDAP * ld, int deref) { ldap_set_option(ld, LDAP_OPT_DEREF, &deref); } -static void +static void squid_ldap_set_referrals(LDAP * ld, int referrals) { int *value = referrals ? LDAP_OPT_ON : LDAP_OPT_OFF; ldap_set_option(ld, LDAP_OPT_REFERRALS, value); } static void -squid_ldap_set_timelimit(LDAP *ld, int timelimit) +squid_ldap_set_timelimit(LDAP * ld, int timelimit) { ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &timelimit); } static void -squid_ldap_set_connect_timeout(LDAP *ld, int timelimit) +squid_ldap_set_connect_timeout(LDAP * ld, int timelimit) { #if defined(LDAP_OPT_NETWORK_TIMEOUT) struct timeval tv; @@ -115,23 +122,24 @@ ldap_set_option(ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timelimit); #endif } -static void +static void squid_ldap_memfree(char *p) { ldap_memfree(p); } + #else -static int +static int squid_ldap_errno(LDAP * ld) { return ld->ld_errno; } -static void +static void squid_ldap_set_aliasderef(LDAP * ld, int deref) { ld->ld_deref = deref; } -static void +static void squid_ldap_set_referrals(LDAP * ld, int referrals) { if (referrals) @@ -140,26 +148,27 @@ ld->ld_options &= ~LDAP_OPT_REFERRALS; } static void -squid_ldap_set_timelimit(LDAP *ld, int timelimit) +squid_ldap_set_timelimit(LDAP * ld, int timelimit) { ld->ld_timelimit = timelimit; } static void -squid_ldap_set_connect_timeout(LDAP *ld, int timelimit) +squid_ldap_set_connect_timeout(LDAP * ld, int timelimit) { fprintf(stderr, "Connect timeouts not supported in your LDAP library\n"); } -static void +static void squid_ldap_memfree(char *p) { free(p); } + #endif #ifdef LDAP_API_FEATURE_X_OPENLDAP - #if LDAP_VENDOR_VERSION > 194 - #define HAS_URI_SUPPORT 1 - #endif +#if LDAP_VENDOR_VERSION > 194 +#define HAS_URI_SUPPORT 1 +#endif #endif static char * @@ -218,6 +227,9 @@ int port = LDAP_PORT; int use_extension_dn = 0; int strip_nt_domain = 0; +#if defined (CYRUS_SASL) + int use_sasl_bind = 0; +#endif setbuf(stdout, NULL); @@ -328,7 +340,7 @@ bindpasswd = value; break; case 'W': - readSecret (value); + readSecret(value); break; case 'P': persistent = !persistent; @@ -372,12 +384,18 @@ case 'S': strip_nt_domain = 1; break; +#if defined (CYRUS_SASL) + case 'k': + use_sasl_bind = 1; + break; +#endif default: fprintf(stderr, PROGRAM_NAME " ERROR: Unknown command line option '%c'\n", option); exit(1); } } + version = 3; while (argc > 1) { char *value = argv[1]; if (ldapServer) { @@ -425,6 +443,9 @@ #endif fprintf(stderr, "\t-g\t\t\tfirst query parameter is base DN extension\n\t\t\t\tfor this query\n"); fprintf(stderr, "\t-S\t\t\tStrip NT domain from usernames\n"); +#if defined (CYRUS_SASL) + fprintf(stderr, "\t-k\t\t\tuse GSSAPI sasl authentication\n"); +#endif fprintf(stderr, "\n"); fprintf(stderr, "\tIf you need to bind as a user to perform searches then use the\n\t-D binddn -w bindpasswd or -D binddn -W secretfile options\n\n"); exit(1); @@ -441,42 +462,41 @@ user = u + 1; } if (use_extension_dn) - extension_dn = strwordtok(NULL, &tptr); + extension_dn = strwordtok(NULL, &tptr); while (!found && user && (group = strwordtok(NULL, &tptr)) != NULL) { recover: if (ld == NULL) { #if HAS_URI_SUPPORT - if (strstr(ldapServer, "://") != NULL) { - rc = ldap_initialize( &ld, ldapServer ); - if( rc != LDAP_SUCCESS ) { + if (strstr(ldapServer, "://") != NULL) { + rc = ldap_initialize(&ld, ldapServer); + if (rc != LDAP_SUCCESS) { fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer); break; } - } else + } else #endif #if NETSCAPE_SSL if (sslpath) { - if ( !sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) { + if (!sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) { fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n", - sslpath); + sslpath); exit(1); } else { sslinit++; } if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) { fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n", - ldapServer, port); + ldapServer, port); exit(1); } } else #endif if ((ld = ldap_init(ldapServer, port)) == NULL) { - fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n",ldapServer, port); + fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, port); break; } - if (connect_timeout) squid_ldap_set_connect_timeout(ld, connect_timeout); @@ -502,10 +522,23 @@ squid_ldap_set_timelimit(ld, timelimit); squid_ldap_set_referrals(ld, !noreferrals); squid_ldap_set_aliasderef(ld, aliasderef); + +#if defined (CYRUS_SASL) + if (use_sasl_bind) { + rc = ldap_sasl_interactive_bind_s(ld, binddn, NULL, NULL, NULL, LDAP_SASL_QUIET, do_sasl_interact, (void *) bindpasswd); + if (rc != LDAP_SUCCESS) { + fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s' (sasl)\n", ldap_err2string(rc)); + ldap_unbind(ld); + ld = NULL; + break; + } + } else if (binddn && bindpasswd && *binddn && *bindpasswd) { +#else if (binddn && bindpasswd && *binddn && *bindpasswd) { +#endif rc = ldap_simple_bind_s(ld, binddn, bindpasswd); if (rc != LDAP_SUCCESS) { - fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc)); + fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s' (simple)\n", ldap_err2string(rc)); ldap_unbind(ld); ld = NULL; break; @@ -550,7 +583,7 @@ { int n = 0; while (size > 4 && *src) { - switch(*src) { + switch (*src) { case '*': case '(': case ')': @@ -559,8 +592,8 @@ size -= 3; if (size > 0) { *escaped++ = '\\'; - snprintf(escaped, 3, "%02x", (unsigned char)*src++); - escaped+=2; + snprintf(escaped, 3, "%02x", (unsigned char) *src++); + escaped += 2; } break; default: @@ -577,8 +610,8 @@ build_filter(char *filter, int size, const char *template, const char *user, const char *group) { int n; - while(*template && size > 0) { - switch(*template) { + while (*template && size > 0) { + switch (*template) { case '%': template++; switch (*template) { @@ -641,7 +674,6 @@ fprintf(stderr, PROGRAM_NAME " ERROR, Failed to construct LDAP search filter. filter=\"%s\", user=\"%s\", group=\"%s\"\n", filter, member, group); return 1; } - if (debug) fprintf(stderr, "group filter '%s', searchbase '%s'\n", filter, searchbase); @@ -673,7 +705,7 @@ } static int -searchLDAP(LDAP *ld, char *group, char *login, char *extension_dn) +searchLDAP(LDAP * ld, char *group, char *login, char *extension_dn) { if (usersearchfilter) { @@ -734,35 +766,64 @@ } -int readSecret(char *filename) +int +readSecret(char *filename) { - char buf[BUFSIZ]; - char *e=0; - FILE *f; - - if(!(f=fopen(filename, "r"))) { - fprintf(stderr, PROGRAM_NAME " ERROR: Can not read secret file %s\n", filename); - return 1; - } + char buf[BUFSIZ]; + char *e = 0; + FILE *f; + + if (!(f = fopen(filename, "r"))) { + fprintf(stderr, PROGRAM_NAME " ERROR: Can not read secret file %s\n", filename); + return 1; + } + if (!fgets(buf, sizeof(buf) - 1, f)) { + fprintf(stderr, PROGRAM_NAME " ERROR: Secret file %s is empty\n", filename); + fclose(f); + return 1; + } + /* strip whitespaces on end */ + if ((e = strrchr(buf, '\n'))) + *e = 0; + if ((e = strrchr(buf, '\r'))) + *e = 0; + + bindpasswd = (char *) calloc(sizeof(char), strlen(buf) + 1); + if (bindpasswd) { + strcpy(bindpasswd, buf); + } else { + fprintf(stderr, PROGRAM_NAME " ERROR: can not allocate memory\n"); + } - if( !fgets(buf, sizeof(buf)-1, f)) { - fprintf(stderr, PROGRAM_NAME " ERROR: Secret file %s is empty\n", filename); fclose(f); - return 1; - } - /* strip whitespaces on end */ - if((e = strrchr(buf, '\n'))) *e = 0; - if((e = strrchr(buf, '\r'))) *e = 0; - - bindpasswd = (char *) calloc(sizeof(char), strlen(buf)+1); - if (bindpasswd) { - strcpy(bindpasswd, buf); - } else { - fprintf(stderr, PROGRAM_NAME " ERROR: can not allocate memory\n"); - } + return 0; +} - fclose(f); +#if defined (CYRUS_SASL) +static int +do_sasl_interact(LDAP * ld, unsigned flags, void *defaults, void *_interact) +{ + char *authzid = (char *) defaults; + sasl_interact_t *interact = (sasl_interact_t *) _interact; - return 0; + while (interact->id != SASL_CB_LIST_END) { + if (interact->id == SASL_CB_USER) { + if (authzid != NULL) { + interact->result = authzid; + interact->len = strlen(authzid); + } else if (interact->defresult != NULL) { + interact->result = interact->defresult; + interact->len = strlen(interact->defresult); + } else { + interact->result = ""; + interact->len = 0; + } + } else { + return LDAP_PARAM_ERROR; + } + interact++; + } + return LDAP_SUCCESS; } +#endif