]> git.ipfire.org Git - thirdparty/squid.git/blame - src/auth/digest/LDAP/ldap_backend.cc
Source Format Enforcement (#963)
[thirdparty/squid.git] / src / auth / digest / LDAP / ldap_backend.cc
CommitLineData
7ed0602b 1/*
bf95c10a 2 * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
7ed0602b 3 *
ca02e0ec
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/*
7ed0602b 10 * AUTHOR: Flavio Pescuma, MARA Systems AB <flavio@marasystems.com>
11 */
ca02e0ec 12
f7f3304a 13#include "squid.h"
bb85e424 14#include "util.h"
46962e36 15
16#define LDAP_DEPRECATED 1
17
d4d7f6dd 18#include "auth/digest/LDAP/ldap_backend.h"
7ed0602b 19
7aa9bb3e 20#if _SQUID_WINDOWS_ && !_SQUID_CYGWIN_
7ed0602b 21
22#define snprintf _snprintf
23#include <windows.h>
24#include <winldap.h>
25#ifndef LDAPAPI
26#define LDAPAPI __cdecl
27#endif
28#ifdef LDAP_VERSION3
29#ifndef LDAP_OPT_X_TLS
30#define LDAP_OPT_X_TLS 0x6000
31#endif
32/* Some tricks to allow dynamic bind with ldap_start_tls_s entry point at
068d42c5 33 * run time.
7ed0602b 34 */
35#undef ldap_start_tls_s
36#if LDAP_UNICODE
37#define LDAP_START_TLS_S "ldap_start_tls_sW"
068d42c5 38typedef WINLDAPAPI ULONG(LDAPAPI * PFldap_start_tls_s) (IN PLDAP, OUT PULONG, OUT LDAPMessage **, IN PLDAPControlW *, IN PLDAPControlW *);
7ed0602b 39#else
40#define LDAP_START_TLS_S "ldap_start_tls_sA"
068d42c5 41typedef WINLDAPAPI ULONG(LDAPAPI * PFldap_start_tls_s) (IN PLDAP, OUT PULONG, OUT LDAPMessage **, IN PLDAPControlA *, IN PLDAPControlA *);
7ed0602b 42#endif /* LDAP_UNICODE */
43PFldap_start_tls_s Win32_ldap_start_tls_s;
44#define ldap_start_tls_s(l,s,c) Win32_ldap_start_tls_s(l,NULL,NULL,s,c)
45#endif /* LDAP_VERSION3 */
46
47#else
48
49#include <lber.h>
50#include <ldap.h>
51
52#endif
53#define PROGRAM_NAME "digest_pw_auth(LDAP_backend)"
54
55/* Globals */
56
57static LDAP *ld = NULL;
e9505fad 58static const char *passattr = NULL;
7ed0602b 59static char *ldapServer = NULL;
e9505fad 60static const char *userbasedn = NULL;
61static const char *userdnattr = NULL;
62static const char *usersearchfilter = NULL;
63static const char *binddn = NULL;
64static const char *bindpasswd = NULL;
65static const char *delimiter = ":";
46e791c6 66static const char *frealm = "";
7ed0602b 67static int encrpass = 0;
68static int searchscope = LDAP_SCOPE_SUBTREE;
69static int persistent = 0;
70static int noreferrals = 0;
7ed0602b 71static int port = LDAP_PORT;
72static int strip_nt_domain = 0;
73static int aliasderef = LDAP_DEREF_NEVER;
74#if defined(NETSCAPE_SSL)
75static char *sslpath = NULL;
76static int sslinit = 0;
77#endif
78static int connect_timeout = 0;
79static int timelimit = LDAP_NO_LIMIT;
80
81#ifdef LDAP_VERSION3
82/* Added for TLS support and version 3 */
83static int use_tls = 0;
84static int version = -1;
85#endif
86
87static void ldapconnect(void);
e9505fad 88static int readSecret(const char *filename);
7ed0602b 89
90/* Yuck.. we need to glue to different versions of the API */
91
92#if defined(LDAP_API_VERSION) && LDAP_API_VERSION > 1823
93static void
94squid_ldap_set_aliasderef(int deref)
95{
96 ldap_set_option(ld, LDAP_OPT_DEREF, &deref);
97}
98static void
99squid_ldap_set_referrals(int referrals)
100{
56ff4687 101 int *value = static_cast<int*>(referrals ? LDAP_OPT_ON :LDAP_OPT_OFF);
7ed0602b 102 ldap_set_option(ld, LDAP_OPT_REFERRALS, value);
103}
104static void
d5f8d05f 105squid_ldap_set_timelimit(int aTimeLimit)
7ed0602b 106{
d5f8d05f 107 ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &aTimeLimit);
7ed0602b 108}
109static void
d5f8d05f 110squid_ldap_set_connect_timeout(int aTimeLimit)
7ed0602b 111{
112#if defined(LDAP_OPT_NETWORK_TIMEOUT)
113 struct timeval tv;
d5f8d05f 114 tv.tv_sec = aTimeLimit;
7ed0602b 115 tv.tv_usec = 0;
116 ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);
117#elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
d5f8d05f
FC
118 aTimeLimit *= 1000;
119 ldap_set_option(ld, LDAP_X_OPT_CONNECT_TIMEOUT, &aTimeLimit);
7ed0602b 120#endif
121}
122
123#else
124static int
125squid_ldap_errno(LDAP * ld)
126{
127 return ld->ld_errno;
128}
129static void
130squid_ldap_set_aliasderef(int deref)
131{
132 ld->ld_deref = deref;
133}
134static void
135squid_ldap_set_referrals(int referrals)
136{
137 if (referrals)
26ac0430 138 ld->ld_options |= ~LDAP_OPT_REFERRALS;
7ed0602b 139 else
26ac0430 140 ld->ld_options &= ~LDAP_OPT_REFERRALS;
7ed0602b 141}
142static void
d5f8d05f 143squid_ldap_set_timelimit(int aTimeLimit)
7ed0602b 144{
d5f8d05f 145 ld->ld_timelimit = aTimeLimit;
7ed0602b 146}
147static void
d5f8d05f 148squid_ldap_set_connect_timeout(int aTimeLimit)
7ed0602b 149{
150 fprintf(stderr, "Connect timeouts not supported in your LDAP library\n");
151}
152static void
153squid_ldap_memfree(char *p)
154{
155 free(p);
156}
157
158#endif
159
160#ifdef LDAP_API_FEATURE_X_OPENLDAP
161#if LDAP_VENDOR_VERSION > 194
162#define HAS_URI_SUPPORT 1
163#endif
164#endif
165
166static int
167ldap_escape_value(char *escaped, int size, const char *src)
168{
169 int n = 0;
170 while (size > 4 && *src) {
26ac0430
AJ
171 switch (*src) {
172 case '*':
173 case '(':
174 case ')':
175 case '\\':
176 n += 3;
177 size -= 3;
178 if (size > 0) {
f207fe64
FC
179 *escaped = '\\';
180 ++escaped;
14942edd
FC
181 snprintf(escaped, 3, "%02x", (int) *src);
182 ++src;
26ac0430
AJ
183 escaped += 2;
184 }
185 break;
186 default:
14942edd
FC
187 *escaped = *src;
188 ++escaped;
189 ++src;
755494da
FC
190 ++n;
191 --size;
26ac0430 192 }
7ed0602b 193 }
194 *escaped = '\0';
195 return n;
196}
197
198static char *
199getpassword(char *login, char *realm)
200{
201 LDAPMessage *res = NULL;
202 LDAPMessage *entry;
203 char **values = NULL;
204 char **value = NULL;
205 char *password = NULL;
206 int retry = 0;
207 char filter[8192];
208 char searchbase[8192];
209 int rc = -1;
210 if (ld) {
26ac0430
AJ
211 if (usersearchfilter) {
212 char escaped_login[1024];
213 snprintf(searchbase, sizeof(searchbase), "%s", userbasedn);
214 ldap_escape_value(escaped_login, sizeof(escaped_login), login);
215 snprintf(filter, sizeof(filter), usersearchfilter, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login);
216
217retrysrch:
56ff4687 218 debug("user filter '%s', searchbase '%s'\n", filter, searchbase);
26ac0430
AJ
219
220 rc = ldap_search_s(ld, searchbase, searchscope, filter, NULL, 0, &res);
221 if (rc != LDAP_SUCCESS) {
222 if (noreferrals && rc == LDAP_PARTIAL_RESULTS) {
223 /* Everything is fine. This is expected when referrals
224 * are disabled.
225 */
226 rc = LDAP_SUCCESS;
227 } else {
228 fprintf(stderr, PROGRAM_NAME " WARNING, LDAP search error '%s'\n", ldap_err2string(rc));
7ed0602b 229#if defined(NETSCAPE_SSL)
26ac0430
AJ
230 if (sslpath && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))) {
231 int sslerr = PORT_GetError();
232 fprintf(stderr, PROGRAM_NAME ": WARNING, SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr));
233 }
7ed0602b 234#endif
26ac0430
AJ
235 fprintf(stderr, PROGRAM_NAME " WARNING, LDAP search error, trying to recover'%s'\n", ldap_err2string(rc));
236 ldap_msgfree(res);
2f8abb64 237 /* try to connect to the LDAP server again, maybe my persistent conexion failed. */
26ac0430 238 if (!retry) {
755494da 239 ++retry;
26ac0430
AJ
240 ldap_unbind(ld);
241 ld = NULL;
242 ldapconnect();
243 goto retrysrch;
244 }
245 return NULL;
246
247 }
248 }
249 } else if (userdnattr) {
0e0f1358 250 snprintf(filter,8192,"%s=%s",userdnattr,login);
26ac0430
AJ
251
252retrydnattr:
0e0f1358
AJ
253 debug("searchbase '%s'\n", userbasedn);
254 rc = ldap_search_s(ld, userbasedn, searchscope, filter, NULL, 0, &res);
26ac0430
AJ
255 }
256 if (rc == LDAP_SUCCESS) {
257 entry = ldap_first_entry(ld, res);
258 if (entry)
259 values = ldap_get_values(ld, entry, passattr);
260 else {
261 ldap_msgfree(res);
262 return NULL;
263 }
264 if (!values) {
56ff4687 265 debug("No attribute value found\n");
26ac0430
AJ
266 ldap_msgfree(res);
267 return NULL;
268 }
269 value = values;
270 while (*value) {
46e791c6 271 if (encrpass && *delimiter ) {
aa8c6def
AJ
272 const char *t = strtok(*value, delimiter);
273 if (t && strcmp(t, realm) == 0) {
26ac0430
AJ
274 password = strtok(NULL, delimiter);
275 break;
276 }
277 } else {
278 password = *value;
279 break;
280 }
755494da 281 ++value;
26ac0430 282 }
56ff4687 283 debug("password: %s\n", password);
26ac0430 284 if (password)
bb85e424 285 password = xstrdup(password);
26ac0430
AJ
286 ldap_value_free(values);
287 ldap_msgfree(res);
288 return password;
289 } else {
290 fprintf(stderr, PROGRAM_NAME " WARNING, LDAP error '%s'\n", ldap_err2string(rc));
2f8abb64 291 /* try to connect to the LDAP server again, maybe my persistent conexion failed. */
26ac0430 292 if (!retry) {
755494da 293 ++retry;
26ac0430
AJ
294 ldap_unbind(ld);
295 ld = NULL;
296 ldapconnect();
297 goto retrydnattr;
298 }
299 return NULL;
300 }
7ed0602b 301 }
302 return NULL;
303}
304
7ed0602b 305static void
306ldapconnect(void)
307{
308 int rc;
309
26ac0430
AJ
310 /* On Windows ldap_start_tls_s is available starting from Windows XP,
311 * so we need to bind at run-time with the function entry point
312 */
7aa9bb3e 313#if _SQUID_WINDOWS_
7ed0602b 314 if (use_tls) {
315
26ac0430 316 HMODULE WLDAP32Handle;
7ed0602b 317
26ac0430
AJ
318 WLDAP32Handle = GetModuleHandle("wldap32");
319 if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) {
320 fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n");
24885773 321 exit(EXIT_FAILURE);
26ac0430 322 }
7ed0602b 323 }
324#endif
325
326 if (ld == NULL) {
327#if HAS_URI_SUPPORT
26ac0430
AJ
328 if (strstr(ldapServer, "://") != NULL) {
329 rc = ldap_initialize(&ld, ldapServer);
330 if (rc != LDAP_SUCCESS) {
331 fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer);
332 }
333 } else
7ed0602b 334#endif
335#if NETSCAPE_SSL
26ac0430
AJ
336 if (sslpath) {
337 if (!sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) {
338 fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n",
339 sslpath);
24885773 340 exit(EXIT_FAILURE);
26ac0430 341 } else {
755494da 342 ++sslinit;
26ac0430
AJ
343 }
344 if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) {
345 fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n",
346 ldapServer, port);
24885773 347 exit(EXIT_FAILURE);
26ac0430
AJ
348 }
349 } else
7ed0602b 350#endif
26ac0430
AJ
351 if ((ld = ldap_init(ldapServer, port)) == NULL) {
352 fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, port);
353 }
354 if (connect_timeout)
355 squid_ldap_set_connect_timeout(connect_timeout);
7ed0602b 356
357#ifdef LDAP_VERSION3
26ac0430
AJ
358 if (version == -1) {
359 version = LDAP_VERSION2;
360 }
361 if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version)
362 != LDAP_SUCCESS) {
363 fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
364 version);
365 ldap_unbind(ld);
366 ld = NULL;
367 }
368 if (use_tls) {
e11ffec3 369#ifdef LDAP_OPT_X_TLS
59bce1e8
AJ
370 if (version != LDAP_VERSION3) {
371 fprintf(stderr, "TLS requires LDAP version 3\n");
24885773 372 exit(EXIT_FAILURE);
59bce1e8 373 } else if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) {
26ac0430 374 fprintf(stderr, "Could not Activate TLS connection\n");
24885773 375 exit(EXIT_FAILURE);
26ac0430 376 }
e11ffec3 377#else
26ac0430
AJ
378 fprintf(stderr, "TLS not supported with your LDAP library\n");
379 ldap_unbind(ld);
380 ld = NULL;
e11ffec3 381#endif
26ac0430 382 }
7ed0602b 383#endif
26ac0430
AJ
384 squid_ldap_set_timelimit(timelimit);
385 squid_ldap_set_referrals(!noreferrals);
386 squid_ldap_set_aliasderef(aliasderef);
387 if (binddn && bindpasswd && *binddn && *bindpasswd) {
388 rc = ldap_simple_bind_s(ld, binddn, bindpasswd);
389 if (rc != LDAP_SUCCESS) {
390 fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc));
391 ldap_unbind(ld);
392 ld = NULL;
393 }
394 }
56ff4687 395 debug("Connected OK\n");
7ed0602b 396 }
397}
398int
399LDAPArguments(int argc, char **argv)
400{
401 setbuf(stdout, NULL);
402
403 while (argc > 1 && argv[1][0] == '-') {
26ac0430
AJ
404 const char *value = "";
405 char option = argv[1][1];
406 switch (option) {
407 case 'P':
408 case 'R':
409 case 'z':
410 case 'Z':
411 case 'g':
412 case 'e':
413 case 'S':
414 break;
415 default:
416 if (strlen(argv[1]) > 2) {
417 value = argv[1] + 2;
418 } else if (argc > 2) {
419 value = argv[2];
755494da
FC
420 ++argv;
421 --argc;
26ac0430
AJ
422 } else
423 value = "";
424 break;
425 }
755494da
FC
426 ++argv;
427 --argc;
26ac0430
AJ
428 switch (option) {
429 case 'H':
7ed0602b 430#if !HAS_URI_SUPPORT
26ac0430
AJ
431 fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n");
432 return 1;
7ed0602b 433#endif
f53969cc 434 /* Fall thru to -h */
26ac0430
AJ
435 case 'h':
436 if (ldapServer) {
437 int len = strlen(ldapServer) + 1 + strlen(value) + 1;
c14fb378 438 char *newhost = static_cast<char*>(xmalloc(len));
26ac0430
AJ
439 snprintf(newhost, len, "%s %s", ldapServer, value);
440 free(ldapServer);
441 ldapServer = newhost;
442 } else {
bb85e424 443 ldapServer = xstrdup(value);
26ac0430
AJ
444 }
445 break;
446 case 'A':
447 passattr = value;
448 break;
449 case 'e':
450 encrpass = 1;
451 break;
452 case 'l':
453 delimiter = value;
454 break;
46e791c6
EF
455 case 'r':
456 frealm = value;
457 break;
26ac0430
AJ
458 case 'b':
459 userbasedn = value;
460 break;
461 case 'F':
462 usersearchfilter = value;
463 break;
464 case 'u':
465 userdnattr = value;
466 break;
467 case 's':
468 if (strcmp(value, "base") == 0)
469 searchscope = LDAP_SCOPE_BASE;
470 else if (strcmp(value, "one") == 0)
471 searchscope = LDAP_SCOPE_ONELEVEL;
472 else if (strcmp(value, "sub") == 0)
473 searchscope = LDAP_SCOPE_SUBTREE;
474 else {
475 fprintf(stderr, PROGRAM_NAME " ERROR: Unknown search scope '%s'\n", value);
476 return 1;
477 }
478 break;
479 case 'S':
7ed0602b 480#if defined(NETSCAPE_SSL)
26ac0430
AJ
481 sslpath = value;
482 if (port == LDAP_PORT)
483 port = LDAPS_PORT;
7ed0602b 484#else
26ac0430
AJ
485 fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n");
486 return 1;
7ed0602b 487#endif
26ac0430
AJ
488 break;
489 case 'c':
490 connect_timeout = atoi(value);
491 break;
492 case 't':
493 timelimit = atoi(value);
494 break;
495 case 'a':
496 if (strcmp(value, "never") == 0)
497 aliasderef = LDAP_DEREF_NEVER;
498 else if (strcmp(value, "always") == 0)
499 aliasderef = LDAP_DEREF_ALWAYS;
500 else if (strcmp(value, "search") == 0)
501 aliasderef = LDAP_DEREF_SEARCHING;
502 else if (strcmp(value, "find") == 0)
503 aliasderef = LDAP_DEREF_FINDING;
504 else {
505 fprintf(stderr, PROGRAM_NAME " ERROR: Unknown alias dereference method '%s'\n", value);
506 return 1;
507 }
508 break;
509 case 'D':
510 binddn = value;
511 break;
512 case 'w':
513 bindpasswd = value;
514 break;
515 case 'W':
516 readSecret(value);
517 break;
518 case 'P':
519 persistent = !persistent;
520 break;
521 case 'p':
522 port = atoi(value);
523 break;
524 case 'R':
525 noreferrals = !noreferrals;
526 break;
7ed0602b 527#ifdef LDAP_VERSION3
26ac0430
AJ
528 case 'v':
529 switch (atoi(value)) {
530 case 2:
531 version = LDAP_VERSION2;
532 break;
533 case 3:
534 version = LDAP_VERSION3;
535 break;
536 default:
537 fprintf(stderr, "Protocol version should be 2 or 3\n");
538 return 1;
539 }
540 break;
541 case 'Z':
542 if (version == LDAP_VERSION2) {
543 fprintf(stderr, "TLS (-Z) is incompatible with version %d\n",
544 version);
545 return 1;
546 }
547 version = LDAP_VERSION3;
548 use_tls = 1;
549 break;
7ed0602b 550#endif
26ac0430 551 case 'd':
56ff4687 552 debug_enabled = 1;
26ac0430
AJ
553 break;
554 case 'E':
555 strip_nt_domain = 1;
556 break;
557 default:
558 fprintf(stderr, PROGRAM_NAME " ERROR: Unknown command line option '%c'\n", option);
559 return 1;
560 }
7ed0602b 561 }
562
563 while (argc > 1) {
26ac0430
AJ
564 char *value = argv[1];
565 if (ldapServer) {
566 int len = strlen(ldapServer) + 1 + strlen(value) + 1;
c14fb378 567 char *newhost = static_cast<char*>(xmalloc(len));
26ac0430
AJ
568 snprintf(newhost, len, "%s %s", ldapServer, value);
569 free(ldapServer);
570 ldapServer = newhost;
571 } else {
bb85e424 572 ldapServer = xstrdup(value);
26ac0430 573 }
755494da
FC
574 --argc;
575 ++argv;
7ed0602b 576 }
577
578 if (!ldapServer)
26ac0430 579 ldapServer = (char *) "localhost";
7ed0602b 580
46e791c6
EF
581 if (!userbasedn || !passattr || (!*delimiter && !*frealm)) {
582 fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn -F filter [options] ldap_server_name\n\n");
26ac0430 583 fprintf(stderr, "\t-A password attribute(REQUIRED)\t\tUser attribute that contains the password\n");
46e791c6
EF
584 fprintf(stderr, "\t-l password realm delimiter(REQUIRED)\tCharacter(s) that divides the password attribute\n\t\t\t\t\t\tin realm and password tokens, default ':' realm:password, could be\n\t\t\t\t\t\tempty string if the password is alone in the password attribute\n");
585 fprintf(stderr, "\t-r filtered realm\t\t\tonly honor Squid requests for this realm. Mandatory if the password is alone in\n\t\t\t\t\t\tthe password attribute, acting as the implicit realm\n");
26ac0430
AJ
586 fprintf(stderr, "\t-b basedn (REQUIRED)\t\t\tbase dn under where to search for users\n");
587 fprintf(stderr, "\t-e Encrypted passwords(REQUIRED)\tPassword are stored encrypted using HHA1\n");
588 fprintf(stderr, "\t-F filter\t\t\t\tuser search filter pattern. %%s = login\n");
589 fprintf(stderr, "\t-u attribute\t\t\t\tattribute to use in combination with the basedn to create the user DN\n");
590 fprintf(stderr, "\t-s base|one|sub\t\t\t\tsearch scope\n");
591 fprintf(stderr, "\t-D binddn\t\t\t\tDN to bind as to perform searches\n");
592 fprintf(stderr, "\t-w bindpasswd\t\t\t\tpassword for binddn\n");
593 fprintf(stderr, "\t-W secretfile\t\t\t\tread password for binddn from file secretfile\n");
7ed0602b 594#if HAS_URI_SUPPORT
26ac0430 595 fprintf(stderr, "\t-H URI\t\t\t\t\tLDAPURI (defaults to ldap://localhost)\n");
7ed0602b 596#endif
26ac0430
AJ
597 fprintf(stderr, "\t-h server\t\t\t\tLDAP server (defaults to localhost)\n");
598 fprintf(stderr, "\t-p port\t\t\t\t\tLDAP server port (defaults to %d)\n", LDAP_PORT);
599 fprintf(stderr, "\t-P\t\t\t\t\tpersistent LDAP connection\n");
7ed0602b 600#if defined(NETSCAPE_SSL)
26ac0430 601 fprintf(stderr, "\t-E sslcertpath\t\t\t\tenable LDAP over SSL\n");
7ed0602b 602#endif
26ac0430
AJ
603 fprintf(stderr, "\t-c timeout\t\t\t\tconnect timeout\n");
604 fprintf(stderr, "\t-t timelimit\t\t\t\tsearch time limit\n");
605 fprintf(stderr, "\t-R\t\t\t\t\tdo not follow referrals\n");
606 fprintf(stderr, "\t-a never|always|search|find\t\twhen to dereference aliases\n");
7ed0602b 607#ifdef LDAP_VERSION3
26ac0430
AJ
608 fprintf(stderr, "\t-v 2|3\t\t\t\t\tLDAP version\n");
609 fprintf(stderr, "\t-Z\t\t\t\t\tTLS encrypt the LDAP connection, requires\n\t\t\t\tLDAP version 3\n");
7ed0602b 610#endif
26ac0430
AJ
611 fprintf(stderr, "\t-S\t\t\t\t\tStrip NT domain from usernames\n");
612 fprintf(stderr, "\n");
613 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");
614 return -1;
7ed0602b 615 }
616 return 0;
617}
618static int
e9505fad 619readSecret(const char *filename)
7ed0602b 620{
621 char buf[BUFSIZ];
622 char *e = 0;
623 FILE *f;
624
625 if (!(f = fopen(filename, "r"))) {
26ac0430
AJ
626 fprintf(stderr, PROGRAM_NAME " ERROR: Can not read secret file %s\n", filename);
627 return 1;
7ed0602b 628 }
629 if (!fgets(buf, sizeof(buf) - 1, f)) {
26ac0430
AJ
630 fprintf(stderr, PROGRAM_NAME " ERROR: Secret file %s is empty\n", filename);
631 fclose(f);
632 return 1;
7ed0602b 633 }
634 /* strip whitespaces on end */
635 if ((e = strrchr(buf, '\n')))
26ac0430 636 *e = 0;
7ed0602b 637 if ((e = strrchr(buf, '\r')))
26ac0430 638 *e = 0;
7ed0602b 639
bb85e424 640 bindpasswd = xstrdup(buf);
e9505fad 641 if (!bindpasswd) {
26ac0430 642 fprintf(stderr, PROGRAM_NAME " ERROR: can not allocate memory\n");
7ed0602b 643 }
7ed0602b 644 fclose(f);
645
646 return 0;
647}
648
649void
650LDAPHHA1(RequestData * requestData)
651{
46e791c6 652 char *password = NULL;
7ed0602b 653 ldapconnect();
46e791c6
EF
654
655 // use the -l delimiter to find realm, or
656 // only honor the -r specified realm
657 const bool lookup = (!*frealm && *delimiter) ||
859e7e25 658 (*frealm && strcmp(requestData->realm, frealm) == 0);
46e791c6
EF
659
660 if (lookup)
661 password = getpassword(requestData->user, requestData->realm);
662
7ed0602b 663 if (password != NULL) {
26ac0430
AJ
664 if (encrpass)
665 xstrncpy(requestData->HHA1, password, sizeof(requestData->HHA1));
666 else {
667 HASH HA1;
668 DigestCalcHA1("md5", requestData->user, requestData->realm, password, NULL, NULL, HA1, requestData->HHA1);
669 }
670 free(password);
7ed0602b 671 } else {
26ac0430 672 requestData->error = -1;
7ed0602b 673 }
674
675}
f53969cc 676