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

Reply via email to