/* group_ldap_auth: user and group authentication via ldap for squid proxy server Author: Tobias Crawley tocrawle@users.sourceforge.net http://www.fatgut.org/squid/group_ldap_auth/ Based on squid_ldap_auth.c by: Glen Newton glen.newton@nrc.ca Advanced Services CISTI National Research Council Usage: group_ldap_auth [] Dependencies: You need to get the OpenLDAP libraries from http://www.openldap.org License: group_ldap_auth is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. */ #include #include #include #include #include struct _grouplist { char type; char *group; struct _grouplist *next; }; typedef struct _grouplist grouplist; int checkLDAP(LDAP * ld, char *userid, char *password, grouplist * glist, char **group, char *searchBase); //#ifdef USE_LOG FILE *logfd = NULL; //#endif int main(int argc, char **argv) { char buf[256]; char *user, *passwd, *group, *tmpstrptr, *p; char *ldapServer; int groupcount = 0; grouplist *glist = NULL, *currgroup = NULL; int ldapPort = LDAP_PORT; LDAP *ld; char *searchBase; int err = 0; int i; //#ifdef USE_LOG char logfile[256]; //#endif setbuf(stdout, NULL); if (argc < 3 || argc > 4) { fprintf(stderr, "Usage: squid_ldap_auth search_base ldap_server_name [ldap_server_port]\n"); exit(1); } //#ifdef USE_LOG /* setup a log file */ sprintf(logfile, "/usr/local/squid/logs/squid_ldap_auth_log.%d", (int) getpid()); logfd = fopen(logfile, "w"); //#endif searchBase = (char *) argv[1]; ldapServer = (char *) argv[2]; if (argc == 4) { ldapPort = atoi((char *) argv[3]); } if ((ld = ldap_open(ldapServer, ldapPort)) == NULL) { fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, ldapPort); exit(1); } ldap_simple_bind_s(ld, "", ""); //#ifdef USE_LOG fprintf(logfd, "bound to %s:%d\n", ldapServer, ldapPort); //#endif while (fgets(buf, 256, stdin) != NULL) { //#ifdef USE_LOG // fprintf(logfd, "received %s", buf); //#endif if ((p = strchr(buf, '\n')) != NULL) *p = '\0'; /* strip \n */ if ((user = strtok(buf, " ")) == NULL) { printf("f\n"); continue; } /* Modification CJM (Louis-Steve Desjardins) pour enlever le mot de passe du fichier log */ fprintf(logfd, "received %s *****\n", user); if ((passwd = strtok(NULL, " ")) == NULL) { printf("f\n"); continue; } if ((tmpstrptr = strtok(NULL, " ")) == NULL) { printf("f\n"); continue; } groupcount = atoi(tmpstrptr); for (i = 0; i < groupcount; i++) { if (!glist) { currgroup = glist = (grouplist *) malloc(sizeof(grouplist)); } else { currgroup->next = (grouplist *) malloc(sizeof(grouplist)); currgroup = currgroup->next; } currgroup->next = NULL; if ((tmpstrptr = strtok(NULL, " ")) == NULL) { printf("f\n"); continue; } currgroup->type = tmpstrptr[0]; if ((currgroup->group = strtok(NULL, "#\0")) == NULL) { printf("f\n"); continue; } } group = NULL; err = checkLDAP(ld, user, passwd, glist, &group, searchBase); //#ifdef USE_LOG fprintf(logfd, "checkLdap returned %d %s\n", err, (group == NULL) ? "" : group); //#endif if (err == 0) { if (group == NULL) { printf("p\n"); } else { printf("p %s\n", group); } } else { printf("f\n"); } /* free the glist */ while (glist != NULL) { currgroup = glist->next; free(glist); glist = currgroup; } glist = currgroup = NULL; ldap_simple_bind_s(ld, "", ""); //#ifdef USE_LOG fflush(logfd); //#endif } //#ifdef USE_LOG fclose(logfd); //#endif ldap_unbind(ld); } int checkLDAP(LDAP * ld, char *userid, char *password, grouplist * glist, char **group, char *searchBase) { char filter[1024]; char *attrs[2]; char *userdn; LDAPMessage *result; int entryCount = 0; char **vals, **prevals; char found = 0; char *resultdn; /* Modifie le 9 avril 2001 Pour fonctionnement avec serveur LDAP/NDS des CJM // verify user exists sprintf(filter, "(uid=%s)", userid); */ /* verify user exists */ /* Modifie le 9 avril 2001 */ /* Pour fonctionnement avec serveur LDAP/NDS des CJM */ sprintf(filter, "(cn=%s)", userid); // Modification : Louis-Steve Desjardins //#ifdef USE_LOG fprintf(logfd, "searching for user with filter %s\n", filter); //#endif attrs[0] = NULL; if (ldap_search_s(ld, searchBase, LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result) != LDAP_SUCCESS) { return 1; } /* get the user's dn */ if ((result = ldap_first_entry(ld, result)) == NULL) { return 2; } if ((userdn = ldap_get_dn(ld, result)) == NULL) { return 3; } if (glist != NULL) { while (glist != NULL && !found) { if (glist->type == 'd') { attrs[0] = NULL; //#ifdef USE_LOG fprintf(logfd, "searching for dynamic group %s\n", glist->group); //#endif if (ldap_search_s(ld, searchBase, LDAP_SCOPE_SUBTREE, glist->group, attrs, 0, &result) != LDAP_SUCCESS) { free(userdn); return 4; } entryCount = ldap_count_entries(ld, result); if (entryCount > 0) { result = ldap_first_entry(ld, result); while (result != NULL && !found) { resultdn = ldap_get_dn(ld, result); if (!strcmp(userdn, resultdn)) { found = 1; *group = glist->group; } free(resultdn); result = ldap_next_entry(ld, result); } } } else { /* static group */ sprintf(filter, "(& (cn=%s) (| (objectclass=groupofuniquenames) (objectclass=groupofnames)))", glist->group); attrs[0] = strdup("uniquemember"); attrs[1] = NULL; //#ifdef USE_LOG fprintf(logfd, "searching for static group %s using filter %s\n", glist->group, filter); //#endif if (ldap_search_s(ld, searchBase, LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result) != LDAP_SUCCESS) { free(userdn); free(attrs[0]); return 4; } entryCount = ldap_count_entries(ld, result); if (entryCount > 0) { result = ldap_first_entry(ld, result); while (result != NULL && !found) { prevals = vals = ldap_get_values(ld, result, "uniquemember"); while (vals != NULL && *vals != NULL && !found) { if (!strcmp(userdn, *vals++)) { found = 1; *group = glist->group; } } ldap_value_free(prevals); result = ldap_next_entry(ld, result); } } free(attrs[0]); } //#ifdef USE_LOG if (!found) fprintf(logfd, "user %s not found in group %s\n", userdn, glist->group); else fprintf(logfd, "user %s found in group %s\n", userdn, glist->group); //#endif glist = glist->next; } if (!found) { free(userdn); return 5; } } //#ifdef USE_LOG fprintf(logfd, "binding as %s\n", userdn); //#endif if (ldap_simple_bind_s(ld, userdn, password) != LDAP_SUCCESS) { free(userdn); return 6; } free(userdn); return 0; }