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