140266059SGregory Neil Shapiro /* 240266059SGregory Neil Shapiro * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers. 340266059SGregory Neil Shapiro * All rights reserved. 440266059SGregory Neil Shapiro * 540266059SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set 640266059SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of 740266059SGregory Neil Shapiro * the sendmail distribution. 840266059SGregory Neil Shapiro */ 940266059SGregory Neil Shapiro 1040266059SGregory Neil Shapiro #include <sm/gen.h> 11a7ec597cSGregory Neil Shapiro SM_RCSID("@(#)$Id: ldap.c,v 1.44.2.3 2003/07/07 20:16:16 gshapiro Exp $") 1240266059SGregory Neil Shapiro 1340266059SGregory Neil Shapiro #if LDAPMAP 1440266059SGregory Neil Shapiro # include <sys/types.h> 1540266059SGregory Neil Shapiro # include <errno.h> 1640266059SGregory Neil Shapiro # include <setjmp.h> 1740266059SGregory Neil Shapiro # include <stdlib.h> 1840266059SGregory Neil Shapiro # include <unistd.h> 1940266059SGregory Neil Shapiro 2040266059SGregory Neil Shapiro # include <sm/bitops.h> 2140266059SGregory Neil Shapiro # include <sm/clock.h> 2240266059SGregory Neil Shapiro # include <sm/conf.h> 2340266059SGregory Neil Shapiro # include <sm/debug.h> 2440266059SGregory Neil Shapiro # include <sm/errstring.h> 2540266059SGregory Neil Shapiro # include <sm/ldap.h> 2640266059SGregory Neil Shapiro # include <sm/string.h> 27605302a5SGregory Neil Shapiro # ifdef EX_OK 28605302a5SGregory Neil Shapiro # undef EX_OK /* for SVr4.2 SMP */ 29605302a5SGregory Neil Shapiro # endif /* EX_OK */ 3040266059SGregory Neil Shapiro # include <sm/sysexits.h> 3140266059SGregory Neil Shapiro 3240266059SGregory Neil Shapiro SM_DEBUG_T SmLDAPTrace = SM_DEBUG_INITIALIZER("sm_trace_ldap", 3340266059SGregory Neil Shapiro "@(#)$Debug: sm_trace_ldap - trace LDAP operations $"); 3440266059SGregory Neil Shapiro 3540266059SGregory Neil Shapiro static void ldaptimeout __P((int)); 3640266059SGregory Neil Shapiro 3740266059SGregory Neil Shapiro /* 3840266059SGregory Neil Shapiro ** SM_LDAP_CLEAR -- set default values for SM_LDAP_STRUCT 3940266059SGregory Neil Shapiro ** 4040266059SGregory Neil Shapiro ** Parameters: 4140266059SGregory Neil Shapiro ** lmap -- pointer to SM_LDAP_STRUCT to clear 4240266059SGregory Neil Shapiro ** 4340266059SGregory Neil Shapiro ** Returns: 4440266059SGregory Neil Shapiro ** None. 4540266059SGregory Neil Shapiro ** 4640266059SGregory Neil Shapiro */ 4740266059SGregory Neil Shapiro 4840266059SGregory Neil Shapiro void 4940266059SGregory Neil Shapiro sm_ldap_clear(lmap) 5040266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap; 5140266059SGregory Neil Shapiro { 5240266059SGregory Neil Shapiro if (lmap == NULL) 5340266059SGregory Neil Shapiro return; 5440266059SGregory Neil Shapiro 55605302a5SGregory Neil Shapiro lmap->ldap_target = NULL; 5640266059SGregory Neil Shapiro lmap->ldap_port = LDAP_PORT; 57605302a5SGregory Neil Shapiro #if _FFR_LDAP_URI 58605302a5SGregory Neil Shapiro lmap->ldap_uri = false; 59605302a5SGregory Neil Shapiro #endif /* _FFR_LDAP_URI */ 60605302a5SGregory Neil Shapiro # if _FFR_LDAP_SETVERSION 61605302a5SGregory Neil Shapiro lmap->ldap_version = 0; 62605302a5SGregory Neil Shapiro # endif /* _FFR_LDAP_SETVERSION */ 6340266059SGregory Neil Shapiro lmap->ldap_deref = LDAP_DEREF_NEVER; 6440266059SGregory Neil Shapiro lmap->ldap_timelimit = LDAP_NO_LIMIT; 6540266059SGregory Neil Shapiro lmap->ldap_sizelimit = LDAP_NO_LIMIT; 6640266059SGregory Neil Shapiro # ifdef LDAP_REFERRALS 6740266059SGregory Neil Shapiro lmap->ldap_options = LDAP_OPT_REFERRALS; 6840266059SGregory Neil Shapiro # else /* LDAP_REFERRALS */ 6940266059SGregory Neil Shapiro lmap->ldap_options = 0; 7040266059SGregory Neil Shapiro # endif /* LDAP_REFERRALS */ 7140266059SGregory Neil Shapiro lmap->ldap_attrsep = '\0'; 7240266059SGregory Neil Shapiro lmap->ldap_binddn = NULL; 7340266059SGregory Neil Shapiro lmap->ldap_secret = NULL; 7440266059SGregory Neil Shapiro lmap->ldap_method = LDAP_AUTH_SIMPLE; 7540266059SGregory Neil Shapiro lmap->ldap_base = NULL; 7640266059SGregory Neil Shapiro lmap->ldap_scope = LDAP_SCOPE_SUBTREE; 7740266059SGregory Neil Shapiro lmap->ldap_attrsonly = LDAPMAP_FALSE; 7840266059SGregory Neil Shapiro lmap->ldap_timeout.tv_sec = 0; 7940266059SGregory Neil Shapiro lmap->ldap_timeout.tv_usec = 0; 8040266059SGregory Neil Shapiro lmap->ldap_ld = NULL; 8140266059SGregory Neil Shapiro lmap->ldap_filter = NULL; 8240266059SGregory Neil Shapiro lmap->ldap_attr[0] = NULL; 8340266059SGregory Neil Shapiro #if _FFR_LDAP_RECURSION 84605302a5SGregory Neil Shapiro lmap->ldap_attr_type[0] = SM_LDAP_ATTR_NONE; 85605302a5SGregory Neil Shapiro lmap->ldap_attr_needobjclass[0] = NULL; 8640266059SGregory Neil Shapiro #endif /* _FFR_LDAP_RECURSION */ 8740266059SGregory Neil Shapiro lmap->ldap_res = NULL; 8840266059SGregory Neil Shapiro lmap->ldap_next = NULL; 8940266059SGregory Neil Shapiro lmap->ldap_pid = 0; 9040266059SGregory Neil Shapiro } 9140266059SGregory Neil Shapiro 9240266059SGregory Neil Shapiro /* 9340266059SGregory Neil Shapiro ** SM_LDAP_START -- actually connect to an LDAP server 9440266059SGregory Neil Shapiro ** 9540266059SGregory Neil Shapiro ** Parameters: 9640266059SGregory Neil Shapiro ** name -- name of map for debug output. 9740266059SGregory Neil Shapiro ** lmap -- the LDAP map being opened. 9840266059SGregory Neil Shapiro ** 9940266059SGregory Neil Shapiro ** Returns: 10040266059SGregory Neil Shapiro ** true if connection is successful, false otherwise. 10140266059SGregory Neil Shapiro ** 10240266059SGregory Neil Shapiro ** Side Effects: 10340266059SGregory Neil Shapiro ** Populates lmap->ldap_ld. 10440266059SGregory Neil Shapiro */ 10540266059SGregory Neil Shapiro 10640266059SGregory Neil Shapiro static jmp_buf LDAPTimeout; 10740266059SGregory Neil Shapiro 10840266059SGregory Neil Shapiro #define SM_LDAP_SETTIMEOUT(to) \ 10940266059SGregory Neil Shapiro do \ 11040266059SGregory Neil Shapiro { \ 11140266059SGregory Neil Shapiro if (to != 0) \ 11240266059SGregory Neil Shapiro { \ 11340266059SGregory Neil Shapiro if (setjmp(LDAPTimeout) != 0) \ 11440266059SGregory Neil Shapiro { \ 11540266059SGregory Neil Shapiro errno = ETIMEDOUT; \ 11640266059SGregory Neil Shapiro return false; \ 11740266059SGregory Neil Shapiro } \ 11840266059SGregory Neil Shapiro ev = sm_setevent(to, ldaptimeout, 0); \ 11940266059SGregory Neil Shapiro } \ 12040266059SGregory Neil Shapiro } while (0) 12140266059SGregory Neil Shapiro 12240266059SGregory Neil Shapiro #define SM_LDAP_CLEARTIMEOUT() \ 12340266059SGregory Neil Shapiro do \ 12440266059SGregory Neil Shapiro { \ 12540266059SGregory Neil Shapiro if (ev != NULL) \ 12640266059SGregory Neil Shapiro sm_clrevent(ev); \ 12740266059SGregory Neil Shapiro } while (0) 12840266059SGregory Neil Shapiro 12940266059SGregory Neil Shapiro bool 13040266059SGregory Neil Shapiro sm_ldap_start(name, lmap) 13140266059SGregory Neil Shapiro char *name; 13240266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap; 13340266059SGregory Neil Shapiro { 13440266059SGregory Neil Shapiro int bind_result; 13540266059SGregory Neil Shapiro int save_errno; 13640266059SGregory Neil Shapiro SM_EVENT *ev = NULL; 13740266059SGregory Neil Shapiro LDAP *ld; 13840266059SGregory Neil Shapiro 13940266059SGregory Neil Shapiro if (sm_debug_active(&SmLDAPTrace, 2)) 14040266059SGregory Neil Shapiro sm_dprintf("ldapmap_start(%s)\n", name == NULL ? "" : name); 14140266059SGregory Neil Shapiro 14240266059SGregory Neil Shapiro if (sm_debug_active(&SmLDAPTrace, 9)) 14340266059SGregory Neil Shapiro sm_dprintf("ldapmap_start(%s, %d)\n", 144605302a5SGregory Neil Shapiro lmap->ldap_target == NULL ? "localhost" : lmap->ldap_target, 14540266059SGregory Neil Shapiro lmap->ldap_port); 14640266059SGregory Neil Shapiro 14740266059SGregory Neil Shapiro # if USE_LDAP_INIT 148605302a5SGregory Neil Shapiro # if _FFR_LDAP_URI 149605302a5SGregory Neil Shapiro if (lmap->ldap_uri) 150605302a5SGregory Neil Shapiro errno = ldap_initialize(&ld, lmap->ldap_target); 151605302a5SGregory Neil Shapiro else 152605302a5SGregory Neil Shapiro # endif /* _FFR_LDAP_URI */ 153605302a5SGregory Neil Shapiro ld = ldap_init(lmap->ldap_target, lmap->ldap_port); 15440266059SGregory Neil Shapiro save_errno = errno; 15540266059SGregory Neil Shapiro # else /* USE_LDAP_INIT */ 15640266059SGregory Neil Shapiro /* 15740266059SGregory Neil Shapiro ** If using ldap_open(), the actual connection to the server 15840266059SGregory Neil Shapiro ** happens now so we need the timeout here. For ldap_init(), 15940266059SGregory Neil Shapiro ** the connection happens at bind time. 16040266059SGregory Neil Shapiro */ 16140266059SGregory Neil Shapiro 16240266059SGregory Neil Shapiro SM_LDAP_SETTIMEOUT(lmap->ldap_timeout.tv_sec); 163605302a5SGregory Neil Shapiro ld = ldap_open(lmap->ldap_target, lmap->ldap_port); 16440266059SGregory Neil Shapiro save_errno = errno; 16540266059SGregory Neil Shapiro 16640266059SGregory Neil Shapiro /* clear the event if it has not sprung */ 16740266059SGregory Neil Shapiro SM_LDAP_CLEARTIMEOUT(); 16840266059SGregory Neil Shapiro # endif /* USE_LDAP_INIT */ 16940266059SGregory Neil Shapiro 17040266059SGregory Neil Shapiro errno = save_errno; 17140266059SGregory Neil Shapiro if (ld == NULL) 17240266059SGregory Neil Shapiro return false; 17340266059SGregory Neil Shapiro 17440266059SGregory Neil Shapiro sm_ldap_setopts(ld, lmap); 17540266059SGregory Neil Shapiro 17640266059SGregory Neil Shapiro # if USE_LDAP_INIT 17740266059SGregory Neil Shapiro /* 17840266059SGregory Neil Shapiro ** If using ldap_init(), the actual connection to the server 17940266059SGregory Neil Shapiro ** happens at ldap_bind_s() so we need the timeout here. 18040266059SGregory Neil Shapiro */ 18140266059SGregory Neil Shapiro 18240266059SGregory Neil Shapiro SM_LDAP_SETTIMEOUT(lmap->ldap_timeout.tv_sec); 18340266059SGregory Neil Shapiro # endif /* USE_LDAP_INIT */ 18440266059SGregory Neil Shapiro 18540266059SGregory Neil Shapiro # ifdef LDAP_AUTH_KRBV4 18640266059SGregory Neil Shapiro if (lmap->ldap_method == LDAP_AUTH_KRBV4 && 18740266059SGregory Neil Shapiro lmap->ldap_secret != NULL) 18840266059SGregory Neil Shapiro { 18940266059SGregory Neil Shapiro /* 19040266059SGregory Neil Shapiro ** Need to put ticket in environment here instead of 19140266059SGregory Neil Shapiro ** during parseargs as there may be different tickets 19240266059SGregory Neil Shapiro ** for different LDAP connections. 19340266059SGregory Neil Shapiro */ 19440266059SGregory Neil Shapiro 19540266059SGregory Neil Shapiro (void) putenv(lmap->ldap_secret); 19640266059SGregory Neil Shapiro } 19740266059SGregory Neil Shapiro # endif /* LDAP_AUTH_KRBV4 */ 19840266059SGregory Neil Shapiro 19940266059SGregory Neil Shapiro bind_result = ldap_bind_s(ld, lmap->ldap_binddn, 20040266059SGregory Neil Shapiro lmap->ldap_secret, lmap->ldap_method); 20140266059SGregory Neil Shapiro 20240266059SGregory Neil Shapiro # if USE_LDAP_INIT 20340266059SGregory Neil Shapiro /* clear the event if it has not sprung */ 20440266059SGregory Neil Shapiro SM_LDAP_CLEARTIMEOUT(); 20540266059SGregory Neil Shapiro # endif /* USE_LDAP_INIT */ 20640266059SGregory Neil Shapiro 20740266059SGregory Neil Shapiro if (bind_result != LDAP_SUCCESS) 20840266059SGregory Neil Shapiro { 20940266059SGregory Neil Shapiro errno = bind_result + E_LDAPBASE; 21040266059SGregory Neil Shapiro return false; 21140266059SGregory Neil Shapiro } 21240266059SGregory Neil Shapiro 21340266059SGregory Neil Shapiro /* Save PID to make sure only this PID closes the LDAP connection */ 21440266059SGregory Neil Shapiro lmap->ldap_pid = getpid(); 21540266059SGregory Neil Shapiro lmap->ldap_ld = ld; 21640266059SGregory Neil Shapiro return true; 21740266059SGregory Neil Shapiro } 21840266059SGregory Neil Shapiro 21940266059SGregory Neil Shapiro /* ARGSUSED */ 22040266059SGregory Neil Shapiro static void 22140266059SGregory Neil Shapiro ldaptimeout(unused) 22240266059SGregory Neil Shapiro int unused; 22340266059SGregory Neil Shapiro { 22440266059SGregory Neil Shapiro /* 22540266059SGregory Neil Shapiro ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 22640266059SGregory Neil Shapiro ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 22740266059SGregory Neil Shapiro ** DOING. 22840266059SGregory Neil Shapiro */ 22940266059SGregory Neil Shapiro 23040266059SGregory Neil Shapiro errno = ETIMEDOUT; 23140266059SGregory Neil Shapiro longjmp(LDAPTimeout, 1); 23240266059SGregory Neil Shapiro } 23340266059SGregory Neil Shapiro 23440266059SGregory Neil Shapiro /* 23540266059SGregory Neil Shapiro ** SM_LDAP_SEARCH -- iniate LDAP search 23640266059SGregory Neil Shapiro ** 23740266059SGregory Neil Shapiro ** Initiate an LDAP search, return the msgid. 23840266059SGregory Neil Shapiro ** The calling function must collect the results. 23940266059SGregory Neil Shapiro ** 24040266059SGregory Neil Shapiro ** Parameters: 24140266059SGregory Neil Shapiro ** lmap -- LDAP map information 24240266059SGregory Neil Shapiro ** key -- key to substitute in LDAP filter 24340266059SGregory Neil Shapiro ** 24440266059SGregory Neil Shapiro ** Returns: 24540266059SGregory Neil Shapiro ** -1 on failure, msgid on success 24640266059SGregory Neil Shapiro ** 24740266059SGregory Neil Shapiro */ 24840266059SGregory Neil Shapiro 24940266059SGregory Neil Shapiro int 25040266059SGregory Neil Shapiro sm_ldap_search(lmap, key) 25140266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap; 25240266059SGregory Neil Shapiro char *key; 25340266059SGregory Neil Shapiro { 25440266059SGregory Neil Shapiro int msgid; 25540266059SGregory Neil Shapiro char *fp, *p, *q; 25640266059SGregory Neil Shapiro char filter[LDAPMAP_MAX_FILTER + 1]; 25740266059SGregory Neil Shapiro 25840266059SGregory Neil Shapiro /* substitute key into filter, perhaps multiple times */ 25940266059SGregory Neil Shapiro memset(filter, '\0', sizeof filter); 26040266059SGregory Neil Shapiro fp = filter; 26140266059SGregory Neil Shapiro p = lmap->ldap_filter; 26240266059SGregory Neil Shapiro while ((q = strchr(p, '%')) != NULL) 26340266059SGregory Neil Shapiro { 26440266059SGregory Neil Shapiro if (q[1] == 's') 26540266059SGregory Neil Shapiro { 26640266059SGregory Neil Shapiro (void) sm_snprintf(fp, SPACELEFT(filter, fp), 26740266059SGregory Neil Shapiro "%.*s%s", (int) (q - p), p, key); 26840266059SGregory Neil Shapiro fp += strlen(fp); 26940266059SGregory Neil Shapiro p = q + 2; 27040266059SGregory Neil Shapiro } 27140266059SGregory Neil Shapiro else if (q[1] == '0') 27240266059SGregory Neil Shapiro { 27340266059SGregory Neil Shapiro char *k = key; 27440266059SGregory Neil Shapiro 27540266059SGregory Neil Shapiro (void) sm_snprintf(fp, SPACELEFT(filter, fp), 27640266059SGregory Neil Shapiro "%.*s", (int) (q - p), p); 27740266059SGregory Neil Shapiro fp += strlen(fp); 27840266059SGregory Neil Shapiro p = q + 2; 27940266059SGregory Neil Shapiro 28040266059SGregory Neil Shapiro /* Properly escape LDAP special characters */ 28140266059SGregory Neil Shapiro while (SPACELEFT(filter, fp) > 0 && 28240266059SGregory Neil Shapiro *k != '\0') 28340266059SGregory Neil Shapiro { 28440266059SGregory Neil Shapiro if (*k == '*' || *k == '(' || 28540266059SGregory Neil Shapiro *k == ')' || *k == '\\') 28640266059SGregory Neil Shapiro { 28740266059SGregory Neil Shapiro (void) sm_strlcat(fp, 28840266059SGregory Neil Shapiro (*k == '*' ? "\\2A" : 28940266059SGregory Neil Shapiro (*k == '(' ? "\\28" : 29040266059SGregory Neil Shapiro (*k == ')' ? "\\29" : 29140266059SGregory Neil Shapiro (*k == '\\' ? "\\5C" : 29240266059SGregory Neil Shapiro "\00")))), 29340266059SGregory Neil Shapiro SPACELEFT(filter, fp)); 29440266059SGregory Neil Shapiro fp += strlen(fp); 29540266059SGregory Neil Shapiro k++; 29640266059SGregory Neil Shapiro } 29740266059SGregory Neil Shapiro else 29840266059SGregory Neil Shapiro *fp++ = *k++; 29940266059SGregory Neil Shapiro } 30040266059SGregory Neil Shapiro } 30140266059SGregory Neil Shapiro else 30240266059SGregory Neil Shapiro { 30340266059SGregory Neil Shapiro (void) sm_snprintf(fp, SPACELEFT(filter, fp), 30440266059SGregory Neil Shapiro "%.*s", (int) (q - p + 1), p); 30540266059SGregory Neil Shapiro p = q + (q[1] == '%' ? 2 : 1); 30640266059SGregory Neil Shapiro fp += strlen(fp); 30740266059SGregory Neil Shapiro } 30840266059SGregory Neil Shapiro } 30940266059SGregory Neil Shapiro (void) sm_strlcpy(fp, p, SPACELEFT(filter, fp)); 31040266059SGregory Neil Shapiro if (sm_debug_active(&SmLDAPTrace, 20)) 31140266059SGregory Neil Shapiro sm_dprintf("ldap search filter=%s\n", filter); 31240266059SGregory Neil Shapiro 31340266059SGregory Neil Shapiro lmap->ldap_res = NULL; 314605302a5SGregory Neil Shapiro msgid = ldap_search(lmap->ldap_ld, lmap->ldap_base, 315605302a5SGregory Neil Shapiro lmap->ldap_scope, filter, 31640266059SGregory Neil Shapiro (lmap->ldap_attr[0] == NULL ? NULL : 31740266059SGregory Neil Shapiro lmap->ldap_attr), 31840266059SGregory Neil Shapiro lmap->ldap_attrsonly); 31940266059SGregory Neil Shapiro return msgid; 32040266059SGregory Neil Shapiro } 32140266059SGregory Neil Shapiro 32240266059SGregory Neil Shapiro # if _FFR_LDAP_RECURSION 32340266059SGregory Neil Shapiro /* 324605302a5SGregory Neil Shapiro ** SM_LDAP_HAS_OBJECTCLASS -- determine if an LDAP entry is part of a 325605302a5SGregory Neil Shapiro ** particular objectClass 326605302a5SGregory Neil Shapiro ** 327605302a5SGregory Neil Shapiro ** Parameters: 328605302a5SGregory Neil Shapiro ** lmap -- pointer to SM_LDAP_STRUCT in use 329605302a5SGregory Neil Shapiro ** entry -- current LDAP entry struct 330605302a5SGregory Neil Shapiro ** ocvalue -- particular objectclass in question. 331605302a5SGregory Neil Shapiro ** may be of form (fee|foo|fum) meaning 332605302a5SGregory Neil Shapiro ** any entry can be part of either fee, 333605302a5SGregory Neil Shapiro ** foo or fum objectclass 334605302a5SGregory Neil Shapiro ** 335605302a5SGregory Neil Shapiro ** Returns: 336605302a5SGregory Neil Shapiro ** true if item has that objectClass 337605302a5SGregory Neil Shapiro */ 338605302a5SGregory Neil Shapiro 339605302a5SGregory Neil Shapiro static bool 340605302a5SGregory Neil Shapiro sm_ldap_has_objectclass(lmap, entry, ocvalue) 341605302a5SGregory Neil Shapiro SM_LDAP_STRUCT *lmap; 342605302a5SGregory Neil Shapiro LDAPMessage *entry; 343605302a5SGregory Neil Shapiro char *ocvalue; 344605302a5SGregory Neil Shapiro { 345605302a5SGregory Neil Shapiro char **vals = NULL; 346605302a5SGregory Neil Shapiro int i; 347605302a5SGregory Neil Shapiro 348605302a5SGregory Neil Shapiro if (ocvalue == NULL) 349605302a5SGregory Neil Shapiro return false; 350605302a5SGregory Neil Shapiro 351605302a5SGregory Neil Shapiro vals = ldap_get_values(lmap->ldap_ld, entry, "objectClass"); 352605302a5SGregory Neil Shapiro if (vals == NULL) 353605302a5SGregory Neil Shapiro return false; 354605302a5SGregory Neil Shapiro 355605302a5SGregory Neil Shapiro for (i = 0; vals[i] != NULL; i++) 356605302a5SGregory Neil Shapiro { 357605302a5SGregory Neil Shapiro char *p; 358605302a5SGregory Neil Shapiro char *q; 359605302a5SGregory Neil Shapiro 360605302a5SGregory Neil Shapiro p = q = ocvalue; 361605302a5SGregory Neil Shapiro while (*p != '\0') 362605302a5SGregory Neil Shapiro { 363605302a5SGregory Neil Shapiro while (*p != '\0' && *p != '|') 364605302a5SGregory Neil Shapiro p++; 365605302a5SGregory Neil Shapiro 366605302a5SGregory Neil Shapiro if ((p - q) == strlen(vals[i]) && 367605302a5SGregory Neil Shapiro sm_strncasecmp(vals[i], q, p - q) == 0) 368605302a5SGregory Neil Shapiro { 369605302a5SGregory Neil Shapiro ldap_value_free(vals); 370605302a5SGregory Neil Shapiro return true; 371605302a5SGregory Neil Shapiro } 372605302a5SGregory Neil Shapiro 373605302a5SGregory Neil Shapiro while (*p == '|') 374605302a5SGregory Neil Shapiro p++; 375605302a5SGregory Neil Shapiro q = p; 376605302a5SGregory Neil Shapiro } 377605302a5SGregory Neil Shapiro } 378605302a5SGregory Neil Shapiro 379605302a5SGregory Neil Shapiro ldap_value_free(vals); 380605302a5SGregory Neil Shapiro return false; 381605302a5SGregory Neil Shapiro } 382605302a5SGregory Neil Shapiro 383605302a5SGregory Neil Shapiro /* 38440266059SGregory Neil Shapiro ** SM_LDAP_RESULTS -- return results from an LDAP lookup in result 38540266059SGregory Neil Shapiro ** 38640266059SGregory Neil Shapiro ** Parameters: 38740266059SGregory Neil Shapiro ** lmap -- pointer to SM_LDAP_STRUCT in use 38840266059SGregory Neil Shapiro ** msgid -- msgid returned by sm_ldap_search() 38940266059SGregory Neil Shapiro ** flags -- flags for the lookup 39040266059SGregory Neil Shapiro ** delim -- delimiter for result concatenation 39140266059SGregory Neil Shapiro ** rpool -- memory pool for storage 39240266059SGregory Neil Shapiro ** result -- return string 39340266059SGregory Neil Shapiro ** recurse -- recursion list 39440266059SGregory Neil Shapiro ** 39540266059SGregory Neil Shapiro ** Returns: 39640266059SGregory Neil Shapiro ** status (sysexit) 39740266059SGregory Neil Shapiro */ 39840266059SGregory Neil Shapiro 399605302a5SGregory Neil Shapiro # define SM_LDAP_ERROR_CLEANUP() \ 40040266059SGregory Neil Shapiro { \ 40140266059SGregory Neil Shapiro if (lmap->ldap_res != NULL) \ 40240266059SGregory Neil Shapiro { \ 40340266059SGregory Neil Shapiro ldap_msgfree(lmap->ldap_res); \ 40440266059SGregory Neil Shapiro lmap->ldap_res = NULL; \ 40540266059SGregory Neil Shapiro } \ 40640266059SGregory Neil Shapiro (void) ldap_abandon(lmap->ldap_ld, msgid); \ 40740266059SGregory Neil Shapiro } 40840266059SGregory Neil Shapiro 409605302a5SGregory Neil Shapiro static SM_LDAP_RECURSE_ENTRY * 410605302a5SGregory Neil Shapiro sm_ldap_add_recurse(top, item, type, rpool) 41140266059SGregory Neil Shapiro SM_LDAP_RECURSE_LIST **top; 41240266059SGregory Neil Shapiro char *item; 41340266059SGregory Neil Shapiro int type; 41440266059SGregory Neil Shapiro SM_RPOOL_T *rpool; 41540266059SGregory Neil Shapiro { 416605302a5SGregory Neil Shapiro int n; 417605302a5SGregory Neil Shapiro int m; 418605302a5SGregory Neil Shapiro int p; 419605302a5SGregory Neil Shapiro int insertat; 420605302a5SGregory Neil Shapiro int moveb; 421605302a5SGregory Neil Shapiro int oldsizeb; 422605302a5SGregory Neil Shapiro int rc; 423605302a5SGregory Neil Shapiro SM_LDAP_RECURSE_ENTRY *newe; 424605302a5SGregory Neil Shapiro SM_LDAP_RECURSE_ENTRY **olddata; 42540266059SGregory Neil Shapiro 426605302a5SGregory Neil Shapiro /* 427605302a5SGregory Neil Shapiro ** This code will maintain a list of 428605302a5SGregory Neil Shapiro ** SM_LDAP_RECURSE_ENTRY structures 429605302a5SGregory Neil Shapiro ** in ascending order. 430605302a5SGregory Neil Shapiro */ 431605302a5SGregory Neil Shapiro 432605302a5SGregory Neil Shapiro if (*top == NULL) 43340266059SGregory Neil Shapiro { 434605302a5SGregory Neil Shapiro /* Allocate an initial SM_LDAP_RECURSE_LIST struct */ 435605302a5SGregory Neil Shapiro *top = sm_rpool_malloc_x(rpool, sizeof **top); 436605302a5SGregory Neil Shapiro (*top)->lr_cnt = 0; 437605302a5SGregory Neil Shapiro (*top)->lr_size = 0; 438605302a5SGregory Neil Shapiro (*top)->lr_data = NULL; 43940266059SGregory Neil Shapiro } 44040266059SGregory Neil Shapiro 441605302a5SGregory Neil Shapiro if ((*top)->lr_cnt >= (*top)->lr_size) 442605302a5SGregory Neil Shapiro { 443605302a5SGregory Neil Shapiro /* Grow the list of SM_LDAP_RECURSE_ENTRY ptrs */ 444605302a5SGregory Neil Shapiro olddata = (*top)->lr_data; 445605302a5SGregory Neil Shapiro if ((*top)->lr_size == 0) 446605302a5SGregory Neil Shapiro { 447605302a5SGregory Neil Shapiro oldsizeb = 0; 448605302a5SGregory Neil Shapiro (*top)->lr_size = 256; 449605302a5SGregory Neil Shapiro } 45040266059SGregory Neil Shapiro else 451605302a5SGregory Neil Shapiro { 452605302a5SGregory Neil Shapiro oldsizeb = (*top)->lr_size * sizeof *((*top)->lr_data); 453605302a5SGregory Neil Shapiro (*top)->lr_size *= 2; 454605302a5SGregory Neil Shapiro } 455605302a5SGregory Neil Shapiro (*top)->lr_data = sm_rpool_malloc_x(rpool, 456605302a5SGregory Neil Shapiro (*top)->lr_size * sizeof *((*top)->lr_data)); 457605302a5SGregory Neil Shapiro if (oldsizeb > 0) 458605302a5SGregory Neil Shapiro memcpy((*top)->lr_data, olddata, oldsizeb); 459605302a5SGregory Neil Shapiro } 460605302a5SGregory Neil Shapiro 461605302a5SGregory Neil Shapiro /* 462605302a5SGregory Neil Shapiro ** Binary search/insert item:type into list. 463605302a5SGregory Neil Shapiro ** Return current entry pointer if already exists. 464605302a5SGregory Neil Shapiro */ 465605302a5SGregory Neil Shapiro 466605302a5SGregory Neil Shapiro n = 0; 467605302a5SGregory Neil Shapiro m = (*top)->lr_cnt - 1; 468605302a5SGregory Neil Shapiro if (m < 0) 469605302a5SGregory Neil Shapiro insertat = 0; 470605302a5SGregory Neil Shapiro else 471605302a5SGregory Neil Shapiro insertat = -1; 472605302a5SGregory Neil Shapiro 473605302a5SGregory Neil Shapiro while (insertat == -1) 474605302a5SGregory Neil Shapiro { 475605302a5SGregory Neil Shapiro p = (m + n) / 2; 476605302a5SGregory Neil Shapiro 477605302a5SGregory Neil Shapiro rc = sm_strcasecmp(item, (*top)->lr_data[p]->lr_search); 478605302a5SGregory Neil Shapiro if (rc == 0) 479605302a5SGregory Neil Shapiro rc = type - (*top)->lr_data[p]->lr_type; 480605302a5SGregory Neil Shapiro 481605302a5SGregory Neil Shapiro if (rc < 0) 482605302a5SGregory Neil Shapiro m = p - 1; 483605302a5SGregory Neil Shapiro else if (rc > 0) 484605302a5SGregory Neil Shapiro n = p + 1; 485605302a5SGregory Neil Shapiro else 486605302a5SGregory Neil Shapiro return (*top)->lr_data[p]; 487605302a5SGregory Neil Shapiro 488605302a5SGregory Neil Shapiro if (m == -1) 489605302a5SGregory Neil Shapiro insertat = 0; 490605302a5SGregory Neil Shapiro else if (n >= (*top)->lr_cnt) 491605302a5SGregory Neil Shapiro insertat = (*top)->lr_cnt; 492605302a5SGregory Neil Shapiro else if (m < n) 493605302a5SGregory Neil Shapiro insertat = m + 1; 494605302a5SGregory Neil Shapiro } 495605302a5SGregory Neil Shapiro 496605302a5SGregory Neil Shapiro /* 497605302a5SGregory Neil Shapiro ** Not found in list, make room 498605302a5SGregory Neil Shapiro ** at insert point and add it. 499605302a5SGregory Neil Shapiro */ 500605302a5SGregory Neil Shapiro 501605302a5SGregory Neil Shapiro newe = sm_rpool_malloc_x(rpool, sizeof *newe); 502605302a5SGregory Neil Shapiro if (newe != NULL) 503605302a5SGregory Neil Shapiro { 504605302a5SGregory Neil Shapiro moveb = ((*top)->lr_cnt - insertat) * sizeof *((*top)->lr_data); 505605302a5SGregory Neil Shapiro if (moveb > 0) 506605302a5SGregory Neil Shapiro memmove(&((*top)->lr_data[insertat + 1]), 507605302a5SGregory Neil Shapiro &((*top)->lr_data[insertat]), 508605302a5SGregory Neil Shapiro moveb); 509605302a5SGregory Neil Shapiro 510605302a5SGregory Neil Shapiro newe->lr_search = sm_rpool_strdup_x(rpool, item); 511605302a5SGregory Neil Shapiro newe->lr_type = type; 512605302a5SGregory Neil Shapiro newe->lr_done = false; 513605302a5SGregory Neil Shapiro 514605302a5SGregory Neil Shapiro ((*top)->lr_data)[insertat] = newe; 515605302a5SGregory Neil Shapiro (*top)->lr_cnt++; 516605302a5SGregory Neil Shapiro } 517605302a5SGregory Neil Shapiro return newe; 51840266059SGregory Neil Shapiro } 51940266059SGregory Neil Shapiro 52040266059SGregory Neil Shapiro int 521605302a5SGregory Neil Shapiro sm_ldap_results(lmap, msgid, flags, delim, rpool, result, 522605302a5SGregory Neil Shapiro resultln, resultsz, recurse) 52340266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap; 52440266059SGregory Neil Shapiro int msgid; 52540266059SGregory Neil Shapiro int flags; 526605302a5SGregory Neil Shapiro int delim; 52740266059SGregory Neil Shapiro SM_RPOOL_T *rpool; 52840266059SGregory Neil Shapiro char **result; 529605302a5SGregory Neil Shapiro int *resultln; 530605302a5SGregory Neil Shapiro int *resultsz; 53140266059SGregory Neil Shapiro SM_LDAP_RECURSE_LIST *recurse; 53240266059SGregory Neil Shapiro { 53340266059SGregory Neil Shapiro bool toplevel; 53440266059SGregory Neil Shapiro int i; 53540266059SGregory Neil Shapiro int statp; 53640266059SGregory Neil Shapiro int vsize; 53740266059SGregory Neil Shapiro int ret; 53840266059SGregory Neil Shapiro int save_errno; 53940266059SGregory Neil Shapiro char *p; 540605302a5SGregory Neil Shapiro SM_LDAP_RECURSE_ENTRY *rl; 54140266059SGregory Neil Shapiro 54240266059SGregory Neil Shapiro /* Are we the top top level of the search? */ 54340266059SGregory Neil Shapiro toplevel = (recurse == NULL); 54440266059SGregory Neil Shapiro 54540266059SGregory Neil Shapiro /* Get results */ 54640266059SGregory Neil Shapiro statp = EX_NOTFOUND; 54740266059SGregory Neil Shapiro while ((ret = ldap_result(lmap->ldap_ld, msgid, 0, 54840266059SGregory Neil Shapiro (lmap->ldap_timeout.tv_sec == 0 ? NULL : 54940266059SGregory Neil Shapiro &(lmap->ldap_timeout)), 55040266059SGregory Neil Shapiro &(lmap->ldap_res))) == LDAP_RES_SEARCH_ENTRY) 55140266059SGregory Neil Shapiro { 55240266059SGregory Neil Shapiro LDAPMessage *entry; 55340266059SGregory Neil Shapiro 55440266059SGregory Neil Shapiro /* If we don't want multiple values and we have one, break */ 555605302a5SGregory Neil Shapiro if ((char) delim == '\0' && *result != NULL) 55640266059SGregory Neil Shapiro break; 55740266059SGregory Neil Shapiro 55840266059SGregory Neil Shapiro /* Cycle through all entries */ 55940266059SGregory Neil Shapiro for (entry = ldap_first_entry(lmap->ldap_ld, lmap->ldap_res); 56040266059SGregory Neil Shapiro entry != NULL; 56140266059SGregory Neil Shapiro entry = ldap_next_entry(lmap->ldap_ld, lmap->ldap_res)) 56240266059SGregory Neil Shapiro { 56340266059SGregory Neil Shapiro BerElement *ber; 56440266059SGregory Neil Shapiro char *attr; 56540266059SGregory Neil Shapiro char **vals = NULL; 56640266059SGregory Neil Shapiro char *dn; 56740266059SGregory Neil Shapiro 56840266059SGregory Neil Shapiro /* 56940266059SGregory Neil Shapiro ** If matching only and found an entry, 57040266059SGregory Neil Shapiro ** no need to spin through attributes 57140266059SGregory Neil Shapiro */ 57240266059SGregory Neil Shapiro 57340266059SGregory Neil Shapiro if (statp == EX_OK && 57440266059SGregory Neil Shapiro bitset(SM_LDAP_MATCHONLY, flags)) 57540266059SGregory Neil Shapiro continue; 57640266059SGregory Neil Shapiro 57740266059SGregory Neil Shapiro /* record completed DN's to prevent loops */ 57840266059SGregory Neil Shapiro dn = ldap_get_dn(lmap->ldap_ld, entry); 57940266059SGregory Neil Shapiro if (dn == NULL) 58040266059SGregory Neil Shapiro { 58140266059SGregory Neil Shapiro save_errno = sm_ldap_geterrno(lmap->ldap_ld); 58240266059SGregory Neil Shapiro save_errno += E_LDAPBASE; 583605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 58440266059SGregory Neil Shapiro errno = save_errno; 585a7ec597cSGregory Neil Shapiro return EX_TEMPFAIL; 58640266059SGregory Neil Shapiro } 58740266059SGregory Neil Shapiro 588605302a5SGregory Neil Shapiro rl = sm_ldap_add_recurse(&recurse, dn, 589605302a5SGregory Neil Shapiro SM_LDAP_ATTR_DN, 590605302a5SGregory Neil Shapiro rpool); 591605302a5SGregory Neil Shapiro 592605302a5SGregory Neil Shapiro if (rl == NULL) 59340266059SGregory Neil Shapiro { 59440266059SGregory Neil Shapiro ldap_memfree(dn); 595605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 59640266059SGregory Neil Shapiro errno = ENOMEM; 59740266059SGregory Neil Shapiro return EX_OSERR; 598605302a5SGregory Neil Shapiro } 599605302a5SGregory Neil Shapiro else if (rl->lr_done) 600605302a5SGregory Neil Shapiro { 60140266059SGregory Neil Shapiro /* already on list, skip it */ 60240266059SGregory Neil Shapiro ldap_memfree(dn); 60340266059SGregory Neil Shapiro continue; 60440266059SGregory Neil Shapiro } 60540266059SGregory Neil Shapiro ldap_memfree(dn); 60640266059SGregory Neil Shapiro 60740266059SGregory Neil Shapiro # if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT) 60840266059SGregory Neil Shapiro /* 60940266059SGregory Neil Shapiro ** Reset value to prevent lingering 61040266059SGregory Neil Shapiro ** LDAP_DECODING_ERROR due to 61140266059SGregory Neil Shapiro ** OpenLDAP 1.X's hack (see below) 61240266059SGregory Neil Shapiro */ 61340266059SGregory Neil Shapiro 61440266059SGregory Neil Shapiro lmap->ldap_ld->ld_errno = LDAP_SUCCESS; 61540266059SGregory Neil Shapiro # endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */ 61640266059SGregory Neil Shapiro 61740266059SGregory Neil Shapiro for (attr = ldap_first_attribute(lmap->ldap_ld, entry, 61840266059SGregory Neil Shapiro &ber); 61940266059SGregory Neil Shapiro attr != NULL; 62040266059SGregory Neil Shapiro attr = ldap_next_attribute(lmap->ldap_ld, entry, 62140266059SGregory Neil Shapiro ber)) 62240266059SGregory Neil Shapiro { 62340266059SGregory Neil Shapiro char *tmp, *vp_tmp; 62440266059SGregory Neil Shapiro int type; 625605302a5SGregory Neil Shapiro char *needobjclass = NULL; 62640266059SGregory Neil Shapiro 627605302a5SGregory Neil Shapiro type = SM_LDAP_ATTR_NONE; 62840266059SGregory Neil Shapiro for (i = 0; lmap->ldap_attr[i] != NULL; i++) 62940266059SGregory Neil Shapiro { 63040266059SGregory Neil Shapiro if (sm_strcasecmp(lmap->ldap_attr[i], 63140266059SGregory Neil Shapiro attr) == 0) 63240266059SGregory Neil Shapiro { 63340266059SGregory Neil Shapiro type = lmap->ldap_attr_type[i]; 634605302a5SGregory Neil Shapiro needobjclass = lmap->ldap_attr_needobjclass[i]; 63540266059SGregory Neil Shapiro break; 63640266059SGregory Neil Shapiro } 63740266059SGregory Neil Shapiro } 638605302a5SGregory Neil Shapiro 639605302a5SGregory Neil Shapiro if (bitset(SM_LDAP_USE_ALLATTR, flags) && 640605302a5SGregory Neil Shapiro type == SM_LDAP_ATTR_NONE) 641605302a5SGregory Neil Shapiro { 642605302a5SGregory Neil Shapiro /* URL lookups specify attrs to use */ 643605302a5SGregory Neil Shapiro type = SM_LDAP_ATTR_NORMAL; 644605302a5SGregory Neil Shapiro needobjclass = NULL; 645605302a5SGregory Neil Shapiro } 646605302a5SGregory Neil Shapiro 647605302a5SGregory Neil Shapiro if (type == SM_LDAP_ATTR_NONE) 64840266059SGregory Neil Shapiro { 64940266059SGregory Neil Shapiro /* attribute not requested */ 65040266059SGregory Neil Shapiro ldap_memfree(attr); 651605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 65240266059SGregory Neil Shapiro errno = EFAULT; 65340266059SGregory Neil Shapiro return EX_SOFTWARE; 65440266059SGregory Neil Shapiro } 65540266059SGregory Neil Shapiro 656605302a5SGregory Neil Shapiro /* 657605302a5SGregory Neil Shapiro ** For recursion on a particular attribute, 658605302a5SGregory Neil Shapiro ** we may need to see if this entry is 659605302a5SGregory Neil Shapiro ** part of a particular objectclass. 660605302a5SGregory Neil Shapiro ** Also, ignore objectClass attribute. 661605302a5SGregory Neil Shapiro ** Otherwise we just ignore this attribute. 662605302a5SGregory Neil Shapiro */ 663605302a5SGregory Neil Shapiro 664605302a5SGregory Neil Shapiro if (type == SM_LDAP_ATTR_OBJCLASS || 665605302a5SGregory Neil Shapiro (needobjclass != NULL && 666605302a5SGregory Neil Shapiro !sm_ldap_has_objectclass(lmap, entry, 667605302a5SGregory Neil Shapiro needobjclass))) 668605302a5SGregory Neil Shapiro { 669605302a5SGregory Neil Shapiro ldap_memfree(attr); 670605302a5SGregory Neil Shapiro continue; 671605302a5SGregory Neil Shapiro } 672605302a5SGregory Neil Shapiro 67340266059SGregory Neil Shapiro if (lmap->ldap_attrsonly == LDAPMAP_FALSE) 67440266059SGregory Neil Shapiro { 67540266059SGregory Neil Shapiro vals = ldap_get_values(lmap->ldap_ld, 67640266059SGregory Neil Shapiro entry, 67740266059SGregory Neil Shapiro attr); 67840266059SGregory Neil Shapiro if (vals == NULL) 67940266059SGregory Neil Shapiro { 68040266059SGregory Neil Shapiro save_errno = sm_ldap_geterrno(lmap->ldap_ld); 68140266059SGregory Neil Shapiro if (save_errno == LDAP_SUCCESS) 68240266059SGregory Neil Shapiro { 68340266059SGregory Neil Shapiro ldap_memfree(attr); 68440266059SGregory Neil Shapiro continue; 68540266059SGregory Neil Shapiro } 68640266059SGregory Neil Shapiro 68740266059SGregory Neil Shapiro /* Must be an error */ 68840266059SGregory Neil Shapiro save_errno += E_LDAPBASE; 68940266059SGregory Neil Shapiro ldap_memfree(attr); 690605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 69140266059SGregory Neil Shapiro errno = save_errno; 69240266059SGregory Neil Shapiro return EX_TEMPFAIL; 69340266059SGregory Neil Shapiro } 69440266059SGregory Neil Shapiro } 69540266059SGregory Neil Shapiro 69640266059SGregory Neil Shapiro statp = EX_OK; 69740266059SGregory Neil Shapiro 69840266059SGregory Neil Shapiro # if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT) 69940266059SGregory Neil Shapiro /* 70040266059SGregory Neil Shapiro ** Reset value to prevent lingering 70140266059SGregory Neil Shapiro ** LDAP_DECODING_ERROR due to 70240266059SGregory Neil Shapiro ** OpenLDAP 1.X's hack (see below) 70340266059SGregory Neil Shapiro */ 70440266059SGregory Neil Shapiro 70540266059SGregory Neil Shapiro lmap->ldap_ld->ld_errno = LDAP_SUCCESS; 70640266059SGregory Neil Shapiro # endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */ 70740266059SGregory Neil Shapiro 70840266059SGregory Neil Shapiro /* 70940266059SGregory Neil Shapiro ** If matching only, 71040266059SGregory Neil Shapiro ** no need to spin through entries 71140266059SGregory Neil Shapiro */ 71240266059SGregory Neil Shapiro 71340266059SGregory Neil Shapiro if (bitset(SM_LDAP_MATCHONLY, flags)) 71440266059SGregory Neil Shapiro { 71540266059SGregory Neil Shapiro if (lmap->ldap_attrsonly == LDAPMAP_FALSE) 71640266059SGregory Neil Shapiro ldap_value_free(vals); 71740266059SGregory Neil Shapiro ldap_memfree(attr); 71840266059SGregory Neil Shapiro continue; 71940266059SGregory Neil Shapiro } 72040266059SGregory Neil Shapiro 72140266059SGregory Neil Shapiro /* 72240266059SGregory Neil Shapiro ** If we don't want multiple values, 72340266059SGregory Neil Shapiro ** return first found. 72440266059SGregory Neil Shapiro */ 72540266059SGregory Neil Shapiro 726605302a5SGregory Neil Shapiro if ((char) delim == '\0') 72740266059SGregory Neil Shapiro { 728605302a5SGregory Neil Shapiro if (*result != NULL) 729605302a5SGregory Neil Shapiro { 730605302a5SGregory Neil Shapiro /* already have a value */ 731605302a5SGregory Neil Shapiro break; 732605302a5SGregory Neil Shapiro } 733605302a5SGregory Neil Shapiro 734605302a5SGregory Neil Shapiro if (bitset(SM_LDAP_SINGLEMATCH, 735605302a5SGregory Neil Shapiro flags) && 736605302a5SGregory Neil Shapiro *result != NULL) 737605302a5SGregory Neil Shapiro { 738605302a5SGregory Neil Shapiro /* only wanted one match */ 739605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 740605302a5SGregory Neil Shapiro errno = ENOENT; 741605302a5SGregory Neil Shapiro return EX_NOTFOUND; 742605302a5SGregory Neil Shapiro } 743605302a5SGregory Neil Shapiro 74440266059SGregory Neil Shapiro if (lmap->ldap_attrsonly == LDAPMAP_TRUE) 74540266059SGregory Neil Shapiro { 74640266059SGregory Neil Shapiro *result = sm_rpool_strdup_x(rpool, 74740266059SGregory Neil Shapiro attr); 74840266059SGregory Neil Shapiro ldap_memfree(attr); 74940266059SGregory Neil Shapiro break; 75040266059SGregory Neil Shapiro } 75140266059SGregory Neil Shapiro 75240266059SGregory Neil Shapiro if (vals[0] == NULL) 75340266059SGregory Neil Shapiro { 75440266059SGregory Neil Shapiro ldap_value_free(vals); 75540266059SGregory Neil Shapiro ldap_memfree(attr); 75640266059SGregory Neil Shapiro continue; 75740266059SGregory Neil Shapiro } 75840266059SGregory Neil Shapiro 75940266059SGregory Neil Shapiro vsize = strlen(vals[0]) + 1; 76040266059SGregory Neil Shapiro if (lmap->ldap_attrsep != '\0') 76140266059SGregory Neil Shapiro vsize += strlen(attr) + 1; 76240266059SGregory Neil Shapiro *result = sm_rpool_malloc_x(rpool, 76340266059SGregory Neil Shapiro vsize); 76440266059SGregory Neil Shapiro if (lmap->ldap_attrsep != '\0') 76540266059SGregory Neil Shapiro sm_snprintf(*result, vsize, 76640266059SGregory Neil Shapiro "%s%c%s", 76740266059SGregory Neil Shapiro attr, 76840266059SGregory Neil Shapiro lmap->ldap_attrsep, 76940266059SGregory Neil Shapiro vals[0]); 77040266059SGregory Neil Shapiro else 77140266059SGregory Neil Shapiro sm_strlcpy(*result, vals[0], 77240266059SGregory Neil Shapiro vsize); 77340266059SGregory Neil Shapiro ldap_value_free(vals); 77440266059SGregory Neil Shapiro ldap_memfree(attr); 77540266059SGregory Neil Shapiro break; 77640266059SGregory Neil Shapiro } 77740266059SGregory Neil Shapiro 77840266059SGregory Neil Shapiro /* attributes only */ 77940266059SGregory Neil Shapiro if (lmap->ldap_attrsonly == LDAPMAP_TRUE) 78040266059SGregory Neil Shapiro { 78140266059SGregory Neil Shapiro if (*result == NULL) 78240266059SGregory Neil Shapiro *result = sm_rpool_strdup_x(rpool, 78340266059SGregory Neil Shapiro attr); 78440266059SGregory Neil Shapiro else 78540266059SGregory Neil Shapiro { 786605302a5SGregory Neil Shapiro if (bitset(SM_LDAP_SINGLEMATCH, 787605302a5SGregory Neil Shapiro flags) && 788605302a5SGregory Neil Shapiro *result != NULL) 789605302a5SGregory Neil Shapiro { 790605302a5SGregory Neil Shapiro /* only wanted one match */ 791605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 792605302a5SGregory Neil Shapiro errno = ENOENT; 793605302a5SGregory Neil Shapiro return EX_NOTFOUND; 794605302a5SGregory Neil Shapiro } 795605302a5SGregory Neil Shapiro 79640266059SGregory Neil Shapiro vsize = strlen(*result) + 79740266059SGregory Neil Shapiro strlen(attr) + 2; 79840266059SGregory Neil Shapiro tmp = sm_rpool_malloc_x(rpool, 79940266059SGregory Neil Shapiro vsize); 80040266059SGregory Neil Shapiro (void) sm_snprintf(tmp, 80140266059SGregory Neil Shapiro vsize, "%s%c%s", 802605302a5SGregory Neil Shapiro *result, (char) delim, 80340266059SGregory Neil Shapiro attr); 80440266059SGregory Neil Shapiro *result = tmp; 80540266059SGregory Neil Shapiro } 80640266059SGregory Neil Shapiro ldap_memfree(attr); 80740266059SGregory Neil Shapiro continue; 80840266059SGregory Neil Shapiro } 80940266059SGregory Neil Shapiro 81040266059SGregory Neil Shapiro /* 811605302a5SGregory Neil Shapiro ** If there is more than one, munge then 812605302a5SGregory Neil Shapiro ** into a map_coldelim separated string. 813605302a5SGregory Neil Shapiro ** If we are recursing we may have an entry 814605302a5SGregory Neil Shapiro ** with no 'normal' values to put in the 815605302a5SGregory Neil Shapiro ** string. 816605302a5SGregory Neil Shapiro ** This is not an error. 81740266059SGregory Neil Shapiro */ 81840266059SGregory Neil Shapiro 819605302a5SGregory Neil Shapiro if (type == SM_LDAP_ATTR_NORMAL && 820605302a5SGregory Neil Shapiro bitset(SM_LDAP_SINGLEMATCH, flags) && 821605302a5SGregory Neil Shapiro *result != NULL) 822605302a5SGregory Neil Shapiro { 823605302a5SGregory Neil Shapiro /* only wanted one match */ 824605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 825605302a5SGregory Neil Shapiro errno = ENOENT; 826605302a5SGregory Neil Shapiro return EX_NOTFOUND; 827605302a5SGregory Neil Shapiro } 828605302a5SGregory Neil Shapiro 82940266059SGregory Neil Shapiro vsize = 0; 83040266059SGregory Neil Shapiro for (i = 0; vals[i] != NULL; i++) 83140266059SGregory Neil Shapiro { 832605302a5SGregory Neil Shapiro if (type == SM_LDAP_ATTR_DN || 833605302a5SGregory Neil Shapiro type == SM_LDAP_ATTR_FILTER || 834605302a5SGregory Neil Shapiro type == SM_LDAP_ATTR_URL) 83540266059SGregory Neil Shapiro { 836605302a5SGregory Neil Shapiro /* add to recursion */ 837605302a5SGregory Neil Shapiro if (sm_ldap_add_recurse(&recurse, 83840266059SGregory Neil Shapiro vals[i], 839605302a5SGregory Neil Shapiro type, 840605302a5SGregory Neil Shapiro rpool) == NULL) 84140266059SGregory Neil Shapiro { 842605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 84340266059SGregory Neil Shapiro errno = ENOMEM; 84440266059SGregory Neil Shapiro return EX_OSERR; 84540266059SGregory Neil Shapiro } 84640266059SGregory Neil Shapiro continue; 84740266059SGregory Neil Shapiro } 848605302a5SGregory Neil Shapiro 84940266059SGregory Neil Shapiro vsize += strlen(vals[i]) + 1; 85040266059SGregory Neil Shapiro if (lmap->ldap_attrsep != '\0') 85140266059SGregory Neil Shapiro vsize += strlen(attr) + 1; 85240266059SGregory Neil Shapiro } 853605302a5SGregory Neil Shapiro 854605302a5SGregory Neil Shapiro /* 855605302a5SGregory Neil Shapiro ** Create/Append to string any normal 856605302a5SGregory Neil Shapiro ** attribute values. Otherwise, just free 857605302a5SGregory Neil Shapiro ** memory and move on to the next 858605302a5SGregory Neil Shapiro ** attribute in this entry. 859605302a5SGregory Neil Shapiro */ 860605302a5SGregory Neil Shapiro 861605302a5SGregory Neil Shapiro if (type == SM_LDAP_ATTR_NORMAL && vsize > 0) 862605302a5SGregory Neil Shapiro { 863605302a5SGregory Neil Shapiro char *pe; 864605302a5SGregory Neil Shapiro 865605302a5SGregory Neil Shapiro /* Grow result string if needed */ 866605302a5SGregory Neil Shapiro if ((*resultln + vsize) >= *resultsz) 867605302a5SGregory Neil Shapiro { 868605302a5SGregory Neil Shapiro while ((*resultln + vsize) >= *resultsz) 869605302a5SGregory Neil Shapiro { 870605302a5SGregory Neil Shapiro if (*resultsz == 0) 871605302a5SGregory Neil Shapiro *resultsz = 1024; 872605302a5SGregory Neil Shapiro else 873605302a5SGregory Neil Shapiro *resultsz *= 2; 874605302a5SGregory Neil Shapiro } 875605302a5SGregory Neil Shapiro 876605302a5SGregory Neil Shapiro vp_tmp = sm_rpool_malloc_x(rpool, *resultsz); 87740266059SGregory Neil Shapiro *vp_tmp = '\0'; 87840266059SGregory Neil Shapiro 879605302a5SGregory Neil Shapiro if (*result != NULL) 880605302a5SGregory Neil Shapiro sm_strlcpy(vp_tmp, 881605302a5SGregory Neil Shapiro *result, 882605302a5SGregory Neil Shapiro *resultsz); 883605302a5SGregory Neil Shapiro *result = vp_tmp; 884605302a5SGregory Neil Shapiro } 885605302a5SGregory Neil Shapiro 886605302a5SGregory Neil Shapiro p = *result + *resultln; 887605302a5SGregory Neil Shapiro pe = *result + *resultsz; 888605302a5SGregory Neil Shapiro 88940266059SGregory Neil Shapiro for (i = 0; vals[i] != NULL; i++) 89040266059SGregory Neil Shapiro { 891959366dcSGregory Neil Shapiro if (*resultln > 0 && 892959366dcSGregory Neil Shapiro p < pe) 893605302a5SGregory Neil Shapiro *p++ = (char) delim; 894605302a5SGregory Neil Shapiro 89540266059SGregory Neil Shapiro if (lmap->ldap_attrsep != '\0') 89640266059SGregory Neil Shapiro { 89740266059SGregory Neil Shapiro p += sm_strlcpy(p, attr, 898605302a5SGregory Neil Shapiro pe - p); 899605302a5SGregory Neil Shapiro if (p < pe) 90040266059SGregory Neil Shapiro *p++ = lmap->ldap_attrsep; 90140266059SGregory Neil Shapiro } 902605302a5SGregory Neil Shapiro 90340266059SGregory Neil Shapiro p += sm_strlcpy(p, vals[i], 904605302a5SGregory Neil Shapiro pe - p); 905605302a5SGregory Neil Shapiro *resultln = p - (*result); 906605302a5SGregory Neil Shapiro if (p >= pe) 90740266059SGregory Neil Shapiro { 90840266059SGregory Neil Shapiro /* Internal error: buffer too small for LDAP values */ 909605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 91040266059SGregory Neil Shapiro errno = ENOMEM; 91140266059SGregory Neil Shapiro return EX_OSERR; 91240266059SGregory Neil Shapiro } 913605302a5SGregory Neil Shapiro } 91440266059SGregory Neil Shapiro } 91540266059SGregory Neil Shapiro 91640266059SGregory Neil Shapiro ldap_value_free(vals); 91740266059SGregory Neil Shapiro ldap_memfree(attr); 91840266059SGregory Neil Shapiro } 91940266059SGregory Neil Shapiro save_errno = sm_ldap_geterrno(lmap->ldap_ld); 92040266059SGregory Neil Shapiro 92140266059SGregory Neil Shapiro /* 92240266059SGregory Neil Shapiro ** We check save_errno != LDAP_DECODING_ERROR since 92340266059SGregory Neil Shapiro ** OpenLDAP 1.X has a very ugly *undocumented* 92440266059SGregory Neil Shapiro ** hack of returning this error code from 92540266059SGregory Neil Shapiro ** ldap_next_attribute() if the library freed the 92640266059SGregory Neil Shapiro ** ber attribute. See: 92740266059SGregory Neil Shapiro ** http://www.openldap.org/lists/openldap-devel/9901/msg00064.html 92840266059SGregory Neil Shapiro */ 92940266059SGregory Neil Shapiro 93040266059SGregory Neil Shapiro if (save_errno != LDAP_SUCCESS && 93140266059SGregory Neil Shapiro save_errno != LDAP_DECODING_ERROR) 93240266059SGregory Neil Shapiro { 93340266059SGregory Neil Shapiro /* Must be an error */ 93440266059SGregory Neil Shapiro save_errno += E_LDAPBASE; 935605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 93640266059SGregory Neil Shapiro errno = save_errno; 93740266059SGregory Neil Shapiro return EX_TEMPFAIL; 93840266059SGregory Neil Shapiro } 93940266059SGregory Neil Shapiro 940605302a5SGregory Neil Shapiro /* mark this DN as done */ 941605302a5SGregory Neil Shapiro rl->lr_done = true; 942605302a5SGregory Neil Shapiro 94340266059SGregory Neil Shapiro /* We don't want multiple values and we have one */ 944605302a5SGregory Neil Shapiro if ((char) delim == '\0' && *result != NULL) 94540266059SGregory Neil Shapiro break; 94640266059SGregory Neil Shapiro } 94740266059SGregory Neil Shapiro save_errno = sm_ldap_geterrno(lmap->ldap_ld); 94840266059SGregory Neil Shapiro if (save_errno != LDAP_SUCCESS && 94940266059SGregory Neil Shapiro save_errno != LDAP_DECODING_ERROR) 95040266059SGregory Neil Shapiro { 95140266059SGregory Neil Shapiro /* Must be an error */ 95240266059SGregory Neil Shapiro save_errno += E_LDAPBASE; 953605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 95440266059SGregory Neil Shapiro errno = save_errno; 95540266059SGregory Neil Shapiro return EX_TEMPFAIL; 95640266059SGregory Neil Shapiro } 95740266059SGregory Neil Shapiro ldap_msgfree(lmap->ldap_res); 95840266059SGregory Neil Shapiro lmap->ldap_res = NULL; 95940266059SGregory Neil Shapiro } 96040266059SGregory Neil Shapiro 96140266059SGregory Neil Shapiro if (ret == 0) 96240266059SGregory Neil Shapiro save_errno = ETIMEDOUT; 96340266059SGregory Neil Shapiro else 96440266059SGregory Neil Shapiro save_errno = sm_ldap_geterrno(lmap->ldap_ld); 96540266059SGregory Neil Shapiro if (save_errno != LDAP_SUCCESS) 96640266059SGregory Neil Shapiro { 96740266059SGregory Neil Shapiro statp = EX_TEMPFAIL; 96840266059SGregory Neil Shapiro if (ret != 0) 96940266059SGregory Neil Shapiro { 97040266059SGregory Neil Shapiro switch (save_errno) 97140266059SGregory Neil Shapiro { 97240266059SGregory Neil Shapiro #ifdef LDAP_SERVER_DOWN 97340266059SGregory Neil Shapiro case LDAP_SERVER_DOWN: 97440266059SGregory Neil Shapiro #endif /* LDAP_SERVER_DOWN */ 97540266059SGregory Neil Shapiro case LDAP_TIMEOUT: 97640266059SGregory Neil Shapiro case LDAP_UNAVAILABLE: 977605302a5SGregory Neil Shapiro 978605302a5SGregory Neil Shapiro /* 979605302a5SGregory Neil Shapiro ** server disappeared, 980605302a5SGregory Neil Shapiro ** try reopen on next search 981605302a5SGregory Neil Shapiro */ 982605302a5SGregory Neil Shapiro 98340266059SGregory Neil Shapiro statp = EX_RESTART; 98440266059SGregory Neil Shapiro break; 98540266059SGregory Neil Shapiro } 98640266059SGregory Neil Shapiro save_errno += E_LDAPBASE; 98740266059SGregory Neil Shapiro } 988605302a5SGregory Neil Shapiro SM_LDAP_ERROR_CLEANUP(); 98940266059SGregory Neil Shapiro errno = save_errno; 99040266059SGregory Neil Shapiro return statp; 99140266059SGregory Neil Shapiro } 99240266059SGregory Neil Shapiro 99340266059SGregory Neil Shapiro if (lmap->ldap_res != NULL) 99440266059SGregory Neil Shapiro { 99540266059SGregory Neil Shapiro ldap_msgfree(lmap->ldap_res); 99640266059SGregory Neil Shapiro lmap->ldap_res = NULL; 99740266059SGregory Neil Shapiro } 99840266059SGregory Neil Shapiro 99940266059SGregory Neil Shapiro if (toplevel) 100040266059SGregory Neil Shapiro { 1001605302a5SGregory Neil Shapiro int rlidx; 100240266059SGregory Neil Shapiro 100340266059SGregory Neil Shapiro /* 100440266059SGregory Neil Shapiro ** Spin through the built-up recurse list at the top 100540266059SGregory Neil Shapiro ** of the recursion. Since new items are added at the 100640266059SGregory Neil Shapiro ** end of the shared list, we actually only ever get 100740266059SGregory Neil Shapiro ** one level of recursion before things pop back to the 100840266059SGregory Neil Shapiro ** top. Any items added to the list during that recursion 100940266059SGregory Neil Shapiro ** will be expanded by the top level. 101040266059SGregory Neil Shapiro */ 101140266059SGregory Neil Shapiro 1012605302a5SGregory Neil Shapiro for (rlidx = 0; recurse != NULL && rlidx < recurse->lr_cnt; rlidx++) 101340266059SGregory Neil Shapiro { 1014605302a5SGregory Neil Shapiro int newflags; 101540266059SGregory Neil Shapiro int sid; 101640266059SGregory Neil Shapiro int status; 101740266059SGregory Neil Shapiro 1018605302a5SGregory Neil Shapiro rl = recurse->lr_data[rlidx]; 1019605302a5SGregory Neil Shapiro 1020605302a5SGregory Neil Shapiro newflags = flags; 1021605302a5SGregory Neil Shapiro if (rl->lr_done) 102240266059SGregory Neil Shapiro { 102340266059SGregory Neil Shapiro /* already expanded */ 102440266059SGregory Neil Shapiro continue; 102540266059SGregory Neil Shapiro } 1026605302a5SGregory Neil Shapiro 1027605302a5SGregory Neil Shapiro if (rl->lr_type == SM_LDAP_ATTR_DN) 102840266059SGregory Neil Shapiro { 102940266059SGregory Neil Shapiro /* do DN search */ 103040266059SGregory Neil Shapiro sid = ldap_search(lmap->ldap_ld, 103140266059SGregory Neil Shapiro rl->lr_search, 103240266059SGregory Neil Shapiro lmap->ldap_scope, 103340266059SGregory Neil Shapiro "(objectClass=*)", 1034605302a5SGregory Neil Shapiro (lmap->ldap_attr[0] == NULL ? 1035605302a5SGregory Neil Shapiro NULL : lmap->ldap_attr), 103640266059SGregory Neil Shapiro lmap->ldap_attrsonly); 103740266059SGregory Neil Shapiro } 1038605302a5SGregory Neil Shapiro else if (rl->lr_type == SM_LDAP_ATTR_FILTER) 103940266059SGregory Neil Shapiro { 104040266059SGregory Neil Shapiro /* do new search */ 104140266059SGregory Neil Shapiro sid = ldap_search(lmap->ldap_ld, 104240266059SGregory Neil Shapiro lmap->ldap_base, 104340266059SGregory Neil Shapiro lmap->ldap_scope, 104440266059SGregory Neil Shapiro rl->lr_search, 1045605302a5SGregory Neil Shapiro (lmap->ldap_attr[0] == NULL ? 1046605302a5SGregory Neil Shapiro NULL : lmap->ldap_attr), 104740266059SGregory Neil Shapiro lmap->ldap_attrsonly); 104840266059SGregory Neil Shapiro } 1049605302a5SGregory Neil Shapiro else if (rl->lr_type == SM_LDAP_ATTR_URL) 105040266059SGregory Neil Shapiro { 105140266059SGregory Neil Shapiro /* do new URL search */ 105240266059SGregory Neil Shapiro sid = ldap_url_search(lmap->ldap_ld, 105340266059SGregory Neil Shapiro rl->lr_search, 105440266059SGregory Neil Shapiro lmap->ldap_attrsonly); 1055605302a5SGregory Neil Shapiro newflags |= SM_LDAP_USE_ALLATTR; 105640266059SGregory Neil Shapiro } 105740266059SGregory Neil Shapiro else 105840266059SGregory Neil Shapiro { 105940266059SGregory Neil Shapiro /* unknown or illegal attribute type */ 106040266059SGregory Neil Shapiro errno = EFAULT; 106140266059SGregory Neil Shapiro return EX_SOFTWARE; 106240266059SGregory Neil Shapiro } 106340266059SGregory Neil Shapiro 106440266059SGregory Neil Shapiro /* Collect results */ 106540266059SGregory Neil Shapiro if (sid == -1) 106640266059SGregory Neil Shapiro { 106740266059SGregory Neil Shapiro save_errno = sm_ldap_geterrno(lmap->ldap_ld); 106840266059SGregory Neil Shapiro statp = EX_TEMPFAIL; 106940266059SGregory Neil Shapiro switch (save_errno) 107040266059SGregory Neil Shapiro { 107140266059SGregory Neil Shapiro #ifdef LDAP_SERVER_DOWN 107240266059SGregory Neil Shapiro case LDAP_SERVER_DOWN: 107340266059SGregory Neil Shapiro #endif /* LDAP_SERVER_DOWN */ 107440266059SGregory Neil Shapiro case LDAP_TIMEOUT: 107540266059SGregory Neil Shapiro case LDAP_UNAVAILABLE: 1076605302a5SGregory Neil Shapiro 1077605302a5SGregory Neil Shapiro /* 1078605302a5SGregory Neil Shapiro ** server disappeared, 1079605302a5SGregory Neil Shapiro ** try reopen on next search 1080605302a5SGregory Neil Shapiro */ 1081605302a5SGregory Neil Shapiro 108240266059SGregory Neil Shapiro statp = EX_RESTART; 108340266059SGregory Neil Shapiro break; 108440266059SGregory Neil Shapiro } 108540266059SGregory Neil Shapiro errno = save_errno + E_LDAPBASE; 108640266059SGregory Neil Shapiro return statp; 108740266059SGregory Neil Shapiro } 108840266059SGregory Neil Shapiro 1089605302a5SGregory Neil Shapiro status = sm_ldap_results(lmap, sid, newflags, delim, 1090605302a5SGregory Neil Shapiro rpool, result, resultln, 1091605302a5SGregory Neil Shapiro resultsz, recurse); 109240266059SGregory Neil Shapiro save_errno = errno; 109340266059SGregory Neil Shapiro if (status != EX_OK && status != EX_NOTFOUND) 109440266059SGregory Neil Shapiro { 109540266059SGregory Neil Shapiro errno = save_errno; 109640266059SGregory Neil Shapiro return status; 109740266059SGregory Neil Shapiro } 109840266059SGregory Neil Shapiro 109940266059SGregory Neil Shapiro /* Mark as done */ 1100605302a5SGregory Neil Shapiro rl->lr_done = true; 1101605302a5SGregory Neil Shapiro 1102605302a5SGregory Neil Shapiro /* Reset rlidx as new items may have been added */ 1103605302a5SGregory Neil Shapiro rlidx = -1; 110440266059SGregory Neil Shapiro } 110540266059SGregory Neil Shapiro } 110640266059SGregory Neil Shapiro return statp; 110740266059SGregory Neil Shapiro } 110840266059SGregory Neil Shapiro #endif /* _FFR_LDAP_RECURSION */ 110940266059SGregory Neil Shapiro 111040266059SGregory Neil Shapiro /* 111140266059SGregory Neil Shapiro ** SM_LDAP_CLOSE -- close LDAP connection 111240266059SGregory Neil Shapiro ** 111340266059SGregory Neil Shapiro ** Parameters: 111440266059SGregory Neil Shapiro ** lmap -- LDAP map information 111540266059SGregory Neil Shapiro ** 111640266059SGregory Neil Shapiro ** Returns: 111740266059SGregory Neil Shapiro ** None. 111840266059SGregory Neil Shapiro ** 111940266059SGregory Neil Shapiro */ 112040266059SGregory Neil Shapiro 112140266059SGregory Neil Shapiro void 112240266059SGregory Neil Shapiro sm_ldap_close(lmap) 112340266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap; 112440266059SGregory Neil Shapiro { 112540266059SGregory Neil Shapiro if (lmap->ldap_ld == NULL) 112640266059SGregory Neil Shapiro return; 112740266059SGregory Neil Shapiro 112840266059SGregory Neil Shapiro if (lmap->ldap_pid == getpid()) 112940266059SGregory Neil Shapiro ldap_unbind(lmap->ldap_ld); 113040266059SGregory Neil Shapiro lmap->ldap_ld = NULL; 113140266059SGregory Neil Shapiro lmap->ldap_pid = 0; 113240266059SGregory Neil Shapiro } 113340266059SGregory Neil Shapiro 113440266059SGregory Neil Shapiro /* 113540266059SGregory Neil Shapiro ** SM_LDAP_SETOPTS -- set LDAP options 113640266059SGregory Neil Shapiro ** 113740266059SGregory Neil Shapiro ** Parameters: 113840266059SGregory Neil Shapiro ** ld -- LDAP session handle 113940266059SGregory Neil Shapiro ** lmap -- LDAP map information 114040266059SGregory Neil Shapiro ** 114140266059SGregory Neil Shapiro ** Returns: 114240266059SGregory Neil Shapiro ** None. 114340266059SGregory Neil Shapiro ** 114440266059SGregory Neil Shapiro */ 114540266059SGregory Neil Shapiro 114640266059SGregory Neil Shapiro void 114740266059SGregory Neil Shapiro sm_ldap_setopts(ld, lmap) 114840266059SGregory Neil Shapiro LDAP *ld; 114940266059SGregory Neil Shapiro SM_LDAP_STRUCT *lmap; 115040266059SGregory Neil Shapiro { 115140266059SGregory Neil Shapiro # if USE_LDAP_SET_OPTION 1152605302a5SGregory Neil Shapiro # if _FFR_LDAP_SETVERSION 1153605302a5SGregory Neil Shapiro if (lmap->ldap_version != 0) 1154605302a5SGregory Neil Shapiro { 1155605302a5SGregory Neil Shapiro ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, 1156605302a5SGregory Neil Shapiro &lmap->ldap_version); 1157605302a5SGregory Neil Shapiro } 1158605302a5SGregory Neil Shapiro # endif /* _FFR_LDAP_SETVERSION */ 115940266059SGregory Neil Shapiro ldap_set_option(ld, LDAP_OPT_DEREF, &lmap->ldap_deref); 116040266059SGregory Neil Shapiro if (bitset(LDAP_OPT_REFERRALS, lmap->ldap_options)) 116140266059SGregory Neil Shapiro ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON); 116240266059SGregory Neil Shapiro else 116340266059SGregory Neil Shapiro ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); 116440266059SGregory Neil Shapiro ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &lmap->ldap_sizelimit); 116540266059SGregory Neil Shapiro ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &lmap->ldap_timelimit); 1166959366dcSGregory Neil Shapiro # ifdef LDAP_OPT_RESTART 1167959366dcSGregory Neil Shapiro ldap_set_option(ld, LDAP_OPT_RESTART, LDAP_OPT_ON); 1168959366dcSGregory Neil Shapiro # endif /* LDAP_OPT_RESTART */ 116940266059SGregory Neil Shapiro # else /* USE_LDAP_SET_OPTION */ 117040266059SGregory Neil Shapiro /* From here on in we can use ldap internal timelimits */ 117140266059SGregory Neil Shapiro ld->ld_deref = lmap->ldap_deref; 117240266059SGregory Neil Shapiro ld->ld_options = lmap->ldap_options; 117340266059SGregory Neil Shapiro ld->ld_sizelimit = lmap->ldap_sizelimit; 117440266059SGregory Neil Shapiro ld->ld_timelimit = lmap->ldap_timelimit; 117540266059SGregory Neil Shapiro # endif /* USE_LDAP_SET_OPTION */ 117640266059SGregory Neil Shapiro } 117740266059SGregory Neil Shapiro 117840266059SGregory Neil Shapiro /* 117940266059SGregory Neil Shapiro ** SM_LDAP_GETERRNO -- get ldap errno value 118040266059SGregory Neil Shapiro ** 118140266059SGregory Neil Shapiro ** Parameters: 118240266059SGregory Neil Shapiro ** ld -- LDAP session handle 118340266059SGregory Neil Shapiro ** 118440266059SGregory Neil Shapiro ** Returns: 118540266059SGregory Neil Shapiro ** LDAP errno. 118640266059SGregory Neil Shapiro ** 118740266059SGregory Neil Shapiro */ 118840266059SGregory Neil Shapiro 118940266059SGregory Neil Shapiro int 119040266059SGregory Neil Shapiro sm_ldap_geterrno(ld) 119140266059SGregory Neil Shapiro LDAP *ld; 119240266059SGregory Neil Shapiro { 119340266059SGregory Neil Shapiro int err = LDAP_SUCCESS; 119440266059SGregory Neil Shapiro 119540266059SGregory Neil Shapiro # if defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3 119640266059SGregory Neil Shapiro (void) ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err); 119740266059SGregory Neil Shapiro # else /* defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3 */ 119840266059SGregory Neil Shapiro # ifdef LDAP_OPT_SIZELIMIT 119940266059SGregory Neil Shapiro err = ldap_get_lderrno(ld, NULL, NULL); 120040266059SGregory Neil Shapiro # else /* LDAP_OPT_SIZELIMIT */ 120140266059SGregory Neil Shapiro err = ld->ld_errno; 120240266059SGregory Neil Shapiro 120340266059SGregory Neil Shapiro /* 120440266059SGregory Neil Shapiro ** Reset value to prevent lingering LDAP_DECODING_ERROR due to 120540266059SGregory Neil Shapiro ** OpenLDAP 1.X's hack (see above) 120640266059SGregory Neil Shapiro */ 120740266059SGregory Neil Shapiro 120840266059SGregory Neil Shapiro ld->ld_errno = LDAP_SUCCESS; 120940266059SGregory Neil Shapiro # endif /* LDAP_OPT_SIZELIMIT */ 121040266059SGregory Neil Shapiro # endif /* defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3 */ 121140266059SGregory Neil Shapiro return err; 121240266059SGregory Neil Shapiro } 121340266059SGregory Neil Shapiro # endif /* LDAPMAP */ 1214