--- squid_ldap_group.c.orig 2010-05-30 15:21:11.000000000 +0200 +++ squid_ldap_group.c 2010-08-30 11:18:01.072325145 +0200 @@ -74,6 +74,9 @@ #include #include +#if defined (CYRUS_SASL) +#include +#endif #endif @@ -115,6 +118,10 @@ static int readSecret(const 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 */ #ifndef LDAP_NO_ATTRS @@ -220,6 +227,9 @@ int strip_nt_domain = 0; int strip_kerberos_realm = 0; int err = 0; +#if defined (CYRUS_SASL) + int use_sasl_bind = 0; +#endif setbuf(stdout, NULL); @@ -378,12 +388,18 @@ case 'K': strip_kerberos_realm = 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) { @@ -433,6 +449,9 @@ 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"); fprintf(stderr, "\t-K\t\t\tStrip Kerberos realm from usernames\n"); +#if defined (CYRUS_SASL) + fprintf(stderr, "\t-k\t\t\tuse GSSAPI sasl authentication\n"); +#endif fprintf(stderr, "\t-d\t\t\tenable debug mode\n"); 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"); @@ -563,10 +582,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; @@ -829,3 +861,32 @@ return 0; } + +#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; + + 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 +