17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5f8f1c176Svt115884 * Common Development and Distribution License (the "License"). 6f8f1c176Svt115884 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*9f2fd570SJulian Pullen * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate #include <stdio.h> 267c478bd9Sstevel@tonic-gate #include <sys/types.h> 277c478bd9Sstevel@tonic-gate #include <stdlib.h> 287c478bd9Sstevel@tonic-gate #include <libintl.h> 297c478bd9Sstevel@tonic-gate #include <ctype.h> 307c478bd9Sstevel@tonic-gate #include <syslog.h> 317c478bd9Sstevel@tonic-gate #include <sys/stat.h> 327c478bd9Sstevel@tonic-gate #include <fcntl.h> 337c478bd9Sstevel@tonic-gate #include <unistd.h> 347c478bd9Sstevel@tonic-gate #include <string.h> 357c478bd9Sstevel@tonic-gate #include <strings.h> 36b57459abSJulian Pullen #include <priv.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #include "ns_sldap.h" 397c478bd9Sstevel@tonic-gate #include "ns_internal.h" 407c478bd9Sstevel@tonic-gate #include "ns_cache_door.h" 41e1dd0a2fSth160488 #include "ns_connmgmt.h" 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate #define _NIS_FILTER "nisdomain=*" 447c478bd9Sstevel@tonic-gate #define _NIS_DOMAIN "nisdomain" 457c478bd9Sstevel@tonic-gate static const char *nis_domain_attrs[] = { 467c478bd9Sstevel@tonic-gate _NIS_DOMAIN, 477c478bd9Sstevel@tonic-gate (char *)NULL 487c478bd9Sstevel@tonic-gate }; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate static int validate_filter(ns_ldap_cookie_t *cookie); 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate void 537c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ns_ldap_entry_t *ep) 547c478bd9Sstevel@tonic-gate { 557c478bd9Sstevel@tonic-gate int j, k = 0; 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate if (ep == NULL) 587c478bd9Sstevel@tonic-gate return; 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate if (ep->attr_pair == NULL) { 617c478bd9Sstevel@tonic-gate free(ep); 627c478bd9Sstevel@tonic-gate return; 637c478bd9Sstevel@tonic-gate } 647c478bd9Sstevel@tonic-gate for (j = 0; j < ep->attr_count; j++) { 657c478bd9Sstevel@tonic-gate if (ep->attr_pair[j] == NULL) 667c478bd9Sstevel@tonic-gate continue; 677c478bd9Sstevel@tonic-gate if (ep->attr_pair[j]->attrname) 687c478bd9Sstevel@tonic-gate free(ep->attr_pair[j]->attrname); 697c478bd9Sstevel@tonic-gate if (ep->attr_pair[j]->attrvalue) { 707c478bd9Sstevel@tonic-gate for (k = 0; (k < ep->attr_pair[j]->value_count) && 717c478bd9Sstevel@tonic-gate (ep->attr_pair[j]->attrvalue[k]); k++) { 727c478bd9Sstevel@tonic-gate free(ep->attr_pair[j]->attrvalue[k]); 737c478bd9Sstevel@tonic-gate } 747c478bd9Sstevel@tonic-gate free(ep->attr_pair[j]->attrvalue); 757c478bd9Sstevel@tonic-gate } 767c478bd9Sstevel@tonic-gate free(ep->attr_pair[j]); 777c478bd9Sstevel@tonic-gate } 787c478bd9Sstevel@tonic-gate free(ep->attr_pair); 797c478bd9Sstevel@tonic-gate free(ep); 807c478bd9Sstevel@tonic-gate } 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate static void 837c478bd9Sstevel@tonic-gate _freeControlList(LDAPControl ***ctrls) 847c478bd9Sstevel@tonic-gate { 857c478bd9Sstevel@tonic-gate LDAPControl **ctrl; 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate if (ctrls == NULL || *ctrls == NULL) 887c478bd9Sstevel@tonic-gate return; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate for (ctrl = *ctrls; *ctrl != NULL; ctrl++) 917c478bd9Sstevel@tonic-gate ldap_control_free(*ctrl); 927c478bd9Sstevel@tonic-gate free(*ctrls); 937c478bd9Sstevel@tonic-gate *ctrls = NULL; 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate /* 967c478bd9Sstevel@tonic-gate * Convert attribute type in a RDN that has an attribute mapping to the 977c478bd9Sstevel@tonic-gate * original mappped type. 987c478bd9Sstevel@tonic-gate * e.g. 997c478bd9Sstevel@tonic-gate * cn<->cn-st and iphostnumber<->iphostnumber-st 1007c478bd9Sstevel@tonic-gate * cn-st=aaa+iphostnumber-st=10.10.01.01 1017c478bd9Sstevel@tonic-gate * is mapped to 1027c478bd9Sstevel@tonic-gate * cn=aaa+iphostnumber=10.10.01.01 1037c478bd9Sstevel@tonic-gate * 1047c478bd9Sstevel@tonic-gate * Input - service: e.g. hosts, passwd etc. 1057c478bd9Sstevel@tonic-gate * rdn: RDN 1067c478bd9Sstevel@tonic-gate * Return: NULL - No attribute mapping in the RDN 1077c478bd9Sstevel@tonic-gate * Non-NULL - The attribute type(s) in the RDN are mapped and 1087c478bd9Sstevel@tonic-gate * the memory is allocated for the new rdn. 1097c478bd9Sstevel@tonic-gate * 1107c478bd9Sstevel@tonic-gate */ 1117c478bd9Sstevel@tonic-gate static char * 1127c478bd9Sstevel@tonic-gate _cvtRDN(const char *service, const char *rdn) { 1137c478bd9Sstevel@tonic-gate char **attrs, **mapped_attrs, **mapp, *type, *value, *attr; 1147c478bd9Sstevel@tonic-gate char *new_rdn = NULL; 1157c478bd9Sstevel@tonic-gate int nAttr = 0, i, attr_mapped, len = 0; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate /* Break down "type=value\0" pairs. Assume RDN is normalized */ 1187c478bd9Sstevel@tonic-gate if ((attrs = ldap_explode_rdn(rdn, 0)) == NULL) 1197c478bd9Sstevel@tonic-gate return (NULL); 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate for (nAttr = 0; attrs[nAttr] != NULL; nAttr++); 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate if ((mapped_attrs = (char **)calloc(nAttr, sizeof (char *))) == NULL) { 1247c478bd9Sstevel@tonic-gate ldap_value_free(attrs); 1257c478bd9Sstevel@tonic-gate return (NULL); 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate attr_mapped = 0; 1297c478bd9Sstevel@tonic-gate for (i = 0; i < nAttr; i++) { 1307c478bd9Sstevel@tonic-gate /* Parse type=value pair */ 1317c478bd9Sstevel@tonic-gate if ((type = strtok_r(attrs[i], "=", &value)) == NULL || 1327c478bd9Sstevel@tonic-gate value == NULL) 1337c478bd9Sstevel@tonic-gate goto cleanup; 1347c478bd9Sstevel@tonic-gate /* Reverse map: e.g. cn-sm -> cn */ 1357c478bd9Sstevel@tonic-gate mapp = __ns_ldap_getOrigAttribute(service, type); 1367c478bd9Sstevel@tonic-gate if (mapp != NULL && mapp[0] != NULL) { 1377c478bd9Sstevel@tonic-gate /* The attribute mapping is found */ 1387c478bd9Sstevel@tonic-gate type = mapp[0]; 1397c478bd9Sstevel@tonic-gate attr_mapped = 1; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate /* "type=value\0" */ 1427c478bd9Sstevel@tonic-gate len = strlen(type) + strlen(value) + 2; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate /* Reconstruct type=value pair. A string is allocated */ 1457c478bd9Sstevel@tonic-gate if ((attr = (char *)calloc(1, len)) == NULL) { 1467c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapp); 1477c478bd9Sstevel@tonic-gate goto cleanup; 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate (void) snprintf(attr, len, "%s=%s", 1507c478bd9Sstevel@tonic-gate type, value); 1517c478bd9Sstevel@tonic-gate mapped_attrs[i] = attr; 1527c478bd9Sstevel@tonic-gate } else { 1537c478bd9Sstevel@tonic-gate /* 1547c478bd9Sstevel@tonic-gate * No attribute mapping. attrs[i] is going to be copied 1557c478bd9Sstevel@tonic-gate * later. Restore "type\0value\0" back to 1567c478bd9Sstevel@tonic-gate * "type=value\0". 1577c478bd9Sstevel@tonic-gate */ 1587c478bd9Sstevel@tonic-gate type[strlen(type)] = '='; 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapp); 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate if (attr_mapped == 0) 1637c478bd9Sstevel@tonic-gate /* No attribute mapping. Don't bother to reconstruct RDN */ 1647c478bd9Sstevel@tonic-gate goto cleanup; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate len = 0; 1677c478bd9Sstevel@tonic-gate /* Reconstruct RDN from type=value pairs */ 1687c478bd9Sstevel@tonic-gate for (i = 0; i < nAttr; i++) { 1697c478bd9Sstevel@tonic-gate if (mapped_attrs[i]) 1707c478bd9Sstevel@tonic-gate len += strlen(mapped_attrs[i]); 1717c478bd9Sstevel@tonic-gate else 1727c478bd9Sstevel@tonic-gate len += strlen(attrs[i]); 1737c478bd9Sstevel@tonic-gate /* Add 1 for "+" */ 1747c478bd9Sstevel@tonic-gate len++; 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate if ((new_rdn = (char *)calloc(1, ++len)) == NULL) 1777c478bd9Sstevel@tonic-gate goto cleanup; 1787c478bd9Sstevel@tonic-gate for (i = 0; i < nAttr; i++) { 1797c478bd9Sstevel@tonic-gate if (i > 0) 1807c478bd9Sstevel@tonic-gate /* Add seperator */ 1817c478bd9Sstevel@tonic-gate (void) strlcat(new_rdn, "+", len); 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate if (mapped_attrs[i]) 1847c478bd9Sstevel@tonic-gate (void) strlcat(new_rdn, mapped_attrs[i], len); 1857c478bd9Sstevel@tonic-gate else 1867c478bd9Sstevel@tonic-gate (void) strlcat(new_rdn, attrs[i], len); 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate cleanup: 1907c478bd9Sstevel@tonic-gate ldap_value_free(attrs); 1917c478bd9Sstevel@tonic-gate if (mapped_attrs) { 1927c478bd9Sstevel@tonic-gate if (attr_mapped) { 1937c478bd9Sstevel@tonic-gate for (i = 0; i < nAttr; i++) { 1947c478bd9Sstevel@tonic-gate if (mapped_attrs[i]) 1957c478bd9Sstevel@tonic-gate free(mapped_attrs[i]); 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate free(mapped_attrs); 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate return (new_rdn); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate /* 2047c478bd9Sstevel@tonic-gate * Convert attribute type in a DN that has an attribute mapping to the 2057c478bd9Sstevel@tonic-gate * original mappped type. 2067c478bd9Sstevel@tonic-gate * e.g 2077c478bd9Sstevel@tonic-gate * The mappings are cn<->cn-sm, iphostnumber<->iphostnumber-sm 2087c478bd9Sstevel@tonic-gate * 2097c478bd9Sstevel@tonic-gate * dn: cn-sm=aaa+iphostnumber-sm=9.9.9.9,dc=central,dc=sun,dc=com 2107c478bd9Sstevel@tonic-gate * is converted to 2117c478bd9Sstevel@tonic-gate * dn: cn=aaa+iphostnumber=9.9.9.9,dc=central,dc=sun,dc=com 2127c478bd9Sstevel@tonic-gate * 2137c478bd9Sstevel@tonic-gate * Input - service: e.g. hosts, passwd etc. 2147c478bd9Sstevel@tonic-gate * dn: the value of a distinguished name 2157c478bd9Sstevel@tonic-gate * Return - NULL: error 2167c478bd9Sstevel@tonic-gate * non-NULL: A converted DN and the memory is allocated 2177c478bd9Sstevel@tonic-gate */ 2187c478bd9Sstevel@tonic-gate static char * 2197c478bd9Sstevel@tonic-gate _cvtDN(const char *service, const char *dn) { 2207c478bd9Sstevel@tonic-gate char **mapped_rdns; 2217c478bd9Sstevel@tonic-gate char **rdns, *new_rdn, *new_dn = NULL; 2227c478bd9Sstevel@tonic-gate int nRdn = 0, i, len = 0, rdn_mapped; 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate if (service == NULL || dn == NULL) 2257c478bd9Sstevel@tonic-gate return (NULL); 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate if ((rdns = ldap_explode_dn(dn, 0)) == NULL) 2287c478bd9Sstevel@tonic-gate return (NULL); 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate for (nRdn = 0; rdns[nRdn] != NULL; nRdn++); 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate if ((mapped_rdns = (char **)calloc(nRdn, sizeof (char *))) == NULL) { 2337c478bd9Sstevel@tonic-gate ldap_value_free(rdns); 2347c478bd9Sstevel@tonic-gate return (NULL); 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate rdn_mapped = 0; 2387c478bd9Sstevel@tonic-gate /* Break down RDNs in a DN */ 2397c478bd9Sstevel@tonic-gate for (i = 0; i < nRdn; i++) { 2407c478bd9Sstevel@tonic-gate if ((new_rdn = _cvtRDN(service, rdns[i])) != NULL) { 2417c478bd9Sstevel@tonic-gate mapped_rdns[i] = new_rdn; 2427c478bd9Sstevel@tonic-gate rdn_mapped = 1; 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate if (rdn_mapped == 0) { 2467c478bd9Sstevel@tonic-gate /* 2477c478bd9Sstevel@tonic-gate * No RDN contains any attribute mapping. 2487c478bd9Sstevel@tonic-gate * Don't bother to reconstruct DN from RDN. Copy DN directly. 2497c478bd9Sstevel@tonic-gate */ 2507c478bd9Sstevel@tonic-gate new_dn = strdup(dn); 2517c478bd9Sstevel@tonic-gate goto cleanup; 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate /* 2547c478bd9Sstevel@tonic-gate * Reconstruct dn from RDNs. 2557c478bd9Sstevel@tonic-gate * Calculate the length first. 2567c478bd9Sstevel@tonic-gate */ 2577c478bd9Sstevel@tonic-gate for (i = 0; i < nRdn; i++) { 2587c478bd9Sstevel@tonic-gate if (mapped_rdns[i]) 2597c478bd9Sstevel@tonic-gate len += strlen(mapped_rdns[i]); 2607c478bd9Sstevel@tonic-gate else 2617c478bd9Sstevel@tonic-gate len += strlen(rdns[i]); 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate /* add 1 for ',' */ 2647c478bd9Sstevel@tonic-gate len ++; 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate if ((new_dn = (char *)calloc(1, ++len)) == NULL) 2677c478bd9Sstevel@tonic-gate goto cleanup; 2687c478bd9Sstevel@tonic-gate for (i = 0; i < nRdn; i++) { 2697c478bd9Sstevel@tonic-gate if (i > 0) 2707c478bd9Sstevel@tonic-gate /* Add seperator */ 2717c478bd9Sstevel@tonic-gate (void) strlcat(new_dn, ",", len); 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate if (mapped_rdns[i]) 2747c478bd9Sstevel@tonic-gate (void) strlcat(new_dn, mapped_rdns[i], len); 2757c478bd9Sstevel@tonic-gate else 2767c478bd9Sstevel@tonic-gate (void) strlcat(new_dn, rdns[i], len); 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate cleanup: 2817c478bd9Sstevel@tonic-gate ldap_value_free(rdns); 2827c478bd9Sstevel@tonic-gate if (mapped_rdns) { 2837c478bd9Sstevel@tonic-gate if (rdn_mapped) { 2847c478bd9Sstevel@tonic-gate for (i = 0; i < nRdn; i++) { 2857c478bd9Sstevel@tonic-gate if (mapped_rdns[i]) 2867c478bd9Sstevel@tonic-gate free(mapped_rdns[i]); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate free(mapped_rdns); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate return (new_dn); 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate /* 2957c478bd9Sstevel@tonic-gate * Convert a single ldap entry from a LDAPMessage 2967c478bd9Sstevel@tonic-gate * into an ns_ldap_entry structure. 2977c478bd9Sstevel@tonic-gate * Schema map the entry if specified in flags 2987c478bd9Sstevel@tonic-gate */ 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate static int 3017c478bd9Sstevel@tonic-gate __s_api_cvtEntry(LDAP *ld, 3027c478bd9Sstevel@tonic-gate const char *service, 3037c478bd9Sstevel@tonic-gate LDAPMessage *e, 3047c478bd9Sstevel@tonic-gate int flags, 3057c478bd9Sstevel@tonic-gate ns_ldap_entry_t **ret, 3067c478bd9Sstevel@tonic-gate ns_ldap_error_t **error) 3077c478bd9Sstevel@tonic-gate { 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate ns_ldap_entry_t *ep = NULL; 3107c478bd9Sstevel@tonic-gate ns_ldap_attr_t **ap = NULL; 3117c478bd9Sstevel@tonic-gate BerElement *ber; 3127c478bd9Sstevel@tonic-gate char *attr = NULL; 3137c478bd9Sstevel@tonic-gate char **vals = NULL; 3147c478bd9Sstevel@tonic-gate char **mapping; 3157c478bd9Sstevel@tonic-gate char *dn; 3167c478bd9Sstevel@tonic-gate int nAttrs = 0; 3177c478bd9Sstevel@tonic-gate int i, j, k = 0; 3187c478bd9Sstevel@tonic-gate char **gecos_mapping = NULL; 3197c478bd9Sstevel@tonic-gate int gecos_val_index[3] = { -1, -1, -1}; 3207c478bd9Sstevel@tonic-gate char errstr[MAXERROR]; 3217c478bd9Sstevel@tonic-gate int schema_mapping_existed = FALSE; 3227c478bd9Sstevel@tonic-gate int gecos_mapping_existed = FALSE; 3237c478bd9Sstevel@tonic-gate int gecos_attr_matched; 3247c478bd9Sstevel@tonic-gate int auto_service = FALSE; 3257c478bd9Sstevel@tonic-gate int rc = NS_LDAP_SUCCESS; 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate if (e == NULL || ret == NULL || error == NULL) 3287c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate *error = NULL; 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate ep = (ns_ldap_entry_t *)calloc(1, sizeof (ns_ldap_entry_t)); 3337c478bd9Sstevel@tonic-gate if (ep == NULL) 3347c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate if (service != NULL && 3377c478bd9Sstevel@tonic-gate (strncasecmp(service, "auto_", 5) == 0 || 3387c478bd9Sstevel@tonic-gate strcasecmp(service, "automount") == 0)) 3397c478bd9Sstevel@tonic-gate auto_service = TRUE; 3407c478bd9Sstevel@tonic-gate /* 3417c478bd9Sstevel@tonic-gate * see if schema mapping existed for the given service 3427c478bd9Sstevel@tonic-gate */ 3437c478bd9Sstevel@tonic-gate mapping = __ns_ldap_getOrigAttribute(service, 3447c478bd9Sstevel@tonic-gate NS_HASH_SCHEMA_MAPPING_EXISTED); 3457c478bd9Sstevel@tonic-gate if (mapping) { 3467c478bd9Sstevel@tonic-gate schema_mapping_existed = TRUE; 3477c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapping); 3487c478bd9Sstevel@tonic-gate mapping = NULL; 3497c478bd9Sstevel@tonic-gate } else if (auto_service) { 3507c478bd9Sstevel@tonic-gate /* 3517c478bd9Sstevel@tonic-gate * If service == auto_* and no 3527c478bd9Sstevel@tonic-gate * schema mapping found 3537c478bd9Sstevel@tonic-gate * then try automount 3547c478bd9Sstevel@tonic-gate * There is certain case that schema mapping exist 3557c478bd9Sstevel@tonic-gate * but __ns_ldap_getOrigAttribute(service, 3567c478bd9Sstevel@tonic-gate * NS_HASH_SCHEMA_MAPPING_EXISTED); 3577c478bd9Sstevel@tonic-gate * returns NULL. 3587c478bd9Sstevel@tonic-gate * e.g. 3597c478bd9Sstevel@tonic-gate * NS_LDAP_ATTRIBUTEMAP = automount:automountMapName=AAA 3607c478bd9Sstevel@tonic-gate * NS_LDAP_OBJECTCLASSMAP = automount:automountMap=MynisMap 3617c478bd9Sstevel@tonic-gate * NS_LDAP_OBJECTCLASSMAP = automount:automount=MynisObject 3627c478bd9Sstevel@tonic-gate * 3637c478bd9Sstevel@tonic-gate * Make a check for schema_mapping_existed here 3647c478bd9Sstevel@tonic-gate * so later on __s_api_convert_automountmapname won't be called 3657c478bd9Sstevel@tonic-gate * unnecessarily. It is also used for attribute mapping 3667c478bd9Sstevel@tonic-gate * and objectclass mapping. 3677c478bd9Sstevel@tonic-gate */ 3687c478bd9Sstevel@tonic-gate mapping = __ns_ldap_getOrigAttribute("automount", 3697c478bd9Sstevel@tonic-gate NS_HASH_SCHEMA_MAPPING_EXISTED); 3707c478bd9Sstevel@tonic-gate if (mapping) { 3717c478bd9Sstevel@tonic-gate schema_mapping_existed = TRUE; 3727c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapping); 3737c478bd9Sstevel@tonic-gate mapping = NULL; 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate nAttrs = 1; /* start with 1 for the DN attr */ 3787c478bd9Sstevel@tonic-gate for (attr = ldap_first_attribute(ld, e, &ber); attr != NULL; 3797c478bd9Sstevel@tonic-gate attr = ldap_next_attribute(ld, e, ber)) { 3807c478bd9Sstevel@tonic-gate nAttrs++; 3817c478bd9Sstevel@tonic-gate ldap_memfree(attr); 3827c478bd9Sstevel@tonic-gate attr = NULL; 3837c478bd9Sstevel@tonic-gate } 3847c478bd9Sstevel@tonic-gate ber_free(ber, 0); 3857c478bd9Sstevel@tonic-gate ber = NULL; 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate ep->attr_count = nAttrs; 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate /* 3907c478bd9Sstevel@tonic-gate * add 1 for "gecos" 1 to N attribute mapping, 3917c478bd9Sstevel@tonic-gate * just in case it is needed. 3927c478bd9Sstevel@tonic-gate * ep->attr_count will be updated later if that is true. 3937c478bd9Sstevel@tonic-gate */ 3947c478bd9Sstevel@tonic-gate ap = (ns_ldap_attr_t **)calloc(ep->attr_count + 1, 3957c478bd9Sstevel@tonic-gate sizeof (ns_ldap_attr_t *)); 3967c478bd9Sstevel@tonic-gate if (ap == NULL) { 3977c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 3987c478bd9Sstevel@tonic-gate ep = NULL; 3997c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate ep->attr_pair = ap; 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate /* DN attribute */ 4047c478bd9Sstevel@tonic-gate dn = ldap_get_dn(ld, e); 4057c478bd9Sstevel@tonic-gate ap[0] = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t)); 4067c478bd9Sstevel@tonic-gate if (ap[0] == NULL) { 4077c478bd9Sstevel@tonic-gate ldap_memfree(dn); 4087c478bd9Sstevel@tonic-gate dn = NULL; 4097c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 4107c478bd9Sstevel@tonic-gate ep = NULL; 4117c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate if ((ap[0]->attrname = strdup("dn")) == NULL) { 4157c478bd9Sstevel@tonic-gate ldap_memfree(dn); 4167c478bd9Sstevel@tonic-gate dn = NULL; 4177c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 4187c478bd9Sstevel@tonic-gate ep = NULL; 4197c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate ap[0]->value_count = 1; 4227c478bd9Sstevel@tonic-gate if ((ap[0]->attrvalue = (char **) 4237c478bd9Sstevel@tonic-gate calloc(2, sizeof (char *))) == NULL) { 4247c478bd9Sstevel@tonic-gate ldap_memfree(dn); 4257c478bd9Sstevel@tonic-gate dn = NULL; 4267c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 4277c478bd9Sstevel@tonic-gate ep = NULL; 4287c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 4297c478bd9Sstevel@tonic-gate } 4307c478bd9Sstevel@tonic-gate 431f5c3c7a7Ssdussud if (schema_mapping_existed && ((flags & NS_LDAP_NOT_CVT_DN) == 0)) 4327c478bd9Sstevel@tonic-gate ap[0]->attrvalue[0] = _cvtDN(service, dn); 4337c478bd9Sstevel@tonic-gate else 4347c478bd9Sstevel@tonic-gate ap[0]->attrvalue[0] = strdup(dn); 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate if (ap[0]->attrvalue[0] == NULL) { 4377c478bd9Sstevel@tonic-gate ldap_memfree(dn); 4387c478bd9Sstevel@tonic-gate dn = NULL; 4397c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 4407c478bd9Sstevel@tonic-gate ep = NULL; 4417c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate ldap_memfree(dn); 4447c478bd9Sstevel@tonic-gate dn = NULL; 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate if ((flags & NS_LDAP_NOMAP) == 0 && auto_service && 4477c478bd9Sstevel@tonic-gate schema_mapping_existed) { 4487c478bd9Sstevel@tonic-gate rc = __s_api_convert_automountmapname(service, 4497c478bd9Sstevel@tonic-gate &ap[0]->attrvalue[0], 4507c478bd9Sstevel@tonic-gate error); 4517c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 4527c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 4537c478bd9Sstevel@tonic-gate ep = NULL; 4547c478bd9Sstevel@tonic-gate return (rc); 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate /* other attributes */ 4597c478bd9Sstevel@tonic-gate for (attr = ldap_first_attribute(ld, e, &ber), j = 1; 4607c478bd9Sstevel@tonic-gate attr != NULL && j != nAttrs; 4617c478bd9Sstevel@tonic-gate attr = ldap_next_attribute(ld, e, ber), j++) { 4627c478bd9Sstevel@tonic-gate /* allocate new attr name */ 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate if ((ap[j] = (ns_ldap_attr_t *) 4657c478bd9Sstevel@tonic-gate calloc(1, sizeof (ns_ldap_attr_t))) == NULL) { 4667c478bd9Sstevel@tonic-gate ber_free(ber, 0); 4677c478bd9Sstevel@tonic-gate ber = NULL; 4687c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 4697c478bd9Sstevel@tonic-gate ep = NULL; 4707c478bd9Sstevel@tonic-gate if (gecos_mapping) 4717c478bd9Sstevel@tonic-gate __s_api_free2dArray(gecos_mapping); 4727c478bd9Sstevel@tonic-gate gecos_mapping = NULL; 4737c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate if ((flags & NS_LDAP_NOMAP) || schema_mapping_existed == FALSE) 4777c478bd9Sstevel@tonic-gate mapping = NULL; 4787c478bd9Sstevel@tonic-gate else 4797c478bd9Sstevel@tonic-gate mapping = __ns_ldap_getOrigAttribute(service, attr); 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate if (mapping == NULL && auto_service && 482699bceb8Smj162486 schema_mapping_existed && (flags & NS_LDAP_NOMAP) == 0) 4837c478bd9Sstevel@tonic-gate /* 484699bceb8Smj162486 * if service == auto_* and no schema mapping found 485699bceb8Smj162486 * and schema_mapping_existed is TRUE and NS_LDAP_NOMAP 486699bceb8Smj162486 * is not set then try automount e.g. 4877c478bd9Sstevel@tonic-gate * NS_LDAP_ATTRIBUTEMAP = automount:automountMapName=AAA 4887c478bd9Sstevel@tonic-gate */ 489699bceb8Smj162486 mapping = __ns_ldap_getOrigAttribute("automount", 490699bceb8Smj162486 attr); 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate if (mapping == NULL) { 4937c478bd9Sstevel@tonic-gate if ((ap[j]->attrname = strdup(attr)) == NULL) { 4947c478bd9Sstevel@tonic-gate ber_free(ber, 0); 4957c478bd9Sstevel@tonic-gate ber = NULL; 4967c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 4977c478bd9Sstevel@tonic-gate ep = NULL; 4987c478bd9Sstevel@tonic-gate if (gecos_mapping) 4997c478bd9Sstevel@tonic-gate __s_api_free2dArray(gecos_mapping); 5007c478bd9Sstevel@tonic-gate gecos_mapping = NULL; 5017c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate } else { 5047c478bd9Sstevel@tonic-gate /* 5057c478bd9Sstevel@tonic-gate * for "gecos" 1 to N mapping, 5067c478bd9Sstevel@tonic-gate * do not remove the mapped attribute, 5077c478bd9Sstevel@tonic-gate * just create a new gecos attribute 5087c478bd9Sstevel@tonic-gate * and append it to the end of the attribute list 5097c478bd9Sstevel@tonic-gate */ 5107c478bd9Sstevel@tonic-gate if (strcasecmp(mapping[0], "gecos") == 0) { 5117c478bd9Sstevel@tonic-gate ap[j]->attrname = strdup(attr); 5127c478bd9Sstevel@tonic-gate gecos_mapping_existed = TRUE; 5137c478bd9Sstevel@tonic-gate } else 5147c478bd9Sstevel@tonic-gate ap[j]->attrname = strdup(mapping[0]); 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate if (ap[j]->attrname == NULL) { 5177c478bd9Sstevel@tonic-gate ber_free(ber, 0); 5187c478bd9Sstevel@tonic-gate ber = NULL; 5197c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 5207c478bd9Sstevel@tonic-gate ep = NULL; 5217c478bd9Sstevel@tonic-gate if (gecos_mapping) 5227c478bd9Sstevel@tonic-gate __s_api_free2dArray(gecos_mapping); 5237c478bd9Sstevel@tonic-gate gecos_mapping = NULL; 5247c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate /* 5277c478bd9Sstevel@tonic-gate * 1 to N attribute mapping processing 5287c478bd9Sstevel@tonic-gate * is only done for "gecos" 5297c478bd9Sstevel@tonic-gate */ 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate if (strcasecmp(mapping[0], "gecos") == 0) { 5327c478bd9Sstevel@tonic-gate /* 5337c478bd9Sstevel@tonic-gate * get attribute mapping for "gecos", 5347c478bd9Sstevel@tonic-gate * need to know the number and order of the 5357c478bd9Sstevel@tonic-gate * mapped attributes 5367c478bd9Sstevel@tonic-gate */ 5377c478bd9Sstevel@tonic-gate if (gecos_mapping == NULL) { 5387c478bd9Sstevel@tonic-gate gecos_mapping = 539699bceb8Smj162486 __ns_ldap_getMappedAttributes( 540699bceb8Smj162486 service, mapping[0]); 5417c478bd9Sstevel@tonic-gate if (gecos_mapping == NULL || 5427c478bd9Sstevel@tonic-gate gecos_mapping[0] == NULL) { 5437c478bd9Sstevel@tonic-gate /* 5447c478bd9Sstevel@tonic-gate * this should never happens, 5457c478bd9Sstevel@tonic-gate * syslog the error 5467c478bd9Sstevel@tonic-gate */ 5477c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 5487c478bd9Sstevel@tonic-gate gettext( 5497c478bd9Sstevel@tonic-gate "Attribute mapping " 5507c478bd9Sstevel@tonic-gate "inconsistency " 5517c478bd9Sstevel@tonic-gate "found for attributes " 5527c478bd9Sstevel@tonic-gate "'%s' and '%s'."), 5537c478bd9Sstevel@tonic-gate mapping[0], attr); 554699bceb8Smj162486 syslog(LOG_ERR, "libsldap: %s", 555699bceb8Smj162486 errstr); 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate ber_free(ber, 0); 5587c478bd9Sstevel@tonic-gate ber = NULL; 5597c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 5607c478bd9Sstevel@tonic-gate ep = NULL; 5617c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapping); 5627c478bd9Sstevel@tonic-gate mapping = NULL; 5637c478bd9Sstevel@tonic-gate if (gecos_mapping) 5647c478bd9Sstevel@tonic-gate __s_api_free2dArray( 5657c478bd9Sstevel@tonic-gate gecos_mapping); 5667c478bd9Sstevel@tonic-gate gecos_mapping = NULL; 5677c478bd9Sstevel@tonic-gate return (NS_LDAP_INTERNAL); 5687c478bd9Sstevel@tonic-gate } 5697c478bd9Sstevel@tonic-gate } 5707c478bd9Sstevel@tonic-gate 5717c478bd9Sstevel@tonic-gate /* 5727c478bd9Sstevel@tonic-gate * is this attribute the 1st, 2nd, or 5737c478bd9Sstevel@tonic-gate * 3rd attr in the mapping list? 5747c478bd9Sstevel@tonic-gate */ 5757c478bd9Sstevel@tonic-gate gecos_attr_matched = FALSE; 5767c478bd9Sstevel@tonic-gate for (i = 0; i < 3 && gecos_mapping[i]; i++) { 5777c478bd9Sstevel@tonic-gate if (gecos_mapping[i] && 5787c478bd9Sstevel@tonic-gate strcasecmp(gecos_mapping[i], 5797c478bd9Sstevel@tonic-gate attr) == 0) { 5807c478bd9Sstevel@tonic-gate gecos_val_index[i] = j; 5817c478bd9Sstevel@tonic-gate gecos_attr_matched = TRUE; 5827c478bd9Sstevel@tonic-gate break; 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate if (gecos_attr_matched == FALSE) { 5867c478bd9Sstevel@tonic-gate /* 5877c478bd9Sstevel@tonic-gate * Not match found. 5887c478bd9Sstevel@tonic-gate * This should never happens, 5897c478bd9Sstevel@tonic-gate * syslog the error 5907c478bd9Sstevel@tonic-gate */ 5917c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 5927c478bd9Sstevel@tonic-gate gettext( 5937c478bd9Sstevel@tonic-gate "Attribute mapping " 5947c478bd9Sstevel@tonic-gate "inconsistency " 5957c478bd9Sstevel@tonic-gate "found for attributes " 5967c478bd9Sstevel@tonic-gate "'%s' and '%s'."), 5977c478bd9Sstevel@tonic-gate mapping[0], attr); 5987c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "libsldap: %s", errstr); 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate ber_free(ber, 0); 6017c478bd9Sstevel@tonic-gate ber = NULL; 6027c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 6037c478bd9Sstevel@tonic-gate ep = NULL; 6047c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapping); 6057c478bd9Sstevel@tonic-gate mapping = NULL; 6067c478bd9Sstevel@tonic-gate __s_api_free2dArray(gecos_mapping); 6077c478bd9Sstevel@tonic-gate gecos_mapping = NULL; 6087c478bd9Sstevel@tonic-gate return (NS_LDAP_INTERNAL); 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapping); 6127c478bd9Sstevel@tonic-gate mapping = NULL; 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate if ((vals = ldap_get_values(ld, e, attr)) != NULL) { 6167c478bd9Sstevel@tonic-gate 617699bceb8Smj162486 if ((ap[j]->value_count = 618699bceb8Smj162486 ldap_count_values(vals)) == 0) { 6197c478bd9Sstevel@tonic-gate ldap_value_free(vals); 6207c478bd9Sstevel@tonic-gate vals = NULL; 6217c478bd9Sstevel@tonic-gate continue; 6227c478bd9Sstevel@tonic-gate } else { 6237c478bd9Sstevel@tonic-gate ap[j]->attrvalue = (char **) 624699bceb8Smj162486 calloc(ap[j]->value_count+1, 625699bceb8Smj162486 sizeof (char *)); 6267c478bd9Sstevel@tonic-gate if (ap[j]->attrvalue == NULL) { 6277c478bd9Sstevel@tonic-gate ber_free(ber, 0); 6287c478bd9Sstevel@tonic-gate ber = NULL; 6297c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 6307c478bd9Sstevel@tonic-gate ep = NULL; 6317c478bd9Sstevel@tonic-gate if (gecos_mapping) 632699bceb8Smj162486 __s_api_free2dArray( 633699bceb8Smj162486 gecos_mapping); 6347c478bd9Sstevel@tonic-gate gecos_mapping = NULL; 6357c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 6367c478bd9Sstevel@tonic-gate } 6377c478bd9Sstevel@tonic-gate } 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate /* map object classes if necessary */ 6407c478bd9Sstevel@tonic-gate if ((flags & NS_LDAP_NOMAP) == 0 && 6417c478bd9Sstevel@tonic-gate schema_mapping_existed && ap[j]->attrname && 6427c478bd9Sstevel@tonic-gate strcasecmp(ap[j]->attrname, "objectclass") == 0) { 6437c478bd9Sstevel@tonic-gate for (k = 0; k < ap[j]->value_count; k++) { 6447c478bd9Sstevel@tonic-gate mapping = 645699bceb8Smj162486 __ns_ldap_getOrigObjectClass( 646699bceb8Smj162486 service, vals[k]); 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate if (mapping == NULL && auto_service) 6497c478bd9Sstevel@tonic-gate /* 6507c478bd9Sstevel@tonic-gate * if service == auto_* and no 6517c478bd9Sstevel@tonic-gate * schema mapping found 6527c478bd9Sstevel@tonic-gate * then try automount 6537c478bd9Sstevel@tonic-gate */ 6547c478bd9Sstevel@tonic-gate mapping = 6557c478bd9Sstevel@tonic-gate __ns_ldap_getOrigObjectClass( 6567c478bd9Sstevel@tonic-gate "automount", vals[k]); 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate if (mapping == NULL) { 659699bceb8Smj162486 ap[j]->attrvalue[k] = 660699bceb8Smj162486 strdup(vals[k]); 6617c478bd9Sstevel@tonic-gate } else { 662699bceb8Smj162486 ap[j]->attrvalue[k] = 663699bceb8Smj162486 strdup(mapping[0]); 6647c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapping); 6657c478bd9Sstevel@tonic-gate mapping = NULL; 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate if (ap[j]->attrvalue[k] == NULL) { 6687c478bd9Sstevel@tonic-gate ber_free(ber, 0); 6697c478bd9Sstevel@tonic-gate ber = NULL; 6707c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 6717c478bd9Sstevel@tonic-gate ep = NULL; 6727c478bd9Sstevel@tonic-gate if (gecos_mapping) 673699bceb8Smj162486 __s_api_free2dArray( 674699bceb8Smj162486 gecos_mapping); 6757c478bd9Sstevel@tonic-gate gecos_mapping = NULL; 6767c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 6777c478bd9Sstevel@tonic-gate } 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate } else { 6807c478bd9Sstevel@tonic-gate for (k = 0; k < ap[j]->value_count; k++) { 681699bceb8Smj162486 if ((ap[j]->attrvalue[k] = 682699bceb8Smj162486 strdup(vals[k])) == NULL) { 6837c478bd9Sstevel@tonic-gate ber_free(ber, 0); 6847c478bd9Sstevel@tonic-gate ber = NULL; 6857c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 6867c478bd9Sstevel@tonic-gate ep = NULL; 6877c478bd9Sstevel@tonic-gate if (gecos_mapping) 688699bceb8Smj162486 __s_api_free2dArray( 689699bceb8Smj162486 gecos_mapping); 6907c478bd9Sstevel@tonic-gate gecos_mapping = NULL; 6917c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate } 6947c478bd9Sstevel@tonic-gate } 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate ap[j]->attrvalue[k] = NULL; 6977c478bd9Sstevel@tonic-gate ldap_value_free(vals); 6987c478bd9Sstevel@tonic-gate vals = NULL; 6997c478bd9Sstevel@tonic-gate } 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate ldap_memfree(attr); 7027c478bd9Sstevel@tonic-gate attr = NULL; 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate ber_free(ber, 0); 7067c478bd9Sstevel@tonic-gate ber = NULL; 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate if (gecos_mapping) { 7097c478bd9Sstevel@tonic-gate __s_api_free2dArray(gecos_mapping); 7107c478bd9Sstevel@tonic-gate gecos_mapping = NULL; 7117c478bd9Sstevel@tonic-gate } 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate /* special processing for gecos 1 to up to 3 attribute mapping */ 7147c478bd9Sstevel@tonic-gate if (schema_mapping_existed && gecos_mapping_existed) { 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate int f = -1; 7177c478bd9Sstevel@tonic-gate 7187c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 7197c478bd9Sstevel@tonic-gate k = gecos_val_index[i]; 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate /* 7227c478bd9Sstevel@tonic-gate * f is the index of the first returned 7237c478bd9Sstevel@tonic-gate * attribute which "gecos" attribute mapped to 7247c478bd9Sstevel@tonic-gate */ 7257c478bd9Sstevel@tonic-gate if (k != -1 && f == -1) 7267c478bd9Sstevel@tonic-gate f = k; 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate if (k != -1 && ap[k]->value_count > 0 && 7297c478bd9Sstevel@tonic-gate ap[k]->attrvalue[0] && 7307c478bd9Sstevel@tonic-gate strlen(ap[k]->attrvalue[0]) > 0) { 7317c478bd9Sstevel@tonic-gate 7327c478bd9Sstevel@tonic-gate if (k == f) { 7337c478bd9Sstevel@tonic-gate /* 7347c478bd9Sstevel@tonic-gate * Create and fill in the last reserved 7357c478bd9Sstevel@tonic-gate * ap with the data from the "gecos" 7367c478bd9Sstevel@tonic-gate * mapping attributes 7377c478bd9Sstevel@tonic-gate */ 7387c478bd9Sstevel@tonic-gate ap[nAttrs] = (ns_ldap_attr_t *) 7397c478bd9Sstevel@tonic-gate calloc(1, 7407c478bd9Sstevel@tonic-gate sizeof (ns_ldap_attr_t)); 7417c478bd9Sstevel@tonic-gate if (ap[nAttrs] == NULL) { 7427c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 7437c478bd9Sstevel@tonic-gate ep = NULL; 7447c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 7457c478bd9Sstevel@tonic-gate } 7467c478bd9Sstevel@tonic-gate ap[nAttrs]->attrvalue = (char **)calloc( 7477c478bd9Sstevel@tonic-gate 2, sizeof (char *)); 7487c478bd9Sstevel@tonic-gate if (ap[nAttrs]->attrvalue == NULL) { 7497c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 7507c478bd9Sstevel@tonic-gate ep = NULL; 7517c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 7527c478bd9Sstevel@tonic-gate } 7537c478bd9Sstevel@tonic-gate /* add 1 more for a possible "," */ 7547c478bd9Sstevel@tonic-gate ap[nAttrs]->attrvalue[0] = 7557c478bd9Sstevel@tonic-gate (char *)calloc( 7567c478bd9Sstevel@tonic-gate strlen(ap[f]->attrvalue[0]) + 7577c478bd9Sstevel@tonic-gate 2, 1); 7587c478bd9Sstevel@tonic-gate if (ap[nAttrs]->attrvalue[0] == NULL) { 7597c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 7607c478bd9Sstevel@tonic-gate ep = NULL; 7617c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 7627c478bd9Sstevel@tonic-gate } 7637c478bd9Sstevel@tonic-gate (void) strcpy(ap[nAttrs]->attrvalue[0], 7647c478bd9Sstevel@tonic-gate ap[f]->attrvalue[0]); 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate ap[nAttrs]->attrname = strdup("gecos"); 7677c478bd9Sstevel@tonic-gate if (ap[nAttrs]->attrname == NULL) { 7687c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 7697c478bd9Sstevel@tonic-gate ep = NULL; 7707c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 7717c478bd9Sstevel@tonic-gate } 7727c478bd9Sstevel@tonic-gate 7737c478bd9Sstevel@tonic-gate ap[nAttrs]->value_count = 1; 7747c478bd9Sstevel@tonic-gate ep->attr_count = nAttrs + 1; 7757c478bd9Sstevel@tonic-gate 7767c478bd9Sstevel@tonic-gate } else { 7774142e9a2Ssdussud char *tmp = NULL; 7784142e9a2Ssdussud 7794142e9a2Ssdussud /* 7804142e9a2Ssdussud * realloc to add "," and 7814142e9a2Ssdussud * ap[k]->attrvalue[0] 7824142e9a2Ssdussud */ 7834142e9a2Ssdussud tmp = (char *)realloc( 7847c478bd9Sstevel@tonic-gate ap[nAttrs]->attrvalue[0], 7857c478bd9Sstevel@tonic-gate strlen(ap[nAttrs]-> 7864142e9a2Ssdussud attrvalue[0]) + 7874142e9a2Ssdussud strlen(ap[k]-> 7887c478bd9Sstevel@tonic-gate attrvalue[0]) + 2); 7894142e9a2Ssdussud if (tmp == NULL) { 7907c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(ep); 7917c478bd9Sstevel@tonic-gate ep = NULL; 7927c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 7937c478bd9Sstevel@tonic-gate } 7944142e9a2Ssdussud ap[nAttrs]->attrvalue[0] = tmp; 7954142e9a2Ssdussud (void) strcat(ap[nAttrs]->attrvalue[0], 7964142e9a2Ssdussud ","); 7977c478bd9Sstevel@tonic-gate (void) strcat(ap[nAttrs]->attrvalue[0], 7987c478bd9Sstevel@tonic-gate ap[k]->attrvalue[0]); 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate } 8017c478bd9Sstevel@tonic-gate } 8027c478bd9Sstevel@tonic-gate } 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate *ret = ep; 8057c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 8067c478bd9Sstevel@tonic-gate } 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate static int 8097c478bd9Sstevel@tonic-gate __s_api_getEntry(ns_ldap_cookie_t *cookie) 8107c478bd9Sstevel@tonic-gate { 8117c478bd9Sstevel@tonic-gate ns_ldap_entry_t *curEntry = NULL; 8127c478bd9Sstevel@tonic-gate int ret; 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate #ifdef DEBUG 8157c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "__s_api_getEntry START\n"); 8167c478bd9Sstevel@tonic-gate #endif 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate if (cookie->resultMsg == NULL) { 8197c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 8207c478bd9Sstevel@tonic-gate } 8217c478bd9Sstevel@tonic-gate ret = __s_api_cvtEntry(cookie->conn->ld, cookie->service, 8227c478bd9Sstevel@tonic-gate cookie->resultMsg, cookie->i_flags, 8237c478bd9Sstevel@tonic-gate &curEntry, &cookie->errorp); 8247c478bd9Sstevel@tonic-gate if (ret != NS_LDAP_SUCCESS) { 8257c478bd9Sstevel@tonic-gate return (ret); 8267c478bd9Sstevel@tonic-gate } 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate if (cookie->result == NULL) { 8297c478bd9Sstevel@tonic-gate cookie->result = (ns_ldap_result_t *) 8307c478bd9Sstevel@tonic-gate calloc(1, sizeof (ns_ldap_result_t)); 8317c478bd9Sstevel@tonic-gate if (cookie->result == NULL) { 8327c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(curEntry); 8337c478bd9Sstevel@tonic-gate curEntry = NULL; 8347c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 8357c478bd9Sstevel@tonic-gate } 8367c478bd9Sstevel@tonic-gate cookie->result->entry = curEntry; 8377c478bd9Sstevel@tonic-gate cookie->nextEntry = curEntry; 8387c478bd9Sstevel@tonic-gate } else { 8397c478bd9Sstevel@tonic-gate cookie->nextEntry->next = curEntry; 8407c478bd9Sstevel@tonic-gate cookie->nextEntry = curEntry; 8417c478bd9Sstevel@tonic-gate } 8427c478bd9Sstevel@tonic-gate cookie->result->entries_count++; 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate static int 8487c478bd9Sstevel@tonic-gate __s_api_get_cachemgr_data(const char *type, 8497c478bd9Sstevel@tonic-gate const char *from, char **to) 8507c478bd9Sstevel@tonic-gate { 8517c478bd9Sstevel@tonic-gate union { 8527c478bd9Sstevel@tonic-gate ldap_data_t s_d; 8537c478bd9Sstevel@tonic-gate char s_b[DOORBUFFERSIZE]; 8547c478bd9Sstevel@tonic-gate } space; 8557c478bd9Sstevel@tonic-gate ldap_data_t *sptr; 8567c478bd9Sstevel@tonic-gate int ndata; 8577c478bd9Sstevel@tonic-gate int adata; 8587c478bd9Sstevel@tonic-gate int rc; 8597c478bd9Sstevel@tonic-gate 8607c478bd9Sstevel@tonic-gate #ifdef DEBUG 8617c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "__s_api_get_cachemgr_data START\n"); 8627c478bd9Sstevel@tonic-gate #endif 863e1dd0a2fSth160488 /* 864e1dd0a2fSth160488 * We are not going to perform DN to domain mapping 865e1dd0a2fSth160488 * in the Standalone mode 866e1dd0a2fSth160488 */ 867e1dd0a2fSth160488 if (__s_api_isStandalone()) { 868e1dd0a2fSth160488 return (-1); 869e1dd0a2fSth160488 } 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate if (from == NULL || from[0] == '\0' || to == NULL) 8727c478bd9Sstevel@tonic-gate return (-1); 8737c478bd9Sstevel@tonic-gate 8747c478bd9Sstevel@tonic-gate *to = NULL; 8757c478bd9Sstevel@tonic-gate (void) memset(space.s_b, 0, DOORBUFFERSIZE); 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate space.s_d.ldap_call.ldap_callnumber = GETCACHE; 8787c478bd9Sstevel@tonic-gate (void) snprintf(space.s_d.ldap_call.ldap_u.domainname, 8797c478bd9Sstevel@tonic-gate DOORBUFFERSIZE - sizeof (space.s_d.ldap_call.ldap_callnumber), 8807c478bd9Sstevel@tonic-gate "%s%s%s", 8817c478bd9Sstevel@tonic-gate type, 8827c478bd9Sstevel@tonic-gate DOORLINESEP, 8837c478bd9Sstevel@tonic-gate from); 8847c478bd9Sstevel@tonic-gate ndata = sizeof (space); 8857c478bd9Sstevel@tonic-gate adata = sizeof (ldap_call_t) + 8867c478bd9Sstevel@tonic-gate strlen(space.s_d.ldap_call.ldap_u.domainname) + 1; 8877c478bd9Sstevel@tonic-gate sptr = &space.s_d; 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate rc = __ns_ldap_trydoorcall(&sptr, &ndata, &adata); 890e1dd0a2fSth160488 if (rc != NS_CACHE_SUCCESS) 8917c478bd9Sstevel@tonic-gate return (-1); 8927c478bd9Sstevel@tonic-gate else 8937c478bd9Sstevel@tonic-gate *to = strdup(sptr->ldap_ret.ldap_u.buff); 8947c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 8957c478bd9Sstevel@tonic-gate } 8967c478bd9Sstevel@tonic-gate 8977c478bd9Sstevel@tonic-gate static int 8987c478bd9Sstevel@tonic-gate __s_api_set_cachemgr_data(const char *type, 8997c478bd9Sstevel@tonic-gate const char *from, const char *to) 9007c478bd9Sstevel@tonic-gate { 9017c478bd9Sstevel@tonic-gate union { 9027c478bd9Sstevel@tonic-gate ldap_data_t s_d; 9037c478bd9Sstevel@tonic-gate char s_b[DOORBUFFERSIZE]; 9047c478bd9Sstevel@tonic-gate } space; 9057c478bd9Sstevel@tonic-gate ldap_data_t *sptr; 9067c478bd9Sstevel@tonic-gate int ndata; 9077c478bd9Sstevel@tonic-gate int adata; 9087c478bd9Sstevel@tonic-gate int rc; 9097c478bd9Sstevel@tonic-gate 9107c478bd9Sstevel@tonic-gate #ifdef DEBUG 9117c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "__s_api_set_cachemgr_data START\n"); 9127c478bd9Sstevel@tonic-gate #endif 913e1dd0a2fSth160488 /* 914e1dd0a2fSth160488 * We are not going to perform DN to domain mapping 915e1dd0a2fSth160488 * in the Standalone mode 916e1dd0a2fSth160488 */ 917e1dd0a2fSth160488 if (__s_api_isStandalone()) { 918e1dd0a2fSth160488 return (-1); 919e1dd0a2fSth160488 } 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate if ((from == NULL) || (from[0] == '\0') || 9227c478bd9Sstevel@tonic-gate (to == NULL) || (to[0] == '\0')) 9237c478bd9Sstevel@tonic-gate return (-1); 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate (void) memset(space.s_b, 0, DOORBUFFERSIZE); 9267c478bd9Sstevel@tonic-gate 9277c478bd9Sstevel@tonic-gate space.s_d.ldap_call.ldap_callnumber = SETCACHE; 9287c478bd9Sstevel@tonic-gate (void) snprintf(space.s_d.ldap_call.ldap_u.domainname, 9297c478bd9Sstevel@tonic-gate DOORBUFFERSIZE - sizeof (space.s_d.ldap_call.ldap_callnumber), 9307c478bd9Sstevel@tonic-gate "%s%s%s%s%s", 9317c478bd9Sstevel@tonic-gate type, 9327c478bd9Sstevel@tonic-gate DOORLINESEP, 9337c478bd9Sstevel@tonic-gate from, 9347c478bd9Sstevel@tonic-gate DOORLINESEP, 9357c478bd9Sstevel@tonic-gate to); 9367c478bd9Sstevel@tonic-gate 9377c478bd9Sstevel@tonic-gate ndata = sizeof (space); 9387c478bd9Sstevel@tonic-gate adata = sizeof (ldap_call_t) + 9397c478bd9Sstevel@tonic-gate strlen(space.s_d.ldap_call.ldap_u.domainname) + 1; 9407c478bd9Sstevel@tonic-gate sptr = &space.s_d; 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate rc = __ns_ldap_trydoorcall(&sptr, &ndata, &adata); 943e1dd0a2fSth160488 if (rc != NS_CACHE_SUCCESS) 9447c478bd9Sstevel@tonic-gate return (-1); 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 9477c478bd9Sstevel@tonic-gate } 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate static char * 9517c478bd9Sstevel@tonic-gate __s_api_remove_rdn_space(char *rdn) 9527c478bd9Sstevel@tonic-gate { 9537c478bd9Sstevel@tonic-gate char *tf, *tl, *vf, *vl, *eqsign; 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate /* if no space(s) to remove, return */ 9567c478bd9Sstevel@tonic-gate if (strchr(rdn, SPACETOK) == NULL) 9577c478bd9Sstevel@tonic-gate return (rdn); 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate /* if no '=' separator, return */ 9607c478bd9Sstevel@tonic-gate eqsign = strchr(rdn, '='); 9617c478bd9Sstevel@tonic-gate if (eqsign == NULL) 9627c478bd9Sstevel@tonic-gate return (rdn); 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate tf = rdn; 9657c478bd9Sstevel@tonic-gate tl = eqsign - 1; 9667c478bd9Sstevel@tonic-gate vf = eqsign + 1; 9677c478bd9Sstevel@tonic-gate vl = rdn + strlen(rdn) - 1; 9687c478bd9Sstevel@tonic-gate 9697c478bd9Sstevel@tonic-gate /* now two strings, type and value */ 9707c478bd9Sstevel@tonic-gate *eqsign = '\0'; 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate /* remove type's leading spaces */ 9737c478bd9Sstevel@tonic-gate while (tf < tl && *tf == SPACETOK) 9747c478bd9Sstevel@tonic-gate tf++; 9757c478bd9Sstevel@tonic-gate /* remove type's trailing spaces */ 9767c478bd9Sstevel@tonic-gate while (tf < tl && *tl == SPACETOK) 9777c478bd9Sstevel@tonic-gate tl--; 9787c478bd9Sstevel@tonic-gate /* add '=' separator back */ 9797c478bd9Sstevel@tonic-gate *(++tl) = '='; 9807c478bd9Sstevel@tonic-gate /* remove value's leading spaces */ 9817c478bd9Sstevel@tonic-gate while (vf < vl && *vf == SPACETOK) 9827c478bd9Sstevel@tonic-gate vf++; 9837c478bd9Sstevel@tonic-gate /* remove value's trailing spaces */ 9847c478bd9Sstevel@tonic-gate while (vf < vl && *vl == SPACETOK) 9857c478bd9Sstevel@tonic-gate *vl-- = '\0'; 9867c478bd9Sstevel@tonic-gate 9877c478bd9Sstevel@tonic-gate /* move value up if necessary */ 9887c478bd9Sstevel@tonic-gate if (vf != tl + 1) 9897c478bd9Sstevel@tonic-gate (void) strcpy(tl + 1, vf); 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate return (tf); 9927c478bd9Sstevel@tonic-gate } 9937c478bd9Sstevel@tonic-gate 9947c478bd9Sstevel@tonic-gate static 9957c478bd9Sstevel@tonic-gate ns_ldap_cookie_t * 9967c478bd9Sstevel@tonic-gate init_search_state_machine() 9977c478bd9Sstevel@tonic-gate { 9987c478bd9Sstevel@tonic-gate ns_ldap_cookie_t *cookie; 9997c478bd9Sstevel@tonic-gate ns_config_t *cfg; 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate cookie = (ns_ldap_cookie_t *)calloc(1, sizeof (ns_ldap_cookie_t)); 10027c478bd9Sstevel@tonic-gate if (cookie == NULL) 10037c478bd9Sstevel@tonic-gate return (NULL); 10047c478bd9Sstevel@tonic-gate cookie->state = INIT; 10057c478bd9Sstevel@tonic-gate /* assign other state variables */ 10067c478bd9Sstevel@tonic-gate cfg = __s_api_loadrefresh_config(); 10077c478bd9Sstevel@tonic-gate cookie->connectionId = -1; 10087c478bd9Sstevel@tonic-gate if (cfg == NULL || 10097c478bd9Sstevel@tonic-gate cfg->paramList[NS_LDAP_SEARCH_TIME_P].ns_ptype == NS_UNKNOWN) { 10107c478bd9Sstevel@tonic-gate cookie->search_timeout.tv_sec = NS_DEFAULT_SEARCH_TIMEOUT; 10117c478bd9Sstevel@tonic-gate } else { 10127c478bd9Sstevel@tonic-gate cookie->search_timeout.tv_sec = 10137c478bd9Sstevel@tonic-gate cfg->paramList[NS_LDAP_SEARCH_TIME_P].ns_i; 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate if (cfg != NULL) 10167c478bd9Sstevel@tonic-gate __s_api_release_config(cfg); 10177c478bd9Sstevel@tonic-gate cookie->search_timeout.tv_usec = 0; 10187c478bd9Sstevel@tonic-gate 10197c478bd9Sstevel@tonic-gate return (cookie); 10207c478bd9Sstevel@tonic-gate } 10217c478bd9Sstevel@tonic-gate 10227c478bd9Sstevel@tonic-gate static void 10237c478bd9Sstevel@tonic-gate delete_search_cookie(ns_ldap_cookie_t *cookie) 10247c478bd9Sstevel@tonic-gate { 10257c478bd9Sstevel@tonic-gate if (cookie == NULL) 10267c478bd9Sstevel@tonic-gate return; 10277c478bd9Sstevel@tonic-gate if (cookie->connectionId > -1) 10287c478bd9Sstevel@tonic-gate DropConnection(cookie->connectionId, cookie->i_flags); 10297c478bd9Sstevel@tonic-gate if (cookie->filter) 10307c478bd9Sstevel@tonic-gate free(cookie->filter); 10317c478bd9Sstevel@tonic-gate if (cookie->i_filter) 10327c478bd9Sstevel@tonic-gate free(cookie->i_filter); 10337c478bd9Sstevel@tonic-gate if (cookie->service) 10347c478bd9Sstevel@tonic-gate free(cookie->service); 10357c478bd9Sstevel@tonic-gate if (cookie->sdlist) 10367c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeSearchDescriptors(&(cookie->sdlist)); 10377c478bd9Sstevel@tonic-gate if (cookie->result) 10387c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&cookie->result); 10397c478bd9Sstevel@tonic-gate if (cookie->attribute) 10407c478bd9Sstevel@tonic-gate __s_api_free2dArray(cookie->attribute); 10417c478bd9Sstevel@tonic-gate if (cookie->errorp) 10427c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&cookie->errorp); 10437c478bd9Sstevel@tonic-gate if (cookie->reflist) 10447c478bd9Sstevel@tonic-gate __s_api_deleteRefInfo(cookie->reflist); 10457c478bd9Sstevel@tonic-gate if (cookie->basedn) 10467c478bd9Sstevel@tonic-gate free(cookie->basedn); 10477c478bd9Sstevel@tonic-gate if (cookie->ctrlCookie) 10487c478bd9Sstevel@tonic-gate ber_bvfree(cookie->ctrlCookie); 10497c478bd9Sstevel@tonic-gate _freeControlList(&cookie->p_serverctrls); 105047789246Svv149972 if (cookie->resultctrl) 105147789246Svv149972 ldap_controls_free(cookie->resultctrl); 10527c478bd9Sstevel@tonic-gate free(cookie); 10537c478bd9Sstevel@tonic-gate } 10547c478bd9Sstevel@tonic-gate 10557c478bd9Sstevel@tonic-gate static int 10567c478bd9Sstevel@tonic-gate get_mapped_filter(ns_ldap_cookie_t *cookie, char **new_filter) 10577c478bd9Sstevel@tonic-gate { 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate typedef struct filter_mapping_info { 10607c478bd9Sstevel@tonic-gate char oc_or_attr; 10617c478bd9Sstevel@tonic-gate char *name_start; 10627c478bd9Sstevel@tonic-gate char *name_end; 10637c478bd9Sstevel@tonic-gate char *veq_pos; 10647c478bd9Sstevel@tonic-gate char *from_name; 10657c478bd9Sstevel@tonic-gate char *to_name; 10667c478bd9Sstevel@tonic-gate char **mapping; 10677c478bd9Sstevel@tonic-gate } filter_mapping_info_t; 10687c478bd9Sstevel@tonic-gate 10697c478bd9Sstevel@tonic-gate char *c, *last_copied; 10707c478bd9Sstevel@tonic-gate char *filter_c, *filter_c_next; 10717c478bd9Sstevel@tonic-gate char *key, *tail, *head; 10727c478bd9Sstevel@tonic-gate char errstr[MAXERROR]; 10737c478bd9Sstevel@tonic-gate int num_eq = 0, num_veq = 0; 10747c478bd9Sstevel@tonic-gate int in_quote = FALSE; 1075f8f1c176Svt115884 int is_value = FALSE; 10767c478bd9Sstevel@tonic-gate int i, j, oc_len, len; 10777c478bd9Sstevel@tonic-gate int at_least_one = FALSE; 10787c478bd9Sstevel@tonic-gate filter_mapping_info_t **info, *info1; 10797c478bd9Sstevel@tonic-gate char **mapping; 10807c478bd9Sstevel@tonic-gate char *service, *filter, *err; 10817c478bd9Sstevel@tonic-gate int auto_service = FALSE; 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gate if (cookie == NULL || new_filter == NULL) 10847c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 10857c478bd9Sstevel@tonic-gate 10867c478bd9Sstevel@tonic-gate *new_filter = NULL; 10877c478bd9Sstevel@tonic-gate service = cookie->service; 10887c478bd9Sstevel@tonic-gate filter = cookie->filter; 10897c478bd9Sstevel@tonic-gate 10907c478bd9Sstevel@tonic-gate /* 10917c478bd9Sstevel@tonic-gate * count the number of '=' char 10927c478bd9Sstevel@tonic-gate */ 10937c478bd9Sstevel@tonic-gate for (c = filter; *c; c++) { 10947c478bd9Sstevel@tonic-gate if (*c == TOKENSEPARATOR) 10957c478bd9Sstevel@tonic-gate num_eq++; 10967c478bd9Sstevel@tonic-gate } 10977c478bd9Sstevel@tonic-gate 10987c478bd9Sstevel@tonic-gate if (service != NULL && strncasecmp(service, "auto_", 5) == 0) 10997c478bd9Sstevel@tonic-gate auto_service = TRUE; 11007c478bd9Sstevel@tonic-gate 11017c478bd9Sstevel@tonic-gate /* 11027c478bd9Sstevel@tonic-gate * See if schema mapping existed for the given service. 11037c478bd9Sstevel@tonic-gate * If not, just return success. 11047c478bd9Sstevel@tonic-gate */ 11057c478bd9Sstevel@tonic-gate mapping = __ns_ldap_getOrigAttribute(service, 11067c478bd9Sstevel@tonic-gate NS_HASH_SCHEMA_MAPPING_EXISTED); 11077c478bd9Sstevel@tonic-gate 11087c478bd9Sstevel@tonic-gate if (mapping == NULL && auto_service) 11097c478bd9Sstevel@tonic-gate /* 11107c478bd9Sstevel@tonic-gate * if service == auto_* and no 11117c478bd9Sstevel@tonic-gate * schema mapping found 11127c478bd9Sstevel@tonic-gate * then try automount 11137c478bd9Sstevel@tonic-gate */ 11147c478bd9Sstevel@tonic-gate mapping = __ns_ldap_getOrigAttribute( 11157c478bd9Sstevel@tonic-gate "automount", NS_HASH_SCHEMA_MAPPING_EXISTED); 11167c478bd9Sstevel@tonic-gate 11177c478bd9Sstevel@tonic-gate if (mapping) 11187c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapping); 11197c478bd9Sstevel@tonic-gate else 11207c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 11217c478bd9Sstevel@tonic-gate 11227c478bd9Sstevel@tonic-gate /* 11237c478bd9Sstevel@tonic-gate * no '=' sign, just say OK and return nothing 11247c478bd9Sstevel@tonic-gate */ 11257c478bd9Sstevel@tonic-gate if (num_eq == 0) 11267c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 11277c478bd9Sstevel@tonic-gate 11287c478bd9Sstevel@tonic-gate /* 11297c478bd9Sstevel@tonic-gate * Make a copy of the filter string 11307c478bd9Sstevel@tonic-gate * for saving the name of the objectclasses or 11317c478bd9Sstevel@tonic-gate * attributes that need to be passed to the 11327c478bd9Sstevel@tonic-gate * objectclass or attribute mapping functions. 11337c478bd9Sstevel@tonic-gate * pointer "info->from_name" points to the locations 11347c478bd9Sstevel@tonic-gate * within this string. 11357c478bd9Sstevel@tonic-gate * 11367c478bd9Sstevel@tonic-gate * The input filter string, filter, will be used 11377c478bd9Sstevel@tonic-gate * to indicate where these names start and end. 11387c478bd9Sstevel@tonic-gate * pointers "info->name_start" and "info->name_end" 11397c478bd9Sstevel@tonic-gate * point to locations within the input filter string, 11407c478bd9Sstevel@tonic-gate * and are used at the end of this function to 11417c478bd9Sstevel@tonic-gate * merge the original filter data with the 11427c478bd9Sstevel@tonic-gate * mapped objectclass or attribute names. 11437c478bd9Sstevel@tonic-gate */ 11447c478bd9Sstevel@tonic-gate filter_c = strdup(filter); 11457c478bd9Sstevel@tonic-gate if (filter_c == NULL) 11467c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 11477c478bd9Sstevel@tonic-gate filter_c_next = filter_c; 11487c478bd9Sstevel@tonic-gate 11497c478bd9Sstevel@tonic-gate /* 11507c478bd9Sstevel@tonic-gate * get memory for info arrays 11517c478bd9Sstevel@tonic-gate */ 11527c478bd9Sstevel@tonic-gate info = (filter_mapping_info_t **)calloc(num_eq + 1, 11537c478bd9Sstevel@tonic-gate sizeof (filter_mapping_info_t *)); 11547c478bd9Sstevel@tonic-gate 11557c478bd9Sstevel@tonic-gate if (info == NULL) { 11567c478bd9Sstevel@tonic-gate free(filter_c); 11577c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 11587c478bd9Sstevel@tonic-gate } 11597c478bd9Sstevel@tonic-gate 11607c478bd9Sstevel@tonic-gate /* 11617c478bd9Sstevel@tonic-gate * find valid '=' for further processing, 11627c478bd9Sstevel@tonic-gate * ignore the "escaped =" (.i.e. "\="), or 11637c478bd9Sstevel@tonic-gate * "=" in quoted string 11647c478bd9Sstevel@tonic-gate */ 11657c478bd9Sstevel@tonic-gate for (c = filter_c; *c; c++) { 11667c478bd9Sstevel@tonic-gate 11677c478bd9Sstevel@tonic-gate switch (*c) { 11687c478bd9Sstevel@tonic-gate case TOKENSEPARATOR: 1169f8f1c176Svt115884 if (!in_quote && !is_value) { 11707c478bd9Sstevel@tonic-gate info1 = (filter_mapping_info_t *)calloc(1, 11717c478bd9Sstevel@tonic-gate sizeof (filter_mapping_info_t)); 11727c478bd9Sstevel@tonic-gate if (!info1) { 11737c478bd9Sstevel@tonic-gate free(filter_c); 11747c478bd9Sstevel@tonic-gate for (i = 0; i < num_veq; i++) 11757c478bd9Sstevel@tonic-gate free(info[i]); 11767c478bd9Sstevel@tonic-gate free(info); 11777c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 11787c478bd9Sstevel@tonic-gate } 11797c478bd9Sstevel@tonic-gate info[num_veq] = info1; 11807c478bd9Sstevel@tonic-gate 11817c478bd9Sstevel@tonic-gate /* 11827c478bd9Sstevel@tonic-gate * remember the location of this "=" 11837c478bd9Sstevel@tonic-gate */ 11847c478bd9Sstevel@tonic-gate info[num_veq++]->veq_pos = c; 1185f8f1c176Svt115884 1186f8f1c176Svt115884 /* 1187f8f1c176Svt115884 * skip until the end of the attribute value 1188f8f1c176Svt115884 */ 1189f8f1c176Svt115884 is_value = TRUE; 11907c478bd9Sstevel@tonic-gate } 11917c478bd9Sstevel@tonic-gate break; 1192f8f1c176Svt115884 case CPARATOK: 1193f8f1c176Svt115884 /* 1194f8f1c176Svt115884 * mark the end of the attribute value 1195f8f1c176Svt115884 */ 1196f8f1c176Svt115884 if (!in_quote) 1197f8f1c176Svt115884 is_value = FALSE; 1198f8f1c176Svt115884 break; 11997c478bd9Sstevel@tonic-gate case QUOTETOK: 12007c478bd9Sstevel@tonic-gate /* 12017c478bd9Sstevel@tonic-gate * switch on/off the in_quote mode 12027c478bd9Sstevel@tonic-gate */ 12037c478bd9Sstevel@tonic-gate in_quote = (in_quote == FALSE); 12047c478bd9Sstevel@tonic-gate break; 12057c478bd9Sstevel@tonic-gate case '\\': 12067c478bd9Sstevel@tonic-gate /* 12077c478bd9Sstevel@tonic-gate * ignore escape characters 12087c478bd9Sstevel@tonic-gate * don't skip if next char is '\0' 12097c478bd9Sstevel@tonic-gate */ 12107c478bd9Sstevel@tonic-gate if (!in_quote) 12117c478bd9Sstevel@tonic-gate if (*(++c) == '\0') 12127c478bd9Sstevel@tonic-gate c--; 12137c478bd9Sstevel@tonic-gate break; 12147c478bd9Sstevel@tonic-gate } 12157c478bd9Sstevel@tonic-gate 12167c478bd9Sstevel@tonic-gate } 12177c478bd9Sstevel@tonic-gate 12187c478bd9Sstevel@tonic-gate /* 12197c478bd9Sstevel@tonic-gate * for each valid "=" found, get the name to 12207c478bd9Sstevel@tonic-gate * be mapped 12217c478bd9Sstevel@tonic-gate */ 12227c478bd9Sstevel@tonic-gate oc_len = strlen("objectclass"); 12237c478bd9Sstevel@tonic-gate for (i = 0; i < num_veq; i++) { 12247c478bd9Sstevel@tonic-gate 12257c478bd9Sstevel@tonic-gate /* 12267c478bd9Sstevel@tonic-gate * look at the left side of "=" to see 12277c478bd9Sstevel@tonic-gate * if assertion is "objectclass=<ocname>" 12287c478bd9Sstevel@tonic-gate * or "<attribute name>=<attribute value>" 12297c478bd9Sstevel@tonic-gate * 12307c478bd9Sstevel@tonic-gate * first skip spaces before "=". 12317c478bd9Sstevel@tonic-gate * Note that filter_c_next may not point to the 12327c478bd9Sstevel@tonic-gate * start of the filter string. For i > 0, 12337c478bd9Sstevel@tonic-gate * it points to the end of the last name processed + 2 12347c478bd9Sstevel@tonic-gate */ 12357c478bd9Sstevel@tonic-gate for (tail = info[i]->veq_pos; (tail > filter_c_next) && 1236699bceb8Smj162486 (*(tail - 1) == SPACETOK); tail--) 1237699bceb8Smj162486 ; 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate /* 12407c478bd9Sstevel@tonic-gate * mark the end of the left side string (the key) 12417c478bd9Sstevel@tonic-gate */ 12427c478bd9Sstevel@tonic-gate *tail = '\0'; 12437c478bd9Sstevel@tonic-gate info[i]->name_end = tail - filter_c - 1 + filter; 12447c478bd9Sstevel@tonic-gate 12457c478bd9Sstevel@tonic-gate /* 12467c478bd9Sstevel@tonic-gate * find the start of the key 12477c478bd9Sstevel@tonic-gate */ 12487c478bd9Sstevel@tonic-gate key = filter_c_next; 12497c478bd9Sstevel@tonic-gate for (c = tail; filter_c_next <= c; c--) { 12507c478bd9Sstevel@tonic-gate /* OPARATOK is '(' */ 12517c478bd9Sstevel@tonic-gate if (*c == OPARATOK || 12527c478bd9Sstevel@tonic-gate *c == SPACETOK) { 12537c478bd9Sstevel@tonic-gate key = c + 1; 12547c478bd9Sstevel@tonic-gate break; 12557c478bd9Sstevel@tonic-gate } 12567c478bd9Sstevel@tonic-gate } 12577c478bd9Sstevel@tonic-gate info[i]->name_start = key - filter_c + filter; 12587c478bd9Sstevel@tonic-gate 12597c478bd9Sstevel@tonic-gate if ((key + oc_len) <= tail) { 12607c478bd9Sstevel@tonic-gate if (strncasecmp(key, "objectclass", 12617c478bd9Sstevel@tonic-gate oc_len) == 0) { 12627c478bd9Sstevel@tonic-gate /* 12637c478bd9Sstevel@tonic-gate * assertion is "objectclass=ocname", 12647c478bd9Sstevel@tonic-gate * ocname is the one needs to be mapped 12657c478bd9Sstevel@tonic-gate * 12667c478bd9Sstevel@tonic-gate * skip spaces after "=" to find start 12677c478bd9Sstevel@tonic-gate * of the ocname 12687c478bd9Sstevel@tonic-gate */ 12697c478bd9Sstevel@tonic-gate head = info[i]->veq_pos; 12707c478bd9Sstevel@tonic-gate for (head = info[i]->veq_pos + 1; 1271699bceb8Smj162486 *head && *head == SPACETOK; head++) 1272699bceb8Smj162486 ; 12737c478bd9Sstevel@tonic-gate 12747c478bd9Sstevel@tonic-gate /* ignore empty ocname */ 12757c478bd9Sstevel@tonic-gate if (!(*head)) 12767c478bd9Sstevel@tonic-gate continue; 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate info[i]->name_start = head - filter_c + 12797c478bd9Sstevel@tonic-gate filter; 12807c478bd9Sstevel@tonic-gate 12817c478bd9Sstevel@tonic-gate /* 12827c478bd9Sstevel@tonic-gate * now find the end of the ocname 12837c478bd9Sstevel@tonic-gate */ 12847c478bd9Sstevel@tonic-gate for (c = head; ; c++) { 12857c478bd9Sstevel@tonic-gate /* CPARATOK is ')' */ 12867c478bd9Sstevel@tonic-gate if (*c == CPARATOK || 12877c478bd9Sstevel@tonic-gate *c == '\0' || 12887c478bd9Sstevel@tonic-gate *c == SPACETOK) { 12897c478bd9Sstevel@tonic-gate *c = '\0'; 12907c478bd9Sstevel@tonic-gate info[i]->name_end = 12917c478bd9Sstevel@tonic-gate c - filter_c - 1 + 12927c478bd9Sstevel@tonic-gate filter; 12937c478bd9Sstevel@tonic-gate filter_c_next = c + 1; 12947c478bd9Sstevel@tonic-gate info[i]->oc_or_attr = 'o'; 12957c478bd9Sstevel@tonic-gate info[i]->from_name = head; 12967c478bd9Sstevel@tonic-gate break; 12977c478bd9Sstevel@tonic-gate } 12987c478bd9Sstevel@tonic-gate } 12997c478bd9Sstevel@tonic-gate } 13007c478bd9Sstevel@tonic-gate } 13017c478bd9Sstevel@tonic-gate 13027c478bd9Sstevel@tonic-gate /* 13037c478bd9Sstevel@tonic-gate * assertion is not "objectclass=ocname", 13047c478bd9Sstevel@tonic-gate * assume assertion is "<key> = <value>", 13057c478bd9Sstevel@tonic-gate * <key> is the one needs to be mapped 13067c478bd9Sstevel@tonic-gate */ 13077c478bd9Sstevel@tonic-gate if (info[i]->from_name == NULL && strlen(key) > 0) { 13087c478bd9Sstevel@tonic-gate info[i]->oc_or_attr = 'a'; 13097c478bd9Sstevel@tonic-gate info[i]->from_name = key; 13107c478bd9Sstevel@tonic-gate } 13117c478bd9Sstevel@tonic-gate } 13127c478bd9Sstevel@tonic-gate 13137c478bd9Sstevel@tonic-gate /* perform schema mapping */ 13147c478bd9Sstevel@tonic-gate for (i = 0; i < num_veq; i++) { 13157c478bd9Sstevel@tonic-gate if (info[i]->from_name == NULL) 13167c478bd9Sstevel@tonic-gate continue; 13177c478bd9Sstevel@tonic-gate 13187c478bd9Sstevel@tonic-gate if (info[i]->oc_or_attr == 'a') 13197c478bd9Sstevel@tonic-gate info[i]->mapping = 13207c478bd9Sstevel@tonic-gate __ns_ldap_getMappedAttributes(service, 13217c478bd9Sstevel@tonic-gate info[i]->from_name); 13227c478bd9Sstevel@tonic-gate else 13237c478bd9Sstevel@tonic-gate info[i]->mapping = 13247c478bd9Sstevel@tonic-gate __ns_ldap_getMappedObjectClass(service, 13257c478bd9Sstevel@tonic-gate info[i]->from_name); 13267c478bd9Sstevel@tonic-gate 13277c478bd9Sstevel@tonic-gate if (info[i]->mapping == NULL && auto_service) { 13287c478bd9Sstevel@tonic-gate /* 13297c478bd9Sstevel@tonic-gate * If no mapped attribute/objectclass is found 13307c478bd9Sstevel@tonic-gate * and service == auto* 13317c478bd9Sstevel@tonic-gate * try to find automount's 13327c478bd9Sstevel@tonic-gate * mapped attribute/objectclass 13337c478bd9Sstevel@tonic-gate */ 13347c478bd9Sstevel@tonic-gate if (info[i]->oc_or_attr == 'a') 13357c478bd9Sstevel@tonic-gate info[i]->mapping = 13367c478bd9Sstevel@tonic-gate __ns_ldap_getMappedAttributes("automount", 13377c478bd9Sstevel@tonic-gate info[i]->from_name); 13387c478bd9Sstevel@tonic-gate else 13397c478bd9Sstevel@tonic-gate info[i]->mapping = 13407c478bd9Sstevel@tonic-gate __ns_ldap_getMappedObjectClass("automount", 13417c478bd9Sstevel@tonic-gate info[i]->from_name); 13427c478bd9Sstevel@tonic-gate } 13437c478bd9Sstevel@tonic-gate 13447c478bd9Sstevel@tonic-gate if (info[i]->mapping == NULL || 13457c478bd9Sstevel@tonic-gate info[i]->mapping[0] == NULL) { 13467c478bd9Sstevel@tonic-gate info[i]->to_name = NULL; 13477c478bd9Sstevel@tonic-gate } else if (info[i]->mapping[1] == NULL) { 13487c478bd9Sstevel@tonic-gate info[i]->to_name = info[i]->mapping[0]; 13497c478bd9Sstevel@tonic-gate at_least_one = TRUE; 13507c478bd9Sstevel@tonic-gate } else { 13517c478bd9Sstevel@tonic-gate __s_api_free2dArray(info[i]->mapping); 13527c478bd9Sstevel@tonic-gate /* 13537c478bd9Sstevel@tonic-gate * multiple mapping 13547c478bd9Sstevel@tonic-gate * not allowed 13557c478bd9Sstevel@tonic-gate */ 13567c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 13577c478bd9Sstevel@tonic-gate gettext( 13587c478bd9Sstevel@tonic-gate "Multiple attribute or objectclass " 13597c478bd9Sstevel@tonic-gate "mapping for '%s' in filter " 13607c478bd9Sstevel@tonic-gate "'%s' not allowed."), 13617c478bd9Sstevel@tonic-gate info[i]->from_name, filter); 13627c478bd9Sstevel@tonic-gate err = strdup(errstr); 13637c478bd9Sstevel@tonic-gate if (err) 13647c478bd9Sstevel@tonic-gate MKERROR(LOG_WARNING, cookie->errorp, 13657c478bd9Sstevel@tonic-gate NS_CONFIG_SYNTAX, 13667c478bd9Sstevel@tonic-gate err, NULL); 13677c478bd9Sstevel@tonic-gate 13687c478bd9Sstevel@tonic-gate free(filter_c); 13697c478bd9Sstevel@tonic-gate for (j = 0; j < num_veq; j++) { 13707c478bd9Sstevel@tonic-gate if (info[j]->mapping) 13717c478bd9Sstevel@tonic-gate __s_api_free2dArray( 13727c478bd9Sstevel@tonic-gate info[j]->mapping); 13737c478bd9Sstevel@tonic-gate free(info[j]); 13747c478bd9Sstevel@tonic-gate } 13757c478bd9Sstevel@tonic-gate free(info); 13767c478bd9Sstevel@tonic-gate return (NS_LDAP_CONFIG); 13777c478bd9Sstevel@tonic-gate } 13787c478bd9Sstevel@tonic-gate } 13797c478bd9Sstevel@tonic-gate 13807c478bd9Sstevel@tonic-gate 13817c478bd9Sstevel@tonic-gate if (at_least_one) { 13827c478bd9Sstevel@tonic-gate 13837c478bd9Sstevel@tonic-gate len = strlen(filter); 13847c478bd9Sstevel@tonic-gate last_copied = filter - 1; 13857c478bd9Sstevel@tonic-gate 13867c478bd9Sstevel@tonic-gate for (i = 0; i < num_veq; i++) { 13877c478bd9Sstevel@tonic-gate if (info[i]->to_name) 13887c478bd9Sstevel@tonic-gate len += strlen(info[i]->to_name); 13897c478bd9Sstevel@tonic-gate } 13907c478bd9Sstevel@tonic-gate 13917c478bd9Sstevel@tonic-gate *new_filter = (char *)calloc(1, len); 13927c478bd9Sstevel@tonic-gate if (*new_filter == NULL) { 13937c478bd9Sstevel@tonic-gate free(filter_c); 13947c478bd9Sstevel@tonic-gate for (j = 0; j < num_veq; j++) { 13957c478bd9Sstevel@tonic-gate if (info[j]->mapping) 13967c478bd9Sstevel@tonic-gate __s_api_free2dArray( 13977c478bd9Sstevel@tonic-gate info[j]->mapping); 13987c478bd9Sstevel@tonic-gate free(info[j]); 13997c478bd9Sstevel@tonic-gate } 14007c478bd9Sstevel@tonic-gate free(info); 14017c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 14027c478bd9Sstevel@tonic-gate } 14037c478bd9Sstevel@tonic-gate 14047c478bd9Sstevel@tonic-gate for (i = 0; i < num_veq; i++) { 14057c478bd9Sstevel@tonic-gate if (info[i]->to_name != NULL && 14067c478bd9Sstevel@tonic-gate info[i]->to_name != NULL) { 14077c478bd9Sstevel@tonic-gate 14087c478bd9Sstevel@tonic-gate /* 14097c478bd9Sstevel@tonic-gate * copy the original filter data 14107c478bd9Sstevel@tonic-gate * between the last name and current 14117c478bd9Sstevel@tonic-gate * name 14127c478bd9Sstevel@tonic-gate */ 14137c478bd9Sstevel@tonic-gate if ((last_copied + 1) != info[i]->name_start) 1414699bceb8Smj162486 (void) strncat(*new_filter, 1415699bceb8Smj162486 last_copied + 1, 14167c478bd9Sstevel@tonic-gate info[i]->name_start - 14177c478bd9Sstevel@tonic-gate last_copied - 1); 14187c478bd9Sstevel@tonic-gate 14197c478bd9Sstevel@tonic-gate /* the data is copied */ 14207c478bd9Sstevel@tonic-gate last_copied = info[i]->name_end; 14217c478bd9Sstevel@tonic-gate 14227c478bd9Sstevel@tonic-gate /* 14237c478bd9Sstevel@tonic-gate * replace the name with 14247c478bd9Sstevel@tonic-gate * the mapped name 14257c478bd9Sstevel@tonic-gate */ 14267c478bd9Sstevel@tonic-gate (void) strcat(*new_filter, info[i]->to_name); 14277c478bd9Sstevel@tonic-gate } 14287c478bd9Sstevel@tonic-gate 14297c478bd9Sstevel@tonic-gate /* copy the filter data after the last name */ 14307c478bd9Sstevel@tonic-gate if (i == (num_veq -1) && 14317c478bd9Sstevel@tonic-gate info[i]->name_end < 14327c478bd9Sstevel@tonic-gate (filter + strlen(filter))) 14337c478bd9Sstevel@tonic-gate (void) strncat(*new_filter, last_copied + 1, 14347c478bd9Sstevel@tonic-gate filter + strlen(filter) - 14357c478bd9Sstevel@tonic-gate last_copied - 1); 14367c478bd9Sstevel@tonic-gate } 14377c478bd9Sstevel@tonic-gate 14387c478bd9Sstevel@tonic-gate } 14397c478bd9Sstevel@tonic-gate 14407c478bd9Sstevel@tonic-gate /* free memory */ 14417c478bd9Sstevel@tonic-gate free(filter_c); 14427c478bd9Sstevel@tonic-gate for (j = 0; j < num_veq; j++) { 14437c478bd9Sstevel@tonic-gate if (info[j]->mapping) 14447c478bd9Sstevel@tonic-gate __s_api_free2dArray(info[j]->mapping); 14457c478bd9Sstevel@tonic-gate free(info[j]); 14467c478bd9Sstevel@tonic-gate } 14477c478bd9Sstevel@tonic-gate free(info); 14487c478bd9Sstevel@tonic-gate 14497c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 14507c478bd9Sstevel@tonic-gate } 14517c478bd9Sstevel@tonic-gate 14527c478bd9Sstevel@tonic-gate static int 14537c478bd9Sstevel@tonic-gate setup_next_search(ns_ldap_cookie_t *cookie) 14547c478bd9Sstevel@tonic-gate { 14557c478bd9Sstevel@tonic-gate ns_ldap_search_desc_t *dptr; 14567c478bd9Sstevel@tonic-gate int scope; 14577c478bd9Sstevel@tonic-gate char *filter, *str; 14587c478bd9Sstevel@tonic-gate int baselen; 14597c478bd9Sstevel@tonic-gate int rc; 14607c478bd9Sstevel@tonic-gate void **param; 14617c478bd9Sstevel@tonic-gate 14627c478bd9Sstevel@tonic-gate dptr = *cookie->sdpos; 14637c478bd9Sstevel@tonic-gate scope = cookie->i_flags & (NS_LDAP_SCOPE_BASE | 14647c478bd9Sstevel@tonic-gate NS_LDAP_SCOPE_ONELEVEL | 14657c478bd9Sstevel@tonic-gate NS_LDAP_SCOPE_SUBTREE); 14667c478bd9Sstevel@tonic-gate if (scope) 14677c478bd9Sstevel@tonic-gate cookie->scope = scope; 14687c478bd9Sstevel@tonic-gate else 14697c478bd9Sstevel@tonic-gate cookie->scope = dptr->scope; 14707c478bd9Sstevel@tonic-gate switch (cookie->scope) { 14717c478bd9Sstevel@tonic-gate case NS_LDAP_SCOPE_BASE: 14727c478bd9Sstevel@tonic-gate cookie->scope = LDAP_SCOPE_BASE; 14737c478bd9Sstevel@tonic-gate break; 14747c478bd9Sstevel@tonic-gate case NS_LDAP_SCOPE_ONELEVEL: 14757c478bd9Sstevel@tonic-gate cookie->scope = LDAP_SCOPE_ONELEVEL; 14767c478bd9Sstevel@tonic-gate break; 14777c478bd9Sstevel@tonic-gate case NS_LDAP_SCOPE_SUBTREE: 14787c478bd9Sstevel@tonic-gate cookie->scope = LDAP_SCOPE_SUBTREE; 14797c478bd9Sstevel@tonic-gate break; 14807c478bd9Sstevel@tonic-gate } 14817c478bd9Sstevel@tonic-gate 14827c478bd9Sstevel@tonic-gate filter = NULL; 14837c478bd9Sstevel@tonic-gate if (cookie->use_filtercb && cookie->init_filter_cb && 14847c478bd9Sstevel@tonic-gate dptr->filter && strlen(dptr->filter) > 0) { 14857c478bd9Sstevel@tonic-gate (*cookie->init_filter_cb)(dptr, &filter, 14867c478bd9Sstevel@tonic-gate cookie->userdata); 14877c478bd9Sstevel@tonic-gate } 14887c478bd9Sstevel@tonic-gate if (filter == NULL) { 14897c478bd9Sstevel@tonic-gate if (cookie->i_filter == NULL) { 14907c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_INVALID_PARAM; 14917c478bd9Sstevel@tonic-gate return (-1); 14927c478bd9Sstevel@tonic-gate } else { 149336cd58d3Srm88369 if (cookie->filter) 149436cd58d3Srm88369 free(cookie->filter); 14957c478bd9Sstevel@tonic-gate cookie->filter = strdup(cookie->i_filter); 14967c478bd9Sstevel@tonic-gate if (cookie->filter == NULL) { 14977c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_MEMORY; 14987c478bd9Sstevel@tonic-gate return (-1); 14997c478bd9Sstevel@tonic-gate } 15007c478bd9Sstevel@tonic-gate } 15017c478bd9Sstevel@tonic-gate } else { 150236cd58d3Srm88369 if (cookie->filter) 150336cd58d3Srm88369 free(cookie->filter); 15047c478bd9Sstevel@tonic-gate cookie->filter = strdup(filter); 15057c478bd9Sstevel@tonic-gate free(filter); 15067c478bd9Sstevel@tonic-gate if (cookie->filter == NULL) { 15077c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_MEMORY; 15087c478bd9Sstevel@tonic-gate return (-1); 15097c478bd9Sstevel@tonic-gate } 15107c478bd9Sstevel@tonic-gate } 15117c478bd9Sstevel@tonic-gate 15127c478bd9Sstevel@tonic-gate /* 15137c478bd9Sstevel@tonic-gate * perform attribute/objectclass mapping on filter 15147c478bd9Sstevel@tonic-gate */ 15157c478bd9Sstevel@tonic-gate filter = NULL; 15167c478bd9Sstevel@tonic-gate 15177c478bd9Sstevel@tonic-gate if (cookie->service) { 15187c478bd9Sstevel@tonic-gate rc = get_mapped_filter(cookie, &filter); 15197c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 15207c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 15217c478bd9Sstevel@tonic-gate return (-1); 15227c478bd9Sstevel@tonic-gate } else { 15237c478bd9Sstevel@tonic-gate /* 15247c478bd9Sstevel@tonic-gate * get_mapped_filter returns 15257c478bd9Sstevel@tonic-gate * NULL filter pointer, if 15267c478bd9Sstevel@tonic-gate * no mapping was done 15277c478bd9Sstevel@tonic-gate */ 15287c478bd9Sstevel@tonic-gate if (filter) { 15297c478bd9Sstevel@tonic-gate free(cookie->filter); 15307c478bd9Sstevel@tonic-gate cookie->filter = filter; 15317c478bd9Sstevel@tonic-gate } 15327c478bd9Sstevel@tonic-gate } 15337c478bd9Sstevel@tonic-gate } 15347c478bd9Sstevel@tonic-gate 15357c478bd9Sstevel@tonic-gate /* 15367c478bd9Sstevel@tonic-gate * validate filter to make sure it's legal 15377c478bd9Sstevel@tonic-gate * [remove redundant ()'s] 15387c478bd9Sstevel@tonic-gate */ 15397c478bd9Sstevel@tonic-gate rc = validate_filter(cookie); 15407c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 15417c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 15427c478bd9Sstevel@tonic-gate return (-1); 15437c478bd9Sstevel@tonic-gate } 15447c478bd9Sstevel@tonic-gate 15457c478bd9Sstevel@tonic-gate baselen = strlen(dptr->basedn); 15467c478bd9Sstevel@tonic-gate if (baselen > 0 && dptr->basedn[baselen-1] == COMMATOK) { 15477c478bd9Sstevel@tonic-gate rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P, 15487c478bd9Sstevel@tonic-gate (void ***)¶m, &cookie->errorp); 15497c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 15507c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 15517c478bd9Sstevel@tonic-gate return (-1); 15527c478bd9Sstevel@tonic-gate } 15537c478bd9Sstevel@tonic-gate str = ((char **)param)[0]; 15547c478bd9Sstevel@tonic-gate baselen += strlen(str)+1; 155536cd58d3Srm88369 if (cookie->basedn) 155636cd58d3Srm88369 free(cookie->basedn); 15577c478bd9Sstevel@tonic-gate cookie->basedn = (char *)malloc(baselen); 15587c478bd9Sstevel@tonic-gate if (cookie->basedn == NULL) { 15597c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_MEMORY; 15607c478bd9Sstevel@tonic-gate return (-1); 15617c478bd9Sstevel@tonic-gate } 15627c478bd9Sstevel@tonic-gate (void) strcpy(cookie->basedn, dptr->basedn); 15637c478bd9Sstevel@tonic-gate (void) strcat(cookie->basedn, str); 15647c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶m); 15657c478bd9Sstevel@tonic-gate } else { 156636cd58d3Srm88369 if (cookie->basedn) 156736cd58d3Srm88369 free(cookie->basedn); 15687c478bd9Sstevel@tonic-gate cookie->basedn = strdup(dptr->basedn); 15697c478bd9Sstevel@tonic-gate } 15707c478bd9Sstevel@tonic-gate return (0); 15717c478bd9Sstevel@tonic-gate } 15727c478bd9Sstevel@tonic-gate 15737c478bd9Sstevel@tonic-gate static int 15747c478bd9Sstevel@tonic-gate setup_referral_search(ns_ldap_cookie_t *cookie) 15757c478bd9Sstevel@tonic-gate { 15767c478bd9Sstevel@tonic-gate ns_referral_info_t *ref; 15777c478bd9Sstevel@tonic-gate 15787c478bd9Sstevel@tonic-gate ref = cookie->refpos; 15797c478bd9Sstevel@tonic-gate cookie->scope = ref->refScope; 15807c478bd9Sstevel@tonic-gate if (cookie->filter) { 15817c478bd9Sstevel@tonic-gate free(cookie->filter); 15827c478bd9Sstevel@tonic-gate } 15837c478bd9Sstevel@tonic-gate cookie->filter = strdup(ref->refFilter); 15847c478bd9Sstevel@tonic-gate if (cookie->basedn) { 15857c478bd9Sstevel@tonic-gate free(cookie->basedn); 15867c478bd9Sstevel@tonic-gate } 15877c478bd9Sstevel@tonic-gate cookie->basedn = strdup(ref->refDN); 15887c478bd9Sstevel@tonic-gate if (cookie->filter == NULL || cookie->basedn == NULL) { 15897c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_MEMORY; 15907c478bd9Sstevel@tonic-gate return (-1); 15917c478bd9Sstevel@tonic-gate } 15927c478bd9Sstevel@tonic-gate return (0); 15937c478bd9Sstevel@tonic-gate } 15947c478bd9Sstevel@tonic-gate 15957c478bd9Sstevel@tonic-gate static int 15967c478bd9Sstevel@tonic-gate get_current_session(ns_ldap_cookie_t *cookie) 15977c478bd9Sstevel@tonic-gate { 15987c478bd9Sstevel@tonic-gate ConnectionID connectionId = -1; 15997c478bd9Sstevel@tonic-gate Connection *conp = NULL; 16007c478bd9Sstevel@tonic-gate int rc; 16017c478bd9Sstevel@tonic-gate int fail_if_new_pwd_reqd = 1; 16027c478bd9Sstevel@tonic-gate 16037c478bd9Sstevel@tonic-gate rc = __s_api_getConnection(NULL, cookie->i_flags, 16047c478bd9Sstevel@tonic-gate cookie->i_auth, &connectionId, &conp, 160547789246Svv149972 &cookie->errorp, fail_if_new_pwd_reqd, 1606e1dd0a2fSth160488 cookie->nopasswd_acct_mgmt, cookie->conn_user); 16077c478bd9Sstevel@tonic-gate 16087c478bd9Sstevel@tonic-gate /* 16097c478bd9Sstevel@tonic-gate * If password control attached in *cookie->errorp, 16107c478bd9Sstevel@tonic-gate * e.g. rc == NS_LDAP_SUCCESS_WITH_INFO, 16117c478bd9Sstevel@tonic-gate * free the error structure (we do not need 16127c478bd9Sstevel@tonic-gate * the sec_to_expired info). 16137c478bd9Sstevel@tonic-gate * Reset rc to NS_LDAP_SUCCESS. 16147c478bd9Sstevel@tonic-gate */ 16157c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS_WITH_INFO) { 16167c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError( 16177c478bd9Sstevel@tonic-gate &cookie->errorp); 16187c478bd9Sstevel@tonic-gate cookie->errorp = NULL; 16197c478bd9Sstevel@tonic-gate rc = NS_LDAP_SUCCESS; 16207c478bd9Sstevel@tonic-gate } 16217c478bd9Sstevel@tonic-gate 16227c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 16237c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 16247c478bd9Sstevel@tonic-gate return (-1); 16257c478bd9Sstevel@tonic-gate } 16267c478bd9Sstevel@tonic-gate cookie->conn = conp; 16277c478bd9Sstevel@tonic-gate cookie->connectionId = connectionId; 16287c478bd9Sstevel@tonic-gate 16297c478bd9Sstevel@tonic-gate return (0); 16307c478bd9Sstevel@tonic-gate } 16317c478bd9Sstevel@tonic-gate 16327c478bd9Sstevel@tonic-gate static int 16337c478bd9Sstevel@tonic-gate get_next_session(ns_ldap_cookie_t *cookie) 16347c478bd9Sstevel@tonic-gate { 16357c478bd9Sstevel@tonic-gate ConnectionID connectionId = -1; 16367c478bd9Sstevel@tonic-gate Connection *conp = NULL; 16377c478bd9Sstevel@tonic-gate int rc; 16387c478bd9Sstevel@tonic-gate int fail_if_new_pwd_reqd = 1; 16397c478bd9Sstevel@tonic-gate 16403d047983Smichen if (cookie->connectionId > -1) { 16417c478bd9Sstevel@tonic-gate DropConnection(cookie->connectionId, cookie->i_flags); 16423d047983Smichen cookie->connectionId = -1; 16433d047983Smichen } 16447c478bd9Sstevel@tonic-gate 1645e1dd0a2fSth160488 /* If using a MT connection, return it. */ 1646e1dd0a2fSth160488 if (cookie->conn_user != NULL && 1647e1dd0a2fSth160488 cookie->conn_user->conn_mt != NULL) 1648e1dd0a2fSth160488 __s_api_conn_mt_return(cookie->conn_user); 1649e1dd0a2fSth160488 16507c478bd9Sstevel@tonic-gate rc = __s_api_getConnection(NULL, cookie->i_flags, 16517c478bd9Sstevel@tonic-gate cookie->i_auth, &connectionId, &conp, 165247789246Svv149972 &cookie->errorp, fail_if_new_pwd_reqd, 1653e1dd0a2fSth160488 cookie->nopasswd_acct_mgmt, cookie->conn_user); 16547c478bd9Sstevel@tonic-gate 16557c478bd9Sstevel@tonic-gate /* 16567c478bd9Sstevel@tonic-gate * If password control attached in *cookie->errorp, 16577c478bd9Sstevel@tonic-gate * e.g. rc == NS_LDAP_SUCCESS_WITH_INFO, 16587c478bd9Sstevel@tonic-gate * free the error structure (we do not need 16597c478bd9Sstevel@tonic-gate * the sec_to_expired info). 16607c478bd9Sstevel@tonic-gate * Reset rc to NS_LDAP_SUCCESS. 16617c478bd9Sstevel@tonic-gate */ 16627c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS_WITH_INFO) { 16637c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError( 16647c478bd9Sstevel@tonic-gate &cookie->errorp); 16657c478bd9Sstevel@tonic-gate cookie->errorp = NULL; 16667c478bd9Sstevel@tonic-gate rc = NS_LDAP_SUCCESS; 16677c478bd9Sstevel@tonic-gate } 16687c478bd9Sstevel@tonic-gate 16697c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 16707c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 16717c478bd9Sstevel@tonic-gate return (-1); 16727c478bd9Sstevel@tonic-gate } 16737c478bd9Sstevel@tonic-gate cookie->conn = conp; 16747c478bd9Sstevel@tonic-gate cookie->connectionId = connectionId; 16757c478bd9Sstevel@tonic-gate return (0); 16767c478bd9Sstevel@tonic-gate } 16777c478bd9Sstevel@tonic-gate 16787c478bd9Sstevel@tonic-gate static int 16797c478bd9Sstevel@tonic-gate get_referral_session(ns_ldap_cookie_t *cookie) 16807c478bd9Sstevel@tonic-gate { 16817c478bd9Sstevel@tonic-gate ConnectionID connectionId = -1; 16827c478bd9Sstevel@tonic-gate Connection *conp = NULL; 16837c478bd9Sstevel@tonic-gate int rc; 16847c478bd9Sstevel@tonic-gate int fail_if_new_pwd_reqd = 1; 16857c478bd9Sstevel@tonic-gate 16863d047983Smichen if (cookie->connectionId > -1) { 16877c478bd9Sstevel@tonic-gate DropConnection(cookie->connectionId, cookie->i_flags); 16883d047983Smichen cookie->connectionId = -1; 16893d047983Smichen } 16907c478bd9Sstevel@tonic-gate 1691e1dd0a2fSth160488 /* set it up to use a connection opened for referral */ 1692e1dd0a2fSth160488 if (cookie->conn_user != NULL) { 1693e1dd0a2fSth160488 /* If using a MT connection, return it. */ 1694e1dd0a2fSth160488 if (cookie->conn_user->conn_mt != NULL) 1695e1dd0a2fSth160488 __s_api_conn_mt_return(cookie->conn_user); 1696e1dd0a2fSth160488 cookie->conn_user->referral = B_TRUE; 1697e1dd0a2fSth160488 } 1698e1dd0a2fSth160488 16997c478bd9Sstevel@tonic-gate rc = __s_api_getConnection(cookie->refpos->refHost, 0, 17007c478bd9Sstevel@tonic-gate cookie->i_auth, &connectionId, &conp, 170147789246Svv149972 &cookie->errorp, fail_if_new_pwd_reqd, 1702e1dd0a2fSth160488 cookie->nopasswd_acct_mgmt, cookie->conn_user); 17037c478bd9Sstevel@tonic-gate 17047c478bd9Sstevel@tonic-gate /* 17057c478bd9Sstevel@tonic-gate * If password control attached in *cookie->errorp, 17067c478bd9Sstevel@tonic-gate * e.g. rc == NS_LDAP_SUCCESS_WITH_INFO, 17077c478bd9Sstevel@tonic-gate * free the error structure (we do not need 17087c478bd9Sstevel@tonic-gate * the sec_to_expired info). 17097c478bd9Sstevel@tonic-gate * Reset rc to NS_LDAP_SUCCESS. 17107c478bd9Sstevel@tonic-gate */ 17117c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS_WITH_INFO) { 17127c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError( 17137c478bd9Sstevel@tonic-gate &cookie->errorp); 17147c478bd9Sstevel@tonic-gate cookie->errorp = NULL; 17157c478bd9Sstevel@tonic-gate rc = NS_LDAP_SUCCESS; 17167c478bd9Sstevel@tonic-gate } 17177c478bd9Sstevel@tonic-gate 17187c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 17197c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 17207c478bd9Sstevel@tonic-gate return (-1); 17217c478bd9Sstevel@tonic-gate } 17227c478bd9Sstevel@tonic-gate cookie->conn = conp; 17237c478bd9Sstevel@tonic-gate cookie->connectionId = connectionId; 17247c478bd9Sstevel@tonic-gate return (0); 17257c478bd9Sstevel@tonic-gate } 17267c478bd9Sstevel@tonic-gate 17277c478bd9Sstevel@tonic-gate static int 17287c478bd9Sstevel@tonic-gate paging_supported(ns_ldap_cookie_t *cookie) 17297c478bd9Sstevel@tonic-gate { 17307c478bd9Sstevel@tonic-gate int rc; 17317c478bd9Sstevel@tonic-gate 17327c478bd9Sstevel@tonic-gate cookie->listType = 0; 17337c478bd9Sstevel@tonic-gate rc = __s_api_isCtrlSupported(cookie->conn, 17347c478bd9Sstevel@tonic-gate LDAP_CONTROL_VLVREQUEST); 17357c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS) { 17367c478bd9Sstevel@tonic-gate cookie->listType = VLVCTRLFLAG; 17377c478bd9Sstevel@tonic-gate return (1); 17387c478bd9Sstevel@tonic-gate } 17397c478bd9Sstevel@tonic-gate rc = __s_api_isCtrlSupported(cookie->conn, 17407c478bd9Sstevel@tonic-gate LDAP_CONTROL_SIMPLE_PAGE); 17417c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS) { 17427c478bd9Sstevel@tonic-gate cookie->listType = SIMPLEPAGECTRLFLAG; 17437c478bd9Sstevel@tonic-gate return (1); 17447c478bd9Sstevel@tonic-gate } 17457c478bd9Sstevel@tonic-gate return (0); 17467c478bd9Sstevel@tonic-gate } 17477c478bd9Sstevel@tonic-gate 1748*9f2fd570SJulian Pullen typedef struct servicesorttype { 1749*9f2fd570SJulian Pullen char *service; 1750*9f2fd570SJulian Pullen ns_srvsidesort_t type; 1751*9f2fd570SJulian Pullen } servicesorttype_t; 1752*9f2fd570SJulian Pullen 1753*9f2fd570SJulian Pullen static servicesorttype_t *sort_type = NULL; 1754*9f2fd570SJulian Pullen static int sort_type_size = 0; 1755*9f2fd570SJulian Pullen static int sort_type_hwm = 0; 1756*9f2fd570SJulian Pullen static mutex_t sort_type_mutex = DEFAULTMUTEX; 1757*9f2fd570SJulian Pullen 1758*9f2fd570SJulian Pullen 1759*9f2fd570SJulian Pullen static ns_srvsidesort_t 1760*9f2fd570SJulian Pullen get_srvsidesort_type(char *service) 1761*9f2fd570SJulian Pullen { 1762*9f2fd570SJulian Pullen int i; 1763*9f2fd570SJulian Pullen ns_srvsidesort_t type = SSS_UNKNOWN; 1764*9f2fd570SJulian Pullen 1765*9f2fd570SJulian Pullen if (service == NULL) 1766*9f2fd570SJulian Pullen return (type); 1767*9f2fd570SJulian Pullen 1768*9f2fd570SJulian Pullen (void) mutex_lock(&sort_type_mutex); 1769*9f2fd570SJulian Pullen if (sort_type != NULL) { 1770*9f2fd570SJulian Pullen for (i = 0; i < sort_type_hwm; i++) { 1771*9f2fd570SJulian Pullen if (strcmp(sort_type[i].service, service) == 0) { 1772*9f2fd570SJulian Pullen type = sort_type[i].type; 1773*9f2fd570SJulian Pullen break; 1774*9f2fd570SJulian Pullen } 1775*9f2fd570SJulian Pullen } 1776*9f2fd570SJulian Pullen } 1777*9f2fd570SJulian Pullen (void) mutex_unlock(&sort_type_mutex); 1778*9f2fd570SJulian Pullen return (type); 1779*9f2fd570SJulian Pullen } 1780*9f2fd570SJulian Pullen 1781*9f2fd570SJulian Pullen static void 1782*9f2fd570SJulian Pullen update_srvsidesort_type(char *service, ns_srvsidesort_t type) 1783*9f2fd570SJulian Pullen { 1784*9f2fd570SJulian Pullen int i, size; 1785*9f2fd570SJulian Pullen servicesorttype_t *tmp; 1786*9f2fd570SJulian Pullen 1787*9f2fd570SJulian Pullen if (service == NULL) 1788*9f2fd570SJulian Pullen return; 1789*9f2fd570SJulian Pullen 1790*9f2fd570SJulian Pullen (void) mutex_lock(&sort_type_mutex); 1791*9f2fd570SJulian Pullen 1792*9f2fd570SJulian Pullen for (i = 0; i < sort_type_hwm; i++) { 1793*9f2fd570SJulian Pullen if (strcmp(sort_type[i].service, service) == 0) { 1794*9f2fd570SJulian Pullen sort_type[i].type = type; 1795*9f2fd570SJulian Pullen (void) mutex_unlock(&sort_type_mutex); 1796*9f2fd570SJulian Pullen return; 1797*9f2fd570SJulian Pullen } 1798*9f2fd570SJulian Pullen } 1799*9f2fd570SJulian Pullen if (sort_type == NULL) { 1800*9f2fd570SJulian Pullen size = 10; 1801*9f2fd570SJulian Pullen tmp = malloc(size * sizeof (servicesorttype_t)); 1802*9f2fd570SJulian Pullen if (tmp == NULL) { 1803*9f2fd570SJulian Pullen (void) mutex_unlock(&sort_type_mutex); 1804*9f2fd570SJulian Pullen return; 1805*9f2fd570SJulian Pullen } 1806*9f2fd570SJulian Pullen sort_type = tmp; 1807*9f2fd570SJulian Pullen sort_type_size = size; 1808*9f2fd570SJulian Pullen } else if (sort_type_hwm >= sort_type_size) { 1809*9f2fd570SJulian Pullen size = sort_type_size + 10; 1810*9f2fd570SJulian Pullen tmp = realloc(sort_type, size * sizeof (servicesorttype_t)); 1811*9f2fd570SJulian Pullen if (tmp == NULL) { 1812*9f2fd570SJulian Pullen (void) mutex_unlock(&sort_type_mutex); 1813*9f2fd570SJulian Pullen return; 1814*9f2fd570SJulian Pullen } 1815*9f2fd570SJulian Pullen sort_type = tmp; 1816*9f2fd570SJulian Pullen sort_type_size = size; 1817*9f2fd570SJulian Pullen } 1818*9f2fd570SJulian Pullen sort_type[sort_type_hwm].service = strdup(service); 1819*9f2fd570SJulian Pullen if (sort_type[sort_type_hwm].service == NULL) { 1820*9f2fd570SJulian Pullen (void) mutex_unlock(&sort_type_mutex); 1821*9f2fd570SJulian Pullen return; 1822*9f2fd570SJulian Pullen } 1823*9f2fd570SJulian Pullen sort_type[sort_type_hwm].type = type; 1824*9f2fd570SJulian Pullen sort_type_hwm++; 1825*9f2fd570SJulian Pullen 1826*9f2fd570SJulian Pullen (void) mutex_unlock(&sort_type_mutex); 1827*9f2fd570SJulian Pullen } 1828*9f2fd570SJulian Pullen 18297c478bd9Sstevel@tonic-gate static int 18307c478bd9Sstevel@tonic-gate setup_vlv_params(ns_ldap_cookie_t *cookie) 18317c478bd9Sstevel@tonic-gate { 18327c478bd9Sstevel@tonic-gate LDAPControl **ctrls; 18337c478bd9Sstevel@tonic-gate LDAPsortkey **sortkeylist; 18347c478bd9Sstevel@tonic-gate LDAPControl *sortctrl = NULL; 18357c478bd9Sstevel@tonic-gate LDAPControl *vlvctrl = NULL; 18367c478bd9Sstevel@tonic-gate LDAPVirtualList vlist; 1837*9f2fd570SJulian Pullen char *sortattr; 18387c478bd9Sstevel@tonic-gate int rc; 1839*9f2fd570SJulian Pullen int free_sort = FALSE; 18407c478bd9Sstevel@tonic-gate 18417c478bd9Sstevel@tonic-gate _freeControlList(&cookie->p_serverctrls); 18427c478bd9Sstevel@tonic-gate 1843*9f2fd570SJulian Pullen if (cookie->sortTypeTry == SSS_UNKNOWN) 1844*9f2fd570SJulian Pullen cookie->sortTypeTry = get_srvsidesort_type(cookie->service); 1845*9f2fd570SJulian Pullen if (cookie->sortTypeTry == SSS_UNKNOWN) 1846*9f2fd570SJulian Pullen cookie->sortTypeTry = SSS_SINGLE_ATTR; 1847*9f2fd570SJulian Pullen 1848*9f2fd570SJulian Pullen if (cookie->sortTypeTry == SSS_SINGLE_ATTR) { 1849*9f2fd570SJulian Pullen if ((cookie->i_flags & NS_LDAP_NOMAP) == 0 && 1850*9f2fd570SJulian Pullen cookie->i_sortattr) { 1851*9f2fd570SJulian Pullen sortattr = __ns_ldap_mapAttribute(cookie->service, 1852*9f2fd570SJulian Pullen cookie->i_sortattr); 1853*9f2fd570SJulian Pullen free_sort = TRUE; 1854*9f2fd570SJulian Pullen } else if (cookie->i_sortattr) { 1855*9f2fd570SJulian Pullen sortattr = (char *)cookie->i_sortattr; 1856*9f2fd570SJulian Pullen } else { 1857*9f2fd570SJulian Pullen sortattr = "cn"; 1858*9f2fd570SJulian Pullen } 1859*9f2fd570SJulian Pullen } else { 1860*9f2fd570SJulian Pullen sortattr = "cn uid"; 1861*9f2fd570SJulian Pullen } 1862*9f2fd570SJulian Pullen 1863*9f2fd570SJulian Pullen rc = ldap_create_sort_keylist(&sortkeylist, sortattr); 1864*9f2fd570SJulian Pullen if (free_sort) 1865*9f2fd570SJulian Pullen free(sortattr); 18667c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 18677c478bd9Sstevel@tonic-gate (void) ldap_get_option(cookie->conn->ld, 18687c478bd9Sstevel@tonic-gate LDAP_OPT_ERROR_NUMBER, &rc); 18697c478bd9Sstevel@tonic-gate return (rc); 18707c478bd9Sstevel@tonic-gate } 18717c478bd9Sstevel@tonic-gate rc = ldap_create_sort_control(cookie->conn->ld, 18727c478bd9Sstevel@tonic-gate sortkeylist, 1, &sortctrl); 18737c478bd9Sstevel@tonic-gate ldap_free_sort_keylist(sortkeylist); 18747c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 18757c478bd9Sstevel@tonic-gate (void) ldap_get_option(cookie->conn->ld, 18767c478bd9Sstevel@tonic-gate LDAP_OPT_ERROR_NUMBER, &rc); 18777c478bd9Sstevel@tonic-gate return (rc); 18787c478bd9Sstevel@tonic-gate } 18797c478bd9Sstevel@tonic-gate 18807c478bd9Sstevel@tonic-gate vlist.ldvlist_index = cookie->index; 18817c478bd9Sstevel@tonic-gate vlist.ldvlist_size = 0; 18827c478bd9Sstevel@tonic-gate 18837c478bd9Sstevel@tonic-gate vlist.ldvlist_before_count = 0; 18847c478bd9Sstevel@tonic-gate vlist.ldvlist_after_count = LISTPAGESIZE-1; 18857c478bd9Sstevel@tonic-gate vlist.ldvlist_attrvalue = NULL; 18867c478bd9Sstevel@tonic-gate vlist.ldvlist_extradata = NULL; 18877c478bd9Sstevel@tonic-gate 18887c478bd9Sstevel@tonic-gate rc = ldap_create_virtuallist_control(cookie->conn->ld, 18897c478bd9Sstevel@tonic-gate &vlist, &vlvctrl); 18907c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 18917c478bd9Sstevel@tonic-gate ldap_control_free(sortctrl); 18927c478bd9Sstevel@tonic-gate (void) ldap_get_option(cookie->conn->ld, LDAP_OPT_ERROR_NUMBER, 18937c478bd9Sstevel@tonic-gate &rc); 18947c478bd9Sstevel@tonic-gate return (rc); 18957c478bd9Sstevel@tonic-gate } 18967c478bd9Sstevel@tonic-gate 18977c478bd9Sstevel@tonic-gate ctrls = (LDAPControl **)calloc(3, sizeof (LDAPControl *)); 18987c478bd9Sstevel@tonic-gate if (ctrls == NULL) { 18997c478bd9Sstevel@tonic-gate ldap_control_free(sortctrl); 19007c478bd9Sstevel@tonic-gate ldap_control_free(vlvctrl); 19017c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 19027c478bd9Sstevel@tonic-gate } 19037c478bd9Sstevel@tonic-gate 19047c478bd9Sstevel@tonic-gate ctrls[0] = sortctrl; 19057c478bd9Sstevel@tonic-gate ctrls[1] = vlvctrl; 19067c478bd9Sstevel@tonic-gate 19077c478bd9Sstevel@tonic-gate cookie->p_serverctrls = ctrls; 19087c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 19097c478bd9Sstevel@tonic-gate } 19107c478bd9Sstevel@tonic-gate 19117c478bd9Sstevel@tonic-gate static int 19127c478bd9Sstevel@tonic-gate setup_simplepg_params(ns_ldap_cookie_t *cookie) 19137c478bd9Sstevel@tonic-gate { 19147c478bd9Sstevel@tonic-gate LDAPControl **ctrls; 19157c478bd9Sstevel@tonic-gate LDAPControl *pgctrl = NULL; 19167c478bd9Sstevel@tonic-gate int rc; 19177c478bd9Sstevel@tonic-gate 19187c478bd9Sstevel@tonic-gate _freeControlList(&cookie->p_serverctrls); 19197c478bd9Sstevel@tonic-gate 19207c478bd9Sstevel@tonic-gate rc = ldap_create_page_control(cookie->conn->ld, LISTPAGESIZE, 19217c478bd9Sstevel@tonic-gate cookie->ctrlCookie, (char)0, &pgctrl); 19227c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 19237c478bd9Sstevel@tonic-gate (void) ldap_get_option(cookie->conn->ld, LDAP_OPT_ERROR_NUMBER, 19247c478bd9Sstevel@tonic-gate &rc); 19257c478bd9Sstevel@tonic-gate return (rc); 19267c478bd9Sstevel@tonic-gate } 19277c478bd9Sstevel@tonic-gate 19287c478bd9Sstevel@tonic-gate ctrls = (LDAPControl **)calloc(2, sizeof (LDAPControl *)); 19297c478bd9Sstevel@tonic-gate if (ctrls == NULL) { 19307c478bd9Sstevel@tonic-gate ldap_control_free(pgctrl); 19317c478bd9Sstevel@tonic-gate return (LDAP_NO_MEMORY); 19327c478bd9Sstevel@tonic-gate } 19337c478bd9Sstevel@tonic-gate ctrls[0] = pgctrl; 19347c478bd9Sstevel@tonic-gate cookie->p_serverctrls = ctrls; 19357c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 19367c478bd9Sstevel@tonic-gate } 19377c478bd9Sstevel@tonic-gate 19387c478bd9Sstevel@tonic-gate static void 19397c478bd9Sstevel@tonic-gate proc_result_referrals(ns_ldap_cookie_t *cookie) 19407c478bd9Sstevel@tonic-gate { 19417c478bd9Sstevel@tonic-gate int errCode, i, rc; 19427c478bd9Sstevel@tonic-gate char **referrals = NULL; 19437c478bd9Sstevel@tonic-gate 19447c478bd9Sstevel@tonic-gate /* 19457c478bd9Sstevel@tonic-gate * Only follow one level of referrals, i.e. 19467c478bd9Sstevel@tonic-gate * if already in referral mode, do nothing 19477c478bd9Sstevel@tonic-gate */ 19487c478bd9Sstevel@tonic-gate if (cookie->refpos == NULL) { 19497c478bd9Sstevel@tonic-gate cookie->new_state = END_RESULT; 19507c478bd9Sstevel@tonic-gate rc = ldap_parse_result(cookie->conn->ld, 19517c478bd9Sstevel@tonic-gate cookie->resultMsg, 19527c478bd9Sstevel@tonic-gate &errCode, NULL, 19537c478bd9Sstevel@tonic-gate NULL, &referrals, 19547c478bd9Sstevel@tonic-gate NULL, 0); 19557c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 19567c478bd9Sstevel@tonic-gate (void) ldap_get_option(cookie->conn->ld, 19577c478bd9Sstevel@tonic-gate LDAP_OPT_ERROR_NUMBER, 19587c478bd9Sstevel@tonic-gate &cookie->err_rc); 19597c478bd9Sstevel@tonic-gate cookie->new_state = LDAP_ERROR; 19607c478bd9Sstevel@tonic-gate return; 19617c478bd9Sstevel@tonic-gate } 19627c478bd9Sstevel@tonic-gate if (errCode == LDAP_REFERRAL) { 19637c478bd9Sstevel@tonic-gate for (i = 0; referrals[i] != NULL; 19647c478bd9Sstevel@tonic-gate i++) { 19657c478bd9Sstevel@tonic-gate /* add to referral list */ 19667c478bd9Sstevel@tonic-gate rc = __s_api_addRefInfo( 19677c478bd9Sstevel@tonic-gate &cookie->reflist, 19687c478bd9Sstevel@tonic-gate referrals[i], 19697c478bd9Sstevel@tonic-gate cookie->basedn, 19707c478bd9Sstevel@tonic-gate &cookie->scope, 19717c478bd9Sstevel@tonic-gate cookie->filter, 19727c478bd9Sstevel@tonic-gate cookie->conn->ld); 19737c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 19747c478bd9Sstevel@tonic-gate cookie->new_state = 19757c478bd9Sstevel@tonic-gate ERROR; 19767c478bd9Sstevel@tonic-gate break; 19777c478bd9Sstevel@tonic-gate } 19787c478bd9Sstevel@tonic-gate } 19797c478bd9Sstevel@tonic-gate ldap_value_free(referrals); 19807c478bd9Sstevel@tonic-gate } 19817c478bd9Sstevel@tonic-gate } 19827c478bd9Sstevel@tonic-gate } 19837c478bd9Sstevel@tonic-gate 19847c478bd9Sstevel@tonic-gate static void 19857c478bd9Sstevel@tonic-gate proc_search_references(ns_ldap_cookie_t *cookie) 19867c478bd9Sstevel@tonic-gate { 19877c478bd9Sstevel@tonic-gate char **refurls = NULL; 19887c478bd9Sstevel@tonic-gate int i, rc; 19897c478bd9Sstevel@tonic-gate 19907c478bd9Sstevel@tonic-gate /* 19917c478bd9Sstevel@tonic-gate * Only follow one level of referrals, i.e. 19927c478bd9Sstevel@tonic-gate * if already in referral mode, do nothing 19937c478bd9Sstevel@tonic-gate */ 19947c478bd9Sstevel@tonic-gate if (cookie->refpos == NULL) { 19957c478bd9Sstevel@tonic-gate refurls = ldap_get_reference_urls( 19967c478bd9Sstevel@tonic-gate cookie->conn->ld, 19977c478bd9Sstevel@tonic-gate cookie->resultMsg); 19987c478bd9Sstevel@tonic-gate if (refurls == NULL) { 19997c478bd9Sstevel@tonic-gate (void) ldap_get_option(cookie->conn->ld, 20007c478bd9Sstevel@tonic-gate LDAP_OPT_ERROR_NUMBER, 20017c478bd9Sstevel@tonic-gate &cookie->err_rc); 20027c478bd9Sstevel@tonic-gate cookie->new_state = LDAP_ERROR; 20037c478bd9Sstevel@tonic-gate return; 20047c478bd9Sstevel@tonic-gate } 20057c478bd9Sstevel@tonic-gate for (i = 0; refurls[i] != NULL; i++) { 20067c478bd9Sstevel@tonic-gate /* add to referral list */ 20077c478bd9Sstevel@tonic-gate rc = __s_api_addRefInfo( 20087c478bd9Sstevel@tonic-gate &cookie->reflist, 20097c478bd9Sstevel@tonic-gate refurls[i], 20107c478bd9Sstevel@tonic-gate cookie->basedn, 20117c478bd9Sstevel@tonic-gate &cookie->scope, 20127c478bd9Sstevel@tonic-gate cookie->filter, 20137c478bd9Sstevel@tonic-gate cookie->conn->ld); 20147c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 20157c478bd9Sstevel@tonic-gate cookie->new_state = 20167c478bd9Sstevel@tonic-gate ERROR; 20177c478bd9Sstevel@tonic-gate break; 20187c478bd9Sstevel@tonic-gate } 20197c478bd9Sstevel@tonic-gate } 20207c478bd9Sstevel@tonic-gate /* free allocated storage */ 20217c478bd9Sstevel@tonic-gate for (i = 0; refurls[i] != NULL; i++) 20227c478bd9Sstevel@tonic-gate free(refurls[i]); 20237c478bd9Sstevel@tonic-gate } 20247c478bd9Sstevel@tonic-gate } 20257c478bd9Sstevel@tonic-gate 20267c478bd9Sstevel@tonic-gate static ns_state_t 20277c478bd9Sstevel@tonic-gate multi_result(ns_ldap_cookie_t *cookie) 20287c478bd9Sstevel@tonic-gate { 20297c478bd9Sstevel@tonic-gate char errstr[MAXERROR]; 20307c478bd9Sstevel@tonic-gate char *err; 20317c478bd9Sstevel@tonic-gate ns_ldap_error_t **errorp = NULL; 20327c478bd9Sstevel@tonic-gate LDAPControl **retCtrls = NULL; 20337c478bd9Sstevel@tonic-gate int i, rc; 20347c478bd9Sstevel@tonic-gate int errCode; 20357c478bd9Sstevel@tonic-gate int finished = 0; 20367c478bd9Sstevel@tonic-gate unsigned long target_posp = 0; 20377c478bd9Sstevel@tonic-gate unsigned long list_size = 0; 20387c478bd9Sstevel@tonic-gate unsigned int count = 0; 20397c478bd9Sstevel@tonic-gate char **referrals = NULL; 20407c478bd9Sstevel@tonic-gate 20417c478bd9Sstevel@tonic-gate if (cookie->listType == VLVCTRLFLAG) { 20427c478bd9Sstevel@tonic-gate rc = ldap_parse_result(cookie->conn->ld, cookie->resultMsg, 20437c478bd9Sstevel@tonic-gate &errCode, NULL, NULL, &referrals, &retCtrls, 0); 20447c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 20457c478bd9Sstevel@tonic-gate (void) ldap_get_option(cookie->conn->ld, 20467c478bd9Sstevel@tonic-gate LDAP_OPT_ERROR_NUMBER, 20477c478bd9Sstevel@tonic-gate &cookie->err_rc); 20487c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 20497c478bd9Sstevel@tonic-gate gettext("LDAP ERROR (%d): %s.\n"), 20507c478bd9Sstevel@tonic-gate cookie->err_rc, 20517c478bd9Sstevel@tonic-gate gettext(ldap_err2string(cookie->err_rc))); 20527c478bd9Sstevel@tonic-gate err = strdup(errstr); 20537c478bd9Sstevel@tonic-gate MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, err, 20547c478bd9Sstevel@tonic-gate NULL); 20557c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_INTERNAL; 20567c478bd9Sstevel@tonic-gate cookie->errorp = *errorp; 20577c478bd9Sstevel@tonic-gate return (LDAP_ERROR); 20587c478bd9Sstevel@tonic-gate } 20597c478bd9Sstevel@tonic-gate if (errCode == LDAP_REFERRAL) { 20607c478bd9Sstevel@tonic-gate for (i = 0; referrals[i] != NULL; 20617c478bd9Sstevel@tonic-gate i++) { 20627c478bd9Sstevel@tonic-gate /* add to referral list */ 20637c478bd9Sstevel@tonic-gate rc = __s_api_addRefInfo( 20647c478bd9Sstevel@tonic-gate &cookie->reflist, 20657c478bd9Sstevel@tonic-gate referrals[i], 20667c478bd9Sstevel@tonic-gate cookie->basedn, 20677c478bd9Sstevel@tonic-gate &cookie->scope, 20687c478bd9Sstevel@tonic-gate cookie->filter, 20697c478bd9Sstevel@tonic-gate cookie->conn->ld); 20707c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 20717c478bd9Sstevel@tonic-gate ldap_value_free( 20727c478bd9Sstevel@tonic-gate referrals); 20737c478bd9Sstevel@tonic-gate if (retCtrls) 20747c478bd9Sstevel@tonic-gate ldap_controls_free( 20757c478bd9Sstevel@tonic-gate retCtrls); 20767c478bd9Sstevel@tonic-gate return (ERROR); 20777c478bd9Sstevel@tonic-gate } 20787c478bd9Sstevel@tonic-gate } 20797c478bd9Sstevel@tonic-gate ldap_value_free(referrals); 20807c478bd9Sstevel@tonic-gate if (retCtrls) 20817c478bd9Sstevel@tonic-gate ldap_controls_free(retCtrls); 20827c478bd9Sstevel@tonic-gate return (END_RESULT); 20837c478bd9Sstevel@tonic-gate } 20847c478bd9Sstevel@tonic-gate if (retCtrls) { 20857c478bd9Sstevel@tonic-gate rc = ldap_parse_virtuallist_control( 20867c478bd9Sstevel@tonic-gate cookie->conn->ld, retCtrls, 20877c478bd9Sstevel@tonic-gate &target_posp, &list_size, &errCode); 20887c478bd9Sstevel@tonic-gate if (rc == LDAP_SUCCESS) { 2089*9f2fd570SJulian Pullen /* 2090*9f2fd570SJulian Pullen * AD does not return valid target_posp 2091*9f2fd570SJulian Pullen * and list_size 2092*9f2fd570SJulian Pullen */ 2093*9f2fd570SJulian Pullen if (target_posp != 0 && list_size != 0) { 2094*9f2fd570SJulian Pullen cookie->index = 2095*9f2fd570SJulian Pullen target_posp + LISTPAGESIZE; 2096*9f2fd570SJulian Pullen if (cookie->index > list_size) 20977c478bd9Sstevel@tonic-gate finished = 1; 2098*9f2fd570SJulian Pullen } else { 2099*9f2fd570SJulian Pullen if (cookie->entryCount < LISTPAGESIZE) 2100*9f2fd570SJulian Pullen finished = 1; 2101*9f2fd570SJulian Pullen else 2102*9f2fd570SJulian Pullen cookie->index += 2103*9f2fd570SJulian Pullen cookie->entryCount; 21047c478bd9Sstevel@tonic-gate } 21057c478bd9Sstevel@tonic-gate } 21067c478bd9Sstevel@tonic-gate ldap_controls_free(retCtrls); 21077c478bd9Sstevel@tonic-gate retCtrls = NULL; 21087c478bd9Sstevel@tonic-gate } 21097c478bd9Sstevel@tonic-gate else 21107c478bd9Sstevel@tonic-gate finished = 1; 21117c478bd9Sstevel@tonic-gate } else if (cookie->listType == SIMPLEPAGECTRLFLAG) { 21127c478bd9Sstevel@tonic-gate rc = ldap_parse_result(cookie->conn->ld, cookie->resultMsg, 21137c478bd9Sstevel@tonic-gate &errCode, NULL, NULL, &referrals, &retCtrls, 0); 21147c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 21157c478bd9Sstevel@tonic-gate (void) ldap_get_option(cookie->conn->ld, 21167c478bd9Sstevel@tonic-gate LDAP_OPT_ERROR_NUMBER, 21177c478bd9Sstevel@tonic-gate &cookie->err_rc); 21187c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 21197c478bd9Sstevel@tonic-gate gettext("LDAP ERROR (%d): %s.\n"), 21207c478bd9Sstevel@tonic-gate cookie->err_rc, 21217c478bd9Sstevel@tonic-gate gettext(ldap_err2string(cookie->err_rc))); 21227c478bd9Sstevel@tonic-gate err = strdup(errstr); 21237c478bd9Sstevel@tonic-gate MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, err, 21247c478bd9Sstevel@tonic-gate NULL); 21257c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_INTERNAL; 21267c478bd9Sstevel@tonic-gate cookie->errorp = *errorp; 21277c478bd9Sstevel@tonic-gate return (LDAP_ERROR); 21287c478bd9Sstevel@tonic-gate } 21297c478bd9Sstevel@tonic-gate if (errCode == LDAP_REFERRAL) { 21307c478bd9Sstevel@tonic-gate for (i = 0; referrals[i] != NULL; 21317c478bd9Sstevel@tonic-gate i++) { 21327c478bd9Sstevel@tonic-gate /* add to referral list */ 21337c478bd9Sstevel@tonic-gate rc = __s_api_addRefInfo( 21347c478bd9Sstevel@tonic-gate &cookie->reflist, 21357c478bd9Sstevel@tonic-gate referrals[i], 21367c478bd9Sstevel@tonic-gate cookie->basedn, 21377c478bd9Sstevel@tonic-gate &cookie->scope, 21387c478bd9Sstevel@tonic-gate cookie->filter, 21397c478bd9Sstevel@tonic-gate cookie->conn->ld); 21407c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 21417c478bd9Sstevel@tonic-gate ldap_value_free( 21427c478bd9Sstevel@tonic-gate referrals); 21437c478bd9Sstevel@tonic-gate if (retCtrls) 21447c478bd9Sstevel@tonic-gate ldap_controls_free( 21457c478bd9Sstevel@tonic-gate retCtrls); 21467c478bd9Sstevel@tonic-gate return (ERROR); 21477c478bd9Sstevel@tonic-gate } 21487c478bd9Sstevel@tonic-gate } 21497c478bd9Sstevel@tonic-gate ldap_value_free(referrals); 21507c478bd9Sstevel@tonic-gate if (retCtrls) 21517c478bd9Sstevel@tonic-gate ldap_controls_free(retCtrls); 21527c478bd9Sstevel@tonic-gate return (END_RESULT); 21537c478bd9Sstevel@tonic-gate } 21547c478bd9Sstevel@tonic-gate if (retCtrls) { 21557c478bd9Sstevel@tonic-gate if (cookie->ctrlCookie) 21567c478bd9Sstevel@tonic-gate ber_bvfree(cookie->ctrlCookie); 21577c478bd9Sstevel@tonic-gate cookie->ctrlCookie = NULL; 21587c478bd9Sstevel@tonic-gate rc = ldap_parse_page_control( 21597c478bd9Sstevel@tonic-gate cookie->conn->ld, retCtrls, 21607c478bd9Sstevel@tonic-gate &count, &cookie->ctrlCookie); 21617c478bd9Sstevel@tonic-gate if (rc == LDAP_SUCCESS) { 21627c478bd9Sstevel@tonic-gate if ((cookie->ctrlCookie == NULL) || 21637c478bd9Sstevel@tonic-gate (cookie->ctrlCookie->bv_val == NULL) || 216470a09e7fSav147483 (cookie->ctrlCookie->bv_len == 0)) 21657c478bd9Sstevel@tonic-gate finished = 1; 21667c478bd9Sstevel@tonic-gate } 21677c478bd9Sstevel@tonic-gate ldap_controls_free(retCtrls); 21687c478bd9Sstevel@tonic-gate retCtrls = NULL; 21697c478bd9Sstevel@tonic-gate } 21707c478bd9Sstevel@tonic-gate else 21717c478bd9Sstevel@tonic-gate finished = 1; 21727c478bd9Sstevel@tonic-gate } 21737c478bd9Sstevel@tonic-gate if (!finished && cookie->listType == VLVCTRLFLAG) 21747c478bd9Sstevel@tonic-gate return (NEXT_VLV); 21757c478bd9Sstevel@tonic-gate if (!finished && cookie->listType == SIMPLEPAGECTRLFLAG) 21767c478bd9Sstevel@tonic-gate return (NEXT_PAGE); 21777c478bd9Sstevel@tonic-gate if (finished) 21787c478bd9Sstevel@tonic-gate return (END_RESULT); 21797c478bd9Sstevel@tonic-gate return (ERROR); 21807c478bd9Sstevel@tonic-gate } 21817c478bd9Sstevel@tonic-gate 21827c478bd9Sstevel@tonic-gate /* 2183b5d0e4ebSmj162486 * clear_results(ns_ldap_cookie_t): 2184b5d0e4ebSmj162486 * 2185b5d0e4ebSmj162486 * Attempt to obtain remnants of ldap responses and free them. If remnants are 2186b5d0e4ebSmj162486 * not obtained within a certain time period tell the server we wish to abandon 2187b5d0e4ebSmj162486 * the request. 2188b5d0e4ebSmj162486 * 2189b5d0e4ebSmj162486 * Note that we do not initially tell the server to abandon the request as that 2190b5d0e4ebSmj162486 * can be an expensive operation for the server, while it is cheap for us to 2191b5d0e4ebSmj162486 * just flush the input. 2192b5d0e4ebSmj162486 * 2193b5d0e4ebSmj162486 * If something was to remain in libldap queue as a result of some error then 2194b5d0e4ebSmj162486 * it would be freed later during drop connection call or when no other 2195b5d0e4ebSmj162486 * requests share the connection. 2196b5d0e4ebSmj162486 */ 2197b5d0e4ebSmj162486 static void 2198b5d0e4ebSmj162486 clear_results(ns_ldap_cookie_t *cookie) 2199b5d0e4ebSmj162486 { 2200b5d0e4ebSmj162486 int rc; 2201b5d0e4ebSmj162486 if (cookie->conn != NULL && cookie->conn->ld != NULL && 2202e1dd0a2fSth160488 (cookie->connectionId != -1 || 2203e1dd0a2fSth160488 (cookie->conn_user != NULL && 2204e1dd0a2fSth160488 cookie->conn_user->conn_mt != NULL)) && 2205e1dd0a2fSth160488 cookie->msgId != 0) { 2206b5d0e4ebSmj162486 /* 2207b5d0e4ebSmj162486 * We need to cleanup the rest of response (if there is such) 2208b5d0e4ebSmj162486 * and LDAP abandon is too heavy for LDAP servers, so we will 2209b5d0e4ebSmj162486 * wait for the rest of response till timeout and "process" it. 2210b5d0e4ebSmj162486 */ 2211b5d0e4ebSmj162486 rc = ldap_result(cookie->conn->ld, cookie->msgId, LDAP_MSG_ALL, 2212b5d0e4ebSmj162486 (struct timeval *)&cookie->search_timeout, 2213b5d0e4ebSmj162486 &cookie->resultMsg); 2214*9f2fd570SJulian Pullen if (rc != -1 && rc != 0 && cookie->resultMsg != NULL) { 2215b5d0e4ebSmj162486 (void) ldap_msgfree(cookie->resultMsg); 2216*9f2fd570SJulian Pullen cookie->resultMsg = NULL; 2217*9f2fd570SJulian Pullen } 2218*9f2fd570SJulian Pullen 2219b5d0e4ebSmj162486 /* 2220b5d0e4ebSmj162486 * If there was timeout then we will send ABANDON request to 2221b5d0e4ebSmj162486 * LDAP server to decrease load. 2222b5d0e4ebSmj162486 */ 2223b5d0e4ebSmj162486 if (rc == 0) 2224b5d0e4ebSmj162486 (void) ldap_abandon_ext(cookie->conn->ld, cookie->msgId, 2225b5d0e4ebSmj162486 NULL, NULL); 2226b5d0e4ebSmj162486 /* Disassociate cookie with msgId */ 2227b5d0e4ebSmj162486 cookie->msgId = 0; 2228b5d0e4ebSmj162486 } 2229b5d0e4ebSmj162486 } 2230b5d0e4ebSmj162486 2231b5d0e4ebSmj162486 /* 22327c478bd9Sstevel@tonic-gate * This state machine performs one or more LDAP searches to a given 22337c478bd9Sstevel@tonic-gate * directory server using service search descriptors and schema 22347c478bd9Sstevel@tonic-gate * mapping as appropriate. The approximate pseudocode for 22357c478bd9Sstevel@tonic-gate * this routine is the following: 22367c478bd9Sstevel@tonic-gate * Given the current configuration [set/reset connection etc.] 22377c478bd9Sstevel@tonic-gate * and the current service search descriptor list 22387c478bd9Sstevel@tonic-gate * or default search filter parameters 22397c478bd9Sstevel@tonic-gate * foreach (service search filter) { 22407c478bd9Sstevel@tonic-gate * initialize the filter [via filter_init if appropriate] 22417c478bd9Sstevel@tonic-gate * get a valid session/connection (preferably the current one) 22427c478bd9Sstevel@tonic-gate * Recover if the connection is lost 22437c478bd9Sstevel@tonic-gate * perform the search 22447c478bd9Sstevel@tonic-gate * foreach (result entry) { 22457c478bd9Sstevel@tonic-gate * process result [via callback if appropriate] 22467c478bd9Sstevel@tonic-gate * save result for caller if accepted. 22477c478bd9Sstevel@tonic-gate * exit and return all collected if allResults found; 22487c478bd9Sstevel@tonic-gate * } 22497c478bd9Sstevel@tonic-gate * } 22507c478bd9Sstevel@tonic-gate * return collected results and exit 22517c478bd9Sstevel@tonic-gate */ 22527c478bd9Sstevel@tonic-gate 22537c478bd9Sstevel@tonic-gate static 22547c478bd9Sstevel@tonic-gate ns_state_t 22557c478bd9Sstevel@tonic-gate search_state_machine(ns_ldap_cookie_t *cookie, ns_state_t state, int cycle) 22567c478bd9Sstevel@tonic-gate { 22577c478bd9Sstevel@tonic-gate char errstr[MAXERROR]; 22587c478bd9Sstevel@tonic-gate char *err; 2259e8ac3ceaSsdussud int rc, ret; 2260e1dd0a2fSth160488 int rc_save; 22617c478bd9Sstevel@tonic-gate ns_ldap_entry_t *nextEntry; 22627c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 22637c478bd9Sstevel@tonic-gate ns_ldap_error_t **errorp; 2264479ac375Sdm199847 struct timeval tv; 22657c478bd9Sstevel@tonic-gate 22667c478bd9Sstevel@tonic-gate errorp = &error; 22677c478bd9Sstevel@tonic-gate cookie->state = state; 22688277a58bSchinlong errstr[0] = '\0'; 22697c478bd9Sstevel@tonic-gate 22707c478bd9Sstevel@tonic-gate for (;;) { 22717c478bd9Sstevel@tonic-gate switch (cookie->state) { 2272699bceb8Smj162486 case CLEAR_RESULTS: 2273b5d0e4ebSmj162486 clear_results(cookie); 2274699bceb8Smj162486 cookie->new_state = EXIT; 2275699bceb8Smj162486 break; 227647789246Svv149972 case GET_ACCT_MGMT_INFO: 227747789246Svv149972 /* 227847789246Svv149972 * Set the flag to get ldap account management controls. 227947789246Svv149972 */ 228047789246Svv149972 cookie->nopasswd_acct_mgmt = 1; 228147789246Svv149972 cookie->new_state = INIT; 228247789246Svv149972 break; 22837c478bd9Sstevel@tonic-gate case EXIT: 22847c478bd9Sstevel@tonic-gate /* state engine/connection cleaned up in delete */ 22857c478bd9Sstevel@tonic-gate if (cookie->attribute) { 22867c478bd9Sstevel@tonic-gate __s_api_free2dArray(cookie->attribute); 22877c478bd9Sstevel@tonic-gate cookie->attribute = NULL; 22887c478bd9Sstevel@tonic-gate } 22897c478bd9Sstevel@tonic-gate if (cookie->reflist) { 22907c478bd9Sstevel@tonic-gate __s_api_deleteRefInfo(cookie->reflist); 22917c478bd9Sstevel@tonic-gate cookie->reflist = NULL; 22927c478bd9Sstevel@tonic-gate } 22937c478bd9Sstevel@tonic-gate return (EXIT); 22947c478bd9Sstevel@tonic-gate case INIT: 22957c478bd9Sstevel@tonic-gate cookie->sdpos = NULL; 22967c478bd9Sstevel@tonic-gate cookie->new_state = NEXT_SEARCH_DESCRIPTOR; 22977c478bd9Sstevel@tonic-gate if (cookie->attribute) { 22987c478bd9Sstevel@tonic-gate __s_api_free2dArray(cookie->attribute); 22997c478bd9Sstevel@tonic-gate cookie->attribute = NULL; 23007c478bd9Sstevel@tonic-gate } 23017c478bd9Sstevel@tonic-gate if ((cookie->i_flags & NS_LDAP_NOMAP) == 0 && 23027c478bd9Sstevel@tonic-gate cookie->i_attr) { 23037c478bd9Sstevel@tonic-gate cookie->attribute = 23047c478bd9Sstevel@tonic-gate __ns_ldap_mapAttributeList( 23057c478bd9Sstevel@tonic-gate cookie->service, 23067c478bd9Sstevel@tonic-gate cookie->i_attr); 23077c478bd9Sstevel@tonic-gate } 23087c478bd9Sstevel@tonic-gate break; 2309e1dd0a2fSth160488 case REINIT: 2310e1dd0a2fSth160488 /* Check if we've reached MAX retries. */ 2311e1dd0a2fSth160488 cookie->retries++; 2312e1dd0a2fSth160488 if (cookie->retries > NS_LIST_TRY_MAX - 1) { 2313e1dd0a2fSth160488 cookie->new_state = LDAP_ERROR; 2314e1dd0a2fSth160488 break; 2315e1dd0a2fSth160488 } 2316e1dd0a2fSth160488 2317e1dd0a2fSth160488 /* 2318e1dd0a2fSth160488 * Even if we still have retries left, check 2319e1dd0a2fSth160488 * if retry is possible. 2320e1dd0a2fSth160488 */ 2321e1dd0a2fSth160488 if (cookie->conn_user != NULL) { 2322e1dd0a2fSth160488 int retry; 2323e1dd0a2fSth160488 ns_conn_mgmt_t *cmg; 2324e1dd0a2fSth160488 cmg = cookie->conn_user->conn_mgmt; 2325e1dd0a2fSth160488 retry = cookie->conn_user->retry; 2326e1dd0a2fSth160488 if (cmg != NULL && cmg->cfg_reloaded == 1) 2327e1dd0a2fSth160488 retry = 1; 2328e1dd0a2fSth160488 if (retry == 0) { 2329e1dd0a2fSth160488 cookie->new_state = LDAP_ERROR; 2330e1dd0a2fSth160488 break; 2331e1dd0a2fSth160488 } 2332e1dd0a2fSth160488 } 2333e1dd0a2fSth160488 /* 2334e1dd0a2fSth160488 * Free results if any, reset to the first 2335e1dd0a2fSth160488 * search descriptor and start a new session. 2336e1dd0a2fSth160488 */ 2337e1dd0a2fSth160488 if (cookie->resultMsg != NULL) { 2338e1dd0a2fSth160488 (void) ldap_msgfree(cookie->resultMsg); 2339e1dd0a2fSth160488 cookie->resultMsg = NULL; 2340e1dd0a2fSth160488 } 2341e1dd0a2fSth160488 (void) __ns_ldap_freeError(&cookie->errorp); 2342e1dd0a2fSth160488 (void) __ns_ldap_freeResult(&cookie->result); 2343e1dd0a2fSth160488 cookie->sdpos = cookie->sdlist; 2344e1dd0a2fSth160488 cookie->err_from_result = 0; 2345e1dd0a2fSth160488 cookie->err_rc = 0; 2346e1dd0a2fSth160488 cookie->new_state = NEXT_SESSION; 2347e1dd0a2fSth160488 break; 23487c478bd9Sstevel@tonic-gate case NEXT_SEARCH_DESCRIPTOR: 23497c478bd9Sstevel@tonic-gate /* get next search descriptor */ 23507c478bd9Sstevel@tonic-gate if (cookie->sdpos == NULL) { 23517c478bd9Sstevel@tonic-gate cookie->sdpos = cookie->sdlist; 23527c478bd9Sstevel@tonic-gate cookie->new_state = GET_SESSION; 23537c478bd9Sstevel@tonic-gate } else { 23547c478bd9Sstevel@tonic-gate cookie->sdpos++; 23557c478bd9Sstevel@tonic-gate cookie->new_state = NEXT_SEARCH; 23567c478bd9Sstevel@tonic-gate } 23577c478bd9Sstevel@tonic-gate if (*cookie->sdpos == NULL) 23587c478bd9Sstevel@tonic-gate cookie->new_state = EXIT; 23597c478bd9Sstevel@tonic-gate break; 23607c478bd9Sstevel@tonic-gate case GET_SESSION: 23617c478bd9Sstevel@tonic-gate if (get_current_session(cookie) < 0) 23627c478bd9Sstevel@tonic-gate cookie->new_state = NEXT_SESSION; 23637c478bd9Sstevel@tonic-gate else 23647c478bd9Sstevel@tonic-gate cookie->new_state = NEXT_SEARCH; 23657c478bd9Sstevel@tonic-gate break; 23667c478bd9Sstevel@tonic-gate case NEXT_SESSION: 23677c478bd9Sstevel@tonic-gate if (get_next_session(cookie) < 0) 23687c478bd9Sstevel@tonic-gate cookie->new_state = RESTART_SESSION; 23697c478bd9Sstevel@tonic-gate else 23707c478bd9Sstevel@tonic-gate cookie->new_state = NEXT_SEARCH; 23717c478bd9Sstevel@tonic-gate break; 23727c478bd9Sstevel@tonic-gate case RESTART_SESSION: 23737c478bd9Sstevel@tonic-gate if (cookie->i_flags & NS_LDAP_HARD) { 23747c478bd9Sstevel@tonic-gate cookie->new_state = NEXT_SESSION; 23757c478bd9Sstevel@tonic-gate break; 23767c478bd9Sstevel@tonic-gate } 23777c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 23787c478bd9Sstevel@tonic-gate gettext("Session error no available conn.\n"), 23797c478bd9Sstevel@tonic-gate state); 23807c478bd9Sstevel@tonic-gate err = strdup(errstr); 23817c478bd9Sstevel@tonic-gate MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, err, 23827c478bd9Sstevel@tonic-gate NULL); 23837c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_INTERNAL; 23847c478bd9Sstevel@tonic-gate cookie->errorp = *errorp; 23857c478bd9Sstevel@tonic-gate cookie->new_state = EXIT; 23867c478bd9Sstevel@tonic-gate break; 23877c478bd9Sstevel@tonic-gate case NEXT_SEARCH: 23887c478bd9Sstevel@tonic-gate /* setup referrals search if necessary */ 23897c478bd9Sstevel@tonic-gate if (cookie->refpos) { 23907c478bd9Sstevel@tonic-gate if (setup_referral_search(cookie) < 0) { 23917c478bd9Sstevel@tonic-gate cookie->new_state = EXIT; 23927c478bd9Sstevel@tonic-gate break; 23937c478bd9Sstevel@tonic-gate } 23947c478bd9Sstevel@tonic-gate } else if (setup_next_search(cookie) < 0) { 23957c478bd9Sstevel@tonic-gate cookie->new_state = EXIT; 23967c478bd9Sstevel@tonic-gate break; 23977c478bd9Sstevel@tonic-gate } 23987c478bd9Sstevel@tonic-gate /* only do VLV/PAGE on scopes onelevel/subtree */ 23997c478bd9Sstevel@tonic-gate if (paging_supported(cookie)) { 24007c478bd9Sstevel@tonic-gate if (cookie->use_paging && 24017c478bd9Sstevel@tonic-gate (cookie->scope != LDAP_SCOPE_BASE)) { 24027c478bd9Sstevel@tonic-gate cookie->index = 1; 24037c478bd9Sstevel@tonic-gate if (cookie->listType == VLVCTRLFLAG) 24047c478bd9Sstevel@tonic-gate cookie->new_state = NEXT_VLV; 24057c478bd9Sstevel@tonic-gate else 24067c478bd9Sstevel@tonic-gate cookie->new_state = NEXT_PAGE; 24077c478bd9Sstevel@tonic-gate break; 24087c478bd9Sstevel@tonic-gate } 24097c478bd9Sstevel@tonic-gate } 24107c478bd9Sstevel@tonic-gate cookie->new_state = ONE_SEARCH; 24117c478bd9Sstevel@tonic-gate break; 24127c478bd9Sstevel@tonic-gate case NEXT_VLV: 24137c478bd9Sstevel@tonic-gate rc = setup_vlv_params(cookie); 24147c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 24157c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 24167c478bd9Sstevel@tonic-gate cookie->new_state = LDAP_ERROR; 24177c478bd9Sstevel@tonic-gate break; 24187c478bd9Sstevel@tonic-gate } 24197c478bd9Sstevel@tonic-gate cookie->next_state = MULTI_RESULT; 24207c478bd9Sstevel@tonic-gate cookie->new_state = DO_SEARCH; 24217c478bd9Sstevel@tonic-gate break; 24227c478bd9Sstevel@tonic-gate case NEXT_PAGE: 24237c478bd9Sstevel@tonic-gate rc = setup_simplepg_params(cookie); 24247c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 24257c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 24267c478bd9Sstevel@tonic-gate cookie->new_state = LDAP_ERROR; 24277c478bd9Sstevel@tonic-gate break; 24287c478bd9Sstevel@tonic-gate } 24297c478bd9Sstevel@tonic-gate cookie->next_state = MULTI_RESULT; 24307c478bd9Sstevel@tonic-gate cookie->new_state = DO_SEARCH; 24317c478bd9Sstevel@tonic-gate break; 24327c478bd9Sstevel@tonic-gate case ONE_SEARCH: 24337c478bd9Sstevel@tonic-gate cookie->next_state = NEXT_RESULT; 24347c478bd9Sstevel@tonic-gate cookie->new_state = DO_SEARCH; 24357c478bd9Sstevel@tonic-gate break; 24367c478bd9Sstevel@tonic-gate case DO_SEARCH: 2437*9f2fd570SJulian Pullen cookie->entryCount = 0; 24387c478bd9Sstevel@tonic-gate rc = ldap_search_ext(cookie->conn->ld, 24397c478bd9Sstevel@tonic-gate cookie->basedn, 24407c478bd9Sstevel@tonic-gate cookie->scope, 24417c478bd9Sstevel@tonic-gate cookie->filter, 24427c478bd9Sstevel@tonic-gate cookie->attribute, 24437c478bd9Sstevel@tonic-gate 0, 24447c478bd9Sstevel@tonic-gate cookie->p_serverctrls, 24457c478bd9Sstevel@tonic-gate NULL, 24467c478bd9Sstevel@tonic-gate &cookie->search_timeout, 0, 24477c478bd9Sstevel@tonic-gate &cookie->msgId); 24487c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 24497c478bd9Sstevel@tonic-gate if (rc == LDAP_BUSY || 24507c478bd9Sstevel@tonic-gate rc == LDAP_UNAVAILABLE || 24517c478bd9Sstevel@tonic-gate rc == LDAP_UNWILLING_TO_PERFORM || 24527c478bd9Sstevel@tonic-gate rc == LDAP_CONNECT_ERROR || 24537c478bd9Sstevel@tonic-gate rc == LDAP_SERVER_DOWN) { 24547c478bd9Sstevel@tonic-gate 2455e1dd0a2fSth160488 if (cookie->reinit_on_retriable_err) { 2456e1dd0a2fSth160488 cookie->err_rc = rc; 2457e1dd0a2fSth160488 cookie->new_state = REINIT; 2458e1dd0a2fSth160488 } else 2459e1dd0a2fSth160488 cookie->new_state = 2460e1dd0a2fSth160488 NEXT_SESSION; 24617c478bd9Sstevel@tonic-gate 24627c478bd9Sstevel@tonic-gate /* 24637c478bd9Sstevel@tonic-gate * If not able to reach the 24647c478bd9Sstevel@tonic-gate * server, inform the ldap 24657c478bd9Sstevel@tonic-gate * cache manager that the 24667c478bd9Sstevel@tonic-gate * server should be removed 24677c478bd9Sstevel@tonic-gate * from it's server list. 24687c478bd9Sstevel@tonic-gate * Thus, the manager will not 24697c478bd9Sstevel@tonic-gate * return this server on the next 24707c478bd9Sstevel@tonic-gate * get-server request and will 24717c478bd9Sstevel@tonic-gate * also reduce the server list 24727c478bd9Sstevel@tonic-gate * refresh TTL, so that it will 24737c478bd9Sstevel@tonic-gate * find out sooner when the server 24747c478bd9Sstevel@tonic-gate * is up again. 24757c478bd9Sstevel@tonic-gate */ 2476e1dd0a2fSth160488 if ((rc == LDAP_CONNECT_ERROR || 2477e1dd0a2fSth160488 rc == LDAP_SERVER_DOWN) && 2478e1dd0a2fSth160488 (cookie->conn_user == NULL || 2479e1dd0a2fSth160488 cookie->conn_user->conn_mt == 2480e1dd0a2fSth160488 NULL)) { 2481e8ac3ceaSsdussud ret = __s_api_removeServer( 24827c478bd9Sstevel@tonic-gate cookie->conn->serverAddr); 2483e1dd0a2fSth160488 if (ret == NS_CACHE_NOSERVER && 2484e8ac3ceaSsdussud cookie->conn_auth_type 2485e8ac3ceaSsdussud == NS_LDAP_AUTH_NONE) { 2486e8ac3ceaSsdussud /* 2487e8ac3ceaSsdussud * Couldn't remove 2488e8ac3ceaSsdussud * server from server 2489e8ac3ceaSsdussud * list. 2490e8ac3ceaSsdussud * Exit to avoid 2491e8ac3ceaSsdussud * potential infinite 2492e8ac3ceaSsdussud * loop. 2493e8ac3ceaSsdussud */ 2494e8ac3ceaSsdussud cookie->err_rc = rc; 2495e8ac3ceaSsdussud cookie->new_state = 2496e8ac3ceaSsdussud LDAP_ERROR; 2497e8ac3ceaSsdussud } 24987c478bd9Sstevel@tonic-gate if (cookie->connectionId > -1) { 2499cb5caa98Sdjl /* 2500cb5caa98Sdjl * NS_LDAP_NEW_CONN 2501cb5caa98Sdjl * indicates that the 2502cb5caa98Sdjl * connection should 2503cb5caa98Sdjl * be deleted, not 2504cb5caa98Sdjl * kept alive 2505cb5caa98Sdjl */ 25067c478bd9Sstevel@tonic-gate DropConnection( 2507699bceb8Smj162486 cookie-> 2508699bceb8Smj162486 connectionId, 25097c478bd9Sstevel@tonic-gate NS_LDAP_NEW_CONN); 2510cb5caa98Sdjl cookie->connectionId = 2511cb5caa98Sdjl -1; 25127c478bd9Sstevel@tonic-gate } 2513e1dd0a2fSth160488 } else if ((rc == LDAP_CONNECT_ERROR || 2514e1dd0a2fSth160488 rc == LDAP_SERVER_DOWN) && 2515ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India cookie->conn_user != NULL) { 2516ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India if (cookie-> 2517ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India reinit_on_retriable_err) { 2518e1dd0a2fSth160488 /* 2519ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * MT connection not 2520ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * usable, close it 2521ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * before REINIT. 2522ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * rc has already 2523ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * been saved in 2524ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * cookie->err_rc above. 2525e1dd0a2fSth160488 */ 2526e1dd0a2fSth160488 __s_api_conn_mt_close( 2527e1dd0a2fSth160488 cookie->conn_user, 2528ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India rc, 2529ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India &cookie->errorp); 2530ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India } else { 2531ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India /* 2532ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * MT connection not 2533ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * usable, close it in 2534ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * the LDAP_ERROR state. 2535ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * A retry will be done 2536ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * next if allowed. 2537ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India */ 2538ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India cookie->err_rc = rc; 2539ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India cookie->new_state = 2540ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India LDAP_ERROR; 2541ead6eed0SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India } 25427c478bd9Sstevel@tonic-gate } 25437c478bd9Sstevel@tonic-gate break; 25447c478bd9Sstevel@tonic-gate } 25457c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 25467c478bd9Sstevel@tonic-gate cookie->new_state = LDAP_ERROR; 25477c478bd9Sstevel@tonic-gate break; 25487c478bd9Sstevel@tonic-gate } 25497c478bd9Sstevel@tonic-gate cookie->new_state = cookie->next_state; 25507c478bd9Sstevel@tonic-gate break; 25517c478bd9Sstevel@tonic-gate case NEXT_RESULT: 2552479ac375Sdm199847 /* 2553479ac375Sdm199847 * Caller (e.g. __ns_ldap_list_batch_add) 2554479ac375Sdm199847 * does not want to block on ldap_result(). 2555479ac375Sdm199847 * Therefore we execute ldap_result() with 2556479ac375Sdm199847 * a zeroed timeval. 2557479ac375Sdm199847 */ 2558479ac375Sdm199847 if (cookie->no_wait == B_TRUE) 2559479ac375Sdm199847 (void) memset(&tv, 0, sizeof (tv)); 2560479ac375Sdm199847 else 2561479ac375Sdm199847 tv = cookie->search_timeout; 25627c478bd9Sstevel@tonic-gate rc = ldap_result(cookie->conn->ld, cookie->msgId, 25637c478bd9Sstevel@tonic-gate LDAP_MSG_ONE, 2564479ac375Sdm199847 &tv, 25657c478bd9Sstevel@tonic-gate &cookie->resultMsg); 25667c478bd9Sstevel@tonic-gate if (rc == LDAP_RES_SEARCH_RESULT) { 25677c478bd9Sstevel@tonic-gate cookie->new_state = END_RESULT; 25687c478bd9Sstevel@tonic-gate /* check and process referrals info */ 25697c478bd9Sstevel@tonic-gate if (cookie->followRef) 25707c478bd9Sstevel@tonic-gate proc_result_referrals( 25717c478bd9Sstevel@tonic-gate cookie); 25727c478bd9Sstevel@tonic-gate (void) ldap_msgfree(cookie->resultMsg); 25737c478bd9Sstevel@tonic-gate cookie->resultMsg = NULL; 25747c478bd9Sstevel@tonic-gate break; 25757c478bd9Sstevel@tonic-gate } 25767c478bd9Sstevel@tonic-gate /* handle referrals if necessary */ 25777c478bd9Sstevel@tonic-gate if (rc == LDAP_RES_SEARCH_REFERENCE) { 25787c478bd9Sstevel@tonic-gate if (cookie->followRef) 25797c478bd9Sstevel@tonic-gate proc_search_references(cookie); 25807c478bd9Sstevel@tonic-gate (void) ldap_msgfree(cookie->resultMsg); 25817c478bd9Sstevel@tonic-gate cookie->resultMsg = NULL; 25827c478bd9Sstevel@tonic-gate break; 25837c478bd9Sstevel@tonic-gate } 25847c478bd9Sstevel@tonic-gate if (rc != LDAP_RES_SEARCH_ENTRY) { 25857c478bd9Sstevel@tonic-gate switch (rc) { 25867c478bd9Sstevel@tonic-gate case 0: 2587479ac375Sdm199847 if (cookie->no_wait == B_TRUE) { 2588479ac375Sdm199847 (void) ldap_msgfree( 2589479ac375Sdm199847 cookie->resultMsg); 2590479ac375Sdm199847 cookie->resultMsg = NULL; 2591479ac375Sdm199847 return (cookie->new_state); 2592479ac375Sdm199847 } 25937c478bd9Sstevel@tonic-gate rc = LDAP_TIMEOUT; 25947c478bd9Sstevel@tonic-gate break; 25957c478bd9Sstevel@tonic-gate case -1: 25967c478bd9Sstevel@tonic-gate rc = ldap_get_lderrno(cookie->conn->ld, 25977c478bd9Sstevel@tonic-gate NULL, NULL); 25987c478bd9Sstevel@tonic-gate break; 25997c478bd9Sstevel@tonic-gate default: 26007c478bd9Sstevel@tonic-gate rc = ldap_result2error(cookie->conn->ld, 26017c478bd9Sstevel@tonic-gate cookie->resultMsg, 1); 26027c478bd9Sstevel@tonic-gate break; 26037c478bd9Sstevel@tonic-gate } 2604e1dd0a2fSth160488 if ((rc == LDAP_TIMEOUT || 2605e1dd0a2fSth160488 rc == LDAP_SERVER_DOWN) && 2606e1dd0a2fSth160488 (cookie->conn_user == NULL || 2607e1dd0a2fSth160488 cookie->conn_user->conn_mt == NULL)) { 26088277a58bSchinlong if (rc == LDAP_TIMEOUT) 26098277a58bSchinlong (void) __s_api_removeServer( 26108277a58bSchinlong cookie->conn->serverAddr); 26118277a58bSchinlong if (cookie->connectionId > -1) { 26128277a58bSchinlong DropConnection( 26138277a58bSchinlong cookie->connectionId, 26148277a58bSchinlong NS_LDAP_NEW_CONN); 26158277a58bSchinlong cookie->connectionId = -1; 26168277a58bSchinlong } 26178277a58bSchinlong cookie->err_from_result = 1; 26188277a58bSchinlong } 26197c478bd9Sstevel@tonic-gate (void) ldap_msgfree(cookie->resultMsg); 26207c478bd9Sstevel@tonic-gate cookie->resultMsg = NULL; 26217c478bd9Sstevel@tonic-gate if (rc == LDAP_BUSY || 26227c478bd9Sstevel@tonic-gate rc == LDAP_UNAVAILABLE || 26238277a58bSchinlong rc == LDAP_UNWILLING_TO_PERFORM) { 2624e1dd0a2fSth160488 if (cookie->reinit_on_retriable_err) { 2625e1dd0a2fSth160488 cookie->err_rc = rc; 2626e1dd0a2fSth160488 cookie->err_from_result = 1; 2627e1dd0a2fSth160488 cookie->new_state = REINIT; 2628e1dd0a2fSth160488 } else 2629e1dd0a2fSth160488 cookie->new_state = 2630e1dd0a2fSth160488 NEXT_SESSION; 2631e1dd0a2fSth160488 break; 2632e1dd0a2fSth160488 } 2633e1dd0a2fSth160488 if ((rc == LDAP_CONNECT_ERROR || 2634e1dd0a2fSth160488 rc == LDAP_SERVER_DOWN) && 2635e1dd0a2fSth160488 cookie->reinit_on_retriable_err) { 2636e1dd0a2fSth160488 ns_ldap_error_t *errorp = NULL; 2637e1dd0a2fSth160488 cookie->err_rc = rc; 2638e1dd0a2fSth160488 cookie->err_from_result = 1; 2639e1dd0a2fSth160488 cookie->new_state = REINIT; 2640e1dd0a2fSth160488 if (cookie->conn_user != NULL) 2641e1dd0a2fSth160488 __s_api_conn_mt_close( 2642e1dd0a2fSth160488 cookie->conn_user, 2643e1dd0a2fSth160488 rc, &errorp); 2644e1dd0a2fSth160488 if (errorp != NULL) { 2645e1dd0a2fSth160488 (void) __ns_ldap_freeError( 2646e1dd0a2fSth160488 &cookie->errorp); 2647e1dd0a2fSth160488 cookie->errorp = errorp; 2648e1dd0a2fSth160488 } 26497c478bd9Sstevel@tonic-gate break; 26507c478bd9Sstevel@tonic-gate } 26517c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 26527c478bd9Sstevel@tonic-gate cookie->new_state = LDAP_ERROR; 26537c478bd9Sstevel@tonic-gate break; 26547c478bd9Sstevel@tonic-gate } 26557c478bd9Sstevel@tonic-gate /* else LDAP_RES_SEARCH_ENTRY */ 265647789246Svv149972 /* get account management response control */ 265747789246Svv149972 if (cookie->nopasswd_acct_mgmt == 1) { 265847789246Svv149972 rc = ldap_get_entry_controls(cookie->conn->ld, 265947789246Svv149972 cookie->resultMsg, 266047789246Svv149972 &(cookie->resultctrl)); 266147789246Svv149972 if (rc != LDAP_SUCCESS) { 266247789246Svv149972 cookie->new_state = LDAP_ERROR; 266347789246Svv149972 cookie->err_rc = rc; 266447789246Svv149972 break; 266547789246Svv149972 } 266647789246Svv149972 } 26677c478bd9Sstevel@tonic-gate rc = __s_api_getEntry(cookie); 26687c478bd9Sstevel@tonic-gate (void) ldap_msgfree(cookie->resultMsg); 26697c478bd9Sstevel@tonic-gate cookie->resultMsg = NULL; 26707c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 26717c478bd9Sstevel@tonic-gate cookie->new_state = LDAP_ERROR; 26727c478bd9Sstevel@tonic-gate break; 26737c478bd9Sstevel@tonic-gate } 26747c478bd9Sstevel@tonic-gate cookie->new_state = PROCESS_RESULT; 26757c478bd9Sstevel@tonic-gate cookie->next_state = NEXT_RESULT; 26767c478bd9Sstevel@tonic-gate break; 26777c478bd9Sstevel@tonic-gate case MULTI_RESULT: 2678479ac375Sdm199847 if (cookie->no_wait == B_TRUE) 2679479ac375Sdm199847 (void) memset(&tv, 0, sizeof (tv)); 2680479ac375Sdm199847 else 2681479ac375Sdm199847 tv = cookie->search_timeout; 26827c478bd9Sstevel@tonic-gate rc = ldap_result(cookie->conn->ld, cookie->msgId, 26837c478bd9Sstevel@tonic-gate LDAP_MSG_ONE, 2684479ac375Sdm199847 &tv, 26857c478bd9Sstevel@tonic-gate &cookie->resultMsg); 26867c478bd9Sstevel@tonic-gate if (rc == LDAP_RES_SEARCH_RESULT) { 26877c478bd9Sstevel@tonic-gate rc = ldap_result2error(cookie->conn->ld, 26887c478bd9Sstevel@tonic-gate cookie->resultMsg, 0); 2689*9f2fd570SJulian Pullen if (rc == LDAP_ADMINLIMIT_EXCEEDED && 2690*9f2fd570SJulian Pullen cookie->listType == VLVCTRLFLAG && 2691*9f2fd570SJulian Pullen cookie->sortTypeTry == SSS_SINGLE_ATTR) { 2692*9f2fd570SJulian Pullen /* Try old "cn uid" server side sort */ 2693*9f2fd570SJulian Pullen cookie->sortTypeTry = SSS_CN_UID_ATTRS; 2694*9f2fd570SJulian Pullen cookie->new_state = NEXT_VLV; 2695*9f2fd570SJulian Pullen (void) ldap_msgfree(cookie->resultMsg); 2696*9f2fd570SJulian Pullen cookie->resultMsg = NULL; 2697*9f2fd570SJulian Pullen break; 2698*9f2fd570SJulian Pullen } 26997c478bd9Sstevel@tonic-gate if (rc != LDAP_SUCCESS) { 27007c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 27017c478bd9Sstevel@tonic-gate cookie->new_state = LDAP_ERROR; 27027c478bd9Sstevel@tonic-gate (void) ldap_msgfree(cookie->resultMsg); 2703*9f2fd570SJulian Pullen cookie->resultMsg = NULL; 27047c478bd9Sstevel@tonic-gate break; 27057c478bd9Sstevel@tonic-gate } 27067c478bd9Sstevel@tonic-gate cookie->new_state = multi_result(cookie); 27077c478bd9Sstevel@tonic-gate (void) ldap_msgfree(cookie->resultMsg); 27087c478bd9Sstevel@tonic-gate cookie->resultMsg = NULL; 27097c478bd9Sstevel@tonic-gate break; 27107c478bd9Sstevel@tonic-gate } 27117c478bd9Sstevel@tonic-gate /* handle referrals if necessary */ 27127c478bd9Sstevel@tonic-gate if (rc == LDAP_RES_SEARCH_REFERENCE && 27137c478bd9Sstevel@tonic-gate cookie->followRef) { 27147c478bd9Sstevel@tonic-gate proc_search_references(cookie); 27157c478bd9Sstevel@tonic-gate (void) ldap_msgfree(cookie->resultMsg); 27167c478bd9Sstevel@tonic-gate cookie->resultMsg = NULL; 27177c478bd9Sstevel@tonic-gate break; 27187c478bd9Sstevel@tonic-gate } 27197c478bd9Sstevel@tonic-gate if (rc != LDAP_RES_SEARCH_ENTRY) { 27207c478bd9Sstevel@tonic-gate switch (rc) { 27217c478bd9Sstevel@tonic-gate case 0: 2722479ac375Sdm199847 if (cookie->no_wait == B_TRUE) { 2723479ac375Sdm199847 (void) ldap_msgfree( 2724479ac375Sdm199847 cookie->resultMsg); 2725479ac375Sdm199847 cookie->resultMsg = NULL; 2726479ac375Sdm199847 return (cookie->new_state); 2727479ac375Sdm199847 } 27287c478bd9Sstevel@tonic-gate rc = LDAP_TIMEOUT; 27297c478bd9Sstevel@tonic-gate break; 27307c478bd9Sstevel@tonic-gate case -1: 27317c478bd9Sstevel@tonic-gate rc = ldap_get_lderrno(cookie->conn->ld, 27327c478bd9Sstevel@tonic-gate NULL, NULL); 27337c478bd9Sstevel@tonic-gate break; 27347c478bd9Sstevel@tonic-gate default: 27357c478bd9Sstevel@tonic-gate rc = ldap_result2error(cookie->conn->ld, 27367c478bd9Sstevel@tonic-gate cookie->resultMsg, 1); 27377c478bd9Sstevel@tonic-gate break; 27387c478bd9Sstevel@tonic-gate } 2739e1dd0a2fSth160488 if ((rc == LDAP_TIMEOUT || 2740e1dd0a2fSth160488 rc == LDAP_SERVER_DOWN) && 2741e1dd0a2fSth160488 (cookie->conn_user == NULL || 2742e1dd0a2fSth160488 cookie->conn_user->conn_mt == NULL)) { 27438277a58bSchinlong if (rc == LDAP_TIMEOUT) 27448277a58bSchinlong (void) __s_api_removeServer( 27458277a58bSchinlong cookie->conn->serverAddr); 27468277a58bSchinlong if (cookie->connectionId > -1) { 27478277a58bSchinlong DropConnection( 27488277a58bSchinlong cookie->connectionId, 27498277a58bSchinlong NS_LDAP_NEW_CONN); 27508277a58bSchinlong cookie->connectionId = -1; 27518277a58bSchinlong } 27528277a58bSchinlong cookie->err_from_result = 1; 27538277a58bSchinlong } 27547c478bd9Sstevel@tonic-gate (void) ldap_msgfree(cookie->resultMsg); 27557c478bd9Sstevel@tonic-gate cookie->resultMsg = NULL; 27567c478bd9Sstevel@tonic-gate if (rc == LDAP_BUSY || 27577c478bd9Sstevel@tonic-gate rc == LDAP_UNAVAILABLE || 27588277a58bSchinlong rc == LDAP_UNWILLING_TO_PERFORM) { 2759e1dd0a2fSth160488 if (cookie->reinit_on_retriable_err) { 2760e1dd0a2fSth160488 cookie->err_rc = rc; 2761e1dd0a2fSth160488 cookie->err_from_result = 1; 2762e1dd0a2fSth160488 cookie->new_state = REINIT; 2763e1dd0a2fSth160488 } else 2764e1dd0a2fSth160488 cookie->new_state = 2765e1dd0a2fSth160488 NEXT_SESSION; 2766e1dd0a2fSth160488 break; 2767e1dd0a2fSth160488 } 2768*9f2fd570SJulian Pullen 2769e1dd0a2fSth160488 if ((rc == LDAP_CONNECT_ERROR || 2770e1dd0a2fSth160488 rc == LDAP_SERVER_DOWN) && 2771e1dd0a2fSth160488 cookie->reinit_on_retriable_err) { 2772e1dd0a2fSth160488 ns_ldap_error_t *errorp = NULL; 2773e1dd0a2fSth160488 cookie->err_rc = rc; 2774e1dd0a2fSth160488 cookie->err_from_result = 1; 2775e1dd0a2fSth160488 cookie->new_state = REINIT; 2776e1dd0a2fSth160488 if (cookie->conn_user != NULL) 2777e1dd0a2fSth160488 __s_api_conn_mt_close( 2778e1dd0a2fSth160488 cookie->conn_user, 2779e1dd0a2fSth160488 rc, &errorp); 2780e1dd0a2fSth160488 if (errorp != NULL) { 2781e1dd0a2fSth160488 (void) __ns_ldap_freeError( 2782e1dd0a2fSth160488 &cookie->errorp); 2783e1dd0a2fSth160488 cookie->errorp = errorp; 2784e1dd0a2fSth160488 } 27857c478bd9Sstevel@tonic-gate break; 27867c478bd9Sstevel@tonic-gate } 27877c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 27887c478bd9Sstevel@tonic-gate cookie->new_state = LDAP_ERROR; 27897c478bd9Sstevel@tonic-gate break; 27907c478bd9Sstevel@tonic-gate } 27917c478bd9Sstevel@tonic-gate /* else LDAP_RES_SEARCH_ENTRY */ 2792*9f2fd570SJulian Pullen cookie->entryCount++; 27937c478bd9Sstevel@tonic-gate rc = __s_api_getEntry(cookie); 27947c478bd9Sstevel@tonic-gate (void) ldap_msgfree(cookie->resultMsg); 27957c478bd9Sstevel@tonic-gate cookie->resultMsg = NULL; 27967c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 27977c478bd9Sstevel@tonic-gate cookie->new_state = LDAP_ERROR; 27987c478bd9Sstevel@tonic-gate break; 27997c478bd9Sstevel@tonic-gate } 2800*9f2fd570SJulian Pullen /* 2801*9f2fd570SJulian Pullen * If VLV search was successfull save the server 2802*9f2fd570SJulian Pullen * side sort type tried. 2803*9f2fd570SJulian Pullen */ 2804*9f2fd570SJulian Pullen if (cookie->listType == VLVCTRLFLAG) 2805*9f2fd570SJulian Pullen update_srvsidesort_type(cookie->service, 2806*9f2fd570SJulian Pullen cookie->sortTypeTry); 2807*9f2fd570SJulian Pullen 28087c478bd9Sstevel@tonic-gate cookie->new_state = PROCESS_RESULT; 28097c478bd9Sstevel@tonic-gate cookie->next_state = MULTI_RESULT; 28107c478bd9Sstevel@tonic-gate break; 28117c478bd9Sstevel@tonic-gate case PROCESS_RESULT: 28127c478bd9Sstevel@tonic-gate /* NOTE THIS STATE MAY BE PROCESSED BY CALLER */ 28137c478bd9Sstevel@tonic-gate if (cookie->use_usercb && cookie->callback) { 28147c478bd9Sstevel@tonic-gate rc = 0; 28157c478bd9Sstevel@tonic-gate for (nextEntry = cookie->result->entry; 28167c478bd9Sstevel@tonic-gate nextEntry != NULL; 28177c478bd9Sstevel@tonic-gate nextEntry = nextEntry->next) { 28187c478bd9Sstevel@tonic-gate rc = (*cookie->callback)(nextEntry, 28197c478bd9Sstevel@tonic-gate cookie->userdata); 28207c478bd9Sstevel@tonic-gate 28217c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_CB_DONE) { 28227c478bd9Sstevel@tonic-gate /* cb doesn't want any more data */ 28237c478bd9Sstevel@tonic-gate rc = NS_LDAP_PARTIAL; 28247c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 28257c478bd9Sstevel@tonic-gate break; 28267c478bd9Sstevel@tonic-gate } else if (rc != NS_LDAP_CB_NEXT) { 28277c478bd9Sstevel@tonic-gate /* invalid return code */ 28287c478bd9Sstevel@tonic-gate rc = NS_LDAP_OP_FAILED; 28297c478bd9Sstevel@tonic-gate cookie->err_rc = rc; 28307c478bd9Sstevel@tonic-gate break; 28317c478bd9Sstevel@tonic-gate } 28327c478bd9Sstevel@tonic-gate } 28337c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&cookie->result); 28347c478bd9Sstevel@tonic-gate cookie->result = NULL; 28357c478bd9Sstevel@tonic-gate } 28367c478bd9Sstevel@tonic-gate if (rc != 0) { 28377c478bd9Sstevel@tonic-gate cookie->new_state = EXIT; 28387c478bd9Sstevel@tonic-gate break; 28397c478bd9Sstevel@tonic-gate } 28407c478bd9Sstevel@tonic-gate /* NOTE PREVIOUS STATE SPECIFIES NEXT STATE */ 28417c478bd9Sstevel@tonic-gate cookie->new_state = cookie->next_state; 28427c478bd9Sstevel@tonic-gate break; 28437c478bd9Sstevel@tonic-gate case END_PROCESS_RESULT: 28447c478bd9Sstevel@tonic-gate cookie->new_state = cookie->next_state; 28457c478bd9Sstevel@tonic-gate break; 28467c478bd9Sstevel@tonic-gate case END_RESULT: 28477c478bd9Sstevel@tonic-gate /* 28487c478bd9Sstevel@tonic-gate * XXX DO WE NEED THIS CASE? 28497c478bd9Sstevel@tonic-gate * if (search is complete) { 28507c478bd9Sstevel@tonic-gate * cookie->new_state = EXIT; 28517c478bd9Sstevel@tonic-gate * } else 28527c478bd9Sstevel@tonic-gate */ 28537c478bd9Sstevel@tonic-gate /* 28547c478bd9Sstevel@tonic-gate * entering referral mode if necessary 28557c478bd9Sstevel@tonic-gate */ 28567c478bd9Sstevel@tonic-gate if (cookie->followRef && cookie->reflist) 28577c478bd9Sstevel@tonic-gate cookie->new_state = 28587c478bd9Sstevel@tonic-gate NEXT_REFERRAL; 28597c478bd9Sstevel@tonic-gate else 28607c478bd9Sstevel@tonic-gate cookie->new_state = 28617c478bd9Sstevel@tonic-gate NEXT_SEARCH_DESCRIPTOR; 28627c478bd9Sstevel@tonic-gate break; 28637c478bd9Sstevel@tonic-gate case NEXT_REFERRAL: 28647c478bd9Sstevel@tonic-gate /* get next referral info */ 28657c478bd9Sstevel@tonic-gate if (cookie->refpos == NULL) 28667c478bd9Sstevel@tonic-gate cookie->refpos = 28677c478bd9Sstevel@tonic-gate cookie->reflist; 28687c478bd9Sstevel@tonic-gate else 28697c478bd9Sstevel@tonic-gate cookie->refpos = 28707c478bd9Sstevel@tonic-gate cookie->refpos->next; 28717c478bd9Sstevel@tonic-gate /* check see if done with all referrals */ 28727c478bd9Sstevel@tonic-gate if (cookie->refpos != NULL) 28737c478bd9Sstevel@tonic-gate cookie->new_state = 28747c478bd9Sstevel@tonic-gate GET_REFERRAL_SESSION; 28757c478bd9Sstevel@tonic-gate else { 28767c478bd9Sstevel@tonic-gate __s_api_deleteRefInfo(cookie->reflist); 28777c478bd9Sstevel@tonic-gate cookie->reflist = NULL; 28787c478bd9Sstevel@tonic-gate cookie->new_state = 28797c478bd9Sstevel@tonic-gate NEXT_SEARCH_DESCRIPTOR; 2880e1dd0a2fSth160488 if (cookie->conn_user != NULL) 2881e1dd0a2fSth160488 cookie->conn_user->referral = B_FALSE; 28827c478bd9Sstevel@tonic-gate } 28837c478bd9Sstevel@tonic-gate break; 28847c478bd9Sstevel@tonic-gate case GET_REFERRAL_SESSION: 28857c478bd9Sstevel@tonic-gate if (get_referral_session(cookie) < 0) 28867c478bd9Sstevel@tonic-gate cookie->new_state = EXIT; 28877c478bd9Sstevel@tonic-gate else { 28887c478bd9Sstevel@tonic-gate cookie->new_state = NEXT_SEARCH; 28897c478bd9Sstevel@tonic-gate } 28907c478bd9Sstevel@tonic-gate break; 28917c478bd9Sstevel@tonic-gate case LDAP_ERROR: 2892e1dd0a2fSth160488 rc_save = cookie->err_rc; 28938277a58bSchinlong if (cookie->err_from_result) { 28948277a58bSchinlong if (cookie->err_rc == LDAP_SERVER_DOWN) { 28958277a58bSchinlong (void) sprintf(errstr, 28968277a58bSchinlong gettext("LDAP ERROR (%d): " 28978277a58bSchinlong "Error occurred during" 28988277a58bSchinlong " receiving results. " 289910f9768dSmj162486 "Connection to server lost."), 29008277a58bSchinlong cookie->err_rc); 29018277a58bSchinlong } else if (cookie->err_rc == LDAP_TIMEOUT) { 29028277a58bSchinlong (void) sprintf(errstr, 29038277a58bSchinlong gettext("LDAP ERROR (%d): " 29048277a58bSchinlong "Error occurred during" 29058277a58bSchinlong " receiving results. %s" 29068277a58bSchinlong "."), cookie->err_rc, 29078277a58bSchinlong ldap_err2string( 29088277a58bSchinlong cookie->err_rc)); 29098277a58bSchinlong } 29108277a58bSchinlong } else 29117c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 29127c478bd9Sstevel@tonic-gate gettext("LDAP ERROR (%d): %s."), 29137c478bd9Sstevel@tonic-gate cookie->err_rc, 29147c478bd9Sstevel@tonic-gate ldap_err2string(cookie->err_rc)); 29157c478bd9Sstevel@tonic-gate err = strdup(errstr); 29168277a58bSchinlong if (cookie->err_from_result) { 291710f9768dSmj162486 if (cookie->err_rc == LDAP_SERVER_DOWN) { 291810f9768dSmj162486 MKERROR(LOG_INFO, *errorp, 291910f9768dSmj162486 cookie->err_rc, err, NULL); 292010f9768dSmj162486 } else { 292110f9768dSmj162486 MKERROR(LOG_WARNING, *errorp, 292210f9768dSmj162486 cookie->err_rc, err, NULL); 292310f9768dSmj162486 } 29248277a58bSchinlong } else { 29258277a58bSchinlong MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, 29268277a58bSchinlong err, NULL); 29278277a58bSchinlong } 29287c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_INTERNAL; 29297c478bd9Sstevel@tonic-gate cookie->errorp = *errorp; 2930e1dd0a2fSth160488 if (cookie->conn_user != NULL) { 2931e1dd0a2fSth160488 if (rc_save == LDAP_SERVER_DOWN || 2932e1dd0a2fSth160488 rc_save == LDAP_CONNECT_ERROR) { 2933e1dd0a2fSth160488 /* 2934e1dd0a2fSth160488 * MT connection is not usable, 2935e1dd0a2fSth160488 * close it. 2936e1dd0a2fSth160488 */ 2937e1dd0a2fSth160488 __s_api_conn_mt_close(cookie->conn_user, 2938e1dd0a2fSth160488 rc_save, &cookie->errorp); 2939e1dd0a2fSth160488 return (ERROR); 2940e1dd0a2fSth160488 } 2941e1dd0a2fSth160488 } 29427c478bd9Sstevel@tonic-gate return (ERROR); 29437c478bd9Sstevel@tonic-gate default: 29447c478bd9Sstevel@tonic-gate case ERROR: 29457c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 29467c478bd9Sstevel@tonic-gate gettext("Internal State machine exit (%d).\n"), 29477c478bd9Sstevel@tonic-gate cookie->state); 29487c478bd9Sstevel@tonic-gate err = strdup(errstr); 29497c478bd9Sstevel@tonic-gate MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, err, 29507c478bd9Sstevel@tonic-gate NULL); 29517c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_INTERNAL; 29527c478bd9Sstevel@tonic-gate cookie->errorp = *errorp; 29537c478bd9Sstevel@tonic-gate return (ERROR); 29547c478bd9Sstevel@tonic-gate } 29557c478bd9Sstevel@tonic-gate 2956e1dd0a2fSth160488 if (cookie->conn_user != NULL && 2957e1dd0a2fSth160488 cookie->conn_user->bad_mt_conn == B_TRUE) { 2958e1dd0a2fSth160488 __s_api_conn_mt_close(cookie->conn_user, 0, NULL); 2959e1dd0a2fSth160488 cookie->err_rc = cookie->conn_user->ns_rc; 2960e1dd0a2fSth160488 cookie->errorp = cookie->conn_user->ns_error; 2961e1dd0a2fSth160488 cookie->conn_user->ns_error = NULL; 2962e1dd0a2fSth160488 return (ERROR); 2963e1dd0a2fSth160488 } 2964e1dd0a2fSth160488 29657c478bd9Sstevel@tonic-gate if (cycle == ONE_STEP) { 29667c478bd9Sstevel@tonic-gate return (cookie->new_state); 29677c478bd9Sstevel@tonic-gate } 29687c478bd9Sstevel@tonic-gate cookie->state = cookie->new_state; 29697c478bd9Sstevel@tonic-gate } 29707c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 29717c478bd9Sstevel@tonic-gate #if 0 29727c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 29737c478bd9Sstevel@tonic-gate gettext("Unexpected State machine error.\n")); 29747c478bd9Sstevel@tonic-gate err = strdup(errstr); 29757c478bd9Sstevel@tonic-gate MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, err, NULL); 29767c478bd9Sstevel@tonic-gate cookie->err_rc = NS_LDAP_INTERNAL; 29777c478bd9Sstevel@tonic-gate cookie->errorp = *errorp; 29787c478bd9Sstevel@tonic-gate return (ERROR); 29797c478bd9Sstevel@tonic-gate #endif 29807c478bd9Sstevel@tonic-gate } 29817c478bd9Sstevel@tonic-gate 29827c478bd9Sstevel@tonic-gate /* 2983b57459abSJulian Pullen * For a lookup of shadow data, if shadow update is enabled, 2984b57459abSJulian Pullen * check the calling process' privilege to ensure it's 2985b57459abSJulian Pullen * allowed to perform such operation. 2986b57459abSJulian Pullen */ 2987b57459abSJulian Pullen static int 2988b57459abSJulian Pullen check_shadow(ns_ldap_cookie_t *cookie, const char *service) 2989b57459abSJulian Pullen { 2990b57459abSJulian Pullen char errstr[MAXERROR]; 2991b57459abSJulian Pullen char *err; 2992b57459abSJulian Pullen boolean_t priv; 2993b57459abSJulian Pullen /* caller */ 2994b57459abSJulian Pullen priv_set_t *ps; 2995b57459abSJulian Pullen /* zone */ 2996b57459abSJulian Pullen priv_set_t *zs; 2997b57459abSJulian Pullen 2998b57459abSJulian Pullen /* 2999b57459abSJulian Pullen * If service is "shadow", we may need 3000b57459abSJulian Pullen * to use privilege credentials. 3001b57459abSJulian Pullen */ 3002b57459abSJulian Pullen if ((strcmp(service, "shadow") == 0) && 3003b57459abSJulian Pullen __ns_ldap_is_shadow_update_enabled()) { 3004b57459abSJulian Pullen /* 3005b57459abSJulian Pullen * Since we release admin credentials after 3006b57459abSJulian Pullen * connection is closed and we do not cache 3007b57459abSJulian Pullen * them, we allow any root or all zone 3008b57459abSJulian Pullen * privilege process to read shadow data. 3009b57459abSJulian Pullen */ 3010b57459abSJulian Pullen priv = (geteuid() == 0); 3011b57459abSJulian Pullen if (!priv) { 3012b57459abSJulian Pullen /* caller */ 3013b57459abSJulian Pullen ps = priv_allocset(); 3014b57459abSJulian Pullen 3015b57459abSJulian Pullen (void) getppriv(PRIV_EFFECTIVE, ps); 3016b57459abSJulian Pullen zs = priv_str_to_set("zone", ",", NULL); 3017b57459abSJulian Pullen priv = priv_isequalset(ps, zs); 3018b57459abSJulian Pullen priv_freeset(ps); 3019b57459abSJulian Pullen priv_freeset(zs); 3020b57459abSJulian Pullen } 3021b57459abSJulian Pullen if (!priv) { 3022b57459abSJulian Pullen (void) sprintf(errstr, 3023b57459abSJulian Pullen gettext("Permission denied")); 3024b57459abSJulian Pullen err = strdup(errstr); 3025b57459abSJulian Pullen if (err == NULL) 3026b57459abSJulian Pullen return (NS_LDAP_MEMORY); 3027b57459abSJulian Pullen MKERROR(LOG_INFO, cookie->errorp, NS_LDAP_INTERNAL, err, 3028b57459abSJulian Pullen NULL); 3029b57459abSJulian Pullen return (NS_LDAP_INTERNAL); 3030b57459abSJulian Pullen } 3031b57459abSJulian Pullen cookie->i_flags |= NS_LDAP_READ_SHADOW; 3032b57459abSJulian Pullen /* 3033b57459abSJulian Pullen * We do not want to reuse connection (hence 3034b57459abSJulian Pullen * keep it open) with admin credentials. 3035b57459abSJulian Pullen * If NS_LDAP_KEEP_CONN is set, reject the 3036b57459abSJulian Pullen * request. 3037b57459abSJulian Pullen */ 3038b57459abSJulian Pullen if (cookie->i_flags & NS_LDAP_KEEP_CONN) 3039b57459abSJulian Pullen return (NS_LDAP_INVALID_PARAM); 3040b57459abSJulian Pullen cookie->i_flags |= NS_LDAP_NEW_CONN; 3041b57459abSJulian Pullen } 3042b57459abSJulian Pullen 3043b57459abSJulian Pullen return (NS_LDAP_SUCCESS); 3044b57459abSJulian Pullen } 3045b57459abSJulian Pullen 3046b57459abSJulian Pullen /* 3047479ac375Sdm199847 * internal function for __ns_ldap_list 30487c478bd9Sstevel@tonic-gate */ 3049479ac375Sdm199847 static int 3050479ac375Sdm199847 ldap_list( 3051479ac375Sdm199847 ns_ldap_list_batch_t *batch, 30527c478bd9Sstevel@tonic-gate const char *service, 30537c478bd9Sstevel@tonic-gate const char *filter, 3054*9f2fd570SJulian Pullen const char *sortattr, 30557c478bd9Sstevel@tonic-gate int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, 30567c478bd9Sstevel@tonic-gate char **realfilter, const void *userdata), 30577c478bd9Sstevel@tonic-gate const char * const *attribute, 30587c478bd9Sstevel@tonic-gate const ns_cred_t *auth, 30597c478bd9Sstevel@tonic-gate const int flags, 30607c478bd9Sstevel@tonic-gate ns_ldap_result_t **rResult, /* return result entries */ 30617c478bd9Sstevel@tonic-gate ns_ldap_error_t **errorp, 3062479ac375Sdm199847 int *rcp, 30637c478bd9Sstevel@tonic-gate int (*callback)(const ns_ldap_entry_t *entry, const void *userdata), 3064e1dd0a2fSth160488 const void *userdata, ns_conn_user_t *conn_user) 30657c478bd9Sstevel@tonic-gate { 30667c478bd9Sstevel@tonic-gate ns_ldap_cookie_t *cookie; 30677c478bd9Sstevel@tonic-gate ns_ldap_search_desc_t **sdlist = NULL; 30687c478bd9Sstevel@tonic-gate ns_ldap_search_desc_t *dptr; 30697c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 30707c478bd9Sstevel@tonic-gate char **dns = NULL; 30717c478bd9Sstevel@tonic-gate int scope; 30727c478bd9Sstevel@tonic-gate int rc; 30738277a58bSchinlong int from_result; 30747c478bd9Sstevel@tonic-gate 30757c478bd9Sstevel@tonic-gate *errorp = NULL; 3076479ac375Sdm199847 *rResult = NULL; 3077479ac375Sdm199847 *rcp = NS_LDAP_SUCCESS; 30787c478bd9Sstevel@tonic-gate 3079b57459abSJulian Pullen /* 3080b57459abSJulian Pullen * Sanity check - NS_LDAP_READ_SHADOW is for our 3081b57459abSJulian Pullen * own internal use. 3082b57459abSJulian Pullen */ 3083b57459abSJulian Pullen if (flags & NS_LDAP_READ_SHADOW) 3084b57459abSJulian Pullen return (NS_LDAP_INVALID_PARAM); 3085b57459abSJulian Pullen 30867c478bd9Sstevel@tonic-gate /* Initialize State machine cookie */ 30877c478bd9Sstevel@tonic-gate cookie = init_search_state_machine(); 30887c478bd9Sstevel@tonic-gate if (cookie == NULL) { 3089479ac375Sdm199847 *rcp = NS_LDAP_MEMORY; 30907c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 30917c478bd9Sstevel@tonic-gate } 3092e1dd0a2fSth160488 cookie->conn_user = conn_user; 30937c478bd9Sstevel@tonic-gate 30947c478bd9Sstevel@tonic-gate /* see if need to follow referrals */ 30957c478bd9Sstevel@tonic-gate rc = __s_api_toFollowReferrals(flags, 30967c478bd9Sstevel@tonic-gate &cookie->followRef, errorp); 30977c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 30987c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 3099479ac375Sdm199847 *rcp = rc; 31007c478bd9Sstevel@tonic-gate return (rc); 31017c478bd9Sstevel@tonic-gate } 31027c478bd9Sstevel@tonic-gate 31037c478bd9Sstevel@tonic-gate /* get the service descriptor - or create a default one */ 31047c478bd9Sstevel@tonic-gate rc = __s_api_get_SSD_from_SSDtoUse_service(service, 3105e84b06c3SMichen Chang &sdlist, &error); 31067c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 31077c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 31087c478bd9Sstevel@tonic-gate *errorp = error; 3109479ac375Sdm199847 *rcp = rc; 31107c478bd9Sstevel@tonic-gate return (rc); 31117c478bd9Sstevel@tonic-gate } 31127c478bd9Sstevel@tonic-gate 31137c478bd9Sstevel@tonic-gate if (sdlist == NULL) { 31147c478bd9Sstevel@tonic-gate /* Create default service Desc */ 31157c478bd9Sstevel@tonic-gate sdlist = (ns_ldap_search_desc_t **)calloc(2, 31167c478bd9Sstevel@tonic-gate sizeof (ns_ldap_search_desc_t *)); 31177c478bd9Sstevel@tonic-gate if (sdlist == NULL) { 31187c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 31197c478bd9Sstevel@tonic-gate cookie = NULL; 3120479ac375Sdm199847 *rcp = NS_LDAP_MEMORY; 31217c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 31227c478bd9Sstevel@tonic-gate } 31237c478bd9Sstevel@tonic-gate dptr = (ns_ldap_search_desc_t *) 31247c478bd9Sstevel@tonic-gate calloc(1, sizeof (ns_ldap_search_desc_t)); 31257c478bd9Sstevel@tonic-gate if (dptr == NULL) { 31267c478bd9Sstevel@tonic-gate free(sdlist); 31277c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 31287c478bd9Sstevel@tonic-gate cookie = NULL; 3129479ac375Sdm199847 *rcp = NS_LDAP_MEMORY; 31307c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 31317c478bd9Sstevel@tonic-gate } 31327c478bd9Sstevel@tonic-gate sdlist[0] = dptr; 31337c478bd9Sstevel@tonic-gate 31347c478bd9Sstevel@tonic-gate /* default base */ 31357c478bd9Sstevel@tonic-gate rc = __s_api_getDNs(&dns, service, &cookie->errorp); 31367c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 31377c478bd9Sstevel@tonic-gate if (dns) { 31387c478bd9Sstevel@tonic-gate __s_api_free2dArray(dns); 31397c478bd9Sstevel@tonic-gate dns = NULL; 31407c478bd9Sstevel@tonic-gate } 31417c478bd9Sstevel@tonic-gate *errorp = cookie->errorp; 31427c478bd9Sstevel@tonic-gate cookie->errorp = NULL; 31437c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 31447c478bd9Sstevel@tonic-gate cookie = NULL; 3145479ac375Sdm199847 *rcp = rc; 31467c478bd9Sstevel@tonic-gate return (rc); 31477c478bd9Sstevel@tonic-gate } 31487c478bd9Sstevel@tonic-gate dptr->basedn = strdup(dns[0]); 31497c478bd9Sstevel@tonic-gate __s_api_free2dArray(dns); 31507c478bd9Sstevel@tonic-gate dns = NULL; 31517c478bd9Sstevel@tonic-gate 31527c478bd9Sstevel@tonic-gate /* default scope */ 31537c478bd9Sstevel@tonic-gate scope = 0; 31547c478bd9Sstevel@tonic-gate rc = __s_api_getSearchScope(&scope, &cookie->errorp); 31557c478bd9Sstevel@tonic-gate dptr->scope = scope; 31567c478bd9Sstevel@tonic-gate } 31577c478bd9Sstevel@tonic-gate 31587c478bd9Sstevel@tonic-gate cookie->sdlist = sdlist; 31597c478bd9Sstevel@tonic-gate 31607c478bd9Sstevel@tonic-gate /* 31617c478bd9Sstevel@tonic-gate * use VLV/PAGE control only if NS_LDAP_PAGE_CTRL is set 31627c478bd9Sstevel@tonic-gate */ 31637c478bd9Sstevel@tonic-gate if (flags & NS_LDAP_PAGE_CTRL) 31647c478bd9Sstevel@tonic-gate cookie->use_paging = TRUE; 31657c478bd9Sstevel@tonic-gate else 31667c478bd9Sstevel@tonic-gate cookie->use_paging = FALSE; 31677c478bd9Sstevel@tonic-gate 31687c478bd9Sstevel@tonic-gate /* Set up other arguments */ 31697c478bd9Sstevel@tonic-gate cookie->userdata = userdata; 31707c478bd9Sstevel@tonic-gate if (init_filter_cb != NULL) { 31717c478bd9Sstevel@tonic-gate cookie->init_filter_cb = init_filter_cb; 31727c478bd9Sstevel@tonic-gate cookie->use_filtercb = 1; 31737c478bd9Sstevel@tonic-gate } 31747c478bd9Sstevel@tonic-gate if (callback != NULL) { 31757c478bd9Sstevel@tonic-gate cookie->callback = callback; 31767c478bd9Sstevel@tonic-gate cookie->use_usercb = 1; 31777c478bd9Sstevel@tonic-gate } 3178b57459abSJulian Pullen 3179b57459abSJulian Pullen /* check_shadow() may add extra value to cookie->i_flags */ 3180b57459abSJulian Pullen cookie->i_flags = flags; 31817c478bd9Sstevel@tonic-gate if (service) { 31827c478bd9Sstevel@tonic-gate cookie->service = strdup(service); 31837c478bd9Sstevel@tonic-gate if (cookie->service == NULL) { 31847c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 31857c478bd9Sstevel@tonic-gate cookie = NULL; 3186479ac375Sdm199847 *rcp = NS_LDAP_MEMORY; 31877c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 31887c478bd9Sstevel@tonic-gate } 3189b57459abSJulian Pullen 3190b57459abSJulian Pullen /* 3191b57459abSJulian Pullen * If given, use the credential given by the caller, and 3192b57459abSJulian Pullen * skip the credential check required for shadow update. 3193b57459abSJulian Pullen */ 3194b57459abSJulian Pullen if (auth == NULL) { 3195b57459abSJulian Pullen rc = check_shadow(cookie, service); 3196b57459abSJulian Pullen if (rc != NS_LDAP_SUCCESS) { 3197b57459abSJulian Pullen *errorp = cookie->errorp; 3198b57459abSJulian Pullen cookie->errorp = NULL; 3199b57459abSJulian Pullen delete_search_cookie(cookie); 3200b57459abSJulian Pullen cookie = NULL; 3201b57459abSJulian Pullen *rcp = rc; 3202b57459abSJulian Pullen return (rc); 3203b57459abSJulian Pullen } 3204b57459abSJulian Pullen } 32057c478bd9Sstevel@tonic-gate } 32067c478bd9Sstevel@tonic-gate 32077c478bd9Sstevel@tonic-gate cookie->i_filter = strdup(filter); 32087c478bd9Sstevel@tonic-gate cookie->i_attr = attribute; 32097c478bd9Sstevel@tonic-gate cookie->i_auth = auth; 3210*9f2fd570SJulian Pullen cookie->i_sortattr = sortattr; 32117c478bd9Sstevel@tonic-gate 3212479ac375Sdm199847 if (batch != NULL) { 3213479ac375Sdm199847 cookie->batch = batch; 3214e1dd0a2fSth160488 cookie->reinit_on_retriable_err = B_TRUE; 3215479ac375Sdm199847 cookie->no_wait = B_TRUE; 3216479ac375Sdm199847 (void) search_state_machine(cookie, INIT, 0); 3217479ac375Sdm199847 cookie->no_wait = B_FALSE; 3218479ac375Sdm199847 rc = cookie->err_rc; 3219479ac375Sdm199847 3220479ac375Sdm199847 if (rc == NS_LDAP_SUCCESS) { 3221479ac375Sdm199847 /* 3222479ac375Sdm199847 * Here rc == NS_LDAP_SUCCESS means that the state 3223479ac375Sdm199847 * machine init'ed successfully. The actual status 3224479ac375Sdm199847 * of the search will be determined by 3225479ac375Sdm199847 * __ns_ldap_list_batch_end(). Add the cookie to our 3226479ac375Sdm199847 * batch. 3227479ac375Sdm199847 */ 3228479ac375Sdm199847 cookie->caller_result = rResult; 3229479ac375Sdm199847 cookie->caller_errorp = errorp; 3230479ac375Sdm199847 cookie->caller_rc = rcp; 3231479ac375Sdm199847 cookie->next_cookie_in_batch = batch->cookie_list; 3232479ac375Sdm199847 batch->cookie_list = cookie; 3233479ac375Sdm199847 batch->nactive++; 3234479ac375Sdm199847 return (rc); 3235479ac375Sdm199847 } 3236479ac375Sdm199847 /* 3237479ac375Sdm199847 * If state machine init failed then copy error to the caller 3238479ac375Sdm199847 * and delete the cookie. 3239479ac375Sdm199847 */ 3240479ac375Sdm199847 } else { 3241479ac375Sdm199847 (void) search_state_machine(cookie, INIT, 0); 3242479ac375Sdm199847 } 32437c478bd9Sstevel@tonic-gate 32447c478bd9Sstevel@tonic-gate /* Copy results back to user */ 32457c478bd9Sstevel@tonic-gate rc = cookie->err_rc; 3246e1dd0a2fSth160488 if (rc != NS_LDAP_SUCCESS) { 3247e1dd0a2fSth160488 if (conn_user != NULL && conn_user->ns_error != NULL) { 3248e1dd0a2fSth160488 *errorp = conn_user->ns_error; 3249e1dd0a2fSth160488 conn_user->ns_error = NULL; 3250e1dd0a2fSth160488 } else 32517c478bd9Sstevel@tonic-gate *errorp = cookie->errorp; 3252e1dd0a2fSth160488 } 32537c478bd9Sstevel@tonic-gate *rResult = cookie->result; 32548277a58bSchinlong from_result = cookie->err_from_result; 32557c478bd9Sstevel@tonic-gate 32567c478bd9Sstevel@tonic-gate cookie->errorp = NULL; 32577c478bd9Sstevel@tonic-gate cookie->result = NULL; 32587c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 32597c478bd9Sstevel@tonic-gate cookie = NULL; 32607c478bd9Sstevel@tonic-gate 32618277a58bSchinlong if (from_result == 0 && *rResult == NULL) 32627c478bd9Sstevel@tonic-gate rc = NS_LDAP_NOTFOUND; 3263479ac375Sdm199847 *rcp = rc; 32647c478bd9Sstevel@tonic-gate return (rc); 32657c478bd9Sstevel@tonic-gate } 32667c478bd9Sstevel@tonic-gate 3267479ac375Sdm199847 3268479ac375Sdm199847 /* 3269479ac375Sdm199847 * __ns_ldap_list performs one or more LDAP searches to a given 3270479ac375Sdm199847 * directory server using service search descriptors and schema 3271e1dd0a2fSth160488 * mapping as appropriate. The operation may be retried a 3272e1dd0a2fSth160488 * couple of times in error situations. 3273479ac375Sdm199847 */ 3274479ac375Sdm199847 int 3275479ac375Sdm199847 __ns_ldap_list( 3276479ac375Sdm199847 const char *service, 3277479ac375Sdm199847 const char *filter, 3278479ac375Sdm199847 int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, 3279479ac375Sdm199847 char **realfilter, const void *userdata), 3280479ac375Sdm199847 const char * const *attribute, 3281479ac375Sdm199847 const ns_cred_t *auth, 3282479ac375Sdm199847 const int flags, 3283479ac375Sdm199847 ns_ldap_result_t **rResult, /* return result entries */ 3284479ac375Sdm199847 ns_ldap_error_t **errorp, 3285479ac375Sdm199847 int (*callback)(const ns_ldap_entry_t *entry, const void *userdata), 3286479ac375Sdm199847 const void *userdata) 3287479ac375Sdm199847 { 3288*9f2fd570SJulian Pullen int mod_flags; 3289*9f2fd570SJulian Pullen /* 3290*9f2fd570SJulian Pullen * Strip the NS_LDAP_PAGE_CTRL option as this interface does not 3291*9f2fd570SJulian Pullen * support this. If you want to use this option call the API 3292*9f2fd570SJulian Pullen * __ns_ldap_list_sort() with has the sort attribute. 3293*9f2fd570SJulian Pullen */ 3294*9f2fd570SJulian Pullen mod_flags = flags & (~NS_LDAP_PAGE_CTRL); 3295*9f2fd570SJulian Pullen 3296*9f2fd570SJulian Pullen return (__ns_ldap_list_sort(service, filter, NULL, init_filter_cb, 3297*9f2fd570SJulian Pullen attribute, auth, mod_flags, rResult, errorp, 3298*9f2fd570SJulian Pullen callback, userdata)); 3299*9f2fd570SJulian Pullen } 3300*9f2fd570SJulian Pullen 3301*9f2fd570SJulian Pullen /* 3302*9f2fd570SJulian Pullen * __ns_ldap_list_sort performs one or more LDAP searches to a given 3303*9f2fd570SJulian Pullen * directory server using service search descriptors and schema 3304*9f2fd570SJulian Pullen * mapping as appropriate. The operation may be retried a 3305*9f2fd570SJulian Pullen * couple of times in error situations. 3306*9f2fd570SJulian Pullen */ 3307*9f2fd570SJulian Pullen int 3308*9f2fd570SJulian Pullen __ns_ldap_list_sort( 3309*9f2fd570SJulian Pullen const char *service, 3310*9f2fd570SJulian Pullen const char *filter, 3311*9f2fd570SJulian Pullen const char *sortattr, 3312*9f2fd570SJulian Pullen int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, 3313*9f2fd570SJulian Pullen char **realfilter, const void *userdata), 3314*9f2fd570SJulian Pullen const char * const *attribute, 3315*9f2fd570SJulian Pullen const ns_cred_t *auth, 3316*9f2fd570SJulian Pullen const int flags, 3317*9f2fd570SJulian Pullen ns_ldap_result_t **rResult, /* return result entries */ 3318*9f2fd570SJulian Pullen ns_ldap_error_t **errorp, 3319*9f2fd570SJulian Pullen int (*callback)(const ns_ldap_entry_t *entry, const void *userdata), 3320*9f2fd570SJulian Pullen const void *userdata) 3321*9f2fd570SJulian Pullen { 3322e1dd0a2fSth160488 ns_conn_user_t *cu = NULL; 3323e1dd0a2fSth160488 int try_cnt = 0; 3324e1dd0a2fSth160488 int rc = NS_LDAP_SUCCESS, trc; 3325e1dd0a2fSth160488 3326e1dd0a2fSth160488 for (;;) { 3327e1dd0a2fSth160488 if (__s_api_setup_retry_search(&cu, NS_CONN_USER_SEARCH, 3328e1dd0a2fSth160488 &try_cnt, &rc, errorp) == 0) 3329e1dd0a2fSth160488 break; 3330*9f2fd570SJulian Pullen rc = ldap_list(NULL, service, filter, sortattr, init_filter_cb, 3331*9f2fd570SJulian Pullen attribute, auth, flags, rResult, errorp, &trc, callback, 3332*9f2fd570SJulian Pullen userdata, cu); 3333479ac375Sdm199847 } 3334479ac375Sdm199847 3335e1dd0a2fSth160488 return (rc); 3336e1dd0a2fSth160488 } 3337479ac375Sdm199847 3338479ac375Sdm199847 /* 3339479ac375Sdm199847 * Create and initialize batch for native LDAP lookups 3340479ac375Sdm199847 */ 3341479ac375Sdm199847 int 3342479ac375Sdm199847 __ns_ldap_list_batch_start(ns_ldap_list_batch_t **batch) 3343479ac375Sdm199847 { 3344479ac375Sdm199847 *batch = calloc(1, sizeof (ns_ldap_list_batch_t)); 3345479ac375Sdm199847 if (*batch == NULL) 3346479ac375Sdm199847 return (NS_LDAP_MEMORY); 3347479ac375Sdm199847 return (NS_LDAP_SUCCESS); 3348479ac375Sdm199847 } 3349479ac375Sdm199847 3350479ac375Sdm199847 3351479ac375Sdm199847 /* 3352479ac375Sdm199847 * Add a LDAP search request to the batch. 3353479ac375Sdm199847 */ 3354479ac375Sdm199847 int 3355479ac375Sdm199847 __ns_ldap_list_batch_add( 3356479ac375Sdm199847 ns_ldap_list_batch_t *batch, 3357479ac375Sdm199847 const char *service, 3358479ac375Sdm199847 const char *filter, 3359479ac375Sdm199847 int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, 3360479ac375Sdm199847 char **realfilter, const void *userdata), 3361479ac375Sdm199847 const char * const *attribute, 3362479ac375Sdm199847 const ns_cred_t *auth, 3363479ac375Sdm199847 const int flags, 3364479ac375Sdm199847 ns_ldap_result_t **rResult, /* return result entries */ 3365479ac375Sdm199847 ns_ldap_error_t **errorp, 3366479ac375Sdm199847 int *rcp, 3367479ac375Sdm199847 int (*callback)(const ns_ldap_entry_t *entry, const void *userdata), 3368479ac375Sdm199847 const void *userdata) 3369479ac375Sdm199847 { 3370e1dd0a2fSth160488 ns_conn_user_t *cu; 3371e1dd0a2fSth160488 int rc; 3372*9f2fd570SJulian Pullen int mod_flags; 3373e1dd0a2fSth160488 3374e1dd0a2fSth160488 cu = __s_api_conn_user_init(NS_CONN_USER_SEARCH, NULL, 0); 3375e1dd0a2fSth160488 if (cu == NULL) { 3376e1dd0a2fSth160488 if (rcp != NULL) 3377e1dd0a2fSth160488 *rcp = NS_LDAP_MEMORY; 3378e1dd0a2fSth160488 return (NS_LDAP_MEMORY); 3379e1dd0a2fSth160488 } 3380e1dd0a2fSth160488 3381*9f2fd570SJulian Pullen /* 3382*9f2fd570SJulian Pullen * Strip the NS_LDAP_PAGE_CTRL option as the batch interface does not 3383*9f2fd570SJulian Pullen * support this. 3384*9f2fd570SJulian Pullen */ 3385*9f2fd570SJulian Pullen mod_flags = flags & (~NS_LDAP_PAGE_CTRL); 3386*9f2fd570SJulian Pullen 3387*9f2fd570SJulian Pullen rc = ldap_list(batch, service, filter, NULL, init_filter_cb, attribute, 3388*9f2fd570SJulian Pullen auth, mod_flags, rResult, errorp, rcp, callback, userdata, cu); 3389e1dd0a2fSth160488 3390e1dd0a2fSth160488 /* 3391e1dd0a2fSth160488 * Free the conn_user if the cookie was not batched. If the cookie 3392e1dd0a2fSth160488 * was batched then __ns_ldap_list_batch_end or release will free the 3393e1dd0a2fSth160488 * conn_user. The batch API instructs the search_state_machine 3394e1dd0a2fSth160488 * to reinit and retry (max 3 times) on retriable LDAP errors. 3395e1dd0a2fSth160488 */ 3396e1dd0a2fSth160488 if (rc != NS_LDAP_SUCCESS && cu != NULL) { 3397e1dd0a2fSth160488 if (cu->conn_mt != NULL) 3398e1dd0a2fSth160488 __s_api_conn_mt_return(cu); 3399e1dd0a2fSth160488 __s_api_conn_user_free(cu); 3400e1dd0a2fSth160488 } 3401e1dd0a2fSth160488 return (rc); 3402479ac375Sdm199847 } 3403479ac375Sdm199847 3404479ac375Sdm199847 3405479ac375Sdm199847 /* 3406479ac375Sdm199847 * Free batch. 3407479ac375Sdm199847 */ 3408479ac375Sdm199847 void 3409479ac375Sdm199847 __ns_ldap_list_batch_release(ns_ldap_list_batch_t *batch) 3410479ac375Sdm199847 { 3411479ac375Sdm199847 ns_ldap_cookie_t *c, *next; 3412479ac375Sdm199847 3413479ac375Sdm199847 for (c = batch->cookie_list; c != NULL; c = next) { 3414479ac375Sdm199847 next = c->next_cookie_in_batch; 3415e1dd0a2fSth160488 if (c->conn_user != NULL) { 3416e1dd0a2fSth160488 if (c->conn_user->conn_mt != NULL) 3417e1dd0a2fSth160488 __s_api_conn_mt_return(c->conn_user); 3418e1dd0a2fSth160488 __s_api_conn_user_free(c->conn_user); 3419e1dd0a2fSth160488 c->conn_user = NULL; 3420e1dd0a2fSth160488 } 3421479ac375Sdm199847 delete_search_cookie(c); 3422479ac375Sdm199847 } 3423479ac375Sdm199847 free(batch); 3424479ac375Sdm199847 } 3425479ac375Sdm199847 3426e1dd0a2fSth160488 #define LD_USING_STATE(st) \ 3427e1dd0a2fSth160488 ((st == DO_SEARCH) || (st == MULTI_RESULT) || (st == NEXT_RESULT)) 3428479ac375Sdm199847 3429479ac375Sdm199847 /* 3430479ac375Sdm199847 * Process batch. Everytime this function is called it selects an 3431479ac375Sdm199847 * active cookie from the batch and single steps through the 3432479ac375Sdm199847 * search_state_machine for the selected cookie. If lookup associated 3433479ac375Sdm199847 * with the cookie is complete (success or error) then the cookie is 3434479ac375Sdm199847 * removed from the batch and its memory freed. 3435479ac375Sdm199847 * 3436479ac375Sdm199847 * Returns 1 (if batch still has active cookies) 3437479ac375Sdm199847 * 0 (if batch has no more active cookies) 3438479ac375Sdm199847 * -1 (on errors, *rcp will contain the error code) 3439479ac375Sdm199847 * 3440479ac375Sdm199847 * The caller should call this function in a loop as long as it returns 1 3441479ac375Sdm199847 * to process all the requests added to the batch. The results (and errors) 3442479ac375Sdm199847 * will be available in the locations provided by the caller at the time of 3443479ac375Sdm199847 * __ns_ldap_list_batch_add(). 3444479ac375Sdm199847 */ 3445479ac375Sdm199847 static 3446479ac375Sdm199847 int 3447479ac375Sdm199847 __ns_ldap_list_batch_process(ns_ldap_list_batch_t *batch, int *rcp) 3448479ac375Sdm199847 { 3449479ac375Sdm199847 ns_ldap_cookie_t *c, *ptr, **prev; 3450479ac375Sdm199847 ns_state_t state; 3451e1dd0a2fSth160488 ns_ldap_error_t *errorp = NULL; 3452479ac375Sdm199847 int rc; 3453479ac375Sdm199847 3454479ac375Sdm199847 /* Check if are already done */ 3455479ac375Sdm199847 if (batch->nactive == 0) 3456479ac375Sdm199847 return (0); 3457479ac375Sdm199847 3458479ac375Sdm199847 /* Get the next cookie from the batch */ 3459479ac375Sdm199847 c = (batch->next_cookie == NULL) ? 3460479ac375Sdm199847 batch->cookie_list : batch->next_cookie; 3461479ac375Sdm199847 3462479ac375Sdm199847 batch->next_cookie = c->next_cookie_in_batch; 3463479ac375Sdm199847 3464e1dd0a2fSth160488 /* 3465e1dd0a2fSth160488 * Checks the status of the cookie's connection if it needs 3466e1dd0a2fSth160488 * to use that connection for ldap_search_ext or ldap_result. 3467e1dd0a2fSth160488 * If the connection is no longer good but worth retrying 3468e1dd0a2fSth160488 * then reinit the search_state_machine for this cookie 3469e1dd0a2fSth160488 * starting from the first search descriptor. REINIT will 3470e1dd0a2fSth160488 * clear any leftover results if max retries have not been 3471e1dd0a2fSth160488 * reached and redo the search (which may also involve 3472e1dd0a2fSth160488 * following referrals again). 3473e1dd0a2fSth160488 * 3474e1dd0a2fSth160488 * Note that each cookie in the batch will make this 3475e1dd0a2fSth160488 * determination when it reaches one of the LD_USING_STATES. 3476e1dd0a2fSth160488 */ 3477e1dd0a2fSth160488 if (LD_USING_STATE(c->new_state) && c->conn_user != NULL) { 3478e1dd0a2fSth160488 rc = __s_api_setup_getnext(c->conn_user, &c->err_rc, &errorp); 3479e1dd0a2fSth160488 if (rc == LDAP_BUSY || rc == LDAP_UNAVAILABLE || 3480e1dd0a2fSth160488 rc == LDAP_UNWILLING_TO_PERFORM) { 3481e1dd0a2fSth160488 if (errorp != NULL) { 3482e1dd0a2fSth160488 (void) __ns_ldap_freeError(&c->errorp); 3483e1dd0a2fSth160488 c->errorp = errorp; 3484e1dd0a2fSth160488 } 3485e1dd0a2fSth160488 c->new_state = REINIT; 3486e1dd0a2fSth160488 } else if (rc == LDAP_CONNECT_ERROR || 3487e1dd0a2fSth160488 rc == LDAP_SERVER_DOWN) { 3488e1dd0a2fSth160488 if (errorp != NULL) { 3489e1dd0a2fSth160488 (void) __ns_ldap_freeError(&c->errorp); 3490e1dd0a2fSth160488 c->errorp = errorp; 3491e1dd0a2fSth160488 } 3492e1dd0a2fSth160488 c->new_state = REINIT; 3493e1dd0a2fSth160488 /* 3494e1dd0a2fSth160488 * MT connection is not usable, 3495e1dd0a2fSth160488 * close it before REINIT. 3496e1dd0a2fSth160488 */ 3497e1dd0a2fSth160488 __s_api_conn_mt_close( 3498e1dd0a2fSth160488 c->conn_user, rc, NULL); 3499e1dd0a2fSth160488 } else if (rc != NS_LDAP_SUCCESS) { 3500479ac375Sdm199847 if (rcp != NULL) 3501479ac375Sdm199847 *rcp = rc; 3502e1dd0a2fSth160488 *c->caller_result = NULL; 3503e1dd0a2fSth160488 *c->caller_errorp = errorp; 3504e1dd0a2fSth160488 *c->caller_rc = rc; 3505479ac375Sdm199847 return (-1); 3506479ac375Sdm199847 } 3507479ac375Sdm199847 } 3508479ac375Sdm199847 3509479ac375Sdm199847 for (;;) { 3510479ac375Sdm199847 /* Single step through the search_state_machine */ 3511479ac375Sdm199847 state = search_state_machine(c, c->new_state, ONE_STEP); 3512479ac375Sdm199847 switch (state) { 3513479ac375Sdm199847 case LDAP_ERROR: 3514479ac375Sdm199847 (void) search_state_machine(c, state, ONE_STEP); 3515479ac375Sdm199847 (void) search_state_machine(c, CLEAR_RESULTS, ONE_STEP); 3516479ac375Sdm199847 /* FALLTHROUGH */ 3517479ac375Sdm199847 case ERROR: 3518479ac375Sdm199847 case EXIT: 3519479ac375Sdm199847 *c->caller_result = c->result; 3520479ac375Sdm199847 *c->caller_errorp = c->errorp; 3521479ac375Sdm199847 *c->caller_rc = 3522479ac375Sdm199847 (c->result == NULL && c->err_from_result == 0) 3523479ac375Sdm199847 ? NS_LDAP_NOTFOUND : c->err_rc; 3524479ac375Sdm199847 c->result = NULL; 3525479ac375Sdm199847 c->errorp = NULL; 3526479ac375Sdm199847 /* Remove the cookie from the batch */ 3527479ac375Sdm199847 ptr = batch->cookie_list; 3528479ac375Sdm199847 prev = &batch->cookie_list; 3529479ac375Sdm199847 while (ptr != NULL) { 3530479ac375Sdm199847 if (ptr == c) { 3531479ac375Sdm199847 *prev = ptr->next_cookie_in_batch; 3532479ac375Sdm199847 break; 3533479ac375Sdm199847 } 3534479ac375Sdm199847 prev = &ptr->next_cookie_in_batch; 3535479ac375Sdm199847 ptr = ptr->next_cookie_in_batch; 3536479ac375Sdm199847 } 3537479ac375Sdm199847 /* Delete cookie and decrement active cookie count */ 3538e1dd0a2fSth160488 if (c->conn_user != NULL) { 3539e1dd0a2fSth160488 if (c->conn_user->conn_mt != NULL) 3540e1dd0a2fSth160488 __s_api_conn_mt_return(c->conn_user); 3541e1dd0a2fSth160488 __s_api_conn_user_free(c->conn_user); 3542e1dd0a2fSth160488 c->conn_user = NULL; 3543e1dd0a2fSth160488 } 3544479ac375Sdm199847 delete_search_cookie(c); 3545479ac375Sdm199847 batch->nactive--; 3546479ac375Sdm199847 break; 3547479ac375Sdm199847 case NEXT_RESULT: 3548479ac375Sdm199847 case MULTI_RESULT: 3549479ac375Sdm199847 /* 3550479ac375Sdm199847 * This means that search_state_machine needs to do 3551479ac375Sdm199847 * another ldap_result() for the cookie in question. 3552479ac375Sdm199847 * We only do at most one ldap_result() per call in 3553479ac375Sdm199847 * this function and therefore we return. This allows 3554479ac375Sdm199847 * the caller to process results from other cookies 3555479ac375Sdm199847 * in the batch without getting tied up on just one 3556479ac375Sdm199847 * cookie. 3557479ac375Sdm199847 */ 3558479ac375Sdm199847 break; 3559479ac375Sdm199847 default: 3560479ac375Sdm199847 /* 3561479ac375Sdm199847 * This includes states that follow NEXT_RESULT or 3562479ac375Sdm199847 * MULTI_RESULT such as PROCESS_RESULT and 3563479ac375Sdm199847 * END_PROCESS_RESULT. We continue processing 3564479ac375Sdm199847 * this cookie till we reach either the error, exit 3565479ac375Sdm199847 * or the result states. 3566479ac375Sdm199847 */ 3567479ac375Sdm199847 continue; 3568479ac375Sdm199847 } 3569479ac375Sdm199847 break; 3570479ac375Sdm199847 } 3571479ac375Sdm199847 3572479ac375Sdm199847 /* Return 0 if no more cookies left otherwise 1 */ 3573479ac375Sdm199847 return ((batch->nactive > 0) ? 1 : 0); 3574479ac375Sdm199847 } 3575479ac375Sdm199847 3576479ac375Sdm199847 3577479ac375Sdm199847 /* 3578479ac375Sdm199847 * Process all the active cookies in the batch and when none 3579479ac375Sdm199847 * remains finalize the batch. 3580479ac375Sdm199847 */ 3581479ac375Sdm199847 int 3582479ac375Sdm199847 __ns_ldap_list_batch_end(ns_ldap_list_batch_t *batch) 3583479ac375Sdm199847 { 3584479ac375Sdm199847 int rc = NS_LDAP_SUCCESS; 3585479ac375Sdm199847 while (__ns_ldap_list_batch_process(batch, &rc) > 0) 3586479ac375Sdm199847 ; 3587479ac375Sdm199847 __ns_ldap_list_batch_release(batch); 3588479ac375Sdm199847 return (rc); 3589479ac375Sdm199847 } 3590479ac375Sdm199847 35917c478bd9Sstevel@tonic-gate /* 3592e1dd0a2fSth160488 * find_domainname performs one or more LDAP searches to 35937c478bd9Sstevel@tonic-gate * find the value of the nisdomain attribute associated with 3594e1dd0a2fSth160488 * the input DN (with no retry). 35957c478bd9Sstevel@tonic-gate */ 35967c478bd9Sstevel@tonic-gate 35977c478bd9Sstevel@tonic-gate static int 3598e1dd0a2fSth160488 find_domainname(const char *dn, char **domainname, const ns_cred_t *cred, 3599e1dd0a2fSth160488 ns_ldap_error_t **errorp, ns_conn_user_t *conn_user) 36007c478bd9Sstevel@tonic-gate { 36017c478bd9Sstevel@tonic-gate 36027c478bd9Sstevel@tonic-gate ns_ldap_cookie_t *cookie; 36037c478bd9Sstevel@tonic-gate ns_ldap_search_desc_t **sdlist; 36047c478bd9Sstevel@tonic-gate ns_ldap_search_desc_t *dptr; 36057c478bd9Sstevel@tonic-gate int rc; 36067c478bd9Sstevel@tonic-gate char **value; 36077c478bd9Sstevel@tonic-gate int flags = 0; 36087c478bd9Sstevel@tonic-gate 36097c478bd9Sstevel@tonic-gate *domainname = NULL; 36107c478bd9Sstevel@tonic-gate *errorp = NULL; 36117c478bd9Sstevel@tonic-gate 36127c478bd9Sstevel@tonic-gate /* Initialize State machine cookie */ 36137c478bd9Sstevel@tonic-gate cookie = init_search_state_machine(); 36147c478bd9Sstevel@tonic-gate if (cookie == NULL) { 36157c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 36167c478bd9Sstevel@tonic-gate } 3617e1dd0a2fSth160488 cookie->conn_user = conn_user; 36187c478bd9Sstevel@tonic-gate 36197c478bd9Sstevel@tonic-gate /* see if need to follow referrals */ 36207c478bd9Sstevel@tonic-gate rc = __s_api_toFollowReferrals(flags, 36217c478bd9Sstevel@tonic-gate &cookie->followRef, errorp); 36227c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 36237c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 36247c478bd9Sstevel@tonic-gate return (rc); 36257c478bd9Sstevel@tonic-gate } 36267c478bd9Sstevel@tonic-gate 36277c478bd9Sstevel@tonic-gate /* Create default service Desc */ 36287c478bd9Sstevel@tonic-gate sdlist = (ns_ldap_search_desc_t **)calloc(2, 36297c478bd9Sstevel@tonic-gate sizeof (ns_ldap_search_desc_t *)); 36307c478bd9Sstevel@tonic-gate if (sdlist == NULL) { 36317c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 36327c478bd9Sstevel@tonic-gate cookie = NULL; 36337c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 36347c478bd9Sstevel@tonic-gate } 36357c478bd9Sstevel@tonic-gate dptr = (ns_ldap_search_desc_t *) 36367c478bd9Sstevel@tonic-gate calloc(1, sizeof (ns_ldap_search_desc_t)); 36377c478bd9Sstevel@tonic-gate if (dptr == NULL) { 36387c478bd9Sstevel@tonic-gate free(sdlist); 36397c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 36407c478bd9Sstevel@tonic-gate cookie = NULL; 36417c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 36427c478bd9Sstevel@tonic-gate } 36437c478bd9Sstevel@tonic-gate sdlist[0] = dptr; 36447c478bd9Sstevel@tonic-gate 36457c478bd9Sstevel@tonic-gate /* search base is dn */ 36467c478bd9Sstevel@tonic-gate dptr->basedn = strdup(dn); 36477c478bd9Sstevel@tonic-gate 36487c478bd9Sstevel@tonic-gate /* search scope is base */ 36497c478bd9Sstevel@tonic-gate dptr->scope = NS_LDAP_SCOPE_BASE; 36507c478bd9Sstevel@tonic-gate 36517c478bd9Sstevel@tonic-gate /* search filter is "nisdomain=*" */ 36527c478bd9Sstevel@tonic-gate dptr->filter = strdup(_NIS_FILTER); 36537c478bd9Sstevel@tonic-gate 36547c478bd9Sstevel@tonic-gate cookie->sdlist = sdlist; 36557c478bd9Sstevel@tonic-gate cookie->i_filter = strdup(dptr->filter); 36567c478bd9Sstevel@tonic-gate cookie->i_attr = nis_domain_attrs; 36577c478bd9Sstevel@tonic-gate cookie->i_auth = cred; 36587c478bd9Sstevel@tonic-gate cookie->i_flags = 0; 36597c478bd9Sstevel@tonic-gate 36607c478bd9Sstevel@tonic-gate /* Process search */ 36617c478bd9Sstevel@tonic-gate rc = search_state_machine(cookie, INIT, 0); 36627c478bd9Sstevel@tonic-gate 36637c478bd9Sstevel@tonic-gate /* Copy domain name if found */ 36647c478bd9Sstevel@tonic-gate rc = cookie->err_rc; 3665e1dd0a2fSth160488 if (rc != NS_LDAP_SUCCESS) { 3666e1dd0a2fSth160488 if (conn_user != NULL && conn_user->ns_error != NULL) { 3667e1dd0a2fSth160488 *errorp = conn_user->ns_error; 3668e1dd0a2fSth160488 conn_user->ns_error = NULL; 3669e1dd0a2fSth160488 } else 36707c478bd9Sstevel@tonic-gate *errorp = cookie->errorp; 3671e1dd0a2fSth160488 } 36727c478bd9Sstevel@tonic-gate if (cookie->result == NULL) 36737c478bd9Sstevel@tonic-gate rc = NS_LDAP_NOTFOUND; 36747c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS) { 36757c478bd9Sstevel@tonic-gate value = __ns_ldap_getAttr(cookie->result->entry, 36767c478bd9Sstevel@tonic-gate _NIS_DOMAIN); 36777c478bd9Sstevel@tonic-gate if (value[0]) 36787c478bd9Sstevel@tonic-gate *domainname = strdup(value[0]); 36797c478bd9Sstevel@tonic-gate else 36807c478bd9Sstevel@tonic-gate rc = NS_LDAP_NOTFOUND; 36817c478bd9Sstevel@tonic-gate } 36827c478bd9Sstevel@tonic-gate if (cookie->result != NULL) 36837c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&cookie->result); 36847c478bd9Sstevel@tonic-gate cookie->errorp = NULL; 36857c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 36867c478bd9Sstevel@tonic-gate cookie = NULL; 36877c478bd9Sstevel@tonic-gate return (rc); 36887c478bd9Sstevel@tonic-gate } 36897c478bd9Sstevel@tonic-gate 3690e1dd0a2fSth160488 /* 3691e1dd0a2fSth160488 * __s_api_find_domainname performs one or more LDAP searches to 3692e1dd0a2fSth160488 * find the value of the nisdomain attribute associated with 3693e1dd0a2fSth160488 * the input DN (with retry). 3694e1dd0a2fSth160488 */ 3695e1dd0a2fSth160488 3696e1dd0a2fSth160488 static int 3697e1dd0a2fSth160488 __s_api_find_domainname(const char *dn, char **domainname, 3698e1dd0a2fSth160488 const ns_cred_t *cred, ns_ldap_error_t **errorp) 3699e1dd0a2fSth160488 { 3700e1dd0a2fSth160488 ns_conn_user_t *cu = NULL; 3701e1dd0a2fSth160488 int try_cnt = 0; 3702e1dd0a2fSth160488 int rc = NS_LDAP_SUCCESS; 3703e1dd0a2fSth160488 3704e1dd0a2fSth160488 for (;;) { 3705e1dd0a2fSth160488 if (__s_api_setup_retry_search(&cu, NS_CONN_USER_SEARCH, 3706e1dd0a2fSth160488 &try_cnt, &rc, errorp) == 0) 3707e1dd0a2fSth160488 break; 3708e1dd0a2fSth160488 rc = find_domainname(dn, domainname, cred, errorp, cu); 3709e1dd0a2fSth160488 } 3710e1dd0a2fSth160488 3711e1dd0a2fSth160488 return (rc); 3712e1dd0a2fSth160488 } 3713e1dd0a2fSth160488 3714e1dd0a2fSth160488 static int 3715e1dd0a2fSth160488 firstEntry( 37167c478bd9Sstevel@tonic-gate const char *service, 37177c478bd9Sstevel@tonic-gate const char *filter, 3718*9f2fd570SJulian Pullen const char *sortattr, 37197c478bd9Sstevel@tonic-gate int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, 37207c478bd9Sstevel@tonic-gate char **realfilter, const void *userdata), 37217c478bd9Sstevel@tonic-gate const char * const *attribute, 37227c478bd9Sstevel@tonic-gate const ns_cred_t *auth, 37237c478bd9Sstevel@tonic-gate const int flags, 37247c478bd9Sstevel@tonic-gate void **vcookie, 37257c478bd9Sstevel@tonic-gate ns_ldap_result_t **result, 37267c478bd9Sstevel@tonic-gate ns_ldap_error_t ** errorp, 3727e1dd0a2fSth160488 const void *userdata, 3728e1dd0a2fSth160488 ns_conn_user_t *conn_user) 37297c478bd9Sstevel@tonic-gate { 37307c478bd9Sstevel@tonic-gate ns_ldap_cookie_t *cookie = NULL; 37317c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 37327c478bd9Sstevel@tonic-gate ns_state_t state; 37337c478bd9Sstevel@tonic-gate ns_ldap_search_desc_t **sdlist; 37347c478bd9Sstevel@tonic-gate ns_ldap_search_desc_t *dptr; 37357c478bd9Sstevel@tonic-gate char **dns = NULL; 37367c478bd9Sstevel@tonic-gate int scope; 37377c478bd9Sstevel@tonic-gate int rc; 37387c478bd9Sstevel@tonic-gate 37397c478bd9Sstevel@tonic-gate *errorp = NULL; 37407c478bd9Sstevel@tonic-gate *result = NULL; 37417c478bd9Sstevel@tonic-gate 3742b57459abSJulian Pullen /* 3743b57459abSJulian Pullen * Sanity check - NS_LDAP_READ_SHADOW is for our 3744b57459abSJulian Pullen * own internal use. 3745b57459abSJulian Pullen */ 3746b57459abSJulian Pullen if (flags & NS_LDAP_READ_SHADOW) 3747b57459abSJulian Pullen return (NS_LDAP_INVALID_PARAM); 3748b57459abSJulian Pullen 37497c478bd9Sstevel@tonic-gate /* get the service descriptor - or create a default one */ 37507c478bd9Sstevel@tonic-gate rc = __s_api_get_SSD_from_SSDtoUse_service(service, 3751e84b06c3SMichen Chang &sdlist, &error); 37527c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 37537c478bd9Sstevel@tonic-gate *errorp = error; 37547c478bd9Sstevel@tonic-gate return (rc); 37557c478bd9Sstevel@tonic-gate } 37567c478bd9Sstevel@tonic-gate if (sdlist == NULL) { 37577c478bd9Sstevel@tonic-gate /* Create default service Desc */ 37587c478bd9Sstevel@tonic-gate sdlist = (ns_ldap_search_desc_t **)calloc(2, 37597c478bd9Sstevel@tonic-gate sizeof (ns_ldap_search_desc_t *)); 37607c478bd9Sstevel@tonic-gate if (sdlist == NULL) { 37617c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 37627c478bd9Sstevel@tonic-gate } 37637c478bd9Sstevel@tonic-gate dptr = (ns_ldap_search_desc_t *) 37647c478bd9Sstevel@tonic-gate calloc(1, sizeof (ns_ldap_search_desc_t)); 37657c478bd9Sstevel@tonic-gate if (dptr == NULL) { 37667c478bd9Sstevel@tonic-gate free(sdlist); 37677c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 37687c478bd9Sstevel@tonic-gate } 37697c478bd9Sstevel@tonic-gate sdlist[0] = dptr; 37707c478bd9Sstevel@tonic-gate 37717c478bd9Sstevel@tonic-gate /* default base */ 37727c478bd9Sstevel@tonic-gate rc = __s_api_getDNs(&dns, service, &error); 37737c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 37747c478bd9Sstevel@tonic-gate if (dns) { 37757c478bd9Sstevel@tonic-gate __s_api_free2dArray(dns); 37767c478bd9Sstevel@tonic-gate dns = NULL; 37777c478bd9Sstevel@tonic-gate } 37787c478bd9Sstevel@tonic-gate if (sdlist) { 37797c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeSearchDescriptors( 37807c478bd9Sstevel@tonic-gate &sdlist); 37817c478bd9Sstevel@tonic-gate 37827c478bd9Sstevel@tonic-gate sdlist = NULL; 37837c478bd9Sstevel@tonic-gate } 37847c478bd9Sstevel@tonic-gate *errorp = error; 37857c478bd9Sstevel@tonic-gate return (rc); 37867c478bd9Sstevel@tonic-gate } 37877c478bd9Sstevel@tonic-gate dptr->basedn = strdup(dns[0]); 37887c478bd9Sstevel@tonic-gate __s_api_free2dArray(dns); 37897c478bd9Sstevel@tonic-gate dns = NULL; 37907c478bd9Sstevel@tonic-gate 37917c478bd9Sstevel@tonic-gate /* default scope */ 37927c478bd9Sstevel@tonic-gate scope = 0; 37937c478bd9Sstevel@tonic-gate cookie = init_search_state_machine(); 37947c478bd9Sstevel@tonic-gate if (cookie == NULL) { 37957c478bd9Sstevel@tonic-gate if (sdlist) { 37967c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeSearchDescriptors(&sdlist); 37977c478bd9Sstevel@tonic-gate sdlist = NULL; 37987c478bd9Sstevel@tonic-gate } 37997c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 38007c478bd9Sstevel@tonic-gate } 38017c478bd9Sstevel@tonic-gate rc = __s_api_getSearchScope(&scope, &cookie->errorp); 38027c478bd9Sstevel@tonic-gate dptr->scope = scope; 38037c478bd9Sstevel@tonic-gate } 38047c478bd9Sstevel@tonic-gate 38057c478bd9Sstevel@tonic-gate /* Initialize State machine cookie */ 38067c478bd9Sstevel@tonic-gate if (cookie == NULL) 38077c478bd9Sstevel@tonic-gate cookie = init_search_state_machine(); 38087c478bd9Sstevel@tonic-gate if (cookie == NULL) { 38097c478bd9Sstevel@tonic-gate if (sdlist) { 38107c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeSearchDescriptors(&sdlist); 38117c478bd9Sstevel@tonic-gate sdlist = NULL; 38127c478bd9Sstevel@tonic-gate } 38137c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 38147c478bd9Sstevel@tonic-gate } 38157c478bd9Sstevel@tonic-gate 3816e1dd0a2fSth160488 /* identify self as a getent user */ 3817e1dd0a2fSth160488 cookie->conn_user = conn_user; 3818e1dd0a2fSth160488 38197c478bd9Sstevel@tonic-gate cookie->sdlist = sdlist; 38207c478bd9Sstevel@tonic-gate 38217c478bd9Sstevel@tonic-gate /* see if need to follow referrals */ 38227c478bd9Sstevel@tonic-gate rc = __s_api_toFollowReferrals(flags, 38237c478bd9Sstevel@tonic-gate &cookie->followRef, errorp); 38247c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 38257c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 38267c478bd9Sstevel@tonic-gate return (rc); 38277c478bd9Sstevel@tonic-gate } 38287c478bd9Sstevel@tonic-gate 38297c478bd9Sstevel@tonic-gate /* 38307c478bd9Sstevel@tonic-gate * use VLV/PAGE control only if NS_LDAP_NO_PAGE_CTRL is not set 38317c478bd9Sstevel@tonic-gate */ 38327c478bd9Sstevel@tonic-gate if (flags & NS_LDAP_NO_PAGE_CTRL) 38337c478bd9Sstevel@tonic-gate cookie->use_paging = FALSE; 38347c478bd9Sstevel@tonic-gate else 38357c478bd9Sstevel@tonic-gate cookie->use_paging = TRUE; 38367c478bd9Sstevel@tonic-gate 38377c478bd9Sstevel@tonic-gate /* Set up other arguments */ 38387c478bd9Sstevel@tonic-gate cookie->userdata = userdata; 38397c478bd9Sstevel@tonic-gate if (init_filter_cb != NULL) { 38407c478bd9Sstevel@tonic-gate cookie->init_filter_cb = init_filter_cb; 38417c478bd9Sstevel@tonic-gate cookie->use_filtercb = 1; 38427c478bd9Sstevel@tonic-gate } 38437c478bd9Sstevel@tonic-gate cookie->use_usercb = 0; 3844b57459abSJulian Pullen /* check_shadow() may add extra value to cookie->i_flags */ 3845b57459abSJulian Pullen cookie->i_flags = flags; 38467c478bd9Sstevel@tonic-gate if (service) { 38477c478bd9Sstevel@tonic-gate cookie->service = strdup(service); 38487c478bd9Sstevel@tonic-gate if (cookie->service == NULL) { 38497c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 38507c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 38517c478bd9Sstevel@tonic-gate } 3852b57459abSJulian Pullen 3853b57459abSJulian Pullen /* 3854b57459abSJulian Pullen * If given, use the credential given by the caller, and 3855b57459abSJulian Pullen * skip the credential check required for shadow update. 3856b57459abSJulian Pullen */ 3857b57459abSJulian Pullen if (auth == NULL) { 3858b57459abSJulian Pullen rc = check_shadow(cookie, service); 3859b57459abSJulian Pullen if (rc != NS_LDAP_SUCCESS) { 3860b57459abSJulian Pullen *errorp = cookie->errorp; 3861b57459abSJulian Pullen cookie->errorp = NULL; 3862b57459abSJulian Pullen delete_search_cookie(cookie); 3863b57459abSJulian Pullen cookie = NULL; 3864b57459abSJulian Pullen return (rc); 3865b57459abSJulian Pullen } 3866b57459abSJulian Pullen } 38677c478bd9Sstevel@tonic-gate } 38687c478bd9Sstevel@tonic-gate 38697c478bd9Sstevel@tonic-gate cookie->i_filter = strdup(filter); 38707c478bd9Sstevel@tonic-gate cookie->i_attr = attribute; 3871*9f2fd570SJulian Pullen cookie->i_sortattr = sortattr; 38727c478bd9Sstevel@tonic-gate cookie->i_auth = auth; 38737c478bd9Sstevel@tonic-gate 38747c478bd9Sstevel@tonic-gate state = INIT; 38757c478bd9Sstevel@tonic-gate for (;;) { 38767c478bd9Sstevel@tonic-gate state = search_state_machine(cookie, state, ONE_STEP); 38777c478bd9Sstevel@tonic-gate switch (state) { 38787c478bd9Sstevel@tonic-gate case PROCESS_RESULT: 38797c478bd9Sstevel@tonic-gate *result = cookie->result; 38807c478bd9Sstevel@tonic-gate cookie->result = NULL; 38817c478bd9Sstevel@tonic-gate *vcookie = (void *)cookie; 38827c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 38837c478bd9Sstevel@tonic-gate case LDAP_ERROR: 38843d047983Smichen state = search_state_machine(cookie, state, ONE_STEP); 38853d047983Smichen state = search_state_machine(cookie, CLEAR_RESULTS, 38863d047983Smichen ONE_STEP); 38873d047983Smichen /* FALLTHROUGH */ 38883d047983Smichen case ERROR: 38897c478bd9Sstevel@tonic-gate rc = cookie->err_rc; 3890e1dd0a2fSth160488 if (conn_user != NULL && conn_user->ns_error != NULL) { 3891e1dd0a2fSth160488 *errorp = conn_user->ns_error; 3892e1dd0a2fSth160488 conn_user->ns_error = NULL; 3893e1dd0a2fSth160488 } else { 38947c478bd9Sstevel@tonic-gate *errorp = cookie->errorp; 38957c478bd9Sstevel@tonic-gate cookie->errorp = NULL; 3896e1dd0a2fSth160488 } 38977c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 38987c478bd9Sstevel@tonic-gate return (rc); 38997c478bd9Sstevel@tonic-gate case EXIT: 39007c478bd9Sstevel@tonic-gate rc = cookie->err_rc; 39017c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 39027c478bd9Sstevel@tonic-gate *errorp = cookie->errorp; 39037c478bd9Sstevel@tonic-gate cookie->errorp = NULL; 39047c478bd9Sstevel@tonic-gate } else { 39057c478bd9Sstevel@tonic-gate rc = NS_LDAP_NOTFOUND; 39067c478bd9Sstevel@tonic-gate } 39077c478bd9Sstevel@tonic-gate 39087c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 39097c478bd9Sstevel@tonic-gate return (rc); 39107c478bd9Sstevel@tonic-gate 39117c478bd9Sstevel@tonic-gate default: 39127c478bd9Sstevel@tonic-gate break; 39137c478bd9Sstevel@tonic-gate } 39147c478bd9Sstevel@tonic-gate } 39157c478bd9Sstevel@tonic-gate } 39167c478bd9Sstevel@tonic-gate 3917e1dd0a2fSth160488 int 3918e1dd0a2fSth160488 __ns_ldap_firstEntry( 3919e1dd0a2fSth160488 const char *service, 3920e1dd0a2fSth160488 const char *filter, 3921*9f2fd570SJulian Pullen const char *vlv_sort, 3922e1dd0a2fSth160488 int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, 3923e1dd0a2fSth160488 char **realfilter, const void *userdata), 3924e1dd0a2fSth160488 const char * const *attribute, 3925e1dd0a2fSth160488 const ns_cred_t *auth, 3926e1dd0a2fSth160488 const int flags, 3927e1dd0a2fSth160488 void **vcookie, 3928e1dd0a2fSth160488 ns_ldap_result_t **result, 3929e1dd0a2fSth160488 ns_ldap_error_t ** errorp, 3930e1dd0a2fSth160488 const void *userdata) 3931e1dd0a2fSth160488 { 3932e1dd0a2fSth160488 ns_conn_user_t *cu = NULL; 3933e1dd0a2fSth160488 int try_cnt = 0; 3934e1dd0a2fSth160488 int rc = NS_LDAP_SUCCESS; 3935e1dd0a2fSth160488 3936e1dd0a2fSth160488 for (;;) { 3937e1dd0a2fSth160488 if (__s_api_setup_retry_search(&cu, NS_CONN_USER_GETENT, 3938e1dd0a2fSth160488 &try_cnt, &rc, errorp) == 0) 3939e1dd0a2fSth160488 break; 3940*9f2fd570SJulian Pullen rc = firstEntry(service, filter, vlv_sort, init_filter_cb, 3941*9f2fd570SJulian Pullen attribute, auth, flags, vcookie, result, errorp, userdata, 3942*9f2fd570SJulian Pullen cu); 3943e1dd0a2fSth160488 } 3944e1dd0a2fSth160488 return (rc); 3945e1dd0a2fSth160488 } 3946e1dd0a2fSth160488 39477c478bd9Sstevel@tonic-gate /*ARGSUSED2*/ 39487c478bd9Sstevel@tonic-gate int 3949e1dd0a2fSth160488 __ns_ldap_nextEntry(void *vcookie, ns_ldap_result_t **result, 39507c478bd9Sstevel@tonic-gate ns_ldap_error_t ** errorp) 39517c478bd9Sstevel@tonic-gate { 39527c478bd9Sstevel@tonic-gate ns_ldap_cookie_t *cookie; 39537c478bd9Sstevel@tonic-gate ns_state_t state; 39547c478bd9Sstevel@tonic-gate int rc; 39557c478bd9Sstevel@tonic-gate 39567c478bd9Sstevel@tonic-gate cookie = (ns_ldap_cookie_t *)vcookie; 39577c478bd9Sstevel@tonic-gate cookie->result = NULL; 39587c478bd9Sstevel@tonic-gate *result = NULL; 39597c478bd9Sstevel@tonic-gate 3960e1dd0a2fSth160488 if (cookie->conn_user != NULL) { 3961e1dd0a2fSth160488 rc = __s_api_setup_getnext(cookie->conn_user, 3962e1dd0a2fSth160488 &cookie->err_rc, errorp); 39638277a58bSchinlong if (rc != NS_LDAP_SUCCESS) 39648277a58bSchinlong return (rc); 39658277a58bSchinlong } 39668277a58bSchinlong 3967e1dd0a2fSth160488 state = END_PROCESS_RESULT; 3968e1dd0a2fSth160488 for (;;) { 39697c478bd9Sstevel@tonic-gate state = search_state_machine(cookie, state, ONE_STEP); 39707c478bd9Sstevel@tonic-gate switch (state) { 39717c478bd9Sstevel@tonic-gate case PROCESS_RESULT: 39727c478bd9Sstevel@tonic-gate *result = cookie->result; 39737c478bd9Sstevel@tonic-gate cookie->result = NULL; 39747c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 39757c478bd9Sstevel@tonic-gate case LDAP_ERROR: 39763d047983Smichen state = search_state_machine(cookie, state, ONE_STEP); 39773d047983Smichen state = search_state_machine(cookie, CLEAR_RESULTS, 39783d047983Smichen ONE_STEP); 39793d047983Smichen /* FALLTHROUGH */ 39803d047983Smichen case ERROR: 39817c478bd9Sstevel@tonic-gate rc = cookie->err_rc; 39827c478bd9Sstevel@tonic-gate *errorp = cookie->errorp; 39837c478bd9Sstevel@tonic-gate cookie->errorp = NULL; 39847c478bd9Sstevel@tonic-gate return (rc); 39857c478bd9Sstevel@tonic-gate case EXIT: 39867c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 39877c478bd9Sstevel@tonic-gate } 39887c478bd9Sstevel@tonic-gate } 39897c478bd9Sstevel@tonic-gate } 39907c478bd9Sstevel@tonic-gate 39917c478bd9Sstevel@tonic-gate int 39927c478bd9Sstevel@tonic-gate __ns_ldap_endEntry( 39937c478bd9Sstevel@tonic-gate void **vcookie, 39947c478bd9Sstevel@tonic-gate ns_ldap_error_t ** errorp) 39957c478bd9Sstevel@tonic-gate { 39967c478bd9Sstevel@tonic-gate ns_ldap_cookie_t *cookie; 39977c478bd9Sstevel@tonic-gate int rc; 39987c478bd9Sstevel@tonic-gate 39997c478bd9Sstevel@tonic-gate if (*vcookie == NULL) 40007c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 40017c478bd9Sstevel@tonic-gate 40027c478bd9Sstevel@tonic-gate cookie = (ns_ldap_cookie_t *)(*vcookie); 40037c478bd9Sstevel@tonic-gate cookie->result = NULL; 40047c478bd9Sstevel@tonic-gate 40057c478bd9Sstevel@tonic-gate /* Complete search */ 4006699bceb8Smj162486 rc = search_state_machine(cookie, CLEAR_RESULTS, 0); 40077c478bd9Sstevel@tonic-gate 40087c478bd9Sstevel@tonic-gate /* Copy results back to user */ 40097c478bd9Sstevel@tonic-gate rc = cookie->err_rc; 40107c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) 40117c478bd9Sstevel@tonic-gate *errorp = cookie->errorp; 40127c478bd9Sstevel@tonic-gate 40137c478bd9Sstevel@tonic-gate cookie->errorp = NULL; 4014e1dd0a2fSth160488 if (cookie->conn_user != NULL) { 4015e1dd0a2fSth160488 if (cookie->conn_user->conn_mt != NULL) 4016e1dd0a2fSth160488 __s_api_conn_mt_return(cookie->conn_user); 4017e1dd0a2fSth160488 __s_api_conn_user_free(cookie->conn_user); 4018e1dd0a2fSth160488 } 40197c478bd9Sstevel@tonic-gate delete_search_cookie(cookie); 40207c478bd9Sstevel@tonic-gate cookie = NULL; 40217c478bd9Sstevel@tonic-gate *vcookie = NULL; 40227c478bd9Sstevel@tonic-gate 40237c478bd9Sstevel@tonic-gate return (rc); 40247c478bd9Sstevel@tonic-gate } 40257c478bd9Sstevel@tonic-gate 40267c478bd9Sstevel@tonic-gate 40277c478bd9Sstevel@tonic-gate int 40287c478bd9Sstevel@tonic-gate __ns_ldap_freeResult(ns_ldap_result_t **result) 40297c478bd9Sstevel@tonic-gate { 40307c478bd9Sstevel@tonic-gate 40317c478bd9Sstevel@tonic-gate ns_ldap_entry_t *curEntry = NULL; 40327c478bd9Sstevel@tonic-gate ns_ldap_entry_t *delEntry = NULL; 40337c478bd9Sstevel@tonic-gate int i; 40347c478bd9Sstevel@tonic-gate ns_ldap_result_t *res = *result; 40357c478bd9Sstevel@tonic-gate 40367c478bd9Sstevel@tonic-gate #ifdef DEBUG 40377c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "__ns_ldap_freeResult START\n"); 40387c478bd9Sstevel@tonic-gate #endif 40397c478bd9Sstevel@tonic-gate if (res == NULL) 40407c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 40417c478bd9Sstevel@tonic-gate 40427c478bd9Sstevel@tonic-gate if (res->entry != NULL) 40437c478bd9Sstevel@tonic-gate curEntry = res->entry; 40447c478bd9Sstevel@tonic-gate 40457c478bd9Sstevel@tonic-gate for (i = 0; i < res->entries_count; i++) { 40467c478bd9Sstevel@tonic-gate if (curEntry != NULL) { 40477c478bd9Sstevel@tonic-gate delEntry = curEntry; 40487c478bd9Sstevel@tonic-gate curEntry = curEntry->next; 40497c478bd9Sstevel@tonic-gate __ns_ldap_freeEntry(delEntry); 40507c478bd9Sstevel@tonic-gate } 40517c478bd9Sstevel@tonic-gate } 40527c478bd9Sstevel@tonic-gate 40537c478bd9Sstevel@tonic-gate free(res); 40547c478bd9Sstevel@tonic-gate *result = NULL; 40557c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 40567c478bd9Sstevel@tonic-gate } 40577c478bd9Sstevel@tonic-gate 40587c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 40597c478bd9Sstevel@tonic-gate int 40607c478bd9Sstevel@tonic-gate __ns_ldap_auth(const ns_cred_t *auth, 40617c478bd9Sstevel@tonic-gate const int flags, 40627c478bd9Sstevel@tonic-gate ns_ldap_error_t **errorp, 40637c478bd9Sstevel@tonic-gate LDAPControl **serverctrls, 40647c478bd9Sstevel@tonic-gate LDAPControl **clientctrls) 40657c478bd9Sstevel@tonic-gate { 40667c478bd9Sstevel@tonic-gate 40677c478bd9Sstevel@tonic-gate ConnectionID connectionId = -1; 40687c478bd9Sstevel@tonic-gate Connection *conp; 40697c478bd9Sstevel@tonic-gate int rc = 0; 40707c478bd9Sstevel@tonic-gate int do_not_fail_if_new_pwd_reqd = 0; 407147789246Svv149972 int nopasswd_acct_mgmt = 0; 4072e1dd0a2fSth160488 ns_conn_user_t *conn_user; 40737c478bd9Sstevel@tonic-gate 40747c478bd9Sstevel@tonic-gate 40757c478bd9Sstevel@tonic-gate #ifdef DEBUG 40767c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "__ns_ldap_auth START\n"); 40777c478bd9Sstevel@tonic-gate #endif 40787c478bd9Sstevel@tonic-gate 40797c478bd9Sstevel@tonic-gate *errorp = NULL; 40807c478bd9Sstevel@tonic-gate if (!auth) 40817c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 40827c478bd9Sstevel@tonic-gate 4083e1dd0a2fSth160488 conn_user = __s_api_conn_user_init(NS_CONN_USER_AUTH, 4084e1dd0a2fSth160488 NULL, B_FALSE); 4085e1dd0a2fSth160488 4086cb5caa98Sdjl rc = __s_api_getConnection(NULL, flags | NS_LDAP_NEW_CONN, 40877c478bd9Sstevel@tonic-gate auth, &connectionId, &conp, errorp, 4088e1dd0a2fSth160488 do_not_fail_if_new_pwd_reqd, nopasswd_acct_mgmt, 4089e1dd0a2fSth160488 conn_user); 4090e1dd0a2fSth160488 4091e1dd0a2fSth160488 if (conn_user != NULL) 4092e1dd0a2fSth160488 __s_api_conn_user_free(conn_user); 4093e1dd0a2fSth160488 40947c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_OP_FAILED && *errorp) 40957c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(errorp); 40967c478bd9Sstevel@tonic-gate 40977c478bd9Sstevel@tonic-gate if (connectionId > -1) 40987c478bd9Sstevel@tonic-gate DropConnection(connectionId, flags); 40997c478bd9Sstevel@tonic-gate return (rc); 41007c478bd9Sstevel@tonic-gate } 41017c478bd9Sstevel@tonic-gate 41027c478bd9Sstevel@tonic-gate char ** 41037c478bd9Sstevel@tonic-gate __ns_ldap_getAttr(const ns_ldap_entry_t *entry, const char *attrname) 41047c478bd9Sstevel@tonic-gate { 41057c478bd9Sstevel@tonic-gate int i; 41067c478bd9Sstevel@tonic-gate 41077c478bd9Sstevel@tonic-gate if (entry == NULL) 41087c478bd9Sstevel@tonic-gate return (NULL); 41097c478bd9Sstevel@tonic-gate for (i = 0; i < entry->attr_count; i++) { 41107c478bd9Sstevel@tonic-gate if (strcasecmp(entry->attr_pair[i]->attrname, attrname) == NULL) 41117c478bd9Sstevel@tonic-gate return (entry->attr_pair[i]->attrvalue); 41127c478bd9Sstevel@tonic-gate } 41137c478bd9Sstevel@tonic-gate return (NULL); 41147c478bd9Sstevel@tonic-gate } 41157c478bd9Sstevel@tonic-gate 4116cb5caa98Sdjl ns_ldap_attr_t * 4117cb5caa98Sdjl __ns_ldap_getAttrStruct(const ns_ldap_entry_t *entry, const char *attrname) 4118cb5caa98Sdjl { 4119cb5caa98Sdjl int i; 4120cb5caa98Sdjl 4121cb5caa98Sdjl if (entry == NULL) 4122cb5caa98Sdjl return (NULL); 4123cb5caa98Sdjl for (i = 0; i < entry->attr_count; i++) { 4124cb5caa98Sdjl if (strcasecmp(entry->attr_pair[i]->attrname, attrname) == NULL) 4125cb5caa98Sdjl return (entry->attr_pair[i]); 4126cb5caa98Sdjl } 4127cb5caa98Sdjl return (NULL); 4128cb5caa98Sdjl } 4129cb5caa98Sdjl 41307c478bd9Sstevel@tonic-gate 41317c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 41327c478bd9Sstevel@tonic-gate int 41337c478bd9Sstevel@tonic-gate __ns_ldap_uid2dn(const char *uid, 41347c478bd9Sstevel@tonic-gate char **userDN, 41357c478bd9Sstevel@tonic-gate const ns_cred_t *cred, /* cred is ignored */ 41367c478bd9Sstevel@tonic-gate ns_ldap_error_t **errorp) 41377c478bd9Sstevel@tonic-gate { 41387c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = NULL; 41397c478bd9Sstevel@tonic-gate char *filter, *userdata; 41407c478bd9Sstevel@tonic-gate char errstr[MAXERROR]; 41417c478bd9Sstevel@tonic-gate char **value; 41427c478bd9Sstevel@tonic-gate int rc = 0; 41437c478bd9Sstevel@tonic-gate int i = 0; 41447c478bd9Sstevel@tonic-gate size_t len; 41457c478bd9Sstevel@tonic-gate 41467c478bd9Sstevel@tonic-gate *errorp = NULL; 41477c478bd9Sstevel@tonic-gate *userDN = NULL; 41487c478bd9Sstevel@tonic-gate if ((uid == NULL) || (uid[0] == '\0')) 41497c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 41507c478bd9Sstevel@tonic-gate 41517c478bd9Sstevel@tonic-gate while (uid[i] != '\0') { 41527c478bd9Sstevel@tonic-gate if (uid[i] == '=') { 41537c478bd9Sstevel@tonic-gate *userDN = strdup(uid); 41547c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 41557c478bd9Sstevel@tonic-gate } 41567c478bd9Sstevel@tonic-gate i++; 41577c478bd9Sstevel@tonic-gate } 41587c478bd9Sstevel@tonic-gate i = 0; 41597c478bd9Sstevel@tonic-gate while ((uid[i] != '\0') && (isdigit(uid[i]))) 41607c478bd9Sstevel@tonic-gate i++; 41617c478bd9Sstevel@tonic-gate if (uid[i] == '\0') { 41627c478bd9Sstevel@tonic-gate len = strlen(UIDNUMFILTER) + strlen(uid) + 1; 41637c478bd9Sstevel@tonic-gate filter = (char *)malloc(len); 41647c478bd9Sstevel@tonic-gate if (filter == NULL) { 41657c478bd9Sstevel@tonic-gate *userDN = NULL; 41667c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 41677c478bd9Sstevel@tonic-gate } 41687c478bd9Sstevel@tonic-gate (void) snprintf(filter, len, UIDNUMFILTER, uid); 41697c478bd9Sstevel@tonic-gate 41707c478bd9Sstevel@tonic-gate len = strlen(UIDNUMFILTER_SSD) + strlen(uid) + 1; 41717c478bd9Sstevel@tonic-gate userdata = (char *)malloc(len); 41727c478bd9Sstevel@tonic-gate if (userdata == NULL) { 41737c478bd9Sstevel@tonic-gate *userDN = NULL; 41747c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 41757c478bd9Sstevel@tonic-gate } 41767c478bd9Sstevel@tonic-gate (void) snprintf(userdata, len, UIDNUMFILTER_SSD, uid); 41777c478bd9Sstevel@tonic-gate } else { 41787c478bd9Sstevel@tonic-gate len = strlen(UIDFILTER) + strlen(uid) + 1; 41797c478bd9Sstevel@tonic-gate filter = (char *)malloc(len); 41807c478bd9Sstevel@tonic-gate if (filter == NULL) { 41817c478bd9Sstevel@tonic-gate *userDN = NULL; 41827c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 41837c478bd9Sstevel@tonic-gate } 41847c478bd9Sstevel@tonic-gate (void) snprintf(filter, len, UIDFILTER, uid); 41857c478bd9Sstevel@tonic-gate 41867c478bd9Sstevel@tonic-gate len = strlen(UIDFILTER_SSD) + strlen(uid) + 1; 41877c478bd9Sstevel@tonic-gate userdata = (char *)malloc(len); 41887c478bd9Sstevel@tonic-gate if (userdata == NULL) { 41897c478bd9Sstevel@tonic-gate *userDN = NULL; 41907c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 41917c478bd9Sstevel@tonic-gate } 41927c478bd9Sstevel@tonic-gate (void) snprintf(userdata, len, UIDFILTER_SSD, uid); 41937c478bd9Sstevel@tonic-gate } 41947c478bd9Sstevel@tonic-gate 4195f5c3c7a7Ssdussud /* 4196f5c3c7a7Ssdussud * we want to retrieve the DN as it appears in LDAP 4197f5c3c7a7Ssdussud * hence the use of NS_LDAP_NOT_CVT_DN in flags 4198f5c3c7a7Ssdussud */ 41997c478bd9Sstevel@tonic-gate rc = __ns_ldap_list("passwd", filter, 42007c478bd9Sstevel@tonic-gate __s_api_merge_SSD_filter, 4201f5c3c7a7Ssdussud NULL, cred, NS_LDAP_NOT_CVT_DN, 42027c478bd9Sstevel@tonic-gate &result, errorp, NULL, 42037c478bd9Sstevel@tonic-gate userdata); 42047c478bd9Sstevel@tonic-gate free(filter); 42057c478bd9Sstevel@tonic-gate filter = NULL; 42067c478bd9Sstevel@tonic-gate free(userdata); 42077c478bd9Sstevel@tonic-gate userdata = NULL; 42087c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 42097c478bd9Sstevel@tonic-gate if (result) { 42107c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 42117c478bd9Sstevel@tonic-gate result = NULL; 42127c478bd9Sstevel@tonic-gate } 42137c478bd9Sstevel@tonic-gate return (rc); 42147c478bd9Sstevel@tonic-gate } 42157c478bd9Sstevel@tonic-gate if (result->entries_count > 1) { 42167c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 42177c478bd9Sstevel@tonic-gate result = NULL; 42187c478bd9Sstevel@tonic-gate *userDN = NULL; 42197c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 42207c478bd9Sstevel@tonic-gate gettext("Too many entries are returned for %s"), uid); 42217c478bd9Sstevel@tonic-gate MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, strdup(errstr), 42227c478bd9Sstevel@tonic-gate NULL); 42237c478bd9Sstevel@tonic-gate return (NS_LDAP_INTERNAL); 42247c478bd9Sstevel@tonic-gate } 42257c478bd9Sstevel@tonic-gate 42267c478bd9Sstevel@tonic-gate value = __ns_ldap_getAttr(result->entry, "dn"); 42277c478bd9Sstevel@tonic-gate *userDN = strdup(value[0]); 42287c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 42297c478bd9Sstevel@tonic-gate result = NULL; 42307c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 42317c478bd9Sstevel@tonic-gate } 42327c478bd9Sstevel@tonic-gate 42337c478bd9Sstevel@tonic-gate 42347c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 42357c478bd9Sstevel@tonic-gate int 42367c478bd9Sstevel@tonic-gate __ns_ldap_host2dn(const char *host, 42377c478bd9Sstevel@tonic-gate const char *domain, 42387c478bd9Sstevel@tonic-gate char **hostDN, 42397c478bd9Sstevel@tonic-gate const ns_cred_t *cred, /* cred is ignored */ 42407c478bd9Sstevel@tonic-gate ns_ldap_error_t **errorp) 42417c478bd9Sstevel@tonic-gate { 42427c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = NULL; 42437c478bd9Sstevel@tonic-gate char *filter, *userdata; 42447c478bd9Sstevel@tonic-gate char errstr[MAXERROR]; 42457c478bd9Sstevel@tonic-gate char **value; 42467c478bd9Sstevel@tonic-gate int rc; 42477c478bd9Sstevel@tonic-gate size_t len; 42487c478bd9Sstevel@tonic-gate 42497c478bd9Sstevel@tonic-gate /* 42507c478bd9Sstevel@tonic-gate * XXX 42517c478bd9Sstevel@tonic-gate * the domain parameter needs to be used in case domain is not local, if 42527c478bd9Sstevel@tonic-gate * this routine is to support multi domain setups, it needs lots of work... 42537c478bd9Sstevel@tonic-gate */ 42547c478bd9Sstevel@tonic-gate *errorp = NULL; 42557c478bd9Sstevel@tonic-gate *hostDN = NULL; 42567c478bd9Sstevel@tonic-gate if ((host == NULL) || (host[0] == '\0')) 42577c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 42587c478bd9Sstevel@tonic-gate 42597c478bd9Sstevel@tonic-gate len = strlen(HOSTFILTER) + strlen(host) + 1; 42607c478bd9Sstevel@tonic-gate filter = (char *)malloc(len); 42617c478bd9Sstevel@tonic-gate if (filter == NULL) { 42627c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 42637c478bd9Sstevel@tonic-gate } 42647c478bd9Sstevel@tonic-gate (void) snprintf(filter, len, HOSTFILTER, host); 42657c478bd9Sstevel@tonic-gate 42667c478bd9Sstevel@tonic-gate len = strlen(HOSTFILTER_SSD) + strlen(host) + 1; 42677c478bd9Sstevel@tonic-gate userdata = (char *)malloc(len); 42687c478bd9Sstevel@tonic-gate if (userdata == NULL) { 42697c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 42707c478bd9Sstevel@tonic-gate } 42717c478bd9Sstevel@tonic-gate (void) snprintf(userdata, len, HOSTFILTER_SSD, host); 42727c478bd9Sstevel@tonic-gate 4273f5c3c7a7Ssdussud /* 4274f5c3c7a7Ssdussud * we want to retrieve the DN as it appears in LDAP 4275f5c3c7a7Ssdussud * hence the use of NS_LDAP_NOT_CVT_DN in flags 4276f5c3c7a7Ssdussud */ 42777c478bd9Sstevel@tonic-gate rc = __ns_ldap_list("hosts", filter, 42787c478bd9Sstevel@tonic-gate __s_api_merge_SSD_filter, 4279f5c3c7a7Ssdussud NULL, cred, NS_LDAP_NOT_CVT_DN, &result, 42807c478bd9Sstevel@tonic-gate errorp, NULL, 42817c478bd9Sstevel@tonic-gate userdata); 42827c478bd9Sstevel@tonic-gate free(filter); 42837c478bd9Sstevel@tonic-gate filter = NULL; 42847c478bd9Sstevel@tonic-gate free(userdata); 42857c478bd9Sstevel@tonic-gate userdata = NULL; 42867c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 42877c478bd9Sstevel@tonic-gate if (result) { 42887c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 42897c478bd9Sstevel@tonic-gate result = NULL; 42907c478bd9Sstevel@tonic-gate } 42917c478bd9Sstevel@tonic-gate return (rc); 42927c478bd9Sstevel@tonic-gate } 42937c478bd9Sstevel@tonic-gate 42947c478bd9Sstevel@tonic-gate if (result->entries_count > 1) { 42957c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 42967c478bd9Sstevel@tonic-gate result = NULL; 42977c478bd9Sstevel@tonic-gate *hostDN = NULL; 42987c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 42997c478bd9Sstevel@tonic-gate gettext("Too many entries are returned for %s"), host); 43007c478bd9Sstevel@tonic-gate MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, strdup(errstr), 43017c478bd9Sstevel@tonic-gate NULL); 43027c478bd9Sstevel@tonic-gate return (NS_LDAP_INTERNAL); 43037c478bd9Sstevel@tonic-gate } 43047c478bd9Sstevel@tonic-gate 43057c478bd9Sstevel@tonic-gate value = __ns_ldap_getAttr(result->entry, "dn"); 43067c478bd9Sstevel@tonic-gate *hostDN = strdup(value[0]); 43077c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 43087c478bd9Sstevel@tonic-gate result = NULL; 43097c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 43107c478bd9Sstevel@tonic-gate } 43117c478bd9Sstevel@tonic-gate 43127c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 43137c478bd9Sstevel@tonic-gate int 43147c478bd9Sstevel@tonic-gate __ns_ldap_dn2domain(const char *dn, 43157c478bd9Sstevel@tonic-gate char **domain, 43167c478bd9Sstevel@tonic-gate const ns_cred_t *cred, 43177c478bd9Sstevel@tonic-gate ns_ldap_error_t **errorp) 43187c478bd9Sstevel@tonic-gate { 43197c478bd9Sstevel@tonic-gate int rc, pnum, i, j, len = 0; 43207c478bd9Sstevel@tonic-gate char *newdn, **rdns = NULL; 43217c478bd9Sstevel@tonic-gate char **dns, *dn1; 43227c478bd9Sstevel@tonic-gate 43237c478bd9Sstevel@tonic-gate *errorp = NULL; 43247c478bd9Sstevel@tonic-gate 43257c478bd9Sstevel@tonic-gate if (domain == NULL) 43267c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 43277c478bd9Sstevel@tonic-gate else 43287c478bd9Sstevel@tonic-gate *domain = NULL; 43297c478bd9Sstevel@tonic-gate 43307c478bd9Sstevel@tonic-gate if ((dn == NULL) || (dn[0] == '\0')) 43317c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 43327c478bd9Sstevel@tonic-gate 43337c478bd9Sstevel@tonic-gate /* 43347c478bd9Sstevel@tonic-gate * break dn into rdns 43357c478bd9Sstevel@tonic-gate */ 43367c478bd9Sstevel@tonic-gate dn1 = strdup(dn); 43377c478bd9Sstevel@tonic-gate if (dn1 == NULL) 43387c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 43397c478bd9Sstevel@tonic-gate rdns = ldap_explode_dn(dn1, 0); 43407c478bd9Sstevel@tonic-gate free(dn1); 43417c478bd9Sstevel@tonic-gate if (rdns == NULL || *rdns == NULL) 43427c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 43437c478bd9Sstevel@tonic-gate 43447c478bd9Sstevel@tonic-gate for (i = 0; rdns[i]; i++) 43457c478bd9Sstevel@tonic-gate len += strlen(rdns[i]) + 1; 43467c478bd9Sstevel@tonic-gate pnum = i; 43477c478bd9Sstevel@tonic-gate 43487c478bd9Sstevel@tonic-gate newdn = (char *)malloc(len + 1); 43497c478bd9Sstevel@tonic-gate dns = (char **)calloc(pnum, sizeof (char *)); 43507c478bd9Sstevel@tonic-gate if (newdn == NULL || dns == NULL) { 43517c478bd9Sstevel@tonic-gate if (newdn) 43527c478bd9Sstevel@tonic-gate free(newdn); 43537c478bd9Sstevel@tonic-gate ldap_value_free(rdns); 43547c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 43557c478bd9Sstevel@tonic-gate } 43567c478bd9Sstevel@tonic-gate 43577c478bd9Sstevel@tonic-gate /* construct a semi-normalized dn, newdn */ 43587c478bd9Sstevel@tonic-gate *newdn = '\0'; 43597c478bd9Sstevel@tonic-gate for (i = 0; rdns[i]; i++) { 43607c478bd9Sstevel@tonic-gate dns[i] = newdn + strlen(newdn); 43617c478bd9Sstevel@tonic-gate (void) strcat(newdn, 43627c478bd9Sstevel@tonic-gate __s_api_remove_rdn_space(rdns[i])); 43637c478bd9Sstevel@tonic-gate (void) strcat(newdn, ","); 43647c478bd9Sstevel@tonic-gate } 43657c478bd9Sstevel@tonic-gate /* remove the last ',' */ 43667c478bd9Sstevel@tonic-gate newdn[strlen(newdn) - 1] = '\0'; 43677c478bd9Sstevel@tonic-gate ldap_value_free(rdns); 43687c478bd9Sstevel@tonic-gate 43697c478bd9Sstevel@tonic-gate /* 43707c478bd9Sstevel@tonic-gate * loop and find the domain name associated with newdn, 43717c478bd9Sstevel@tonic-gate * removing rdn one by one from left to right 43727c478bd9Sstevel@tonic-gate */ 43737c478bd9Sstevel@tonic-gate for (i = 0; i < pnum; i++) { 43747c478bd9Sstevel@tonic-gate 43757c478bd9Sstevel@tonic-gate if (*errorp) 43767c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(errorp); 43777c478bd9Sstevel@tonic-gate 43787c478bd9Sstevel@tonic-gate /* 43797c478bd9Sstevel@tonic-gate * try cache manager first 43807c478bd9Sstevel@tonic-gate */ 43817c478bd9Sstevel@tonic-gate rc = __s_api_get_cachemgr_data(NS_CACHE_DN2DOMAIN, 43827c478bd9Sstevel@tonic-gate dns[i], domain); 43837c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) { 43847c478bd9Sstevel@tonic-gate /* 43857c478bd9Sstevel@tonic-gate * try ldap server second 43867c478bd9Sstevel@tonic-gate */ 43877c478bd9Sstevel@tonic-gate rc = __s_api_find_domainname(dns[i], domain, 43887c478bd9Sstevel@tonic-gate cred, errorp); 43897c478bd9Sstevel@tonic-gate } else { 43907c478bd9Sstevel@tonic-gate /* 43917c478bd9Sstevel@tonic-gate * skip the last one, 43927c478bd9Sstevel@tonic-gate * since it is already cached by ldap_cachemgr 43937c478bd9Sstevel@tonic-gate */ 43947c478bd9Sstevel@tonic-gate i--; 43957c478bd9Sstevel@tonic-gate } 43967c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS) { 43978142c2b2Schinlong if (__s_api_nscd_proc()) { 43987c478bd9Sstevel@tonic-gate /* 43998142c2b2Schinlong * If it's nscd, ask cache manager to save the 44007c478bd9Sstevel@tonic-gate * dn to domain mapping(s) 44017c478bd9Sstevel@tonic-gate */ 44027c478bd9Sstevel@tonic-gate for (j = 0; j <= i; j++) { 44037c478bd9Sstevel@tonic-gate (void) __s_api_set_cachemgr_data( 44047c478bd9Sstevel@tonic-gate NS_CACHE_DN2DOMAIN, 44057c478bd9Sstevel@tonic-gate dns[j], 44067c478bd9Sstevel@tonic-gate *domain); 44077c478bd9Sstevel@tonic-gate } 44088142c2b2Schinlong } 44097c478bd9Sstevel@tonic-gate break; 44107c478bd9Sstevel@tonic-gate } 44117c478bd9Sstevel@tonic-gate } 44127c478bd9Sstevel@tonic-gate 44137c478bd9Sstevel@tonic-gate free(dns); 44147c478bd9Sstevel@tonic-gate free(newdn); 44157c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) 44167c478bd9Sstevel@tonic-gate rc = NS_LDAP_NOTFOUND; 44177c478bd9Sstevel@tonic-gate return (rc); 44187c478bd9Sstevel@tonic-gate } 44197c478bd9Sstevel@tonic-gate 44207c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 44217c478bd9Sstevel@tonic-gate int 44227c478bd9Sstevel@tonic-gate __ns_ldap_getServiceAuthMethods(const char *service, 44237c478bd9Sstevel@tonic-gate ns_auth_t ***auth, 44247c478bd9Sstevel@tonic-gate ns_ldap_error_t **errorp) 44257c478bd9Sstevel@tonic-gate { 44267c478bd9Sstevel@tonic-gate char errstr[MAXERROR]; 44277c478bd9Sstevel@tonic-gate int rc, i, done = 0; 44287c478bd9Sstevel@tonic-gate int slen; 44297c478bd9Sstevel@tonic-gate void **param; 44307c478bd9Sstevel@tonic-gate char **sam, *srv, *send; 44317c478bd9Sstevel@tonic-gate ns_auth_t **authpp = NULL, *ap; 44327c478bd9Sstevel@tonic-gate int cnt, max; 44337c478bd9Sstevel@tonic-gate ns_config_t *cfg; 44347c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 44357c478bd9Sstevel@tonic-gate 44367c478bd9Sstevel@tonic-gate if (errorp == NULL) 44377c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 44387c478bd9Sstevel@tonic-gate *errorp = NULL; 44397c478bd9Sstevel@tonic-gate 44407c478bd9Sstevel@tonic-gate if ((service == NULL) || (service[0] == '\0') || 44417c478bd9Sstevel@tonic-gate (auth == NULL)) 44427c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 44437c478bd9Sstevel@tonic-gate 44447c478bd9Sstevel@tonic-gate *auth = NULL; 44457c478bd9Sstevel@tonic-gate rc = __ns_ldap_getParam(NS_LDAP_SERVICE_AUTH_METHOD_P, ¶m, &error); 44467c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS || param == NULL) { 44477c478bd9Sstevel@tonic-gate *errorp = error; 44487c478bd9Sstevel@tonic-gate return (rc); 44497c478bd9Sstevel@tonic-gate } 44507c478bd9Sstevel@tonic-gate sam = (char **)param; 44517c478bd9Sstevel@tonic-gate 44527c478bd9Sstevel@tonic-gate cfg = __s_api_get_default_config(); 44537c478bd9Sstevel@tonic-gate cnt = 0; 44547c478bd9Sstevel@tonic-gate 44557c478bd9Sstevel@tonic-gate slen = strlen(service); 44567c478bd9Sstevel@tonic-gate 44577c478bd9Sstevel@tonic-gate for (; *sam; sam++) { 44587c478bd9Sstevel@tonic-gate srv = *sam; 44597c478bd9Sstevel@tonic-gate if (strncasecmp(service, srv, slen) != 0) 44607c478bd9Sstevel@tonic-gate continue; 44617c478bd9Sstevel@tonic-gate srv += slen; 44627c478bd9Sstevel@tonic-gate if (*srv != COLONTOK) 44637c478bd9Sstevel@tonic-gate continue; 44647c478bd9Sstevel@tonic-gate send = srv; 44657c478bd9Sstevel@tonic-gate srv++; 44667c478bd9Sstevel@tonic-gate for (max = 1; (send = strchr(++send, SEMITOK)) != NULL; 44677c478bd9Sstevel@tonic-gate max++) {} 44687c478bd9Sstevel@tonic-gate authpp = (ns_auth_t **)calloc(++max, sizeof (ns_auth_t *)); 44697c478bd9Sstevel@tonic-gate if (authpp == NULL) { 44707c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶m); 44717c478bd9Sstevel@tonic-gate __s_api_release_config(cfg); 44727c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 44737c478bd9Sstevel@tonic-gate } 44747c478bd9Sstevel@tonic-gate while (!done) { 44757c478bd9Sstevel@tonic-gate send = strchr(srv, SEMITOK); 44767c478bd9Sstevel@tonic-gate if (send != NULL) { 44777c478bd9Sstevel@tonic-gate *send = '\0'; 44787c478bd9Sstevel@tonic-gate send++; 44797c478bd9Sstevel@tonic-gate } 44807c478bd9Sstevel@tonic-gate i = __s_get_enum_value(cfg, srv, NS_LDAP_AUTH_P); 44817c478bd9Sstevel@tonic-gate if (i == -1) { 44827c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶m); 44837c478bd9Sstevel@tonic-gate (void) sprintf(errstr, 4484699bceb8Smj162486 gettext("Unsupported " 4485699bceb8Smj162486 "serviceAuthenticationMethod: %s.\n"), srv); 44867c478bd9Sstevel@tonic-gate MKERROR(LOG_WARNING, *errorp, NS_CONFIG_SYNTAX, 44877c478bd9Sstevel@tonic-gate strdup(errstr), NULL); 44887c478bd9Sstevel@tonic-gate __s_api_release_config(cfg); 44897c478bd9Sstevel@tonic-gate return (NS_LDAP_CONFIG); 44907c478bd9Sstevel@tonic-gate } 44917c478bd9Sstevel@tonic-gate ap = __s_api_AuthEnumtoStruct((EnumAuthType_t)i); 44927c478bd9Sstevel@tonic-gate if (ap == NULL) { 44937c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶m); 44947c478bd9Sstevel@tonic-gate __s_api_release_config(cfg); 44957c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 44967c478bd9Sstevel@tonic-gate } 44977c478bd9Sstevel@tonic-gate authpp[cnt++] = ap; 44987c478bd9Sstevel@tonic-gate if (send == NULL) 44997c478bd9Sstevel@tonic-gate done = TRUE; 45007c478bd9Sstevel@tonic-gate else 45017c478bd9Sstevel@tonic-gate srv = send; 45027c478bd9Sstevel@tonic-gate } 45037c478bd9Sstevel@tonic-gate } 45047c478bd9Sstevel@tonic-gate 45057c478bd9Sstevel@tonic-gate *auth = authpp; 45067c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeParam(¶m); 45077c478bd9Sstevel@tonic-gate __s_api_release_config(cfg); 45087c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 45097c478bd9Sstevel@tonic-gate } 45107c478bd9Sstevel@tonic-gate 45117c478bd9Sstevel@tonic-gate /* 45127c478bd9Sstevel@tonic-gate * This routine is called when certain scenario occurs 45137c478bd9Sstevel@tonic-gate * e.g. 45147c478bd9Sstevel@tonic-gate * service == auto_home 45157c478bd9Sstevel@tonic-gate * SSD = automount: ou = mytest, 45167c478bd9Sstevel@tonic-gate * NS_LDAP_MAPATTRIBUTE= auto_home: automountMapName=AAA 45177c478bd9Sstevel@tonic-gate * NS_LDAP_OBJECTCLASSMAP= auto_home:automountMap=MynisMap 45187c478bd9Sstevel@tonic-gate * NS_LDAP_OBJECTCLASSMAP= auto_home:automount=MynisObject 45197c478bd9Sstevel@tonic-gate * 45207c478bd9Sstevel@tonic-gate * The automountMapName is prepended implicitely but is mapped 45217c478bd9Sstevel@tonic-gate * to AAA. So dn could appers as 45227c478bd9Sstevel@tonic-gate * dn: AAA=auto_home,ou=bar,dc=foo,dc=com 45237c478bd9Sstevel@tonic-gate * dn: automountKey=user_01,AAA=auto_home,ou=bar,dc=foo,dc=com 45247c478bd9Sstevel@tonic-gate * dn: automountKey=user_02,AAA=auto_home,ou=bar,dc=foo,dc=com 45257c478bd9Sstevel@tonic-gate * in the directory. 45267c478bd9Sstevel@tonic-gate * This function is called to covert the mapped attr back to 45277c478bd9Sstevel@tonic-gate * orig attr when the entries are searched and returned 45287c478bd9Sstevel@tonic-gate */ 45297c478bd9Sstevel@tonic-gate 45307c478bd9Sstevel@tonic-gate int 45317c478bd9Sstevel@tonic-gate __s_api_convert_automountmapname(const char *service, char **dn, 45327c478bd9Sstevel@tonic-gate ns_ldap_error_t **errp) { 45337c478bd9Sstevel@tonic-gate 45347c478bd9Sstevel@tonic-gate char **mapping = NULL; 45357c478bd9Sstevel@tonic-gate char *mapped_attr = NULL; 45367c478bd9Sstevel@tonic-gate char *automountmapname = "automountMapName"; 45377c478bd9Sstevel@tonic-gate char *buffer = NULL; 45387c478bd9Sstevel@tonic-gate int rc = NS_LDAP_SUCCESS; 45397c478bd9Sstevel@tonic-gate char errstr[MAXERROR]; 45407c478bd9Sstevel@tonic-gate 45417c478bd9Sstevel@tonic-gate /* 45427c478bd9Sstevel@tonic-gate * dn is an input/out parameter, check it first 45437c478bd9Sstevel@tonic-gate */ 45447c478bd9Sstevel@tonic-gate 45457c478bd9Sstevel@tonic-gate if (service == NULL || dn == NULL || *dn == NULL) 45467c478bd9Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM); 45477c478bd9Sstevel@tonic-gate 45487c478bd9Sstevel@tonic-gate /* 45497c478bd9Sstevel@tonic-gate * Check to see if there is a mapped attribute for auto_xxx 45507c478bd9Sstevel@tonic-gate */ 45517c478bd9Sstevel@tonic-gate 45527c478bd9Sstevel@tonic-gate mapping = __ns_ldap_getMappedAttributes(service, automountmapname); 45537c478bd9Sstevel@tonic-gate 45547c478bd9Sstevel@tonic-gate /* 45557c478bd9Sstevel@tonic-gate * if no mapped attribute for auto_xxx, try automount 45567c478bd9Sstevel@tonic-gate */ 45577c478bd9Sstevel@tonic-gate 45587c478bd9Sstevel@tonic-gate if (mapping == NULL) 45597c478bd9Sstevel@tonic-gate mapping = __ns_ldap_getMappedAttributes( 45607c478bd9Sstevel@tonic-gate "automount", automountmapname); 45617c478bd9Sstevel@tonic-gate 45627c478bd9Sstevel@tonic-gate /* 45637c478bd9Sstevel@tonic-gate * if no mapped attribute is found, return SUCCESS (no op) 45647c478bd9Sstevel@tonic-gate */ 45657c478bd9Sstevel@tonic-gate 45667c478bd9Sstevel@tonic-gate if (mapping == NULL) 45677c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 45687c478bd9Sstevel@tonic-gate 45697c478bd9Sstevel@tonic-gate /* 45707c478bd9Sstevel@tonic-gate * if the mapped attribute is found and attr is not empty, 45717c478bd9Sstevel@tonic-gate * copy it 45727c478bd9Sstevel@tonic-gate */ 45737c478bd9Sstevel@tonic-gate 45747c478bd9Sstevel@tonic-gate if (mapping[0] != NULL) { 45757c478bd9Sstevel@tonic-gate mapped_attr = strdup(mapping[0]); 45767c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapping); 45777c478bd9Sstevel@tonic-gate if (mapped_attr == NULL) { 45787c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 45797c478bd9Sstevel@tonic-gate } 45807c478bd9Sstevel@tonic-gate } else { 45817c478bd9Sstevel@tonic-gate __s_api_free2dArray(mapping); 45827c478bd9Sstevel@tonic-gate 45837c478bd9Sstevel@tonic-gate (void) snprintf(errstr, (2 * MAXERROR), 45847c478bd9Sstevel@tonic-gate gettext( 45857c478bd9Sstevel@tonic-gate "Attribute nisMapName is mapped to an " 45867c478bd9Sstevel@tonic-gate "empty string.\n")); 45877c478bd9Sstevel@tonic-gate 45887c478bd9Sstevel@tonic-gate MKERROR(LOG_ERR, *errp, NS_CONFIG_SYNTAX, 45897c478bd9Sstevel@tonic-gate strdup(errstr), NULL); 45907c478bd9Sstevel@tonic-gate 45917c478bd9Sstevel@tonic-gate return (NS_LDAP_CONFIG); 45927c478bd9Sstevel@tonic-gate } 45937c478bd9Sstevel@tonic-gate 45947c478bd9Sstevel@tonic-gate /* 45957c478bd9Sstevel@tonic-gate * Locate the mapped attribute in the dn 45967c478bd9Sstevel@tonic-gate * and replace it if it exists 45977c478bd9Sstevel@tonic-gate */ 45987c478bd9Sstevel@tonic-gate 45997c478bd9Sstevel@tonic-gate rc = __s_api_replace_mapped_attr_in_dn( 46007c478bd9Sstevel@tonic-gate (const char *) automountmapname, (const char *) mapped_attr, 46017c478bd9Sstevel@tonic-gate (const char *) *dn, &buffer); 46027c478bd9Sstevel@tonic-gate 46037c478bd9Sstevel@tonic-gate /* clean up */ 46047c478bd9Sstevel@tonic-gate 46057c478bd9Sstevel@tonic-gate free(mapped_attr); 46067c478bd9Sstevel@tonic-gate 46077c478bd9Sstevel@tonic-gate /* 46087c478bd9Sstevel@tonic-gate * If mapped attr is found(buffer != NULL) 46097c478bd9Sstevel@tonic-gate * a new dn is returned 46107c478bd9Sstevel@tonic-gate * If no mapped attribute is in dn, 46117c478bd9Sstevel@tonic-gate * return NS_LDAP_SUCCESS (no op) 46127c478bd9Sstevel@tonic-gate * If no memory, 46137c478bd9Sstevel@tonic-gate * return NS_LDAP_MEMORY (no op) 46147c478bd9Sstevel@tonic-gate */ 46157c478bd9Sstevel@tonic-gate 46167c478bd9Sstevel@tonic-gate if (buffer != NULL) { 46177c478bd9Sstevel@tonic-gate free(*dn); 46187c478bd9Sstevel@tonic-gate *dn = buffer; 46197c478bd9Sstevel@tonic-gate } 46207c478bd9Sstevel@tonic-gate 46217c478bd9Sstevel@tonic-gate return (rc); 46227c478bd9Sstevel@tonic-gate } 46237c478bd9Sstevel@tonic-gate 46247c478bd9Sstevel@tonic-gate /* 46257c478bd9Sstevel@tonic-gate * If the mapped attr is found in the dn, 46267c478bd9Sstevel@tonic-gate * return NS_LDAP_SUCCESS and a new_dn. 46277c478bd9Sstevel@tonic-gate * If no mapped attr is found, 46287c478bd9Sstevel@tonic-gate * return NS_LDAP_SUCCESS and *new_dn == NULL 46297c478bd9Sstevel@tonic-gate * If there is not enough memory, 46307c478bd9Sstevel@tonic-gate * return NS_LDAP_MEMORY and *new_dn == NULL 46317c478bd9Sstevel@tonic-gate */ 46327c478bd9Sstevel@tonic-gate 46337c478bd9Sstevel@tonic-gate int 46347c478bd9Sstevel@tonic-gate __s_api_replace_mapped_attr_in_dn( 46357c478bd9Sstevel@tonic-gate const char *orig_attr, const char *mapped_attr, 46367c478bd9Sstevel@tonic-gate const char *dn, char **new_dn) { 46377c478bd9Sstevel@tonic-gate 46387c478bd9Sstevel@tonic-gate char **dnArray = NULL; 46397c478bd9Sstevel@tonic-gate char *cur = NULL, *start = NULL; 46407c478bd9Sstevel@tonic-gate int i = 0, found = 0; 46417c478bd9Sstevel@tonic-gate int len = 0, orig_len = 0, mapped_len = 0; 46427c478bd9Sstevel@tonic-gate int dn_len = 0, tmp_len = 0; 46437c478bd9Sstevel@tonic-gate 46447c478bd9Sstevel@tonic-gate *new_dn = NULL; 46457c478bd9Sstevel@tonic-gate 46467c478bd9Sstevel@tonic-gate /* 46477c478bd9Sstevel@tonic-gate * seperate dn into individual componets 46487c478bd9Sstevel@tonic-gate * e.g. 46497c478bd9Sstevel@tonic-gate * "automountKey=user_01" , "automountMapName_test=auto_home", ... 46507c478bd9Sstevel@tonic-gate */ 46517c478bd9Sstevel@tonic-gate dnArray = ldap_explode_dn(dn, 0); 46527c478bd9Sstevel@tonic-gate 46537c478bd9Sstevel@tonic-gate /* 46547c478bd9Sstevel@tonic-gate * This will find "mapped attr=value" in dn. 46557c478bd9Sstevel@tonic-gate * It won't find match if mapped attr appears 46567c478bd9Sstevel@tonic-gate * in the value. 46577c478bd9Sstevel@tonic-gate */ 46587c478bd9Sstevel@tonic-gate for (i = 0; dnArray[i] != NULL; i++) { 46597c478bd9Sstevel@tonic-gate /* 46607c478bd9Sstevel@tonic-gate * This function is called when reading from 46617c478bd9Sstevel@tonic-gate * the directory so assume each component has "=". 46627c478bd9Sstevel@tonic-gate * Any ill formatted dn should be rejected 46637c478bd9Sstevel@tonic-gate * before adding to the directory 46647c478bd9Sstevel@tonic-gate */ 46657c478bd9Sstevel@tonic-gate cur = strchr(dnArray[i], '='); 46667c478bd9Sstevel@tonic-gate *cur = '\0'; 46677c478bd9Sstevel@tonic-gate if (strcasecmp(mapped_attr, dnArray[i]) == 0) 46687c478bd9Sstevel@tonic-gate found = 1; 46697c478bd9Sstevel@tonic-gate *cur = '='; 46707c478bd9Sstevel@tonic-gate if (found) break; 46717c478bd9Sstevel@tonic-gate } 46727c478bd9Sstevel@tonic-gate 46737c478bd9Sstevel@tonic-gate if (!found) { 46747c478bd9Sstevel@tonic-gate __s_api_free2dArray(dnArray); 46757c478bd9Sstevel@tonic-gate *new_dn = NULL; 46767c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 46777c478bd9Sstevel@tonic-gate } 46787c478bd9Sstevel@tonic-gate /* 46797c478bd9Sstevel@tonic-gate * The new length is *dn length + (difference between 46807c478bd9Sstevel@tonic-gate * orig attr and mapped attr) + 1 ; 46817c478bd9Sstevel@tonic-gate * e.g. 46827c478bd9Sstevel@tonic-gate * automountKey=aa,automountMapName_test=auto_home,dc=foo,dc=com 46837c478bd9Sstevel@tonic-gate * ==> 46847c478bd9Sstevel@tonic-gate * automountKey=aa,automountMapName=auto_home,dc=foo,dc=com 46857c478bd9Sstevel@tonic-gate */ 46867c478bd9Sstevel@tonic-gate mapped_len = strlen(mapped_attr); 46877c478bd9Sstevel@tonic-gate orig_len = strlen(orig_attr); 46887c478bd9Sstevel@tonic-gate dn_len = strlen(dn); 46897c478bd9Sstevel@tonic-gate len = dn_len + orig_len - mapped_len + 1; 46907c478bd9Sstevel@tonic-gate *new_dn = (char *)calloc(1, len); 46917c478bd9Sstevel@tonic-gate if (*new_dn == NULL) { 46927c478bd9Sstevel@tonic-gate __s_api_free2dArray(dnArray); 46937c478bd9Sstevel@tonic-gate return (NS_LDAP_MEMORY); 46947c478bd9Sstevel@tonic-gate } 46957c478bd9Sstevel@tonic-gate 46967c478bd9Sstevel@tonic-gate /* 46977c478bd9Sstevel@tonic-gate * Locate the mapped attr in the dn. 46987c478bd9Sstevel@tonic-gate * Use dnArray[i] instead of mapped_attr 46997c478bd9Sstevel@tonic-gate * because mapped_attr could appear in 47007c478bd9Sstevel@tonic-gate * the value 47017c478bd9Sstevel@tonic-gate */ 47027c478bd9Sstevel@tonic-gate 47037c478bd9Sstevel@tonic-gate cur = strstr(dn, dnArray[i]); 47047c478bd9Sstevel@tonic-gate __s_api_free2dArray(dnArray); 47057c478bd9Sstevel@tonic-gate /* copy the portion before mapped attr in dn */ 47067c478bd9Sstevel@tonic-gate start = *new_dn; 47077c478bd9Sstevel@tonic-gate tmp_len = cur - dn; 47087c478bd9Sstevel@tonic-gate (void) memcpy((void *) start, (const void*) dn, tmp_len); 47097c478bd9Sstevel@tonic-gate 47107c478bd9Sstevel@tonic-gate /* 47117c478bd9Sstevel@tonic-gate * Copy the orig_attr. e.g. automountMapName 47127c478bd9Sstevel@tonic-gate * This replaces mapped attr with orig attr 47137c478bd9Sstevel@tonic-gate */ 47147c478bd9Sstevel@tonic-gate start = start + (cur - dn); /* move cursor in buffer */ 47157c478bd9Sstevel@tonic-gate (void) memcpy((void *) start, (const void*) orig_attr, orig_len); 47167c478bd9Sstevel@tonic-gate 47177c478bd9Sstevel@tonic-gate /* 47187c478bd9Sstevel@tonic-gate * Copy the portion after mapped attr in dn 47197c478bd9Sstevel@tonic-gate */ 47207c478bd9Sstevel@tonic-gate cur = cur + mapped_len; /* move cursor in dn */ 47217c478bd9Sstevel@tonic-gate start = start + orig_len; /* move cursor in buffer */ 47227c478bd9Sstevel@tonic-gate (void) strcpy(start, cur); 47237c478bd9Sstevel@tonic-gate 47247c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 47257c478bd9Sstevel@tonic-gate } 47267c478bd9Sstevel@tonic-gate 47277c478bd9Sstevel@tonic-gate /* 47287c478bd9Sstevel@tonic-gate * Validate Filter functions 47297c478bd9Sstevel@tonic-gate */ 47307c478bd9Sstevel@tonic-gate 47317c478bd9Sstevel@tonic-gate /* ***** Start of modified libldap.so.5 filter parser ***** */ 47327c478bd9Sstevel@tonic-gate 47337c478bd9Sstevel@tonic-gate /* filter parsing routine forward references */ 47347c478bd9Sstevel@tonic-gate static int adj_filter_list(char *str); 47357c478bd9Sstevel@tonic-gate static int adj_simple_filter(char *str); 47367c478bd9Sstevel@tonic-gate static int unescape_filterval(char *val); 47377c478bd9Sstevel@tonic-gate static int hexchar2int(char c); 47387c478bd9Sstevel@tonic-gate static int adj_substring_filter(char *val); 47397c478bd9Sstevel@tonic-gate 47407c478bd9Sstevel@tonic-gate 47417c478bd9Sstevel@tonic-gate /* 47427c478bd9Sstevel@tonic-gate * assumes string manipulation is in-line 47437c478bd9Sstevel@tonic-gate * and all strings are sufficient in size 47447c478bd9Sstevel@tonic-gate * return value is the position after 'c' 47457c478bd9Sstevel@tonic-gate */ 47467c478bd9Sstevel@tonic-gate 47477c478bd9Sstevel@tonic-gate static char * 47487c478bd9Sstevel@tonic-gate resync_str(char *str, char *next, char c) 47497c478bd9Sstevel@tonic-gate { 47507c478bd9Sstevel@tonic-gate char *ret; 47517c478bd9Sstevel@tonic-gate 47527c478bd9Sstevel@tonic-gate ret = str + strlen(str); 47537c478bd9Sstevel@tonic-gate *next = c; 47547c478bd9Sstevel@tonic-gate if (ret == next) 47557c478bd9Sstevel@tonic-gate return (ret); 47567c478bd9Sstevel@tonic-gate (void) strcat(str, next); 47577c478bd9Sstevel@tonic-gate return (ret); 47587c478bd9Sstevel@tonic-gate } 47597c478bd9Sstevel@tonic-gate 47607c478bd9Sstevel@tonic-gate static char * 47617c478bd9Sstevel@tonic-gate find_right_paren(char *s) 47627c478bd9Sstevel@tonic-gate { 47637c478bd9Sstevel@tonic-gate int balance, escape; 47647c478bd9Sstevel@tonic-gate 47657c478bd9Sstevel@tonic-gate balance = 1; 47667c478bd9Sstevel@tonic-gate escape = 0; 47677c478bd9Sstevel@tonic-gate while (*s && balance) { 47687c478bd9Sstevel@tonic-gate if (escape == 0) { 47697c478bd9Sstevel@tonic-gate if (*s == '(') 47707c478bd9Sstevel@tonic-gate balance++; 47717c478bd9Sstevel@tonic-gate else if (*s == ')') 47727c478bd9Sstevel@tonic-gate balance--; 47737c478bd9Sstevel@tonic-gate } 47747c478bd9Sstevel@tonic-gate if (*s == '\\' && ! escape) 47757c478bd9Sstevel@tonic-gate escape = 1; 47767c478bd9Sstevel@tonic-gate else 47777c478bd9Sstevel@tonic-gate escape = 0; 47787c478bd9Sstevel@tonic-gate if (balance) 47797c478bd9Sstevel@tonic-gate s++; 47807c478bd9Sstevel@tonic-gate } 47817c478bd9Sstevel@tonic-gate 47827c478bd9Sstevel@tonic-gate return (*s ? s : NULL); 47837c478bd9Sstevel@tonic-gate } 47847c478bd9Sstevel@tonic-gate 47857c478bd9Sstevel@tonic-gate static char * 47867c478bd9Sstevel@tonic-gate adj_complex_filter(char *str) 47877c478bd9Sstevel@tonic-gate { 47887c478bd9Sstevel@tonic-gate char *next; 47897c478bd9Sstevel@tonic-gate 47907c478bd9Sstevel@tonic-gate /* 47917c478bd9Sstevel@tonic-gate * We have (x(filter)...) with str sitting on 47927c478bd9Sstevel@tonic-gate * the x. We have to find the paren matching 47937c478bd9Sstevel@tonic-gate * the one before the x and put the intervening 47947c478bd9Sstevel@tonic-gate * filters by calling adj_filter_list(). 47957c478bd9Sstevel@tonic-gate */ 47967c478bd9Sstevel@tonic-gate 47977c478bd9Sstevel@tonic-gate str++; 47987c478bd9Sstevel@tonic-gate if ((next = find_right_paren(str)) == NULL) 47997c478bd9Sstevel@tonic-gate return (NULL); 48007c478bd9Sstevel@tonic-gate 48017c478bd9Sstevel@tonic-gate *next = '\0'; 48027c478bd9Sstevel@tonic-gate if (adj_filter_list(str) == -1) 48037c478bd9Sstevel@tonic-gate return (NULL); 48047c478bd9Sstevel@tonic-gate next = resync_str(str, next, ')'); 48057c478bd9Sstevel@tonic-gate next++; 48067c478bd9Sstevel@tonic-gate 48077c478bd9Sstevel@tonic-gate return (next); 48087c478bd9Sstevel@tonic-gate } 48097c478bd9Sstevel@tonic-gate 48107c478bd9Sstevel@tonic-gate static int 48117c478bd9Sstevel@tonic-gate adj_filter(char *str) 48127c478bd9Sstevel@tonic-gate { 48137c478bd9Sstevel@tonic-gate char *next; 48147c478bd9Sstevel@tonic-gate int parens, balance, escape; 48157c478bd9Sstevel@tonic-gate char *np, *cp, *dp; 48167c478bd9Sstevel@tonic-gate 48177c478bd9Sstevel@tonic-gate parens = 0; 48187c478bd9Sstevel@tonic-gate while (*str) { 48197c478bd9Sstevel@tonic-gate switch (*str) { 48207c478bd9Sstevel@tonic-gate case '(': 48217c478bd9Sstevel@tonic-gate str++; 48227c478bd9Sstevel@tonic-gate parens++; 48237c478bd9Sstevel@tonic-gate switch (*str) { 48247c478bd9Sstevel@tonic-gate case '&': 48257c478bd9Sstevel@tonic-gate if ((str = adj_complex_filter(str)) == NULL) 48267c478bd9Sstevel@tonic-gate return (-1); 48277c478bd9Sstevel@tonic-gate 48287c478bd9Sstevel@tonic-gate parens--; 48297c478bd9Sstevel@tonic-gate break; 48307c478bd9Sstevel@tonic-gate 48317c478bd9Sstevel@tonic-gate case '|': 48327c478bd9Sstevel@tonic-gate if ((str = adj_complex_filter(str)) == NULL) 48337c478bd9Sstevel@tonic-gate return (-1); 48347c478bd9Sstevel@tonic-gate 48357c478bd9Sstevel@tonic-gate parens--; 48367c478bd9Sstevel@tonic-gate break; 48377c478bd9Sstevel@tonic-gate 48387c478bd9Sstevel@tonic-gate case '!': 48397c478bd9Sstevel@tonic-gate if ((str = adj_complex_filter(str)) == NULL) 48407c478bd9Sstevel@tonic-gate return (-1); 48417c478bd9Sstevel@tonic-gate 48427c478bd9Sstevel@tonic-gate parens--; 48437c478bd9Sstevel@tonic-gate break; 48447c478bd9Sstevel@tonic-gate 48457c478bd9Sstevel@tonic-gate case '(': 48467c478bd9Sstevel@tonic-gate /* illegal ((case - generated by conversion */ 48477c478bd9Sstevel@tonic-gate 48487c478bd9Sstevel@tonic-gate /* find missing close) */ 48497c478bd9Sstevel@tonic-gate np = find_right_paren(str+1); 48507c478bd9Sstevel@tonic-gate 48517c478bd9Sstevel@tonic-gate /* error if not found */ 48527c478bd9Sstevel@tonic-gate if (np == NULL) 48537c478bd9Sstevel@tonic-gate return (-1); 48547c478bd9Sstevel@tonic-gate 48557c478bd9Sstevel@tonic-gate /* remove redundant (and) */ 48567c478bd9Sstevel@tonic-gate for (dp = str, cp = str+1; cp < np; ) { 48577c478bd9Sstevel@tonic-gate *dp++ = *cp++; 48587c478bd9Sstevel@tonic-gate } 48597c478bd9Sstevel@tonic-gate cp++; 48607c478bd9Sstevel@tonic-gate while (*cp) 48617c478bd9Sstevel@tonic-gate *dp++ = *cp++; 48627c478bd9Sstevel@tonic-gate *dp = '\0'; 48637c478bd9Sstevel@tonic-gate 48647c478bd9Sstevel@tonic-gate /* re-start test at original ( */ 48657c478bd9Sstevel@tonic-gate parens--; 48667c478bd9Sstevel@tonic-gate str--; 48677c478bd9Sstevel@tonic-gate break; 48687c478bd9Sstevel@tonic-gate 48697c478bd9Sstevel@tonic-gate default: 48707c478bd9Sstevel@tonic-gate balance = 1; 48717c478bd9Sstevel@tonic-gate escape = 0; 48727c478bd9Sstevel@tonic-gate next = str; 48737c478bd9Sstevel@tonic-gate while (*next && balance) { 48747c478bd9Sstevel@tonic-gate if (escape == 0) { 48757c478bd9Sstevel@tonic-gate if (*next == '(') 48767c478bd9Sstevel@tonic-gate balance++; 48777c478bd9Sstevel@tonic-gate else if (*next == ')') 48787c478bd9Sstevel@tonic-gate balance--; 48797c478bd9Sstevel@tonic-gate } 48807c478bd9Sstevel@tonic-gate if (*next == '\\' && ! escape) 48817c478bd9Sstevel@tonic-gate escape = 1; 48827c478bd9Sstevel@tonic-gate else 48837c478bd9Sstevel@tonic-gate escape = 0; 48847c478bd9Sstevel@tonic-gate if (balance) 48857c478bd9Sstevel@tonic-gate next++; 48867c478bd9Sstevel@tonic-gate } 48877c478bd9Sstevel@tonic-gate if (balance != 0) 48887c478bd9Sstevel@tonic-gate return (-1); 48897c478bd9Sstevel@tonic-gate 48907c478bd9Sstevel@tonic-gate *next = '\0'; 48917c478bd9Sstevel@tonic-gate if (adj_simple_filter(str) == -1) { 48927c478bd9Sstevel@tonic-gate return (-1); 48937c478bd9Sstevel@tonic-gate } 48947c478bd9Sstevel@tonic-gate next = resync_str(str, next, ')'); 48957c478bd9Sstevel@tonic-gate next++; 48967c478bd9Sstevel@tonic-gate str = next; 48977c478bd9Sstevel@tonic-gate parens--; 48987c478bd9Sstevel@tonic-gate break; 48997c478bd9Sstevel@tonic-gate } 49007c478bd9Sstevel@tonic-gate break; 49017c478bd9Sstevel@tonic-gate 49027c478bd9Sstevel@tonic-gate case ')': 49037c478bd9Sstevel@tonic-gate str++; 49047c478bd9Sstevel@tonic-gate parens--; 49057c478bd9Sstevel@tonic-gate break; 49067c478bd9Sstevel@tonic-gate 49077c478bd9Sstevel@tonic-gate case ' ': 49087c478bd9Sstevel@tonic-gate str++; 49097c478bd9Sstevel@tonic-gate break; 49107c478bd9Sstevel@tonic-gate 49117c478bd9Sstevel@tonic-gate default: /* assume it's a simple type=value filter */ 49127c478bd9Sstevel@tonic-gate next = strchr(str, '\0'); 49137c478bd9Sstevel@tonic-gate if (adj_simple_filter(str) == -1) { 49147c478bd9Sstevel@tonic-gate return (-1); 49157c478bd9Sstevel@tonic-gate } 49167c478bd9Sstevel@tonic-gate str = next; 49177c478bd9Sstevel@tonic-gate break; 49187c478bd9Sstevel@tonic-gate } 49197c478bd9Sstevel@tonic-gate } 49207c478bd9Sstevel@tonic-gate 49217c478bd9Sstevel@tonic-gate return (parens ? -1 : 0); 49227c478bd9Sstevel@tonic-gate } 49237c478bd9Sstevel@tonic-gate 49247c478bd9Sstevel@tonic-gate 49257c478bd9Sstevel@tonic-gate /* 49267c478bd9Sstevel@tonic-gate * Put a list of filters like this "(filter1)(filter2)..." 49277c478bd9Sstevel@tonic-gate */ 49287c478bd9Sstevel@tonic-gate 49297c478bd9Sstevel@tonic-gate static int 49307c478bd9Sstevel@tonic-gate adj_filter_list(char *str) 49317c478bd9Sstevel@tonic-gate { 49327c478bd9Sstevel@tonic-gate char *next; 49337c478bd9Sstevel@tonic-gate char save; 49347c478bd9Sstevel@tonic-gate 49357c478bd9Sstevel@tonic-gate while (*str) { 49367c478bd9Sstevel@tonic-gate while (*str && isspace(*str)) 49377c478bd9Sstevel@tonic-gate str++; 49387c478bd9Sstevel@tonic-gate if (*str == '\0') 49397c478bd9Sstevel@tonic-gate break; 49407c478bd9Sstevel@tonic-gate 49417c478bd9Sstevel@tonic-gate if ((next = find_right_paren(str + 1)) == NULL) 49427c478bd9Sstevel@tonic-gate return (-1); 49437c478bd9Sstevel@tonic-gate save = *++next; 49447c478bd9Sstevel@tonic-gate 49457c478bd9Sstevel@tonic-gate /* now we have "(filter)" with str pointing to it */ 49467c478bd9Sstevel@tonic-gate *next = '\0'; 49477c478bd9Sstevel@tonic-gate if (adj_filter(str) == -1) 49487c478bd9Sstevel@tonic-gate return (-1); 49497c478bd9Sstevel@tonic-gate next = resync_str(str, next, save); 49507c478bd9Sstevel@tonic-gate 49517c478bd9Sstevel@tonic-gate str = next; 49527c478bd9Sstevel@tonic-gate } 49537c478bd9Sstevel@tonic-gate 49547c478bd9Sstevel@tonic-gate return (0); 49557c478bd9Sstevel@tonic-gate } 49567c478bd9Sstevel@tonic-gate 49577c478bd9Sstevel@tonic-gate 49587c478bd9Sstevel@tonic-gate /* 49597c478bd9Sstevel@tonic-gate * is_valid_attr - returns 1 if a is a syntactically valid left-hand side 49607c478bd9Sstevel@tonic-gate * of a filter expression, 0 otherwise. A valid string may contain only 49617c478bd9Sstevel@tonic-gate * letters, numbers, hyphens, semi-colons, colons and periods. examples: 49627c478bd9Sstevel@tonic-gate * cn 49637c478bd9Sstevel@tonic-gate * cn;lang-fr 49647c478bd9Sstevel@tonic-gate * 1.2.3.4;binary;dynamic 49657c478bd9Sstevel@tonic-gate * mail;dynamic 49667c478bd9Sstevel@tonic-gate * cn:dn:1.2.3.4 49677c478bd9Sstevel@tonic-gate * 49687c478bd9Sstevel@tonic-gate * For compatibility with older servers, we also allow underscores in 49697c478bd9Sstevel@tonic-gate * attribute types, even through they are not allowed by the LDAPv3 RFCs. 49707c478bd9Sstevel@tonic-gate */ 49717c478bd9Sstevel@tonic-gate static int 49727c478bd9Sstevel@tonic-gate is_valid_attr(char *a) 49737c478bd9Sstevel@tonic-gate { 49747c478bd9Sstevel@tonic-gate for (; *a; a++) { 49757c478bd9Sstevel@tonic-gate if (!isascii(*a)) { 49767c478bd9Sstevel@tonic-gate return (0); 49777c478bd9Sstevel@tonic-gate } else if (!isalnum(*a)) { 49787c478bd9Sstevel@tonic-gate switch (*a) { 49797c478bd9Sstevel@tonic-gate case '-': 49807c478bd9Sstevel@tonic-gate case '.': 49817c478bd9Sstevel@tonic-gate case ';': 49827c478bd9Sstevel@tonic-gate case ':': 49837c478bd9Sstevel@tonic-gate case '_': 49847c478bd9Sstevel@tonic-gate break; /* valid */ 49857c478bd9Sstevel@tonic-gate default: 49867c478bd9Sstevel@tonic-gate return (0); 49877c478bd9Sstevel@tonic-gate } 49887c478bd9Sstevel@tonic-gate } 49897c478bd9Sstevel@tonic-gate } 49907c478bd9Sstevel@tonic-gate return (1); 49917c478bd9Sstevel@tonic-gate } 49927c478bd9Sstevel@tonic-gate 49937c478bd9Sstevel@tonic-gate static char * 49947c478bd9Sstevel@tonic-gate find_star(char *s) 49957c478bd9Sstevel@tonic-gate { 49967c478bd9Sstevel@tonic-gate for (; *s; ++s) { 49977c478bd9Sstevel@tonic-gate switch (*s) { 49987c478bd9Sstevel@tonic-gate case '*': 49997c478bd9Sstevel@tonic-gate return (s); 50007c478bd9Sstevel@tonic-gate case '\\': 50017c478bd9Sstevel@tonic-gate ++s; 50027c478bd9Sstevel@tonic-gate if (hexchar2int(s[0]) >= 0 && hexchar2int(s[1]) >= 0) 50037c478bd9Sstevel@tonic-gate ++s; 50047c478bd9Sstevel@tonic-gate default: 50057c478bd9Sstevel@tonic-gate break; 50067c478bd9Sstevel@tonic-gate } 50077c478bd9Sstevel@tonic-gate } 50087c478bd9Sstevel@tonic-gate return (NULL); 50097c478bd9Sstevel@tonic-gate } 50107c478bd9Sstevel@tonic-gate 50117c478bd9Sstevel@tonic-gate static int 50127c478bd9Sstevel@tonic-gate adj_simple_filter(char *str) 50137c478bd9Sstevel@tonic-gate { 50147c478bd9Sstevel@tonic-gate char *s, *s2, *s3, filterop; 50157c478bd9Sstevel@tonic-gate char *value; 50167c478bd9Sstevel@tonic-gate int ftype = 0; 50177c478bd9Sstevel@tonic-gate int rc; 50187c478bd9Sstevel@tonic-gate 50197c478bd9Sstevel@tonic-gate rc = -1; /* pessimistic */ 50207c478bd9Sstevel@tonic-gate 50217c478bd9Sstevel@tonic-gate if ((str = strdup(str)) == NULL) { 50227c478bd9Sstevel@tonic-gate return (rc); 50237c478bd9Sstevel@tonic-gate } 50247c478bd9Sstevel@tonic-gate 50257c478bd9Sstevel@tonic-gate if ((s = strchr(str, '=')) == NULL) { 50267c478bd9Sstevel@tonic-gate goto free_and_return; 50277c478bd9Sstevel@tonic-gate } 50287c478bd9Sstevel@tonic-gate value = s + 1; 50297c478bd9Sstevel@tonic-gate *s-- = '\0'; 50307c478bd9Sstevel@tonic-gate filterop = *s; 50317c478bd9Sstevel@tonic-gate if (filterop == '<' || filterop == '>' || filterop == '~' || 50327c478bd9Sstevel@tonic-gate filterop == ':') { 50337c478bd9Sstevel@tonic-gate *s = '\0'; 50347c478bd9Sstevel@tonic-gate } 50357c478bd9Sstevel@tonic-gate 50367c478bd9Sstevel@tonic-gate if (! is_valid_attr(str)) { 50377c478bd9Sstevel@tonic-gate goto free_and_return; 50387c478bd9Sstevel@tonic-gate } 50397c478bd9Sstevel@tonic-gate 50407c478bd9Sstevel@tonic-gate switch (filterop) { 50417c478bd9Sstevel@tonic-gate case '<': /* LDAP_FILTER_LE */ 50427c478bd9Sstevel@tonic-gate case '>': /* LDAP_FILTER_GE */ 50437c478bd9Sstevel@tonic-gate case '~': /* LDAP_FILTER_APPROX */ 50447c478bd9Sstevel@tonic-gate break; 50457c478bd9Sstevel@tonic-gate case ':': /* extended filter - v3 only */ 50467c478bd9Sstevel@tonic-gate /* 50477c478bd9Sstevel@tonic-gate * extended filter looks like this: 50487c478bd9Sstevel@tonic-gate * 50497c478bd9Sstevel@tonic-gate * [type][':dn'][':'oid]':='value 50507c478bd9Sstevel@tonic-gate * 50517c478bd9Sstevel@tonic-gate * where one of type or :oid is required. 50527c478bd9Sstevel@tonic-gate * 50537c478bd9Sstevel@tonic-gate */ 50547c478bd9Sstevel@tonic-gate s2 = s3 = NULL; 50557c478bd9Sstevel@tonic-gate if ((s2 = strrchr(str, ':')) == NULL) { 50567c478bd9Sstevel@tonic-gate goto free_and_return; 50577c478bd9Sstevel@tonic-gate } 50587c478bd9Sstevel@tonic-gate if (strcasecmp(s2, ":dn") == 0) { 50597c478bd9Sstevel@tonic-gate *s2 = '\0'; 50607c478bd9Sstevel@tonic-gate } else { 50617c478bd9Sstevel@tonic-gate *s2 = '\0'; 50627c478bd9Sstevel@tonic-gate if ((s3 = strrchr(str, ':')) != NULL) { 50637c478bd9Sstevel@tonic-gate if (strcasecmp(s3, ":dn") != 0) { 50647c478bd9Sstevel@tonic-gate goto free_and_return; 50657c478bd9Sstevel@tonic-gate } 50667c478bd9Sstevel@tonic-gate *s3 = '\0'; 50677c478bd9Sstevel@tonic-gate } 50687c478bd9Sstevel@tonic-gate } 50697c478bd9Sstevel@tonic-gate if (unescape_filterval(value) < 0) { 50707c478bd9Sstevel@tonic-gate goto free_and_return; 50717c478bd9Sstevel@tonic-gate } 50727c478bd9Sstevel@tonic-gate rc = 0; 50737c478bd9Sstevel@tonic-gate goto free_and_return; 50747c478bd9Sstevel@tonic-gate /* break; */ 50757c478bd9Sstevel@tonic-gate default: 50767c478bd9Sstevel@tonic-gate if (find_star(value) == NULL) { 50777c478bd9Sstevel@tonic-gate ftype = 0; /* LDAP_FILTER_EQUALITY */ 50787c478bd9Sstevel@tonic-gate } else if (strcmp(value, "*") == 0) { 50797c478bd9Sstevel@tonic-gate ftype = 1; /* LDAP_FILTER_PRESENT */ 50807c478bd9Sstevel@tonic-gate } else { 50817c478bd9Sstevel@tonic-gate rc = adj_substring_filter(value); 50827c478bd9Sstevel@tonic-gate goto free_and_return; 50837c478bd9Sstevel@tonic-gate } 50847c478bd9Sstevel@tonic-gate break; 50857c478bd9Sstevel@tonic-gate } 50867c478bd9Sstevel@tonic-gate 50877c478bd9Sstevel@tonic-gate if (ftype != 0) { /* == LDAP_FILTER_PRESENT */ 50887c478bd9Sstevel@tonic-gate rc = 0; 50897c478bd9Sstevel@tonic-gate } else if (unescape_filterval(value) >= 0) { 50907c478bd9Sstevel@tonic-gate rc = 0; 50917c478bd9Sstevel@tonic-gate } 50927c478bd9Sstevel@tonic-gate if (rc != -1) { 50937c478bd9Sstevel@tonic-gate rc = 0; 50947c478bd9Sstevel@tonic-gate } 50957c478bd9Sstevel@tonic-gate 50967c478bd9Sstevel@tonic-gate free_and_return: 50977c478bd9Sstevel@tonic-gate free(str); 50987c478bd9Sstevel@tonic-gate return (rc); 50997c478bd9Sstevel@tonic-gate } 51007c478bd9Sstevel@tonic-gate 51017c478bd9Sstevel@tonic-gate 51027c478bd9Sstevel@tonic-gate /* 51037c478bd9Sstevel@tonic-gate * Check in place both LDAPv2 (RFC-1960) and LDAPv3 (hexadecimal) escape 51047c478bd9Sstevel@tonic-gate * sequences within the null-terminated string 'val'. 51057c478bd9Sstevel@tonic-gate * 51067c478bd9Sstevel@tonic-gate * If 'val' contains invalid escape sequences we return -1. 51077c478bd9Sstevel@tonic-gate * Otherwise return 1 51087c478bd9Sstevel@tonic-gate */ 51097c478bd9Sstevel@tonic-gate static int 51107c478bd9Sstevel@tonic-gate unescape_filterval(char *val) 51117c478bd9Sstevel@tonic-gate { 51127c478bd9Sstevel@tonic-gate int escape, firstdigit; 51137c478bd9Sstevel@tonic-gate char *s; 51147c478bd9Sstevel@tonic-gate 51157c478bd9Sstevel@tonic-gate firstdigit = 0; 51167c478bd9Sstevel@tonic-gate escape = 0; 51177c478bd9Sstevel@tonic-gate for (s = val; *s; s++) { 51187c478bd9Sstevel@tonic-gate if (escape) { 51197c478bd9Sstevel@tonic-gate /* 51207c478bd9Sstevel@tonic-gate * first try LDAPv3 escape (hexadecimal) sequence 51217c478bd9Sstevel@tonic-gate */ 51227c478bd9Sstevel@tonic-gate if (hexchar2int(*s) < 0) { 51237c478bd9Sstevel@tonic-gate if (firstdigit) { 51247c478bd9Sstevel@tonic-gate /* 51257c478bd9Sstevel@tonic-gate * LDAPv2 (RFC1960) escape sequence 51267c478bd9Sstevel@tonic-gate */ 51277c478bd9Sstevel@tonic-gate escape = 0; 51287c478bd9Sstevel@tonic-gate } else { 51297c478bd9Sstevel@tonic-gate return (-1); 51307c478bd9Sstevel@tonic-gate } 51317c478bd9Sstevel@tonic-gate } 51327c478bd9Sstevel@tonic-gate if (firstdigit) { 51337c478bd9Sstevel@tonic-gate firstdigit = 0; 51347c478bd9Sstevel@tonic-gate } else { 51357c478bd9Sstevel@tonic-gate escape = 0; 51367c478bd9Sstevel@tonic-gate } 51377c478bd9Sstevel@tonic-gate 51387c478bd9Sstevel@tonic-gate } else if (*s != '\\') { 51397c478bd9Sstevel@tonic-gate escape = 0; 51407c478bd9Sstevel@tonic-gate 51417c478bd9Sstevel@tonic-gate } else { 51427c478bd9Sstevel@tonic-gate escape = 1; 51437c478bd9Sstevel@tonic-gate firstdigit = 1; 51447c478bd9Sstevel@tonic-gate } 51457c478bd9Sstevel@tonic-gate } 51467c478bd9Sstevel@tonic-gate 51477c478bd9Sstevel@tonic-gate return (1); 51487c478bd9Sstevel@tonic-gate } 51497c478bd9Sstevel@tonic-gate 51507c478bd9Sstevel@tonic-gate 51517c478bd9Sstevel@tonic-gate /* 51527c478bd9Sstevel@tonic-gate * convert character 'c' that represents a hexadecimal digit to an integer. 51537c478bd9Sstevel@tonic-gate * if 'c' is not a hexidecimal digit [0-9A-Fa-f], -1 is returned. 51547c478bd9Sstevel@tonic-gate * otherwise the converted value is returned. 51557c478bd9Sstevel@tonic-gate */ 51567c478bd9Sstevel@tonic-gate static int 51577c478bd9Sstevel@tonic-gate hexchar2int(char c) 51587c478bd9Sstevel@tonic-gate { 51597c478bd9Sstevel@tonic-gate if (c >= '0' && c <= '9') { 51607c478bd9Sstevel@tonic-gate return (c - '0'); 51617c478bd9Sstevel@tonic-gate } 51627c478bd9Sstevel@tonic-gate if (c >= 'A' && c <= 'F') { 51637c478bd9Sstevel@tonic-gate return (c - 'A' + 10); 51647c478bd9Sstevel@tonic-gate } 51657c478bd9Sstevel@tonic-gate if (c >= 'a' && c <= 'f') { 51667c478bd9Sstevel@tonic-gate return (c - 'a' + 10); 51677c478bd9Sstevel@tonic-gate } 51687c478bd9Sstevel@tonic-gate return (-1); 51697c478bd9Sstevel@tonic-gate } 51707c478bd9Sstevel@tonic-gate 51717c478bd9Sstevel@tonic-gate static int 51727c478bd9Sstevel@tonic-gate adj_substring_filter(char *val) 51737c478bd9Sstevel@tonic-gate { 51747c478bd9Sstevel@tonic-gate char *nextstar; 51757c478bd9Sstevel@tonic-gate 51767c478bd9Sstevel@tonic-gate for (; val != NULL; val = nextstar) { 51777c478bd9Sstevel@tonic-gate if ((nextstar = find_star(val)) != NULL) { 51787c478bd9Sstevel@tonic-gate *nextstar++ = '\0'; 51797c478bd9Sstevel@tonic-gate } 51807c478bd9Sstevel@tonic-gate 51817c478bd9Sstevel@tonic-gate if (*val != '\0') { 51827c478bd9Sstevel@tonic-gate if (unescape_filterval(val) < 0) { 51837c478bd9Sstevel@tonic-gate return (-1); 51847c478bd9Sstevel@tonic-gate } 51857c478bd9Sstevel@tonic-gate } 51867c478bd9Sstevel@tonic-gate } 51877c478bd9Sstevel@tonic-gate 51887c478bd9Sstevel@tonic-gate return (0); 51897c478bd9Sstevel@tonic-gate } 51907c478bd9Sstevel@tonic-gate 51917c478bd9Sstevel@tonic-gate /* ***** End of modified libldap.so.5 filter parser ***** */ 51927c478bd9Sstevel@tonic-gate 51937c478bd9Sstevel@tonic-gate 51947c478bd9Sstevel@tonic-gate /* 51957c478bd9Sstevel@tonic-gate * Walk filter, remove redundant parentheses in-line 51967c478bd9Sstevel@tonic-gate * verify that the filter is reasonable 51977c478bd9Sstevel@tonic-gate */ 51987c478bd9Sstevel@tonic-gate static int 51997c478bd9Sstevel@tonic-gate validate_filter(ns_ldap_cookie_t *cookie) 52007c478bd9Sstevel@tonic-gate { 52017c478bd9Sstevel@tonic-gate char *filter = cookie->filter; 52027c478bd9Sstevel@tonic-gate int rc; 52037c478bd9Sstevel@tonic-gate 52047c478bd9Sstevel@tonic-gate /* Parse filter looking for illegal values */ 52057c478bd9Sstevel@tonic-gate 52067c478bd9Sstevel@tonic-gate rc = adj_filter(filter); 52077c478bd9Sstevel@tonic-gate if (rc != 0) { 52087c478bd9Sstevel@tonic-gate return (NS_LDAP_OP_FAILED); 52097c478bd9Sstevel@tonic-gate } 52107c478bd9Sstevel@tonic-gate 52117c478bd9Sstevel@tonic-gate /* end of filter checking */ 52127c478bd9Sstevel@tonic-gate 52137c478bd9Sstevel@tonic-gate return (NS_LDAP_SUCCESS); 52147c478bd9Sstevel@tonic-gate } 521547789246Svv149972 521647789246Svv149972 /* 521747789246Svv149972 * Set the account management request control that needs to be sent to server. 521847789246Svv149972 * This control is required to get the account management information of 521947789246Svv149972 * a user to do local account checking. 522047789246Svv149972 */ 522147789246Svv149972 static int 522247789246Svv149972 setup_acctmgmt_params(ns_ldap_cookie_t *cookie) 522347789246Svv149972 { 522447789246Svv149972 LDAPControl *req = NULL, **requestctrls; 522547789246Svv149972 522647789246Svv149972 req = (LDAPControl *)malloc(sizeof (LDAPControl)); 522747789246Svv149972 522847789246Svv149972 if (req == NULL) 522947789246Svv149972 return (NS_LDAP_MEMORY); 523047789246Svv149972 523147789246Svv149972 /* fill in the fields of this new control */ 523247789246Svv149972 req->ldctl_iscritical = 1; 523347789246Svv149972 req->ldctl_oid = strdup(NS_LDAP_ACCOUNT_USABLE_CONTROL); 523447789246Svv149972 if (req->ldctl_oid == NULL) { 523547789246Svv149972 free(req); 523647789246Svv149972 return (NS_LDAP_MEMORY); 523747789246Svv149972 } 523847789246Svv149972 req->ldctl_value.bv_len = 0; 523947789246Svv149972 req->ldctl_value.bv_val = NULL; 524047789246Svv149972 524147789246Svv149972 requestctrls = (LDAPControl **)calloc(2, sizeof (LDAPControl *)); 524247789246Svv149972 if (requestctrls == NULL) { 524347789246Svv149972 ldap_control_free(req); 524447789246Svv149972 return (NS_LDAP_MEMORY); 524547789246Svv149972 } 524647789246Svv149972 524747789246Svv149972 requestctrls[0] = req; 524847789246Svv149972 524947789246Svv149972 cookie->p_serverctrls = requestctrls; 525047789246Svv149972 525147789246Svv149972 return (NS_LDAP_SUCCESS); 525247789246Svv149972 } 525347789246Svv149972 525447789246Svv149972 /* 5255f47dc443Ssdussud * int get_new_acct_more_info(BerElement *ber, 5256f47dc443Ssdussud * AcctUsableResponse_t *acctResp) 5257f47dc443Ssdussud * 5258f47dc443Ssdussud * Decode the more_info data from an Account Management control response, 5259f47dc443Ssdussud * when the account is not usable and when code style is from recent LDAP 5260f47dc443Ssdussud * servers (see below comments for parse_acct_cont_resp_msg() to get more 5261f47dc443Ssdussud * details on coding styles and ASN1 description). 5262f47dc443Ssdussud * 5263f47dc443Ssdussud * Expected BER encoding: {tbtbtbtiti} 526447789246Svv149972 * +t: tag is 0 526547789246Svv149972 * +b: TRUE if inactive due to account inactivation 5266f47dc443Ssdussud * +t: tag is 1 526747789246Svv149972 * +b: TRUE if password has been reset 5268f47dc443Ssdussud * +t: tag is 2 526947789246Svv149972 * +b: TRUE if password is expired 5270f47dc443Ssdussud * +t: tag is 3 5271f47dc443Ssdussud * +i: contains num of remaining grace, 0 means no grace 5272f47dc443Ssdussud * +t: tag is 4 5273f47dc443Ssdussud * +i: contains num of seconds before auto-unlock. -1 means acct is locked 5274f47dc443Ssdussud * forever (i.e. until reset) 5275f47dc443Ssdussud * 5276f47dc443Ssdussud * Asumptions: 5277f47dc443Ssdussud * - ber is not null 5278f47dc443Ssdussud * - acctResp is not null and is initialized with default values for the 5279f47dc443Ssdussud * fields in its AcctUsableResp.more_info structure 5280f47dc443Ssdussud * - the ber stream is received in the correct order, per the ASN1 description. 5281f47dc443Ssdussud * We do not check this order and make the asumption that it is correct. 5282f47dc443Ssdussud * Note that the ber stream may not (and will not in most cases) contain 5283f47dc443Ssdussud * all fields. 5284f47dc443Ssdussud */ 5285f47dc443Ssdussud static int 5286f47dc443Ssdussud get_new_acct_more_info(BerElement *ber, AcctUsableResponse_t *acctResp) 5287f47dc443Ssdussud { 5288f47dc443Ssdussud int rc = NS_LDAP_SUCCESS; 5289f47dc443Ssdussud char errstr[MAXERROR]; 5290f47dc443Ssdussud ber_tag_t rTag = LBER_DEFAULT; 5291f47dc443Ssdussud ber_len_t rLen = 0; 5292f47dc443Ssdussud ber_int_t rValue; 5293f47dc443Ssdussud char *last; 5294f47dc443Ssdussud int berRC = 0; 5295f47dc443Ssdussud 5296f47dc443Ssdussud /* 5297f47dc443Ssdussud * Look at what more_info BER element is/are left to be decoded. 5298f47dc443Ssdussud * look at each of them 1 by 1, without checking on their order 5299f47dc443Ssdussud * and possible multi values. 5300f47dc443Ssdussud */ 5301f47dc443Ssdussud for (rTag = ber_first_element(ber, &rLen, &last); 5302f47dc443Ssdussud rTag != LBER_END_OF_SEQORSET; 5303f47dc443Ssdussud rTag = ber_next_element(ber, &rLen, last)) { 5304f47dc443Ssdussud 5305f47dc443Ssdussud berRC = 0; 5306f47dc443Ssdussud switch (rTag) { 5307f47dc443Ssdussud case 0 | LBER_CLASS_CONTEXT | LBER_PRIMITIVE: 5308f47dc443Ssdussud /* inactive */ 5309f47dc443Ssdussud berRC = ber_scanf(ber, "b", &rValue); 5310f47dc443Ssdussud if (berRC != LBER_ERROR) { 5311f47dc443Ssdussud (acctResp->AcctUsableResp).more_info. 5312f47dc443Ssdussud inactive = (rValue != 0) ? 1 : 0; 5313f47dc443Ssdussud } 5314f47dc443Ssdussud break; 5315f47dc443Ssdussud 5316f47dc443Ssdussud case 1 | LBER_CLASS_CONTEXT | LBER_PRIMITIVE: 5317f47dc443Ssdussud /* reset */ 5318f47dc443Ssdussud berRC = ber_scanf(ber, "b", &rValue); 5319f47dc443Ssdussud if (berRC != LBER_ERROR) { 5320f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.reset 5321f47dc443Ssdussud = (rValue != 0) ? 1 : 0; 5322f47dc443Ssdussud } 5323f47dc443Ssdussud break; 5324f47dc443Ssdussud 5325f47dc443Ssdussud case 2 | LBER_CLASS_CONTEXT | LBER_PRIMITIVE: 5326f47dc443Ssdussud /* expired */ 5327f47dc443Ssdussud berRC = ber_scanf(ber, "b", &rValue); 5328f47dc443Ssdussud if (berRC != LBER_ERROR) { 5329f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.expired 5330f47dc443Ssdussud = (rValue != 0) ? 1 : 0; 5331f47dc443Ssdussud } 5332f47dc443Ssdussud break; 5333f47dc443Ssdussud 5334f47dc443Ssdussud case 3 | LBER_CLASS_CONTEXT | LBER_PRIMITIVE: 5335f47dc443Ssdussud /* remaining grace */ 5336f47dc443Ssdussud berRC = ber_scanf(ber, "i", &rValue); 5337f47dc443Ssdussud if (berRC != LBER_ERROR) { 5338f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.rem_grace 5339f47dc443Ssdussud = rValue; 5340f47dc443Ssdussud } 5341f47dc443Ssdussud break; 5342f47dc443Ssdussud 5343f47dc443Ssdussud case 4 | LBER_CLASS_CONTEXT | LBER_PRIMITIVE: 5344f47dc443Ssdussud /* seconds before unlock */ 5345f47dc443Ssdussud berRC = ber_scanf(ber, "i", &rValue); 5346f47dc443Ssdussud if (berRC != LBER_ERROR) { 5347f47dc443Ssdussud (acctResp->AcctUsableResp).more_info. 5348f47dc443Ssdussud sec_b4_unlock = rValue; 5349f47dc443Ssdussud } 5350f47dc443Ssdussud break; 5351f47dc443Ssdussud 5352f47dc443Ssdussud default : 5353f47dc443Ssdussud (void) sprintf(errstr, 5354f47dc443Ssdussud gettext("invalid reason tag 0x%x"), rTag); 5355f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5356f47dc443Ssdussud rc = NS_LDAP_INTERNAL; 5357f47dc443Ssdussud break; 5358f47dc443Ssdussud } 5359f47dc443Ssdussud if (berRC == LBER_ERROR) { 5360f47dc443Ssdussud (void) sprintf(errstr, 5361f47dc443Ssdussud gettext("error 0x%x decoding value for " 5362f47dc443Ssdussud "tag 0x%x"), berRC, rTag); 5363f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5364f47dc443Ssdussud rc = NS_LDAP_INTERNAL; 5365f47dc443Ssdussud } 5366f47dc443Ssdussud if (rc != NS_LDAP_SUCCESS) { 5367f47dc443Ssdussud /* exit the for loop */ 5368f47dc443Ssdussud break; 5369f47dc443Ssdussud } 5370f47dc443Ssdussud } 5371f47dc443Ssdussud 5372f47dc443Ssdussud return (rc); 5373f47dc443Ssdussud } 5374f47dc443Ssdussud 5375f47dc443Ssdussud /* 5376f47dc443Ssdussud * int get_old_acct_opt_more_info(BerElement *ber, 5377f47dc443Ssdussud * AcctUsableResponse_t *acctResp) 5378f47dc443Ssdussud * 5379f47dc443Ssdussud * Decode the optional more_info data from an Account Management control 5380f47dc443Ssdussud * response, when the account is not usable and when code style is from LDAP 5381f47dc443Ssdussud * server 5.2p4 (see below comments for parse_acct_cont_resp_msg() to get more 5382f47dc443Ssdussud * details on coding styles and ASN1 description). 5383f47dc443Ssdussud * 5384f47dc443Ssdussud * Expected BER encoding: titi} 538547789246Svv149972 * +t: tag is 2 538647789246Svv149972 * +i: contains num of remaining grace, 0 means no grace 538747789246Svv149972 * +t: tag is 3 538847789246Svv149972 * +i: contains num of seconds before auto-unlock. -1 means acct is locked 538947789246Svv149972 * forever (i.e. until reset) 5390f47dc443Ssdussud * 5391f47dc443Ssdussud * Asumptions: 5392f47dc443Ssdussud * - ber is a valid BER element 5393f47dc443Ssdussud * - acctResp is initialized for the fields in its AcctUsableResp.more_info 5394f47dc443Ssdussud * structure 539547789246Svv149972 */ 539647789246Svv149972 static int 5397f47dc443Ssdussud get_old_acct_opt_more_info(ber_tag_t tag, BerElement *ber, 5398f47dc443Ssdussud AcctUsableResponse_t *acctResp) 5399f47dc443Ssdussud { 5400f47dc443Ssdussud int rc = NS_LDAP_SUCCESS; 5401f47dc443Ssdussud char errstr[MAXERROR]; 5402f47dc443Ssdussud ber_len_t len; 5403f47dc443Ssdussud int rem_grace, sec_b4_unlock; 5404f47dc443Ssdussud 5405f47dc443Ssdussud switch (tag) { 5406f47dc443Ssdussud case 2: 5407f47dc443Ssdussud /* decode and maybe 3 is following */ 5408f47dc443Ssdussud if ((tag = ber_scanf(ber, "i", &rem_grace)) == LBER_ERROR) { 5409f47dc443Ssdussud (void) sprintf(errstr, gettext("Can not get " 5410f47dc443Ssdussud "rem_grace")); 5411f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5412f47dc443Ssdussud rc = NS_LDAP_INTERNAL; 5413f47dc443Ssdussud break; 5414f47dc443Ssdussud } 5415f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.rem_grace = rem_grace; 5416f47dc443Ssdussud 5417f47dc443Ssdussud if ((tag = ber_peek_tag(ber, &len)) == LBER_ERROR) { 5418f47dc443Ssdussud /* this is a success case, break to exit */ 5419f47dc443Ssdussud (void) sprintf(errstr, gettext("No more " 5420f47dc443Ssdussud "optional data")); 5421f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5422f47dc443Ssdussud break; 5423f47dc443Ssdussud } 5424f47dc443Ssdussud 5425f47dc443Ssdussud if (tag == 3) { 5426f47dc443Ssdussud if (ber_scanf(ber, "i", &sec_b4_unlock) == LBER_ERROR) { 5427f47dc443Ssdussud (void) sprintf(errstr, 5428f47dc443Ssdussud gettext("Can not get sec_b4_unlock " 5429f47dc443Ssdussud "- 1st case")); 5430f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5431f47dc443Ssdussud rc = NS_LDAP_INTERNAL; 5432f47dc443Ssdussud break; 5433f47dc443Ssdussud } 5434f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.sec_b4_unlock = 5435f47dc443Ssdussud sec_b4_unlock; 5436f47dc443Ssdussud } else { /* unknown tag */ 5437f47dc443Ssdussud (void) sprintf(errstr, gettext("Unknown tag " 5438f47dc443Ssdussud "- 1st case")); 5439f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5440f47dc443Ssdussud rc = NS_LDAP_INTERNAL; 5441f47dc443Ssdussud break; 5442f47dc443Ssdussud } 5443f47dc443Ssdussud break; 5444f47dc443Ssdussud 5445f47dc443Ssdussud case 3: 5446f47dc443Ssdussud if (ber_scanf(ber, "i", &sec_b4_unlock) == LBER_ERROR) { 5447f47dc443Ssdussud (void) sprintf(errstr, gettext("Can not get " 5448f47dc443Ssdussud "sec_b4_unlock - 2nd case")); 5449f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5450f47dc443Ssdussud rc = NS_LDAP_INTERNAL; 5451f47dc443Ssdussud break; 5452f47dc443Ssdussud } 5453f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.sec_b4_unlock = 5454f47dc443Ssdussud sec_b4_unlock; 5455f47dc443Ssdussud break; 5456f47dc443Ssdussud 5457f47dc443Ssdussud default: /* unknown tag */ 5458f47dc443Ssdussud (void) sprintf(errstr, gettext("Unknown tag - 2nd case")); 5459f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5460f47dc443Ssdussud rc = NS_LDAP_INTERNAL; 5461f47dc443Ssdussud break; 5462f47dc443Ssdussud } 5463f47dc443Ssdussud 5464f47dc443Ssdussud return (rc); 5465f47dc443Ssdussud } 5466f47dc443Ssdussud 5467f47dc443Ssdussud /* 5468f47dc443Ssdussud * **** This function needs to be moved to libldap library **** 5469f47dc443Ssdussud * parse_acct_cont_resp_msg() parses the message received by server according to 5470f47dc443Ssdussud * following format (ASN1 notation): 5471f47dc443Ssdussud * 5472f47dc443Ssdussud * ACCOUNT_USABLE_RESPONSE::= CHOICE { 5473f47dc443Ssdussud * is_available [0] INTEGER, 5474f47dc443Ssdussud * ** seconds before expiration ** 5475f47dc443Ssdussud * is_not_available [1] more_info 5476f47dc443Ssdussud * } 5477f47dc443Ssdussud * more_info::= SEQUENCE { 5478f47dc443Ssdussud * inactive [0] BOOLEAN DEFAULT FALSE, 5479f47dc443Ssdussud * reset [1] BOOLEAN DEFAULT FALSE, 5480f47dc443Ssdussud * expired [2] BOOLEAN DEFAULT FALSE, 5481f47dc443Ssdussud * remaining_grace [3] INTEGER OPTIONAL, 5482f47dc443Ssdussud * seconds_before_unlock [4] INTEGER OPTIONAL 5483f47dc443Ssdussud * } 5484f47dc443Ssdussud */ 5485f47dc443Ssdussud /* 5486f47dc443Ssdussud * #define used to make the difference between coding style as done 5487f47dc443Ssdussud * by LDAP server 5.2p4 and newer LDAP servers. There are 4 values: 5488f47dc443Ssdussud * - DS52p4_USABLE: 5.2p4 coding style, account is usable 5489f47dc443Ssdussud * - DS52p4_NOT_USABLE: 5.2p4 coding style, account is not usable 5490f47dc443Ssdussud * - NEW_USABLE: newer LDAP servers coding style, account is usable 5491f47dc443Ssdussud * - NEW_NOT_USABLE: newer LDAP servers coding style, account is not usable 5492f47dc443Ssdussud * 5493f47dc443Ssdussud * An account would be considered not usable if for instance: 5494f47dc443Ssdussud * - it's been made inactive in the LDAP server 5495f47dc443Ssdussud * - or its password was reset in the LDAP server database 5496f47dc443Ssdussud * - or its password expired 5497f47dc443Ssdussud * - or the account has been locked, possibly forever 5498f47dc443Ssdussud */ 5499f47dc443Ssdussud #define DS52p4_USABLE 0x00 5500f47dc443Ssdussud #define DS52p4_NOT_USABLE 0x01 5501f47dc443Ssdussud #define NEW_USABLE 0x00 | LBER_CLASS_CONTEXT | LBER_PRIMITIVE 5502f47dc443Ssdussud #define NEW_NOT_USABLE 0x01 | LBER_CLASS_CONTEXT | LBER_CONSTRUCTED 5503f47dc443Ssdussud static int 550447789246Svv149972 parse_acct_cont_resp_msg(LDAPControl **ectrls, AcctUsableResponse_t *acctResp) 550547789246Svv149972 { 5506f47dc443Ssdussud int rc = NS_LDAP_SUCCESS; 550747789246Svv149972 BerElement *ber; 5508f47dc443Ssdussud ber_tag_t tag; 550947789246Svv149972 ber_len_t len; 5510f47dc443Ssdussud int i; 5511f47dc443Ssdussud char errstr[MAXERROR]; 5512f47dc443Ssdussud /* used for any coding style when account is usable */ 5513f47dc443Ssdussud int seconds_before_expiry; 5514f47dc443Ssdussud /* used for 5.2p4 coding style when account is not usable */ 5515f47dc443Ssdussud int inactive, reset, expired; 551647789246Svv149972 5517f47dc443Ssdussud if (ectrls == NULL) { 5518f47dc443Ssdussud (void) sprintf(errstr, gettext("Invalid ectrls parameter")); 5519f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 552047789246Svv149972 return (NS_LDAP_INVALID_PARAM); 5521f47dc443Ssdussud } 552247789246Svv149972 552347789246Svv149972 for (i = 0; ectrls[i] != NULL; i++) { 552447789246Svv149972 if (strcmp(ectrls[i]->ldctl_oid, NS_LDAP_ACCOUNT_USABLE_CONTROL) 5525f47dc443Ssdussud == 0) { 5526f47dc443Ssdussud break; 552747789246Svv149972 } 5528f47dc443Ssdussud } 552947789246Svv149972 5530f47dc443Ssdussud if (ectrls[i] == NULL) { 5531f47dc443Ssdussud /* Ldap control is not found */ 5532f47dc443Ssdussud (void) sprintf(errstr, gettext("Account Usable Control " 5533f47dc443Ssdussud "not found")); 5534f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5535f47dc443Ssdussud return (NS_LDAP_NOTFOUND); 5536f47dc443Ssdussud } 5537f47dc443Ssdussud 5538f47dc443Ssdussud /* Allocate a BER element from the control value and parse it. */ 553947789246Svv149972 if ((ber = ber_init(&ectrls[i]->ldctl_value)) == NULL) 554047789246Svv149972 return (NS_LDAP_MEMORY); 554147789246Svv149972 554247789246Svv149972 if ((tag = ber_peek_tag(ber, &len)) == LBER_ERROR) { 554347789246Svv149972 /* Ldap decoding error */ 5544f47dc443Ssdussud (void) sprintf(errstr, gettext("Error decoding 1st tag")); 5545f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 554647789246Svv149972 ber_free(ber, 1); 554747789246Svv149972 return (NS_LDAP_INTERNAL); 554847789246Svv149972 } 554947789246Svv149972 555047789246Svv149972 switch (tag) { 5551f47dc443Ssdussud case DS52p4_USABLE: 5552f47dc443Ssdussud case NEW_USABLE: 5553f47dc443Ssdussud acctResp->choice = 0; 555447789246Svv149972 if (ber_scanf(ber, "i", &seconds_before_expiry) 555547789246Svv149972 == LBER_ERROR) { 555647789246Svv149972 /* Ldap decoding error */ 5557f47dc443Ssdussud (void) sprintf(errstr, gettext("Can not get " 5558f47dc443Ssdussud "seconds_before_expiry")); 5559f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5560f47dc443Ssdussud rc = NS_LDAP_INTERNAL; 5561f47dc443Ssdussud break; 556247789246Svv149972 } 5563f47dc443Ssdussud /* ber_scanf() succeeded */ 556447789246Svv149972 (acctResp->AcctUsableResp).seconds_before_expiry = 556547789246Svv149972 seconds_before_expiry; 5566f47dc443Ssdussud break; 5567f47dc443Ssdussud 5568f47dc443Ssdussud case DS52p4_NOT_USABLE: 5569f47dc443Ssdussud acctResp->choice = 1; 557047789246Svv149972 if (ber_scanf(ber, "{bbb", &inactive, &reset, &expired) 557147789246Svv149972 == LBER_ERROR) { 557247789246Svv149972 /* Ldap decoding error */ 5573f47dc443Ssdussud (void) sprintf(errstr, gettext("Can not get " 5574f47dc443Ssdussud "inactive/reset/expired")); 5575f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5576f47dc443Ssdussud rc = NS_LDAP_INTERNAL; 5577f47dc443Ssdussud break; 557847789246Svv149972 } 5579f47dc443Ssdussud /* ber_scanf() succeeded */ 558047789246Svv149972 (acctResp->AcctUsableResp).more_info.inactive = 5581f47dc443Ssdussud ((inactive == 0) ? 0 : 1); 558247789246Svv149972 (acctResp->AcctUsableResp).more_info.reset = 5583f47dc443Ssdussud ((reset == 0) ? 0 : 1); 558447789246Svv149972 (acctResp->AcctUsableResp).more_info.expired = 5585f47dc443Ssdussud ((expired == 0) ? 0 : 1); 5586f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.rem_grace = 0; 5587f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.sec_b4_unlock = 0; 558847789246Svv149972 558947789246Svv149972 if ((tag = ber_peek_tag(ber, &len)) == LBER_ERROR) { 5590f47dc443Ssdussud /* this is a success case, break to exit */ 5591f47dc443Ssdussud (void) sprintf(errstr, gettext("No optional data")); 5592f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5593f47dc443Ssdussud break; 559447789246Svv149972 } 559547789246Svv149972 5596f47dc443Ssdussud /* 5597f47dc443Ssdussud * Look at what optional more_info BER element is/are 5598f47dc443Ssdussud * left to be decoded. 5599f47dc443Ssdussud */ 5600f47dc443Ssdussud rc = get_old_acct_opt_more_info(tag, ber, acctResp); 560147789246Svv149972 break; 5602f47dc443Ssdussud 5603f47dc443Ssdussud case NEW_NOT_USABLE: 5604f47dc443Ssdussud acctResp->choice = 1; 5605f47dc443Ssdussud /* 5606f47dc443Ssdussud * Recent LDAP servers won't code more_info data for default 5607f47dc443Ssdussud * values (see above comments on ASN1 description for what 5608f47dc443Ssdussud * fields have default values & what fields are optional). 5609f47dc443Ssdussud */ 5610f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.inactive = 0; 5611f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.reset = 0; 5612f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.expired = 0; 5613f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.rem_grace = 0; 5614f47dc443Ssdussud (acctResp->AcctUsableResp).more_info.sec_b4_unlock = 0; 5615f47dc443Ssdussud 5616f47dc443Ssdussud if (len == 0) { 5617f47dc443Ssdussud /* 5618f47dc443Ssdussud * Nothing else to decode; this is valid and we 5619f47dc443Ssdussud * use default values set above. 5620f47dc443Ssdussud */ 5621f47dc443Ssdussud (void) sprintf(errstr, gettext("more_info is " 5622f47dc443Ssdussud "empty, using default values")); 5623f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5624f47dc443Ssdussud break; 5625f47dc443Ssdussud } 5626f47dc443Ssdussud 5627f47dc443Ssdussud /* 5628f47dc443Ssdussud * Look at what more_info BER element is/are left to 5629f47dc443Ssdussud * be decoded. 5630f47dc443Ssdussud */ 5631f47dc443Ssdussud rc = get_new_acct_more_info(ber, acctResp); 5632f47dc443Ssdussud break; 5633f47dc443Ssdussud 563447789246Svv149972 default: 5635f47dc443Ssdussud (void) sprintf(errstr, gettext("unknwon coding style " 5636f47dc443Ssdussud "(tag: 0x%x)"), tag); 5637f47dc443Ssdussud syslog(LOG_DEBUG, "libsldap: %s", errstr); 5638f47dc443Ssdussud rc = NS_LDAP_INTERNAL; 5639f47dc443Ssdussud break; 564047789246Svv149972 } 564147789246Svv149972 564247789246Svv149972 ber_free(ber, 1); 5643f47dc443Ssdussud return (rc); 564447789246Svv149972 } 564547789246Svv149972 564647789246Svv149972 /* 5647e1dd0a2fSth160488 * internal function for __ns_ldap_getAcctMgmt() 564847789246Svv149972 */ 5649e1dd0a2fSth160488 static int 5650e1dd0a2fSth160488 getAcctMgmt(const char *user, AcctUsableResponse_t *acctResp, 5651e1dd0a2fSth160488 ns_conn_user_t *conn_user) 565247789246Svv149972 { 565347789246Svv149972 int scope, rc; 565447789246Svv149972 char ldapfilter[1024]; 565547789246Svv149972 ns_ldap_cookie_t *cookie; 565647789246Svv149972 ns_ldap_search_desc_t **sdlist = NULL; 565747789246Svv149972 ns_ldap_search_desc_t *dptr; 565847789246Svv149972 ns_ldap_error_t *error = NULL; 565947789246Svv149972 char **dns = NULL; 566047789246Svv149972 char service[] = "shadow"; 566147789246Svv149972 566247789246Svv149972 if (user == NULL || acctResp == NULL) 566347789246Svv149972 return (NS_LDAP_INVALID_PARAM); 566447789246Svv149972 566547789246Svv149972 /* Initialize State machine cookie */ 566647789246Svv149972 cookie = init_search_state_machine(); 566747789246Svv149972 if (cookie == NULL) 566847789246Svv149972 return (NS_LDAP_MEMORY); 5669e1dd0a2fSth160488 cookie->conn_user = conn_user; 567047789246Svv149972 567147789246Svv149972 /* see if need to follow referrals */ 567247789246Svv149972 rc = __s_api_toFollowReferrals(0, 567347789246Svv149972 &cookie->followRef, &error); 567447789246Svv149972 if (rc != NS_LDAP_SUCCESS) { 567547789246Svv149972 (void) __ns_ldap_freeError(&error); 567647789246Svv149972 goto out; 567747789246Svv149972 } 567847789246Svv149972 567947789246Svv149972 /* get the service descriptor - or create a default one */ 568047789246Svv149972 rc = __s_api_get_SSD_from_SSDtoUse_service(service, 568147789246Svv149972 &sdlist, &error); 568247789246Svv149972 if (rc != NS_LDAP_SUCCESS) { 568347789246Svv149972 (void) __ns_ldap_freeError(&error); 568447789246Svv149972 goto out; 568547789246Svv149972 } 568647789246Svv149972 568747789246Svv149972 if (sdlist == NULL) { 568847789246Svv149972 /* Create default service Desc */ 568947789246Svv149972 sdlist = (ns_ldap_search_desc_t **)calloc(2, 569047789246Svv149972 sizeof (ns_ldap_search_desc_t *)); 569147789246Svv149972 if (sdlist == NULL) { 569247789246Svv149972 rc = NS_LDAP_MEMORY; 569347789246Svv149972 goto out; 569447789246Svv149972 } 569547789246Svv149972 dptr = (ns_ldap_search_desc_t *) 569647789246Svv149972 calloc(1, sizeof (ns_ldap_search_desc_t)); 569747789246Svv149972 if (dptr == NULL) { 569847789246Svv149972 free(sdlist); 569947789246Svv149972 rc = NS_LDAP_MEMORY; 570047789246Svv149972 goto out; 570147789246Svv149972 } 570247789246Svv149972 sdlist[0] = dptr; 570347789246Svv149972 570447789246Svv149972 /* default base */ 570547789246Svv149972 rc = __s_api_getDNs(&dns, service, &cookie->errorp); 570647789246Svv149972 if (rc != NS_LDAP_SUCCESS) { 570747789246Svv149972 if (dns) { 570847789246Svv149972 __s_api_free2dArray(dns); 570947789246Svv149972 dns = NULL; 571047789246Svv149972 } 571147789246Svv149972 (void) __ns_ldap_freeError(&(cookie->errorp)); 571247789246Svv149972 cookie->errorp = NULL; 571347789246Svv149972 goto out; 571447789246Svv149972 } 571547789246Svv149972 dptr->basedn = strdup(dns[0]); 571647789246Svv149972 if (dptr->basedn == NULL) { 571747789246Svv149972 free(sdlist); 571847789246Svv149972 free(dptr); 571947789246Svv149972 if (dns) { 572047789246Svv149972 __s_api_free2dArray(dns); 572147789246Svv149972 dns = NULL; 572247789246Svv149972 } 572347789246Svv149972 rc = NS_LDAP_MEMORY; 572447789246Svv149972 goto out; 572547789246Svv149972 } 572647789246Svv149972 __s_api_free2dArray(dns); 572747789246Svv149972 dns = NULL; 572847789246Svv149972 572947789246Svv149972 /* default scope */ 573047789246Svv149972 scope = 0; 573147789246Svv149972 rc = __s_api_getSearchScope(&scope, &cookie->errorp); 573247789246Svv149972 dptr->scope = scope; 573347789246Svv149972 } 573447789246Svv149972 573547789246Svv149972 cookie->sdlist = sdlist; 573647789246Svv149972 573747789246Svv149972 cookie->service = strdup(service); 573847789246Svv149972 if (cookie->service == NULL) { 573947789246Svv149972 rc = NS_LDAP_MEMORY; 574047789246Svv149972 goto out; 574147789246Svv149972 } 574247789246Svv149972 574347789246Svv149972 /* search for entries for this particular uid */ 574447789246Svv149972 (void) snprintf(ldapfilter, sizeof (ldapfilter), "(uid=%s)", user); 574547789246Svv149972 cookie->i_filter = strdup(ldapfilter); 574647789246Svv149972 if (cookie->i_filter == NULL) { 574747789246Svv149972 rc = NS_LDAP_MEMORY; 574847789246Svv149972 goto out; 574947789246Svv149972 } 575047789246Svv149972 575147789246Svv149972 /* create the control request */ 575247789246Svv149972 if ((rc = setup_acctmgmt_params(cookie)) != NS_LDAP_SUCCESS) 575347789246Svv149972 goto out; 575447789246Svv149972 575547789246Svv149972 /* Process search */ 575647789246Svv149972 rc = search_state_machine(cookie, GET_ACCT_MGMT_INFO, 0); 575747789246Svv149972 575847789246Svv149972 /* Copy results back to user */ 575947789246Svv149972 rc = cookie->err_rc; 576047789246Svv149972 if (rc != NS_LDAP_SUCCESS) 576147789246Svv149972 (void) __ns_ldap_freeError(&(cookie->errorp)); 576247789246Svv149972 576347789246Svv149972 if (cookie->result == NULL) 576447789246Svv149972 goto out; 576547789246Svv149972 576647789246Svv149972 if ((rc = parse_acct_cont_resp_msg(cookie->resultctrl, acctResp)) 576747789246Svv149972 != NS_LDAP_SUCCESS) 576847789246Svv149972 goto out; 576947789246Svv149972 577047789246Svv149972 rc = NS_LDAP_SUCCESS; 577147789246Svv149972 577247789246Svv149972 out: 577347789246Svv149972 delete_search_cookie(cookie); 577447789246Svv149972 577547789246Svv149972 return (rc); 577647789246Svv149972 } 5777e1dd0a2fSth160488 5778e1dd0a2fSth160488 /* 5779e1dd0a2fSth160488 * __ns_ldap_getAcctMgmt() is called from pam account management stack 5780e1dd0a2fSth160488 * for retrieving accounting information of users with no user password - 5781e1dd0a2fSth160488 * eg. rlogin, rsh, etc. This function uses the account management control 5782e1dd0a2fSth160488 * request to do a search on the server for the user in question. The 5783e1dd0a2fSth160488 * response control returned from the server is got from the cookie. 5784e1dd0a2fSth160488 * Input params: username of whose account mgmt information is to be got 5785e1dd0a2fSth160488 * pointer to hold the parsed account management information 5786e1dd0a2fSth160488 * Return values: NS_LDAP_SUCCESS on success or appropriate error 5787e1dd0a2fSth160488 * code on failure 5788e1dd0a2fSth160488 */ 5789e1dd0a2fSth160488 int 5790e1dd0a2fSth160488 __ns_ldap_getAcctMgmt(const char *user, AcctUsableResponse_t *acctResp) 5791e1dd0a2fSth160488 { 5792e1dd0a2fSth160488 ns_conn_user_t *cu = NULL; 5793e1dd0a2fSth160488 int try_cnt = 0; 5794e1dd0a2fSth160488 int rc = NS_LDAP_SUCCESS; 5795e1dd0a2fSth160488 ns_ldap_error_t *error = NULL; 5796e1dd0a2fSth160488 5797e1dd0a2fSth160488 for (;;) { 5798e1dd0a2fSth160488 if (__s_api_setup_retry_search(&cu, NS_CONN_USER_SEARCH, 5799e1dd0a2fSth160488 &try_cnt, &rc, &error) == 0) 5800e1dd0a2fSth160488 break; 5801e1dd0a2fSth160488 rc = getAcctMgmt(user, acctResp, cu); 5802e1dd0a2fSth160488 } 5803e1dd0a2fSth160488 return (rc); 5804e1dd0a2fSth160488 } 5805