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