📄 ldap_backend.c
字号:
/* * * * * ldap_backend.c * AUTHOR: Flavio Pescuma, MARA Systems AB <flavio@marasystems.com> */#define LDAP_DEPRECATED 1#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include "ldap_backend.h"#ifdef _SQUID_MSWIN_ /* Native Windows port and MinGW */#define snprintf _snprintf#include <windows.h>#include <winldap.h>#ifndef LDAPAPI#define LDAPAPI __cdecl#endif#ifdef LDAP_VERSION3#ifndef LDAP_OPT_X_TLS#define LDAP_OPT_X_TLS 0x6000#endif/* Some tricks to allow dynamic bind with ldap_start_tls_s entry point at * run time. */#undef ldap_start_tls_s#if LDAP_UNICODE#define LDAP_START_TLS_S "ldap_start_tls_sW"typedef WINLDAPAPI ULONG(LDAPAPI * PFldap_start_tls_s) (IN PLDAP, OUT PULONG, OUT LDAPMessage **, IN PLDAPControlW *, IN PLDAPControlW *);#else#define LDAP_START_TLS_S "ldap_start_tls_sA"typedef WINLDAPAPI ULONG(LDAPAPI * PFldap_start_tls_s) (IN PLDAP, OUT PULONG, OUT LDAPMessage **, IN PLDAPControlA *, IN PLDAPControlA *);#endif /* LDAP_UNICODE */PFldap_start_tls_s Win32_ldap_start_tls_s;#define ldap_start_tls_s(l,s,c) Win32_ldap_start_tls_s(l,NULL,NULL,s,c)#endif /* LDAP_VERSION3 */#else#include <lber.h>#include <ldap.h>#endif#define PROGRAM_NAME "digest_pw_auth(LDAP_backend)"/* Globals */static LDAP *ld = NULL;static char *passattr = NULL;static char *ldapServer = NULL;static char *userbasedn = NULL;static char *userdnattr = NULL;static char *usersearchfilter = NULL;static char *binddn = NULL;static char *bindpasswd = NULL;static char *delimiter = ":";static int encrpass = 0;static int searchscope = LDAP_SCOPE_SUBTREE;static int persistent = 0;static int noreferrals = 0;static int debug = 0;static int port = LDAP_PORT;static int strip_nt_domain = 0;static int aliasderef = LDAP_DEREF_NEVER;#if defined(NETSCAPE_SSL)static char *sslpath = NULL;static int sslinit = 0;#endifstatic int connect_timeout = 0;static int timelimit = LDAP_NO_LIMIT;#ifdef LDAP_VERSION3/* Added for TLS support and version 3 */static int use_tls = 0;static int version = -1;#endifstatic void ldapconnect(void);static int readSecret(char *filename);/* Yuck.. we need to glue to different versions of the API */#if defined(LDAP_API_VERSION) && LDAP_API_VERSION > 1823static voidsquid_ldap_set_aliasderef(int deref){ ldap_set_option(ld, LDAP_OPT_DEREF, &deref);}static voidsquid_ldap_set_referrals(int referrals){ int *value = referrals ? LDAP_OPT_ON : LDAP_OPT_OFF; ldap_set_option(ld, LDAP_OPT_REFERRALS, value);}static voidsquid_ldap_set_timelimit(int timelimit){ ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &timelimit);}static voidsquid_ldap_set_connect_timeout(int timelimit){#if defined(LDAP_OPT_NETWORK_TIMEOUT) struct timeval tv; tv.tv_sec = timelimit; tv.tv_usec = 0; ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);#elif defined(LDAP_X_OPT_CONNECT_TIMEOUT) timelimit *= 1000; ldap_set_option(ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timelimit);#endif}#elsestatic intsquid_ldap_errno(LDAP * ld){ return ld->ld_errno;}static voidsquid_ldap_set_aliasderef(int deref){ ld->ld_deref = deref;}static voidsquid_ldap_set_referrals(int referrals){ if (referrals) ld->ld_options |= ~LDAP_OPT_REFERRALS; else ld->ld_options &= ~LDAP_OPT_REFERRALS;}static voidsquid_ldap_set_timelimit(int timelimit){ ld->ld_timelimit = timelimit;}static voidsquid_ldap_set_connect_timeout(int timelimit){ fprintf(stderr, "Connect timeouts not supported in your LDAP library\n");}static voidsquid_ldap_memfree(char *p){ free(p);}#endif#ifdef LDAP_API_FEATURE_X_OPENLDAP#if LDAP_VENDOR_VERSION > 194#define HAS_URI_SUPPORT 1#endif#endifstatic intldap_escape_value(char *escaped, int size, const char *src){ int n = 0; while (size > 4 && *src) { switch (*src) { case '*': case '(': case ')': case '\\': n += 3; size -= 3; if (size > 0) { *escaped++ = '\\'; snprintf(escaped, 3, "%02x", (int) *src++); escaped += 2; } break; default: *escaped++ = *src++; n++; size--; } } *escaped = '\0'; return n;}static char *getpassword(char *login, char *realm){ LDAPMessage *res = NULL; LDAPMessage *entry; char **values = NULL; char **value = NULL; char *password = NULL; int retry = 0; char filter[8192]; char searchbase[8192]; int rc = -1; if (ld) { if (usersearchfilter) { char escaped_login[1024]; snprintf(searchbase, sizeof(searchbase), "%s", userbasedn); ldap_escape_value(escaped_login, sizeof(escaped_login), login); 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); retrysrch: if (debug) fprintf(stderr, "user filter '%s', searchbase '%s'\n", filter, searchbase); rc = ldap_search_s(ld, searchbase, searchscope, filter, NULL, 0, &res); if (rc != LDAP_SUCCESS) { if (noreferrals && rc == LDAP_PARTIAL_RESULTS) { /* Everything is fine. This is expected when referrals * are disabled. */ rc = LDAP_SUCCESS; } else { fprintf(stderr, PROGRAM_NAME " WARNING, LDAP search error '%s'\n", ldap_err2string(rc));#if defined(NETSCAPE_SSL) if (sslpath && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))) { int sslerr = PORT_GetError(); fprintf(stderr, PROGRAM_NAME ": WARNING, SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr)); }#endif fprintf(stderr, PROGRAM_NAME " WARNING, LDAP search error, trying to recover'%s'\n", ldap_err2string(rc)); ldap_msgfree(res); /* try to connect to the LDAP server agin, maybe my persisten conexion failed. */ if (!retry) { retry++; ldap_unbind(ld); ld = NULL; ldapconnect(); goto retrysrch; } return NULL; } } } else if (userdnattr) { sprintf(searchbase, "%s=%s, %s", userdnattr, login, userbasedn); retrydnattr: if (debug) fprintf(stderr, "searchbase '%s'\n", searchbase); rc = ldap_search_s(ld, searchbase, searchscope, NULL, NULL, 0, &res); } if (rc == LDAP_SUCCESS) { entry = ldap_first_entry(ld, res); if (entry) values = ldap_get_values(ld, entry, passattr); else { ldap_msgfree(res); return NULL; } if (!values) { if (debug) printf("No attribute value found\n"); ldap_msgfree(res); return NULL; } value = values; while (*value) { if (encrpass) { if (strcmp(strtok(*value, delimiter), realm) == 0) { password = strtok(NULL, delimiter); break; } } else { password = *value; break; } value++; } if (debug) printf("password: %s\n", password); if (password) password = strdup(password); ldap_value_free(values); ldap_msgfree(res); return password; } else { fprintf(stderr, PROGRAM_NAME " WARNING, LDAP error '%s'\n", ldap_err2string(rc)); /* try to connect to the LDAP server agin, maybe my persisten conexion failed. */ if (!retry) { retry++; ldap_unbind(ld); ld = NULL; ldapconnect(); goto retrydnattr; } return NULL; } } return NULL;}static voidldapconnect(void){ int rc;/* On Windows ldap_start_tls_s is available starting from Windows XP, * so we need to bind at run-time with the function entry point */#ifdef _SQUID_MSWIN_ if (use_tls) { HMODULE WLDAP32Handle; WLDAP32Handle = GetModuleHandle("wldap32"); if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) { fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n"); exit(1); } }#endif if (ld == NULL) {#if HAS_URI_SUPPORT if (strstr(ldapServer, "://") != NULL) { rc = ldap_initialize(&ld, ldapServer); if (rc != LDAP_SUCCESS) { fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer); } } else#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -