Go to the documentation of this file.
   16 #define LDAP_DEPRECATED 1 
   20 #if _SQUID_WINDOWS_ && !_SQUID_CYGWIN_ 
   22 #define snprintf _snprintf 
   26 #define LDAPAPI __cdecl 
   29 #ifndef LDAP_OPT_X_TLS 
   30 #define LDAP_OPT_X_TLS 0x6000 
   35 #undef ldap_start_tls_s 
   37 #define LDAP_START_TLS_S "ldap_start_tls_sW" 
   38 typedef WINLDAPAPI ULONG(LDAPAPI * PFldap_start_tls_s) (IN PLDAP, OUT PULONG, OUT LDAPMessage **, IN PLDAPControlW *, IN PLDAPControlW *);
 
   40 #define LDAP_START_TLS_S "ldap_start_tls_sA" 
   41 typedef WINLDAPAPI ULONG(LDAPAPI * PFldap_start_tls_s) (IN PLDAP, OUT PULONG, OUT LDAPMessage **, IN PLDAPControlA *, IN PLDAPControlA *);
 
   43 PFldap_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) 
   57 #define PROGRAM_NAME "digest_pw_auth(LDAP_backend)" 
   61 static LDAP *
ld = 
nullptr;
 
   75 static int port = LDAP_PORT;
 
   78 #if defined(NETSCAPE_SSL) 
   79 static char *sslpath = 
nullptr;
 
   80 static int sslinit = 0;
 
   96 #if defined(LDAP_API_VERSION) && LDAP_API_VERSION > 1823 
  100     ldap_set_option(
ld, LDAP_OPT_DEREF, &deref);
 
  105     int *value = 
static_cast<int*
>(referrals ? LDAP_OPT_ON :LDAP_OPT_OFF);
 
  106     ldap_set_option(
ld, LDAP_OPT_REFERRALS, value);
 
  111     ldap_set_option(
ld, LDAP_OPT_TIMELIMIT, &aTimeLimit);
 
  116 #if defined(LDAP_OPT_NETWORK_TIMEOUT) 
  118     tv.tv_sec = aTimeLimit;
 
  120     ldap_set_option(
ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);
 
  121 #elif defined(LDAP_X_OPT_CONNECT_TIMEOUT) 
  123     ldap_set_option(
ld, LDAP_X_OPT_CONNECT_TIMEOUT, &aTimeLimit);
 
  136     ld->ld_deref = deref;
 
  142         ld->ld_options |= ~LDAP_OPT_REFERRALS;
 
  144         ld->ld_options &= ~LDAP_OPT_REFERRALS;
 
  149     ld->ld_timelimit = aTimeLimit;
 
  154     fprintf(stderr, 
"Connect timeouts not supported in your LDAP library\n");
 
  164 #ifdef LDAP_API_FEATURE_X_OPENLDAP 
  165 #if LDAP_VENDOR_VERSION > 194 
  166 #define HAS_URI_SUPPORT 1 
  174     while (
size > 4 && *src) {
 
  185                 snprintf(escaped, 3, 
"%02x", (
int) *src);
 
  205     LDAPMessage *res = 
nullptr;
 
  207     char **values = 
nullptr;
 
  208     char **value = 
nullptr;
 
  209     char *password = 
nullptr;
 
  212     char searchbase[8192];
 
  216             char escaped_login[1024];
 
  217             snprintf(searchbase, 
sizeof(searchbase), 
"%s", 
userbasedn);
 
  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);
 
  222             debug(
"user filter '%s', searchbase '%s'\n", filter, searchbase);
 
  224             rc = ldap_search_s(
ld, searchbase, 
searchscope, filter, 
nullptr, 0, &res);
 
  225             if (rc != LDAP_SUCCESS) {
 
  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));
 
  239                     fprintf(stderr, 
PROGRAM_NAME " WARNING, LDAP search error, trying to recover'%s'\n", ldap_err2string(rc));
 
  254             snprintf(filter,8192,
"%s=%s",
userdnattr,login);
 
  260         if (rc == LDAP_SUCCESS) {
 
  261             entry = ldap_first_entry(
ld, res);
 
  263                 values = ldap_get_values(
ld, entry, 
passattr);
 
  269                 debug(
"No attribute value found\n");
 
  276                     const char *t = strtok(*value, 
delimiter);
 
  277                     if (t && strcmp(t, realm) == 0) {
 
  287             debug(
"password: %s\n", password);
 
  290             ldap_value_free(values);
 
  294             fprintf(stderr, 
PROGRAM_NAME " WARNING, LDAP error '%s'\n", ldap_err2string(rc));
 
  320         HMODULE WLDAP32Handle;
 
  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");
 
  334             if (rc != LDAP_SUCCESS) {
 
  335                 fprintf(stderr, 
"\nUnable to connect to LDAPURI:%s\n", 
ldapServer);
 
  341                 if (!sslinit && (ldapssl_client_init(sslpath, 
nullptr) != LDAP_SUCCESS)) {
 
  342                     fprintf(stderr, 
"\nUnable to initialise SSL with cert path %s\n",
 
  349                     fprintf(stderr, 
"\nUnable to connect to SSL LDAP server: %s port:%d\n",
 
  356                     fprintf(stderr, 
"\nUnable to connect to LDAP server:%s port:%d\n", 
ldapServer, 
port);
 
  365         if (ldap_set_option(
ld, LDAP_OPT_PROTOCOL_VERSION, &
version)
 
  367             fprintf(stderr, 
"Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
 
  373 #ifdef LDAP_OPT_X_TLS 
  374             if (
version != LDAP_VERSION3) {
 
  375                 fprintf(stderr, 
"TLS requires LDAP version 3\n");
 
  377             } 
else if (ldap_start_tls_s(
ld, 
nullptr, 
nullptr) != LDAP_SUCCESS) {
 
  378                 fprintf(stderr, 
"Could not Activate TLS connection\n");
 
  382             fprintf(stderr, 
"TLS not supported with your LDAP library\n");
 
  393             if (rc != LDAP_SUCCESS) {
 
  394                 fprintf(stderr, 
PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc));
 
  399         debug(
"Connected OK\n");
 
  405     setbuf(stdout, 
nullptr);
 
  407     while (argc > 1 && argv[1][0] == 
'-') {
 
  408         const char *value = 
"";
 
  409         char option = argv[1][1];
 
  420             if (strlen(argv[1]) > 2) {
 
  422             } 
else if (argc > 2) {
 
  435             fprintf(stderr, 
"ERROR: Your LDAP library does not have URI support\n");
 
  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);
 
  472             if (strcmp(value, 
"base") == 0)
 
  474             else if (strcmp(value, 
"one") == 0)
 
  476             else if (strcmp(value, 
"sub") == 0)
 
  479                 fprintf(stderr, 
PROGRAM_NAME " ERROR: Unknown search scope '%s'\n", value);
 
  484 #if defined(NETSCAPE_SSL) 
  486             if (
port == LDAP_PORT)
 
  489             fprintf(stderr, 
PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n");
 
  500             if (strcmp(value, 
"never") == 0)
 
  502             else if (strcmp(value, 
"always") == 0)
 
  504             else if (strcmp(value, 
"search") == 0)
 
  506             else if (strcmp(value, 
"find") == 0)
 
  509                 fprintf(stderr, 
PROGRAM_NAME " ERROR: Unknown alias dereference method '%s'\n", value);
 
  533             switch (atoi(value)) {
 
  541                 fprintf(stderr, 
"Protocol version should be 2 or 3\n");
 
  546             if (
version == LDAP_VERSION2) {
 
  547                 fprintf(stderr, 
"TLS (-Z) is incompatible with version %d\n",
 
  562             fprintf(stderr, 
PROGRAM_NAME " ERROR: Unknown command line option '%c'\n", option);
 
  568         char *value = argv[1];
 
  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);
 
  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");
 
  599         fprintf(stderr, 
"\t-H URI\t\t\t\t\tLDAPURI (defaults to ldap://localhost)\n");
 
  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");
 
  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");
 
  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");
 
  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");
 
  629     if (!(f = fopen(filename, 
"r"))) {
 
  630         fprintf(stderr, 
PROGRAM_NAME " ERROR: Can not read secret file %s\n", filename);
 
  633     if (!fgets(buf, 
sizeof(buf) - 1, f)) {
 
  634         fprintf(stderr, 
PROGRAM_NAME " ERROR: Secret file %s is empty\n", filename);
 
  639     if ((e = strrchr(buf, 
'\n')))
 
  641     if ((e = strrchr(buf, 
'\r')))
 
  646         fprintf(stderr, 
PROGRAM_NAME " ERROR: can not allocate memory\n");
 
  656     char *password = 
nullptr;
 
  667     if (password != 
nullptr) {
 
  676         requestData->
error = -1;
 
  
static const char * bindpasswd
static const char * usersearchfilter
static const char * userdnattr
static int connect_timeout
static int ldap_escape_value(char *escaped, int size, const char *src)
void debug(const char *format,...)
static int strip_nt_domain
static const char * userbasedn
static void squid_ldap_memfree(char *p)
char * xstrncpy(char *dst, const char *src, size_t n)
static const char * frealm
static int squid_ldap_errno(LDAP *ld)
static int readSecret(const char *filename)
static char * getpassword(char *login, char *realm)
static const char * binddn
static void squid_ldap_set_timelimit(int aTimeLimit)
void LDAPHHA1(RequestData *requestData)
static void squid_ldap_set_referrals(int referrals)
static const char * delimiter
int LDAPArguments(int argc, char **argv)
static void ldapconnect(void)
static void squid_ldap_set_aliasderef(int deref)
void DigestCalcHA1(const char *pszAlg, const char *pszUserName, const char *pszRealm, const char *pszPassword, const char *pszNonce, const char *pszCNonce, HASH HA1, HASHHEX SessionKey)
static const char * passattr
static void squid_ldap_set_connect_timeout(int aTimeLimit)