]>
Commit | Line | Data |
---|---|---|
94439e4e | 1 | /* |
2 | * | |
3 | * squid_ldap_auth: authentication via ldap for squid proxy server | |
4 | * | |
05b7b723 | 5 | * Maintainer: Henrik Nordstrom <hno@squid-cache.org> |
6 | * | |
94439e4e | 7 | * Author: Glen Newton |
8 | * glen.newton@nrc.ca | |
9 | * Advanced Services | |
10 | * CISTI | |
11 | * National Research Council | |
12 | * | |
331ba756 | 13 | * Usage: squid_ldap_auth [-b basedn] [-s searchscope] [-f searchfilter] <ldap_server_name> |
94439e4e | 14 | * |
15 | * Dependencies: You need to get the OpenLDAP libraries | |
16 | * from http://www.openldap.org | |
17 | * | |
18 | * License: squid_ldap_auth is free software; you can redistribute it | |
19 | * and/or modify it under the terms of the GNU General Public License | |
20 | * as published by the Free Software Foundation; either version 2, | |
21 | * or (at your option) any later version. | |
efd2f308 | 22 | * |
23 | * Changes: | |
24 | * 2001-04-15: Henrik Nordstrom <hno@squid-cache.org> | |
25 | * - Added command line option for basedn | |
26 | * - Added the ability to search for the user DN | |
94439e4e | 27 | */ |
28 | ||
29 | #include <stdio.h> | |
30 | #include <string.h> | |
331ba756 | 31 | #include <stdlib.h> |
94439e4e | 32 | #include <lber.h> |
33 | #include <ldap_cdefs.h> | |
34 | #include <ldap.h> | |
35 | ||
36 | /* Change this to your search base */ | |
331ba756 | 37 | static char *basedn = "ou=people,o=nrc.ca"; |
38 | static char *searchfilter = NULL; | |
39 | static int searchscope = LDAP_SCOPE_SUBTREE; | |
94439e4e | 40 | |
41 | int checkLDAP(LDAP * ld, char *userid, char *password); | |
42 | ||
43 | int | |
44 | main(int argc, char **argv) | |
45 | { | |
46 | char buf[256]; | |
47 | char *user, *passwd, *p; | |
48 | char *ldapServer; | |
49 | LDAP *ld; | |
94439e4e | 50 | |
51 | setbuf(stdout, NULL); | |
52 | ||
331ba756 | 53 | while (argc > 2 && argv[1][0] == '-') { |
54 | char *value; | |
55 | char option = argv[1][1]; | |
56 | if (strlen(argv[1]) > 2) { | |
57 | value = argv[1]+2; | |
58 | } else { | |
59 | value = argv[2]; | |
60 | argv++; | |
61 | argc--; | |
62 | } | |
63 | argv++; | |
64 | argc--; | |
65 | switch(option) { | |
66 | case 'b': | |
67 | basedn = value; | |
68 | break; | |
69 | case 'f': | |
70 | searchfilter = value; | |
71 | break; | |
72 | case 's': | |
73 | if (strcmp(value, "base") == 0) | |
74 | searchscope = LDAP_SCOPE_BASE; | |
75 | else if (strcmp(value, "one") == 0) | |
76 | searchscope = LDAP_SCOPE_ONELEVEL; | |
77 | else if (strcmp(value, "sub") == 0) | |
78 | searchscope = LDAP_SCOPE_SUBTREE; | |
79 | else { | |
80 | fprintf(stderr, "squid_ldap_auth: ERROR: Unknown search scope '%s'\n", value); | |
81 | exit(1); | |
82 | } | |
83 | break; | |
84 | default: | |
85 | fprintf(stderr, "squid_ldap_auth: ERROR: Unknown command line option '%c'\n", option); | |
86 | exit(1); | |
87 | } | |
88 | } | |
89 | ||
94439e4e | 90 | if (argc != 2) { |
331ba756 | 91 | fprintf(stderr, "Usage: squid_ldap_auth [-b basedn] [-s searchscope] [-f searchfilter] ldap_server_name\n"); |
94439e4e | 92 | exit(1); |
93 | } | |
94 | ldapServer = (char *) argv[1]; | |
95 | ||
96 | while (fgets(buf, 256, stdin) != NULL) { | |
97 | /* You can put this ldap connect outside the loop, but i didn't want to | |
98 | * have the connection open too much. If you have a site which will | |
99 | * be doing >1 authentication per second, you should move this (and the | |
100 | * below ldap_unbind()) outside the loop. | |
101 | */ | |
102 | if ((ld = ldap_init(ldapServer, LDAP_PORT)) == NULL) { | |
103 | fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", | |
104 | ldapServer, LDAP_PORT); | |
105 | exit(1); | |
106 | } | |
107 | if ((p = strchr(buf, '\n')) != NULL) | |
108 | *p = '\0'; /* strip \n */ | |
109 | ||
110 | if ((user = strtok(buf, " ")) == NULL) { | |
111 | printf("ERR\n"); | |
112 | continue; | |
113 | } | |
114 | if ((passwd = strtok(NULL, "")) == NULL) { | |
115 | printf("ERR\n"); | |
116 | continue; | |
117 | } | |
118 | if (checkLDAP(ld, user, passwd) != 0) { | |
119 | printf("ERR\n"); | |
120 | continue; | |
121 | } else { | |
122 | printf("OK\n"); | |
123 | } | |
124 | ldap_unbind(ld); | |
125 | } | |
331ba756 | 126 | return 0; |
94439e4e | 127 | } |
128 | ||
94439e4e | 129 | int |
130 | checkLDAP(LDAP * ld, char *userid, char *password) | |
131 | { | |
331ba756 | 132 | char dn[256]; |
133 | int result = 1; | |
94439e4e | 134 | |
331ba756 | 135 | if (searchfilter) { |
136 | char filter[256]; | |
137 | LDAPMessage *res = NULL; | |
138 | LDAPMessage *entry; | |
139 | char *searchattr[] = {NULL}; | |
140 | char *userdn; | |
94439e4e | 141 | |
331ba756 | 142 | snprintf(filter, sizeof(filter), "%s%s", searchfilter, userid); |
143 | if (ldap_search_s(ld, basedn, searchscope, filter, searchattr, 1, &res) != LDAP_SUCCESS) | |
144 | return 1; | |
145 | entry = ldap_first_entry(ld, res); | |
146 | if (!entry) { | |
147 | ldap_msgfree(res); | |
148 | return 1; | |
149 | } | |
150 | userdn = ldap_get_dn(ld, entry); | |
151 | if (!userdn) { | |
152 | ldap_msgfree(res); | |
153 | return 1; | |
154 | } | |
155 | snprintf(dn, sizeof(dn), "%s", userdn); | |
156 | free(userdn); | |
157 | ldap_msgfree(res); | |
158 | } else { | |
159 | snprintf(dn, sizeof(dn), "uid=%s, %s", userid, basedn); | |
94439e4e | 160 | } |
331ba756 | 161 | |
162 | if (ldap_simple_bind_s(ld, dn, password) == LDAP_SUCCESS) | |
163 | result = 0; | |
164 | ||
165 | return result; | |
94439e4e | 166 | } |