]>
Commit | Line | Data |
---|---|---|
94439e4e | 1 | /* |
94439e4e | 2 | * squid_ldap_auth: authentication via ldap for squid proxy server |
3 | * | |
d4ce3aef | 4 | * Authors: |
5 | * Henrik Nordstrom | |
6 | * hno@squid-cache.org | |
05b7b723 | 7 | * |
d4ce3aef | 8 | * Glen Newton |
94439e4e | 9 | * glen.newton@nrc.ca |
10 | * Advanced Services | |
11 | * CISTI | |
12 | * National Research Council | |
d4ce3aef | 13 | * |
14 | * with contributions from others mentioned in the Changes section below | |
94439e4e | 15 | * |
7c2a6c51 | 16 | * Usage: squid_ldap_auth -b basedn [-s searchscope] |
b671cc68 | 17 | * [-f searchfilter] [-D binddn -w bindpasswd] |
20b6fc8e | 18 | * [-u attr] [-h host] [-p port] [-P] [-R] [ldap_server_name[:port]] ... |
94439e4e | 19 | * |
20 | * Dependencies: You need to get the OpenLDAP libraries | |
d4ce3aef | 21 | * from http://www.openldap.org or another compatible LDAP C-API |
22 | * implementation. | |
8370dcf2 | 23 | * |
24 | * If you want to make a TLS enabled connection you will also need the | |
25 | * OpenSSL libraries linked into openldap. See http://www.openssl.org/ | |
94439e4e | 26 | * |
27 | * License: squid_ldap_auth is free software; you can redistribute it | |
28 | * and/or modify it under the terms of the GNU General Public License | |
29 | * as published by the Free Software Foundation; either version 2, | |
30 | * or (at your option) any later version. | |
efd2f308 | 31 | * |
32 | * Changes: | |
653b264e | 33 | * 2003-03-01: David J N Begley |
34 | * - Support for Netscape API method of ldap over SSL | |
35 | * connections | |
36 | * - Timeout option for better recovery when using | |
37 | * multiple LDAP servers | |
954a8513 | 38 | * 2003-03-01: Christoph Lechleitner <lech@ibcl.at> |
39 | * - Added -W option to read bindpasswd from file | |
7ba68818 | 40 | * 2003-03-01: Juerg Michel |
41 | * - Added support for ldap URI via the -H option | |
42 | * (requires OpenLDAP) | |
8370dcf2 | 43 | * 2001-12-12: Michael Cunningham <m.cunningham@xpedite.com> |
2c10afe0 | 44 | * - Added TLS support and partial ldap version 3 support. |
49b97dc8 | 45 | * 2001-10-04: Henrik Nordstrom <hno@squid-cache.org> |
46 | * - Be consistent with the other helpers in how | |
20b6fc8e | 47 | * spaces are managed. If there is space characters |
48 | * then these are assumed to be part of the password | |
49 | * 2001-09-05: Henrik Nordstrom <hno@squid-cache.org> | |
50 | * - Added ability to specify another default LDAP port to | |
51 | * connect to. Persistent connections moved to -P | |
87f6d1e1 | 52 | * 2001-05-02: Henrik Nordstrom <hno@squid-cache.org> |
53 | * - Support newer OpenLDAP 2.x libraries using the | |
b671cc68 | 54 | * revised Internet Draft API which unfortunately |
87f6d1e1 | 55 | * is not backwards compatible with RFC1823.. |
efd2f308 | 56 | * 2001-04-15: Henrik Nordstrom <hno@squid-cache.org> |
57 | * - Added command line option for basedn | |
58 | * - Added the ability to search for the user DN | |
c4c1f30c | 59 | * 2001-04-16: Henrik Nordstrom <hno@squid-cache.org> |
60 | * - Added -D binddn -w bindpasswd. | |
50f87883 | 61 | * 2001-04-17: Henrik Nordstrom <hno@squid-cache.org> |
62 | * - Added -R to disable referrals | |
63 | * - Added -a to control alias dereferencing | |
7c2a6c51 | 64 | * 2001-04-17: Henrik Nordstrom <hno@squid-cache.org> |
65 | * - Added -u, DN username attribute name | |
c9acd551 | 66 | * 2001-04-18: Henrik Nordstrom <hno@squid-cache.org> |
67 | * - Allow full filter specifications in -f | |
94439e4e | 68 | */ |
69 | ||
70 | #include <stdio.h> | |
71 | #include <string.h> | |
331ba756 | 72 | #include <stdlib.h> |
94439e4e | 73 | #include <lber.h> |
94439e4e | 74 | #include <ldap.h> |
75 | ||
9bbd1655 | 76 | #include "util.h" |
77 | ||
653b264e | 78 | #define PROGRAM_NAME "squid_ldap_auth" |
79 | ||
80 | /* Global options */ | |
7c2a6c51 | 81 | static char *basedn; |
331ba756 | 82 | static char *searchfilter = NULL; |
c4c1f30c | 83 | static char *binddn = NULL; |
84 | static char *bindpasswd = NULL; | |
963b6afb | 85 | static char *userattr = "uid"; |
331ba756 | 86 | static int searchscope = LDAP_SCOPE_SUBTREE; |
c4c1f30c | 87 | static int persistent = 0; |
50f87883 | 88 | static int noreferrals = 0; |
89 | static int aliasderef = LDAP_DEREF_NEVER; | |
653b264e | 90 | #if defined(NETSCAPE_SSL) |
91 | static char *sslpath = NULL; | |
92 | static int sslinit = 0; | |
93 | #endif | |
94 | static int connect_timeout = 0; | |
95 | static int timelimit = LDAP_NO_LIMIT; | |
94439e4e | 96 | |
8370dcf2 | 97 | /* Added for TLS support and version 3 */ |
98 | static int use_tls = 0; | |
99 | static int version = -1; | |
100 | ||
c4c1f30c | 101 | static int checkLDAP(LDAP * ld, char *userid, char *password); |
954a8513 | 102 | static int readSecret(char *filename); |
94439e4e | 103 | |
87f6d1e1 | 104 | /* Yuck.. we need to glue to different versions of the API */ |
105 | ||
106 | #if defined(LDAP_API_VERSION) && LDAP_API_VERSION > 1823 | |
9bea1d5b | 107 | static int |
b671cc68 | 108 | squid_ldap_errno(LDAP * ld) |
87f6d1e1 | 109 | { |
110 | int err = 0; | |
111 | ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err); | |
112 | return err; | |
113 | } | |
9bea1d5b | 114 | static void |
b671cc68 | 115 | squid_ldap_set_aliasderef(LDAP * ld, int deref) |
87f6d1e1 | 116 | { |
117 | ldap_set_option(ld, LDAP_OPT_DEREF, &deref); | |
118 | } | |
9bea1d5b | 119 | static void |
b671cc68 | 120 | squid_ldap_set_referrals(LDAP * ld, int referrals) |
87f6d1e1 | 121 | { |
122 | int *value = referrals ? LDAP_OPT_ON : LDAP_OPT_OFF; | |
123 | ldap_set_option(ld, LDAP_OPT_REFERRALS, value); | |
124 | } | |
a9ce6538 | 125 | static void |
653b264e | 126 | squid_ldap_set_timelimit(LDAP *ld, int timelimit) |
127 | { | |
128 | ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &timelimit); | |
129 | } | |
130 | static void | |
131 | squid_ldap_set_connect_timeout(LDAP *ld, int timelimit) | |
132 | { | |
133 | #if defined(LDAP_OPT_NETWORK_TIMEOUT) | |
134 | struct timeval tv; | |
135 | tv.tv_sec = timelimit; | |
136 | tv.tv_usec = 0; | |
137 | ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv); | |
138 | #elif defined(LDAP_X_OPT_CONNECT_TIMEOUT) | |
139 | timelimit *= 1000; | |
140 | ldap_set_option(ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timelimit); | |
141 | #endif | |
142 | } | |
143 | static void | |
a9ce6538 | 144 | squid_ldap_memfree(char *p) |
145 | { | |
146 | ldap_memfree(p); | |
147 | } | |
87f6d1e1 | 148 | #else |
9bea1d5b | 149 | static int |
b671cc68 | 150 | squid_ldap_errno(LDAP * ld) |
87f6d1e1 | 151 | { |
152 | return ld->ld_errno; | |
153 | } | |
9bea1d5b | 154 | static void |
b671cc68 | 155 | squid_ldap_set_aliasderef(LDAP * ld, int deref) |
87f6d1e1 | 156 | { |
157 | ld->ld_deref = deref; | |
158 | } | |
9bea1d5b | 159 | static void |
b671cc68 | 160 | squid_ldap_set_referrals(LDAP * ld, int referrals) |
87f6d1e1 | 161 | { |
162 | if (referrals) | |
163 | ld->ld_options |= ~LDAP_OPT_REFERRALS; | |
164 | else | |
165 | ld->ld_options &= ~LDAP_OPT_REFERRALS; | |
166 | } | |
653b264e | 167 | static void squid_ldap_set_timelimit(LDAP *ld, int timelimit) |
168 | { | |
169 | ld->ld_timelimit = timelimit; | |
170 | } | |
171 | static void | |
172 | squid_ldap_set_connect_timeout(LDAP *ld, int timelimit) | |
173 | { | |
174 | fprintf(stderr, "Connect timeouts not supported in your LDAP library\n"); | |
175 | } | |
a9ce6538 | 176 | static void |
177 | squid_ldap_memfree(char *p) | |
178 | { | |
179 | free(p); | |
180 | } | |
87f6d1e1 | 181 | #endif |
182 | ||
7ba68818 | 183 | #ifdef LDAP_API_FEATURE_X_OPENLDAP |
184 | #if LDAP_VENDOR_VERSION > 194 | |
185 | #define HAS_URI_SUPPORT 1 | |
186 | #endif | |
187 | #endif | |
188 | ||
94439e4e | 189 | int |
190 | main(int argc, char **argv) | |
191 | { | |
192 | char buf[256]; | |
49b97dc8 | 193 | char *user, *passwd; |
20b6fc8e | 194 | char *ldapServer = NULL; |
c4c1f30c | 195 | LDAP *ld = NULL; |
c4c1f30c | 196 | int tryagain; |
70c46401 | 197 | int port = LDAP_PORT; |
94439e4e | 198 | |
199 | setbuf(stdout, NULL); | |
200 | ||
20b6fc8e | 201 | while (argc > 1 && argv[1][0] == '-') { |
c4c1f30c | 202 | char *value = ""; |
331ba756 | 203 | char option = argv[1][1]; |
b671cc68 | 204 | switch (option) { |
70c46401 | 205 | case 'P': |
50f87883 | 206 | case 'R': |
8370dcf2 | 207 | case 'z': |
2c10afe0 | 208 | case 'Z': |
c4c1f30c | 209 | break; |
210 | default: | |
2c10afe0 | 211 | if (strlen(argv[1]) > 2) { |
b671cc68 | 212 | value = argv[1] + 2; |
2c10afe0 | 213 | } else if (argc > 2) { |
c4c1f30c | 214 | value = argv[2]; |
215 | argv++; | |
216 | argc--; | |
2c10afe0 | 217 | } else |
218 | value = ""; | |
c4c1f30c | 219 | break; |
331ba756 | 220 | } |
221 | argv++; | |
222 | argc--; | |
b671cc68 | 223 | switch (option) { |
7ba68818 | 224 | case 'H': |
225 | #if !HAS_URI_SUPPORT | |
226 | fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n"); | |
227 | exit(1); | |
228 | #endif | |
229 | /* Fall thru to -h */ | |
20b6fc8e | 230 | case 'h': |
231 | if (ldapServer) { | |
232 | int len = strlen(ldapServer) + 1 + strlen(value) + 1; | |
233 | char *newhost = malloc(len); | |
234 | snprintf(newhost, len, "%s %s", ldapServer, value); | |
235 | free(ldapServer); | |
236 | ldapServer = newhost; | |
237 | } else { | |
238 | ldapServer = strdup(value); | |
239 | } | |
240 | break; | |
331ba756 | 241 | case 'b': |
b671cc68 | 242 | basedn = value; |
243 | break; | |
331ba756 | 244 | case 'f': |
b671cc68 | 245 | searchfilter = value; |
246 | break; | |
7c2a6c51 | 247 | case 'u': |
b671cc68 | 248 | userattr = value; |
249 | break; | |
331ba756 | 250 | case 's': |
b671cc68 | 251 | if (strcmp(value, "base") == 0) |
252 | searchscope = LDAP_SCOPE_BASE; | |
253 | else if (strcmp(value, "one") == 0) | |
254 | searchscope = LDAP_SCOPE_ONELEVEL; | |
255 | else if (strcmp(value, "sub") == 0) | |
256 | searchscope = LDAP_SCOPE_SUBTREE; | |
257 | else { | |
653b264e | 258 | fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown search scope '%s'\n", value); |
b671cc68 | 259 | exit(1); |
260 | } | |
261 | break; | |
653b264e | 262 | case 'E': |
263 | #if defined(NETSCAPE_SSL) | |
264 | sslpath = value; | |
265 | if (port == LDAP_PORT) | |
266 | port = LDAPS_PORT; | |
267 | #else | |
268 | fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n"); | |
269 | exit(1); | |
270 | #endif | |
271 | break; | |
272 | case 'c': | |
273 | connect_timeout = atoi(value); | |
274 | break; | |
275 | case 't': | |
276 | timelimit = atoi(value); | |
277 | break; | |
50f87883 | 278 | case 'a': |
b671cc68 | 279 | if (strcmp(value, "never") == 0) |
280 | aliasderef = LDAP_DEREF_NEVER; | |
281 | else if (strcmp(value, "always") == 0) | |
282 | aliasderef = LDAP_DEREF_ALWAYS; | |
283 | else if (strcmp(value, "search") == 0) | |
284 | aliasderef = LDAP_DEREF_SEARCHING; | |
285 | else if (strcmp(value, "find") == 0) | |
286 | aliasderef = LDAP_DEREF_FINDING; | |
287 | else { | |
653b264e | 288 | fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown alias dereference method '%s'\n", value); |
b671cc68 | 289 | exit(1); |
290 | } | |
291 | break; | |
c4c1f30c | 292 | case 'D': |
b671cc68 | 293 | binddn = value; |
294 | break; | |
c4c1f30c | 295 | case 'w': |
b671cc68 | 296 | bindpasswd = value; |
297 | break; | |
954a8513 | 298 | case 'W': |
299 | readSecret (value); | |
300 | break; | |
70c46401 | 301 | case 'P': |
b671cc68 | 302 | persistent = !persistent; |
303 | break; | |
70c46401 | 304 | case 'p': |
305 | port = atoi(value); | |
306 | break; | |
50f87883 | 307 | case 'R': |
b671cc68 | 308 | noreferrals = !noreferrals; |
309 | break; | |
653b264e | 310 | #ifdef LDAP_VERSION3 |
8370dcf2 | 311 | case 'v': |
312 | switch( atoi(value) ) { | |
313 | case 2: | |
314 | version = LDAP_VERSION2; | |
315 | break; | |
316 | case 3: | |
317 | version = LDAP_VERSION3; | |
318 | break; | |
319 | default: | |
320 | fprintf( stderr, "Protocol version should be 2 or 3\n"); | |
321 | exit(1); | |
322 | } | |
323 | break; | |
324 | case 'Z': | |
325 | if ( version == LDAP_VERSION2 ) { | |
326 | fprintf( stderr, "TLS (-Z) is incompatible with version %d\n", | |
327 | version); | |
328 | exit(1); | |
329 | } | |
330 | version = LDAP_VERSION3; | |
331 | use_tls = 1; | |
332 | break; | |
653b264e | 333 | #endif |
331ba756 | 334 | default: |
653b264e | 335 | fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown command line option '%c'\n", option); |
b671cc68 | 336 | exit(1); |
331ba756 | 337 | } |
338 | } | |
7c2a6c51 | 339 | |
2c10afe0 | 340 | while (argc > 1) { |
20b6fc8e | 341 | char *value = argv[1]; |
342 | if (ldapServer) { | |
343 | int len = strlen(ldapServer) + 1 + strlen(value) + 1; | |
344 | char *newhost = malloc(len); | |
345 | snprintf(newhost, len, "%s %s", ldapServer, value); | |
346 | free(ldapServer); | |
347 | ldapServer = newhost; | |
348 | } else { | |
349 | ldapServer = strdup(value); | |
350 | } | |
351 | argc--; | |
352 | argv++; | |
353 | } | |
354 | if (!ldapServer) | |
355 | ldapServer = "localhost"; | |
356 | ||
357 | if (!basedn) { | |
653b264e | 358 | fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn [options] [ldap_server_name[:port]]...\n\n"); |
7c2a6c51 | 359 | fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under which to search\n"); |
c4c1f30c | 360 | fprintf(stderr, "\t-f filter\t\tsearch filter to locate user DN\n"); |
7c2a6c51 | 361 | fprintf(stderr, "\t-u userattr\t\tusername DN attribute\n"); |
c4c1f30c | 362 | fprintf(stderr, "\t-s base|one|sub\t\tsearch scope\n"); |
363 | fprintf(stderr, "\t-D binddn\t\tDN to bind as to perform searches\n"); | |
364 | fprintf(stderr, "\t-w bindpasswd\t\tpassword for binddn\n"); | |
954a8513 | 365 | fprintf(stderr, "\t-W secretfile\t\tread password for binddn from file secretfile\n"); |
7ba68818 | 366 | #if HAS_URI_SUPPORT |
367 | fprintf(stderr, "\t-H URI\t\t\tLDAPURI (defaults to ldap://localhost)\n"); | |
368 | #endif | |
20b6fc8e | 369 | fprintf(stderr, "\t-h server\t\tLDAP server (defaults to localhost)\n"); |
de896945 | 370 | fprintf(stderr, "\t-p port\t\t\tLDAP server port\n"); |
20b6fc8e | 371 | fprintf(stderr, "\t-P\t\t\tpersistent LDAP connection\n"); |
653b264e | 372 | #if defined(NETSCAPE_SSL) |
373 | fprintf(stderr, "\t-E sslcertpath\t\tenable LDAP over SSL\n"); | |
374 | #endif | |
375 | fprintf(stderr, "\t-c timeout\t\tconnect timeout\n"); | |
376 | fprintf(stderr, "\t-t timelimit\t\tsearch time limit\n"); | |
50f87883 | 377 | fprintf(stderr, "\t-R\t\t\tdo not follow referrals\n"); |
378 | fprintf(stderr, "\t-a never|always|search|find\n\t\t\t\twhen to dereference aliases\n"); | |
7ba68818 | 379 | #ifdef LDAP_VERSION3 |
380 | fprintf(stderr, "\t-v 2|3\t\t\tLDAP version\n"); | |
b3154cd7 | 381 | fprintf(stderr, "\t-Z\t\t\tTLS encrypt the LDAP connection, requires LDAP version 3\n"); |
7ba68818 | 382 | #endif |
c4c1f30c | 383 | fprintf(stderr, "\n"); |
7c2a6c51 | 384 | fprintf(stderr, "\tIf no search filter is specified, then the dn <userattr>=user,basedn\n\twill be used (same as specifying a search filter of '<userattr>=',\n\tbut quicker as as there is no need to search for the user DN)\n\n"); |
954a8513 | 385 | 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"); |
94439e4e | 386 | exit(1); |
387 | } | |
94439e4e | 388 | while (fgets(buf, 256, stdin) != NULL) { |
49b97dc8 | 389 | user = strtok(buf, " \r\n"); |
2542502f | 390 | passwd = strtok(NULL, "\r\n"); |
94439e4e | 391 | |
49b97dc8 | 392 | if (!user || !passwd || !passwd[0]) { |
94439e4e | 393 | printf("ERR\n"); |
394 | continue; | |
395 | } | |
9bbd1655 | 396 | rfc1738_unescape(user); |
397 | rfc1738_unescape(passwd); | |
c4c1f30c | 398 | tryagain = 1; |
b671cc68 | 399 | recover: |
c4c1f30c | 400 | if (ld == NULL) { |
7ba68818 | 401 | #if HAS_URI_SUPPORT |
402 | if (strstr(ldapServer, "://") != NULL) { | |
653b264e | 403 | int rc = ldap_initialize( &ld, ldapServer ); |
7ba68818 | 404 | if( rc != LDAP_SUCCESS ) { |
405 | fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer); | |
406 | break; | |
407 | } | |
408 | } else | |
653b264e | 409 | #endif |
410 | #if NETSCAPE_SSL | |
411 | if (sslpath) { | |
412 | if ( !sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) { | |
413 | fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n", | |
414 | sslpath); | |
415 | exit(1); | |
416 | } else { | |
417 | sslinit++; | |
418 | } | |
419 | if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) { | |
420 | fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n", | |
421 | ldapServer, port); | |
422 | exit(1); | |
423 | } | |
424 | } else | |
7ba68818 | 425 | #endif |
70c46401 | 426 | if ((ld = ldap_init(ldapServer, port)) == NULL) { |
c4c1f30c | 427 | fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", |
70c46401 | 428 | ldapServer, port); |
c4c1f30c | 429 | exit(1); |
430 | } | |
8370dcf2 | 431 | |
653b264e | 432 | if (connect_timeout) |
433 | squid_ldap_set_connect_timeout(ld, connect_timeout); | |
434 | ||
435 | #ifdef LDAP_VERSION3 | |
436 | if (version == -1 ) { | |
8370dcf2 | 437 | version = LDAP_VERSION2; |
653b264e | 438 | } |
8370dcf2 | 439 | |
653b264e | 440 | if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) |
441 | != LDAP_OPT_SUCCESS ) | |
442 | { | |
8370dcf2 | 443 | fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", |
444 | version ); | |
445 | exit(1); | |
653b264e | 446 | } |
8370dcf2 | 447 | |
653b264e | 448 | if ( use_tls && ( version == LDAP_VERSION3 ) && ( ldap_start_tls_s( ld, NULL, NULL ) == LDAP_SUCCESS )) { |
8370dcf2 | 449 | fprintf( stderr, "Could not Activate TLS connection\n"); |
450 | exit(1); | |
653b264e | 451 | } |
452 | #endif | |
453 | squid_ldap_set_timelimit(ld, timelimit); | |
87f6d1e1 | 454 | squid_ldap_set_referrals(ld, !noreferrals); |
455 | squid_ldap_set_aliasderef(ld, aliasderef); | |
94439e4e | 456 | } |
6ee0ef8e | 457 | if (checkLDAP(ld, user, passwd) != 0) { |
87f6d1e1 | 458 | if (tryagain && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS) { |
c4c1f30c | 459 | tryagain = 0; |
460 | ldap_unbind(ld); | |
461 | ld = NULL; | |
462 | goto recover; | |
463 | } | |
94439e4e | 464 | printf("ERR\n"); |
94439e4e | 465 | } else { |
466 | printf("OK\n"); | |
467 | } | |
87f6d1e1 | 468 | if (!persistent || (squid_ldap_errno(ld) != LDAP_SUCCESS && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS)) { |
c4c1f30c | 469 | ldap_unbind(ld); |
470 | ld = NULL; | |
471 | } | |
94439e4e | 472 | } |
c4c1f30c | 473 | if (ld) |
474 | ldap_unbind(ld); | |
331ba756 | 475 | return 0; |
94439e4e | 476 | } |
477 | ||
c4c1f30c | 478 | static int |
94439e4e | 479 | checkLDAP(LDAP * ld, char *userid, char *password) |
480 | { | |
331ba756 | 481 | char dn[256]; |
94439e4e | 482 | |
c4c1f30c | 483 | if (!*password) { |
484 | /* LDAP can't bind with a blank password. Seen as "anonymous" | |
485 | * and always granted access | |
486 | */ | |
487 | return 1; | |
488 | } | |
331ba756 | 489 | if (searchfilter) { |
490 | char filter[256]; | |
491 | LDAPMessage *res = NULL; | |
492 | LDAPMessage *entry; | |
b671cc68 | 493 | char *searchattr[] = |
494 | {NULL}; | |
331ba756 | 495 | char *userdn; |
50f87883 | 496 | int rc; |
94439e4e | 497 | |
c4c1f30c | 498 | if (binddn) { |
50f87883 | 499 | rc = ldap_simple_bind_s(ld, binddn, bindpasswd); |
500 | if (rc != LDAP_SUCCESS) { | |
653b264e | 501 | fprintf(stderr, PROGRAM_NAME ": WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc)); |
c4c1f30c | 502 | return 1; |
503 | } | |
504 | } | |
c9acd551 | 505 | snprintf(filter, sizeof(filter), searchfilter, userid, userid, userid, userid, userid, userid, userid, userid, userid, userid, userid, userid, userid, userid, userid); |
4e9ab9a6 | 506 | rc = ldap_search_s(ld, basedn, searchscope, filter, searchattr, 1, &res); |
507 | if (rc != LDAP_SUCCESS) { | |
60ce38ae | 508 | if (noreferrals && rc == LDAP_PARTIAL_RESULTS) { |
509 | /* Everything is fine. This is expected when referrals | |
510 | * are disabled. | |
50f87883 | 511 | */ |
60ce38ae | 512 | } else { |
653b264e | 513 | fprintf(stderr, PROGRAM_NAME ": WARNING, LDAP search error '%s'\n", ldap_err2string(rc)); |
514 | #if defined(NETSCAPE_SSL) | |
515 | if (sslpath && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))) { | |
516 | int sslerr = PORT_GetError(); | |
517 | fprintf(stderr, PROGRAM_NAME ": WARNING, SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr)); | |
518 | } | |
519 | #endif | |
46412b38 | 520 | ldap_msgfree(res); |
521 | return 1; | |
50f87883 | 522 | } |
523 | } | |
331ba756 | 524 | entry = ldap_first_entry(ld, res); |
525 | if (!entry) { | |
526 | ldap_msgfree(res); | |
527 | return 1; | |
528 | } | |
529 | userdn = ldap_get_dn(ld, entry); | |
530 | if (!userdn) { | |
653b264e | 531 | fprintf(stderr, PROGRAM_NAME ": ERROR, could not get user DN for '%s'\n", userid); |
331ba756 | 532 | ldap_msgfree(res); |
533 | return 1; | |
534 | } | |
535 | snprintf(dn, sizeof(dn), "%s", userdn); | |
8f64c86a | 536 | squid_ldap_memfree(userdn); |
331ba756 | 537 | ldap_msgfree(res); |
538 | } else { | |
7c2a6c51 | 539 | snprintf(dn, sizeof(dn), "%s=%s,%s", userattr, userid, basedn); |
94439e4e | 540 | } |
331ba756 | 541 | |
c4c1f30c | 542 | if (ldap_simple_bind_s(ld, dn, password) != LDAP_SUCCESS) |
543 | return 1; | |
b671cc68 | 544 | |
c4c1f30c | 545 | return 0; |
94439e4e | 546 | } |
954a8513 | 547 | |
548 | int readSecret(char *filename) | |
549 | { | |
550 | char buf[BUFSIZ]; | |
551 | char *e=0; | |
552 | FILE *f; | |
553 | ||
554 | if(!(f=fopen(filename, "r"))) { | |
555 | fprintf(stderr, PROGRAM_NAME " ERROR: Can not read secret file %s\n", filename); | |
556 | return 1; | |
557 | } | |
558 | ||
559 | if( !fgets(buf, sizeof(buf)-1, f)) { | |
560 | fprintf(stderr, PROGRAM_NAME " ERROR: Secret file %s is empty\n", filename); | |
561 | fclose(f); | |
562 | return 1; | |
563 | } | |
564 | ||
565 | /* strip whitespaces on end */ | |
566 | if((e = strrchr(buf, '\n'))) *e = 0; | |
567 | if((e = strrchr(buf, '\r'))) *e = 0; | |
568 | ||
569 | bindpasswd = (char *) calloc(sizeof(char), strlen(buf)+1); | |
570 | if (bindpasswd) { | |
571 | strcpy(bindpasswd, buf); | |
572 | } else { | |
573 | fprintf(stderr, PROGRAM_NAME " ERROR: can not allocate memory\n"); | |
574 | } | |
575 | ||
576 | fclose(f); | |
577 | ||
578 | return 0; | |
579 | } |