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