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