1e8c27ec8Sbaban /* 2e8c27ec8Sbaban * CDDL HEADER START 3e8c27ec8Sbaban * 4e8c27ec8Sbaban * The contents of this file are subject to the terms of the 5e8c27ec8Sbaban * Common Development and Distribution License (the "License"). 6e8c27ec8Sbaban * You may not use this file except in compliance with the License. 7e8c27ec8Sbaban * 8e8c27ec8Sbaban * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9e8c27ec8Sbaban * or http://www.opensolaris.org/os/licensing. 10e8c27ec8Sbaban * See the License for the specific language governing permissions 11e8c27ec8Sbaban * and limitations under the License. 12e8c27ec8Sbaban * 13e8c27ec8Sbaban * When distributing Covered Code, include this CDDL HEADER in each 14e8c27ec8Sbaban * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15e8c27ec8Sbaban * If applicable, add the following below this CDDL HEADER, with the 16e8c27ec8Sbaban * fields enclosed by brackets "[]" replaced with your own identifying 17e8c27ec8Sbaban * information: Portions Copyright [yyyy] [name of copyright owner] 18e8c27ec8Sbaban * 19e8c27ec8Sbaban * CDDL HEADER END 20e8c27ec8Sbaban */ 21e8c27ec8Sbaban 22e8c27ec8Sbaban /* 23148c5f43SAlan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 24*528b7d8bSRichard Lowe * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 25e8c27ec8Sbaban */ 26e8c27ec8Sbaban 27e8c27ec8Sbaban /* 28e8c27ec8Sbaban * native LDAP related utility routines 29e8c27ec8Sbaban */ 30e8c27ec8Sbaban 31e8c27ec8Sbaban #include "idmapd.h" 32479ac375Sdm199847 #include "idmap_priv.h" 33479ac375Sdm199847 #include "ns_sldap.h" 34479ac375Sdm199847 #include "nldaputils.h" 35479ac375Sdm199847 #include <assert.h> 36479ac375Sdm199847 37479ac375Sdm199847 /* 38479ac375Sdm199847 * The following are format strings used to construct LDAP search filters 39479ac375Sdm199847 * when looking up Native LDAP directory service. The _F_XXX_SSD format 40479ac375Sdm199847 * is used by the libsldap API if a corresponding SSD is defined in 41479ac375Sdm199847 * Native LDAP configuration. The SSD contains a string that replaces 42479ac375Sdm199847 * the first %s in _F_XXX_SSD. If no SSD is defined then the regular 43479ac375Sdm199847 * _F_XXX format is used. 44479ac375Sdm199847 * 45479ac375Sdm199847 * Note that '\\' needs to be represented as "\\5c" in LDAP filters. 46479ac375Sdm199847 */ 47479ac375Sdm199847 48479ac375Sdm199847 /* Native LDAP lookup using UNIX username */ 49479ac375Sdm199847 #define _F_GETPWNAM "(&(objectClass=posixAccount)(uid=%s))" 50479ac375Sdm199847 #define _F_GETPWNAM_SSD "(&(%%s)(uid=%s))" 51479ac375Sdm199847 52479ac375Sdm199847 /* 53479ac375Sdm199847 * Native LDAP user lookup using names of well-known SIDs 54479ac375Sdm199847 * Note the use of 1$, 2$ in the format string which basically 55479ac375Sdm199847 * allows snprintf to re-use its first two arguments. 56479ac375Sdm199847 */ 57479ac375Sdm199847 #define _F_GETPWWNAMWK \ 58479ac375Sdm199847 "(&(objectClass=posixAccount)(|(%s=%s)(%1$s=BUILTIN\\5c%2$s)))" 59479ac375Sdm199847 #define _F_GETPWWNAMWK_SSD "(&(%%s)(|(%s=%s)(%1$s=BUILTIN\\5c%2$s)))" 60479ac375Sdm199847 61479ac375Sdm199847 /* Native LDAP user lookup using winname@windomain OR windomain\winname */ 62479ac375Sdm199847 #define _F_GETPWWNAMDOM \ 63479ac375Sdm199847 "(&(objectClass=posixAccount)(|(%s=%s@%s)(%1$s=%3$s\\5c%2$s)))" 64479ac375Sdm199847 #define _F_GETPWWNAMDOM_SSD "(&(%%s)(|(%s=%s@%s)(%1$s=%3$s\\5c%2$s)))" 65479ac375Sdm199847 66479ac375Sdm199847 /* Native LDAP lookup using UID */ 67479ac375Sdm199847 #define _F_GETPWUID "(&(objectClass=posixAccount)(uidNumber=%u))" 68479ac375Sdm199847 #define _F_GETPWUID_SSD "(&(%%s)(uidNumber=%u))" 69479ac375Sdm199847 70479ac375Sdm199847 /* Native LDAP lookup using UNIX groupname */ 71479ac375Sdm199847 #define _F_GETGRNAM "(&(objectClass=posixGroup)(cn=%s))" 72479ac375Sdm199847 #define _F_GETGRNAM_SSD "(&(%%s)(cn=%s))" 73479ac375Sdm199847 74479ac375Sdm199847 /* Native LDAP group lookup using names of well-known SIDs */ 75479ac375Sdm199847 #define _F_GETGRWNAMWK \ 76479ac375Sdm199847 "(&(objectClass=posixGroup)(|(%s=%s)(%1$s=BUILTIN\\5c%2$s)))" 77479ac375Sdm199847 #define _F_GETGRWNAMWK_SSD "(&(%%s)(|(%s=%s)(%1$s=BUILTIN\\5c%2$s)))" 78479ac375Sdm199847 79479ac375Sdm199847 /* Native LDAP group lookup using winname@windomain OR windomain\winname */ 80479ac375Sdm199847 #define _F_GETGRWNAMDOM \ 81479ac375Sdm199847 "(&(objectClass=posixGroup)(|(%s=%s@%s)(%1$s=%3$s\\5c%2$s)))" 82479ac375Sdm199847 #define _F_GETGRWNAMDOM_SSD "(&(%%s)(|(%s=%s@%s)(%1$s=%3$s\\5c%2$s)))" 83479ac375Sdm199847 84479ac375Sdm199847 /* Native LDAP lookup using GID */ 85479ac375Sdm199847 #define _F_GETGRGID "(&(objectClass=posixGroup)(gidNumber=%u))" 86479ac375Sdm199847 #define _F_GETGRGID_SSD "(&(%%s)(gidNumber=%u))" 87479ac375Sdm199847 88479ac375Sdm199847 /* Native LDAP attribute names */ 89479ac375Sdm199847 #define UID "uid" 90479ac375Sdm199847 #define CN "cn" 91479ac375Sdm199847 #define UIDNUMBER "uidnumber" 92479ac375Sdm199847 #define GIDNUMBER "gidnumber" 93479ac375Sdm199847 #define DN "dn" 94479ac375Sdm199847 95479ac375Sdm199847 #define IS_NLDAP_RC_FATAL(x) ((x == NS_LDAP_MEMORY) ? 1 : 0) 96479ac375Sdm199847 97479ac375Sdm199847 typedef struct idmap_nldap_q { 98479ac375Sdm199847 char **winname; 99479ac375Sdm199847 char **windomain; 100479ac375Sdm199847 char **unixname; 101479ac375Sdm199847 uid_t *pid; 102479ac375Sdm199847 char **dn; 103479ac375Sdm199847 char **attr; 104479ac375Sdm199847 char **value; 105479ac375Sdm199847 int is_user; 106479ac375Sdm199847 idmap_retcode *rc; 107479ac375Sdm199847 int lrc; 108479ac375Sdm199847 ns_ldap_result_t *result; 109479ac375Sdm199847 ns_ldap_error_t *errorp; 110479ac375Sdm199847 char *filter; 111479ac375Sdm199847 char *udata; 112479ac375Sdm199847 } idmap_nldap_q_t; 113479ac375Sdm199847 114479ac375Sdm199847 typedef struct idmap_nldap_query_state { 115479ac375Sdm199847 const char *nldap_winname_attr; 116479ac375Sdm199847 const char *defdom; 117479ac375Sdm199847 int nqueries; 118479ac375Sdm199847 int qid; 119479ac375Sdm199847 int flag; 120479ac375Sdm199847 ns_ldap_list_batch_t *batch; 121479ac375Sdm199847 idmap_nldap_q_t queries[1]; 122479ac375Sdm199847 } idmap_nldap_query_state_t; 123479ac375Sdm199847 124479ac375Sdm199847 /* 125479ac375Sdm199847 * This routine has been copied from lib/nsswitch/ldap/common/ldap_utils.c 126479ac375Sdm199847 * after removing the debug statements. 127479ac375Sdm199847 * 128479ac375Sdm199847 * This is a generic filter callback function for merging the filter 129479ac375Sdm199847 * from service search descriptor with an existing search filter. This 130479ac375Sdm199847 * routine expects userdata to contain a format string with a single %s 131479ac375Sdm199847 * in it, and will use the format string with sprintf() to insert the 132479ac375Sdm199847 * SSD filter. 133479ac375Sdm199847 * 134479ac375Sdm199847 * This routine and userdata are passed to the __ns_ldap_list_batch_add() 135479ac375Sdm199847 * API. 136479ac375Sdm199847 * 137479ac375Sdm199847 * Consider an example that uses __ns_ldap_list_batch_add() to lookup 138479ac375Sdm199847 * native LDAP directory using a given userid 'xy12345'. In this 139479ac375Sdm199847 * example the userdata will contain the filter "(&(%s)(cn=xy1234))". 140479ac375Sdm199847 * If a SSD is defined to replace the rfc2307bis specified filter 141479ac375Sdm199847 * i.e. (objectClass=posixAccount) by a site-specific filter 142479ac375Sdm199847 * say (department=sds) then this routine when called will produce 143479ac375Sdm199847 * "(&(department=sds)(uid=xy1234))" as the real search filter. 144479ac375Sdm199847 */ 145479ac375Sdm199847 static 146479ac375Sdm199847 int 147479ac375Sdm199847 merge_SSD_filter(const ns_ldap_search_desc_t *desc, 148479ac375Sdm199847 char **realfilter, const void *userdata) 149479ac375Sdm199847 { 150479ac375Sdm199847 int len; 151*528b7d8bSRichard Lowe char *checker; 152*528b7d8bSRichard Lowe 153479ac375Sdm199847 if (realfilter == NULL) 154479ac375Sdm199847 return (NS_LDAP_INVALID_PARAM); 155479ac375Sdm199847 *realfilter = NULL; 156479ac375Sdm199847 if (desc == NULL || desc->filter == NULL || userdata == NULL) 157479ac375Sdm199847 return (NS_LDAP_INVALID_PARAM); 158*528b7d8bSRichard Lowe 159*528b7d8bSRichard Lowe /* Parameter check. We only want one %s here, otherwise bail. */ 160*528b7d8bSRichard Lowe len = 0; /* Reuse 'len' as "Number of %s hits"... */ 161*528b7d8bSRichard Lowe checker = (char *)userdata; 162*528b7d8bSRichard Lowe do { 163*528b7d8bSRichard Lowe checker = strchr(checker, '%'); 164*528b7d8bSRichard Lowe if (checker != NULL) { 165*528b7d8bSRichard Lowe if (len > 0 || *(checker + 1) != 's') 166*528b7d8bSRichard Lowe return (NS_LDAP_INVALID_PARAM); 167*528b7d8bSRichard Lowe len++; /* Got our %s. */ 168*528b7d8bSRichard Lowe checker += 2; 169*528b7d8bSRichard Lowe } else if (len != 1) 170*528b7d8bSRichard Lowe return (NS_LDAP_INVALID_PARAM); 171*528b7d8bSRichard Lowe } while (checker != NULL); 172*528b7d8bSRichard Lowe 173479ac375Sdm199847 len = strlen(userdata) + strlen(desc->filter) + 1; 174479ac375Sdm199847 *realfilter = (char *)malloc(len); 175479ac375Sdm199847 if (*realfilter == NULL) 176479ac375Sdm199847 return (NS_LDAP_MEMORY); 177479ac375Sdm199847 (void) sprintf(*realfilter, (char *)userdata, desc->filter); 178479ac375Sdm199847 return (NS_LDAP_SUCCESS); 179479ac375Sdm199847 } 180479ac375Sdm199847 181479ac375Sdm199847 static 182479ac375Sdm199847 char 183479ac375Sdm199847 hex_char(int n) 184479ac375Sdm199847 { 185479ac375Sdm199847 return ("0123456789abcdef"[n & 0xf]); 186479ac375Sdm199847 } 187479ac375Sdm199847 188479ac375Sdm199847 /* 189479ac375Sdm199847 * If the input string contains special characters that needs to be 190479ac375Sdm199847 * escaped before the string can be used in a LDAP filter then this 191479ac375Sdm199847 * function will return a new sanitized string. Otherwise this function 192479ac375Sdm199847 * returns the input string (This saves us un-necessary memory allocations 193479ac375Sdm199847 * especially when processing a batch of requests). The caller must free 194479ac375Sdm199847 * the returned string if it isn't the input string. 195479ac375Sdm199847 * 196479ac375Sdm199847 * The escape mechanism for LDAP filter is described in RFC2254 basically 197479ac375Sdm199847 * it's \hh where hh are the two hexadecimal digits representing the ASCII 198479ac375Sdm199847 * value of the encoded character (case of hh is not significant). 199479ac375Sdm199847 * Example: * -> \2a, ( -> \28, ) -> \29, \ -> \5c, 200479ac375Sdm199847 * 201479ac375Sdm199847 * outstring = sanitize_for_ldap_filter(instring); 202479ac375Sdm199847 * if (outstring == NULL) 203479ac375Sdm199847 * Out of memory 204479ac375Sdm199847 * else 205479ac375Sdm199847 * Use outstring 206479ac375Sdm199847 * if (outstring != instring) 207479ac375Sdm199847 * free(outstring); 208479ac375Sdm199847 * done 209479ac375Sdm199847 */ 210479ac375Sdm199847 char * 211479ac375Sdm199847 sanitize_for_ldap_filter(const char *str) 212479ac375Sdm199847 { 213479ac375Sdm199847 const char *p; 214479ac375Sdm199847 char *q, *s_str = NULL; 215479ac375Sdm199847 int n; 216479ac375Sdm199847 217479ac375Sdm199847 /* Get a count of special characters */ 218479ac375Sdm199847 for (p = str, n = 0; *p; p++) 219479ac375Sdm199847 if (*p == '*' || *p == '(' || *p == ')' || 220479ac375Sdm199847 *p == '\\' || *p == '%') 221479ac375Sdm199847 n++; 222479ac375Sdm199847 /* If count is zero then no need to sanitize */ 223479ac375Sdm199847 if (n == 0) 224479ac375Sdm199847 return ((char *)str); 225479ac375Sdm199847 /* Create output buffer that will contain the sanitized value */ 226479ac375Sdm199847 s_str = calloc(1, n * 2 + strlen(str) + 1); 227479ac375Sdm199847 if (s_str == NULL) 228479ac375Sdm199847 return (NULL); 229479ac375Sdm199847 for (p = str, q = s_str; *p; p++) { 230479ac375Sdm199847 if (*p == '*' || *p == '(' || *p == ')' || 231479ac375Sdm199847 *p == '\\' || *p == '%') { 232479ac375Sdm199847 *q++ = '\\'; 233479ac375Sdm199847 *q++ = hex_char(*p >> 4); 234479ac375Sdm199847 *q++ = hex_char(*p & 0xf); 235479ac375Sdm199847 } else 236479ac375Sdm199847 *q++ = *p; 237479ac375Sdm199847 } 238479ac375Sdm199847 return (s_str); 239479ac375Sdm199847 } 240479ac375Sdm199847 241479ac375Sdm199847 /* 242479ac375Sdm199847 * Map libsldap status to idmap status 243479ac375Sdm199847 */ 244479ac375Sdm199847 static 245479ac375Sdm199847 idmap_retcode 246479ac375Sdm199847 nldaprc2retcode(int rc) 247479ac375Sdm199847 { 248479ac375Sdm199847 switch (rc) { 249479ac375Sdm199847 case NS_LDAP_SUCCESS: 250479ac375Sdm199847 case NS_LDAP_SUCCESS_WITH_INFO: 251479ac375Sdm199847 return (IDMAP_SUCCESS); 252479ac375Sdm199847 case NS_LDAP_NOTFOUND: 253479ac375Sdm199847 return (IDMAP_ERR_NOTFOUND); 254479ac375Sdm199847 case NS_LDAP_MEMORY: 255479ac375Sdm199847 return (IDMAP_ERR_MEMORY); 256479ac375Sdm199847 case NS_LDAP_CONFIG: 257479ac375Sdm199847 return (IDMAP_ERR_NS_LDAP_CFG); 258479ac375Sdm199847 case NS_LDAP_OP_FAILED: 259479ac375Sdm199847 return (IDMAP_ERR_NS_LDAP_OP_FAILED); 260479ac375Sdm199847 case NS_LDAP_PARTIAL: 261479ac375Sdm199847 return (IDMAP_ERR_NS_LDAP_PARTIAL); 262479ac375Sdm199847 case NS_LDAP_INTERNAL: 263479ac375Sdm199847 return (IDMAP_ERR_INTERNAL); 264479ac375Sdm199847 case NS_LDAP_INVALID_PARAM: 265479ac375Sdm199847 return (IDMAP_ERR_ARG); 266479ac375Sdm199847 default: 267479ac375Sdm199847 return (IDMAP_ERR_OTHER); 268479ac375Sdm199847 } 269479ac375Sdm199847 /*NOTREACHED*/ 270479ac375Sdm199847 } 271479ac375Sdm199847 272479ac375Sdm199847 /* 273479ac375Sdm199847 * Create a batch for native LDAP lookup. 274479ac375Sdm199847 */ 275479ac375Sdm199847 static 276479ac375Sdm199847 idmap_retcode 277479ac375Sdm199847 idmap_nldap_lookup_batch_start(int nqueries, idmap_nldap_query_state_t **qs) 278479ac375Sdm199847 { 279479ac375Sdm199847 idmap_nldap_query_state_t *s; 280479ac375Sdm199847 281479ac375Sdm199847 s = calloc(1, sizeof (*s) + 282479ac375Sdm199847 (nqueries - 1) * sizeof (idmap_nldap_q_t)); 283479ac375Sdm199847 if (s == NULL) 284479ac375Sdm199847 return (IDMAP_ERR_MEMORY); 285479ac375Sdm199847 if (__ns_ldap_list_batch_start(&s->batch) != NS_LDAP_SUCCESS) { 286479ac375Sdm199847 free(s); 287479ac375Sdm199847 return (IDMAP_ERR_MEMORY); 288479ac375Sdm199847 } 289479ac375Sdm199847 s->nqueries = nqueries; 290479ac375Sdm199847 s->flag = NS_LDAP_KEEP_CONN; 291479ac375Sdm199847 *qs = s; 292479ac375Sdm199847 return (IDMAP_SUCCESS); 293479ac375Sdm199847 } 294479ac375Sdm199847 295479ac375Sdm199847 /* 296479ac375Sdm199847 * Add a lookup by winname request to the batch. 297479ac375Sdm199847 */ 298479ac375Sdm199847 static 299479ac375Sdm199847 idmap_retcode 300479ac375Sdm199847 idmap_nldap_bywinname_batch_add(idmap_nldap_query_state_t *qs, 301479ac375Sdm199847 const char *winname, const char *windomain, int is_user, 302479ac375Sdm199847 char **dn, char **attr, char **value, 303479ac375Sdm199847 char **unixname, uid_t *pid, idmap_retcode *rc) 304479ac375Sdm199847 { 305479ac375Sdm199847 idmap_nldap_q_t *q; 306479ac375Sdm199847 const char *db, *filter, *udata; 307479ac375Sdm199847 int flen, ulen, wksid = 0; 308479ac375Sdm199847 char *s_winname, *s_windomain; 309479ac375Sdm199847 const char **attrs; 310479ac375Sdm199847 const char *pwd_attrs[] = {UID, UIDNUMBER, NULL, NULL}; 311479ac375Sdm199847 const char *grp_attrs[] = {CN, GIDNUMBER, NULL, NULL}; 312479ac375Sdm199847 313479ac375Sdm199847 s_winname = s_windomain = NULL; 314479ac375Sdm199847 q = &(qs->queries[qs->qid++]); 315479ac375Sdm199847 q->unixname = unixname; 316479ac375Sdm199847 q->pid = pid; 317479ac375Sdm199847 q->rc = rc; 318479ac375Sdm199847 q->is_user = is_user; 319479ac375Sdm199847 q->dn = dn; 320479ac375Sdm199847 q->attr = attr; 321479ac375Sdm199847 q->value = value; 322479ac375Sdm199847 323479ac375Sdm199847 if (is_user) { 324479ac375Sdm199847 db = "passwd"; 32508f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States if (lookup_wksids_name2sid(winname, NULL, NULL, NULL, NULL, 32608f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States NULL, NULL) == IDMAP_SUCCESS) { 327479ac375Sdm199847 filter = _F_GETPWWNAMWK; 328479ac375Sdm199847 udata = _F_GETPWWNAMWK_SSD; 329479ac375Sdm199847 wksid = 1; 330479ac375Sdm199847 } else if (windomain != NULL) { 331479ac375Sdm199847 filter = _F_GETPWWNAMDOM; 332479ac375Sdm199847 udata = _F_GETPWWNAMDOM_SSD; 333479ac375Sdm199847 } else { 334479ac375Sdm199847 *q->rc = IDMAP_ERR_DOMAIN_NOTFOUND; 335479ac375Sdm199847 goto errout; 336479ac375Sdm199847 } 337479ac375Sdm199847 pwd_attrs[2] = qs->nldap_winname_attr; 338479ac375Sdm199847 attrs = pwd_attrs; 339479ac375Sdm199847 } else { 340479ac375Sdm199847 db = "group"; 34108f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States if (lookup_wksids_name2sid(winname, NULL, NULL, NULL, NULL, 34208f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States NULL, NULL) == IDMAP_SUCCESS) { 343479ac375Sdm199847 filter = _F_GETGRWNAMWK; 344479ac375Sdm199847 udata = _F_GETGRWNAMWK_SSD; 345479ac375Sdm199847 wksid = 1; 346479ac375Sdm199847 } else if (windomain != NULL) { 347479ac375Sdm199847 filter = _F_GETGRWNAMDOM; 348479ac375Sdm199847 udata = _F_GETGRWNAMDOM_SSD; 349479ac375Sdm199847 } else { 350479ac375Sdm199847 *q->rc = IDMAP_ERR_DOMAIN_NOTFOUND; 351479ac375Sdm199847 goto errout; 352479ac375Sdm199847 } 353479ac375Sdm199847 grp_attrs[2] = qs->nldap_winname_attr; 354479ac375Sdm199847 attrs = grp_attrs; 355479ac375Sdm199847 } 356479ac375Sdm199847 357479ac375Sdm199847 /* 358479ac375Sdm199847 * Sanitize names. No need to sanitize qs->nldap_winname_attr 359479ac375Sdm199847 * because if it contained any of the special characters then 360479ac375Sdm199847 * it would have been rejected by the function that reads it 361479ac375Sdm199847 * from the SMF config. LDAP attribute names can only contain 362479ac375Sdm199847 * letters, digits or hyphens. 363479ac375Sdm199847 */ 364479ac375Sdm199847 s_winname = sanitize_for_ldap_filter(winname); 365479ac375Sdm199847 if (s_winname == NULL) { 366479ac375Sdm199847 *q->rc = IDMAP_ERR_MEMORY; 367479ac375Sdm199847 goto errout; 368479ac375Sdm199847 } 369479ac375Sdm199847 /* windomain could be NULL for names of well-known SIDs */ 370479ac375Sdm199847 if (windomain != NULL) { 371479ac375Sdm199847 s_windomain = sanitize_for_ldap_filter(windomain); 372479ac375Sdm199847 if (s_windomain == NULL) { 373479ac375Sdm199847 *q->rc = IDMAP_ERR_MEMORY; 374479ac375Sdm199847 goto errout; 375479ac375Sdm199847 } 376479ac375Sdm199847 } 377479ac375Sdm199847 378479ac375Sdm199847 /* Construct the filter and udata using snprintf. */ 379479ac375Sdm199847 if (wksid) { 380479ac375Sdm199847 flen = snprintf(NULL, 0, filter, qs->nldap_winname_attr, 381479ac375Sdm199847 s_winname) + 1; 382479ac375Sdm199847 ulen = snprintf(NULL, 0, udata, qs->nldap_winname_attr, 383479ac375Sdm199847 s_winname) + 1; 384479ac375Sdm199847 } else { 385479ac375Sdm199847 flen = snprintf(NULL, 0, filter, qs->nldap_winname_attr, 386479ac375Sdm199847 s_winname, s_windomain) + 1; 387479ac375Sdm199847 ulen = snprintf(NULL, 0, udata, qs->nldap_winname_attr, 388479ac375Sdm199847 s_winname, s_windomain) + 1; 389479ac375Sdm199847 } 390479ac375Sdm199847 391479ac375Sdm199847 q->filter = malloc(flen); 392479ac375Sdm199847 if (q->filter == NULL) { 393479ac375Sdm199847 *q->rc = IDMAP_ERR_MEMORY; 394479ac375Sdm199847 goto errout; 395479ac375Sdm199847 } 396479ac375Sdm199847 q->udata = malloc(ulen); 397479ac375Sdm199847 if (q->udata == NULL) { 398479ac375Sdm199847 *q->rc = IDMAP_ERR_MEMORY; 399479ac375Sdm199847 goto errout; 400479ac375Sdm199847 } 401479ac375Sdm199847 402479ac375Sdm199847 if (wksid) { 403479ac375Sdm199847 (void) snprintf(q->filter, flen, filter, 404479ac375Sdm199847 qs->nldap_winname_attr, s_winname); 405479ac375Sdm199847 (void) snprintf(q->udata, ulen, udata, 406479ac375Sdm199847 qs->nldap_winname_attr, s_winname); 407479ac375Sdm199847 } else { 408479ac375Sdm199847 (void) snprintf(q->filter, flen, filter, 409479ac375Sdm199847 qs->nldap_winname_attr, s_winname, s_windomain); 410479ac375Sdm199847 (void) snprintf(q->udata, ulen, udata, 411479ac375Sdm199847 qs->nldap_winname_attr, s_winname, s_windomain); 412479ac375Sdm199847 } 413479ac375Sdm199847 414479ac375Sdm199847 if (s_winname != winname) 415479ac375Sdm199847 free(s_winname); 416479ac375Sdm199847 if (s_windomain != windomain) 417479ac375Sdm199847 free(s_windomain); 418479ac375Sdm199847 419479ac375Sdm199847 q->lrc = __ns_ldap_list_batch_add(qs->batch, db, q->filter, 420479ac375Sdm199847 merge_SSD_filter, attrs, NULL, qs->flag, &q->result, 421479ac375Sdm199847 &q->errorp, &q->lrc, NULL, q->udata); 422479ac375Sdm199847 423479ac375Sdm199847 if (IS_NLDAP_RC_FATAL(q->lrc)) 424479ac375Sdm199847 return (nldaprc2retcode(q->lrc)); 425479ac375Sdm199847 return (IDMAP_SUCCESS); 426479ac375Sdm199847 427479ac375Sdm199847 errout: 428479ac375Sdm199847 /* query q and its content will be freed by batch_release */ 429479ac375Sdm199847 if (s_winname != winname) 430479ac375Sdm199847 free(s_winname); 431479ac375Sdm199847 if (s_windomain != windomain) 432479ac375Sdm199847 free(s_windomain); 433479ac375Sdm199847 return (*q->rc); 434479ac375Sdm199847 } 435479ac375Sdm199847 436479ac375Sdm199847 /* 437479ac375Sdm199847 * Add a lookup by uid/gid request to the batch. 438479ac375Sdm199847 */ 439479ac375Sdm199847 static 440479ac375Sdm199847 idmap_retcode 441479ac375Sdm199847 idmap_nldap_bypid_batch_add(idmap_nldap_query_state_t *qs, 442479ac375Sdm199847 uid_t pid, int is_user, char **dn, char **attr, char **value, 443479ac375Sdm199847 char **winname, char **windomain, 444479ac375Sdm199847 char **unixname, idmap_retcode *rc) 445479ac375Sdm199847 { 446479ac375Sdm199847 idmap_nldap_q_t *q; 447479ac375Sdm199847 const char *db, *filter, *udata; 448479ac375Sdm199847 int len; 449479ac375Sdm199847 const char **attrs; 450479ac375Sdm199847 const char *pwd_attrs[] = {UID, NULL, NULL}; 451479ac375Sdm199847 const char *grp_attrs[] = {CN, NULL, NULL}; 452479ac375Sdm199847 453479ac375Sdm199847 q = &(qs->queries[qs->qid++]); 454479ac375Sdm199847 q->winname = winname; 455479ac375Sdm199847 q->windomain = windomain; 456479ac375Sdm199847 q->unixname = unixname; 457479ac375Sdm199847 q->rc = rc; 458479ac375Sdm199847 q->is_user = is_user; 459479ac375Sdm199847 q->dn = dn; 460479ac375Sdm199847 q->attr = attr; 461479ac375Sdm199847 q->value = value; 462479ac375Sdm199847 463479ac375Sdm199847 if (is_user) { 464479ac375Sdm199847 db = "passwd"; 465479ac375Sdm199847 filter = _F_GETPWUID; 466479ac375Sdm199847 udata = _F_GETPWUID_SSD; 467479ac375Sdm199847 pwd_attrs[1] = qs->nldap_winname_attr; 468479ac375Sdm199847 attrs = pwd_attrs; 469479ac375Sdm199847 } else { 470479ac375Sdm199847 db = "group"; 471479ac375Sdm199847 filter = _F_GETGRGID; 472479ac375Sdm199847 udata = _F_GETGRGID_SSD; 473479ac375Sdm199847 grp_attrs[1] = qs->nldap_winname_attr; 474479ac375Sdm199847 attrs = grp_attrs; 475479ac375Sdm199847 } 476479ac375Sdm199847 477479ac375Sdm199847 len = snprintf(NULL, 0, filter, pid) + 1; 478479ac375Sdm199847 q->filter = malloc(len); 479479ac375Sdm199847 if (q->filter == NULL) { 480479ac375Sdm199847 *q->rc = IDMAP_ERR_MEMORY; 481479ac375Sdm199847 return (IDMAP_ERR_MEMORY); 482479ac375Sdm199847 } 483479ac375Sdm199847 (void) snprintf(q->filter, len, filter, pid); 484479ac375Sdm199847 485479ac375Sdm199847 len = snprintf(NULL, 0, udata, pid) + 1; 486479ac375Sdm199847 q->udata = malloc(len); 487479ac375Sdm199847 if (q->udata == NULL) { 488479ac375Sdm199847 *q->rc = IDMAP_ERR_MEMORY; 489479ac375Sdm199847 return (IDMAP_ERR_MEMORY); 490479ac375Sdm199847 } 491479ac375Sdm199847 (void) snprintf(q->udata, len, udata, pid); 492479ac375Sdm199847 493479ac375Sdm199847 q->lrc = __ns_ldap_list_batch_add(qs->batch, db, q->filter, 494479ac375Sdm199847 merge_SSD_filter, attrs, NULL, qs->flag, &q->result, 495479ac375Sdm199847 &q->errorp, &q->lrc, NULL, q->udata); 496479ac375Sdm199847 497479ac375Sdm199847 if (IS_NLDAP_RC_FATAL(q->lrc)) 498479ac375Sdm199847 return (nldaprc2retcode(q->lrc)); 499479ac375Sdm199847 return (IDMAP_SUCCESS); 500479ac375Sdm199847 } 501479ac375Sdm199847 502479ac375Sdm199847 /* 503479ac375Sdm199847 * Add a lookup by user/group name request to the batch. 504479ac375Sdm199847 */ 505479ac375Sdm199847 static 506479ac375Sdm199847 idmap_retcode 507479ac375Sdm199847 idmap_nldap_byunixname_batch_add(idmap_nldap_query_state_t *qs, 508479ac375Sdm199847 const char *unixname, int is_user, 509479ac375Sdm199847 char **dn, char **attr, char **value, 510479ac375Sdm199847 char **winname, char **windomain, uid_t *pid, idmap_retcode *rc) 511479ac375Sdm199847 { 512479ac375Sdm199847 idmap_nldap_q_t *q; 513479ac375Sdm199847 const char *db, *filter, *udata; 514479ac375Sdm199847 int len; 515479ac375Sdm199847 char *s_unixname = NULL; 516479ac375Sdm199847 const char **attrs; 517479ac375Sdm199847 const char *pwd_attrs[] = {UIDNUMBER, NULL, NULL}; 518479ac375Sdm199847 const char *grp_attrs[] = {GIDNUMBER, NULL, NULL}; 519479ac375Sdm199847 520479ac375Sdm199847 q = &(qs->queries[qs->qid++]); 521479ac375Sdm199847 q->winname = winname; 522479ac375Sdm199847 q->windomain = windomain; 523479ac375Sdm199847 q->pid = pid; 524479ac375Sdm199847 q->rc = rc; 525479ac375Sdm199847 q->is_user = is_user; 526479ac375Sdm199847 q->dn = dn; 527479ac375Sdm199847 q->attr = attr; 528479ac375Sdm199847 q->value = value; 529479ac375Sdm199847 530479ac375Sdm199847 if (is_user) { 531479ac375Sdm199847 db = "passwd"; 532479ac375Sdm199847 filter = _F_GETPWNAM; 533479ac375Sdm199847 udata = _F_GETPWNAM_SSD; 534479ac375Sdm199847 pwd_attrs[1] = qs->nldap_winname_attr; 535479ac375Sdm199847 attrs = pwd_attrs; 536479ac375Sdm199847 } else { 537479ac375Sdm199847 db = "group"; 538479ac375Sdm199847 filter = _F_GETGRNAM; 539479ac375Sdm199847 udata = _F_GETGRNAM_SSD; 540479ac375Sdm199847 grp_attrs[1] = qs->nldap_winname_attr; 541479ac375Sdm199847 attrs = grp_attrs; 542479ac375Sdm199847 } 543479ac375Sdm199847 544479ac375Sdm199847 s_unixname = sanitize_for_ldap_filter(unixname); 545479ac375Sdm199847 if (s_unixname == NULL) { 546479ac375Sdm199847 *q->rc = IDMAP_ERR_MEMORY; 547479ac375Sdm199847 return (IDMAP_ERR_MEMORY); 548479ac375Sdm199847 } 549479ac375Sdm199847 550479ac375Sdm199847 len = snprintf(NULL, 0, filter, s_unixname) + 1; 551479ac375Sdm199847 q->filter = malloc(len); 552479ac375Sdm199847 if (q->filter == NULL) { 553479ac375Sdm199847 if (s_unixname != unixname) 554479ac375Sdm199847 free(s_unixname); 555479ac375Sdm199847 *q->rc = IDMAP_ERR_MEMORY; 556479ac375Sdm199847 return (IDMAP_ERR_MEMORY); 557479ac375Sdm199847 } 558479ac375Sdm199847 (void) snprintf(q->filter, len, filter, s_unixname); 559479ac375Sdm199847 560479ac375Sdm199847 len = snprintf(NULL, 0, udata, s_unixname) + 1; 561479ac375Sdm199847 q->udata = malloc(len); 562479ac375Sdm199847 if (q->udata == NULL) { 563479ac375Sdm199847 if (s_unixname != unixname) 564479ac375Sdm199847 free(s_unixname); 565479ac375Sdm199847 *q->rc = IDMAP_ERR_MEMORY; 566479ac375Sdm199847 return (IDMAP_ERR_MEMORY); 567479ac375Sdm199847 } 568479ac375Sdm199847 (void) snprintf(q->udata, len, udata, s_unixname); 569479ac375Sdm199847 570479ac375Sdm199847 if (s_unixname != unixname) 571479ac375Sdm199847 free(s_unixname); 572479ac375Sdm199847 573479ac375Sdm199847 q->lrc = __ns_ldap_list_batch_add(qs->batch, db, q->filter, 574479ac375Sdm199847 merge_SSD_filter, attrs, NULL, qs->flag, &q->result, 575479ac375Sdm199847 &q->errorp, &q->lrc, NULL, q->udata); 576479ac375Sdm199847 577479ac375Sdm199847 if (IS_NLDAP_RC_FATAL(q->lrc)) 578479ac375Sdm199847 return (nldaprc2retcode(q->lrc)); 579479ac375Sdm199847 return (IDMAP_SUCCESS); 580479ac375Sdm199847 } 581479ac375Sdm199847 582479ac375Sdm199847 /* 583479ac375Sdm199847 * Free the batch 584479ac375Sdm199847 */ 585479ac375Sdm199847 static 586479ac375Sdm199847 void 587479ac375Sdm199847 idmap_nldap_lookup_batch_release(idmap_nldap_query_state_t *qs) 588479ac375Sdm199847 { 589479ac375Sdm199847 idmap_nldap_q_t *q; 590479ac375Sdm199847 int i; 591479ac375Sdm199847 592479ac375Sdm199847 if (qs->batch != NULL) 593479ac375Sdm199847 (void) __ns_ldap_list_batch_release(qs->batch); 594479ac375Sdm199847 for (i = 0; i < qs->qid; i++) { 595479ac375Sdm199847 q = &(qs->queries[i]); 596479ac375Sdm199847 free(q->filter); 597479ac375Sdm199847 free(q->udata); 598479ac375Sdm199847 if (q->errorp != NULL) 599479ac375Sdm199847 (void) __ns_ldap_freeError(&q->errorp); 600479ac375Sdm199847 if (q->result != NULL) 601479ac375Sdm199847 (void) __ns_ldap_freeResult(&q->result); 602479ac375Sdm199847 } 603479ac375Sdm199847 free(qs); 604479ac375Sdm199847 } 605479ac375Sdm199847 606479ac375Sdm199847 /* 607479ac375Sdm199847 * Process all requests added to the batch and then free the batch. 608479ac375Sdm199847 * The results for individual requests will be accessible using the 609479ac375Sdm199847 * pointers passed during idmap_nldap_lookup_batch_end. 610479ac375Sdm199847 */ 611479ac375Sdm199847 static 612479ac375Sdm199847 idmap_retcode 613479ac375Sdm199847 idmap_nldap_lookup_batch_end(idmap_nldap_query_state_t *qs) 614479ac375Sdm199847 { 615479ac375Sdm199847 idmap_nldap_q_t *q; 616479ac375Sdm199847 int i; 617479ac375Sdm199847 ns_ldap_entry_t *entry; 618479ac375Sdm199847 char **val, *end, *str, *name, *dom; 619479ac375Sdm199847 idmap_retcode rc = IDMAP_SUCCESS; 620479ac375Sdm199847 621479ac375Sdm199847 (void) __ns_ldap_list_batch_end(qs->batch); 622479ac375Sdm199847 qs->batch = NULL; 623479ac375Sdm199847 for (i = 0; i < qs->qid; i++) { 624479ac375Sdm199847 q = &(qs->queries[i]); 625479ac375Sdm199847 *q->rc = nldaprc2retcode(q->lrc); 626479ac375Sdm199847 if (*q->rc != IDMAP_SUCCESS) 627479ac375Sdm199847 continue; 628479ac375Sdm199847 if (q->result == NULL || 629479ac375Sdm199847 !q->result->entries_count || 630479ac375Sdm199847 (entry = q->result->entry) == NULL || 631479ac375Sdm199847 !entry->attr_count) { 632479ac375Sdm199847 *q->rc = IDMAP_ERR_NOTFOUND; 633479ac375Sdm199847 continue; 634479ac375Sdm199847 } 635479ac375Sdm199847 /* Get uid/gid */ 636479ac375Sdm199847 if (q->pid != NULL) { 637479ac375Sdm199847 val = __ns_ldap_getAttr(entry, 638479ac375Sdm199847 (q->is_user) ? UIDNUMBER : GIDNUMBER); 639479ac375Sdm199847 if (val != NULL && *val != NULL) 640479ac375Sdm199847 *q->pid = strtoul(*val, &end, 10); 641479ac375Sdm199847 } 642479ac375Sdm199847 /* Get unixname */ 643479ac375Sdm199847 if (q->unixname != NULL) { 644479ac375Sdm199847 val = __ns_ldap_getAttr(entry, 645479ac375Sdm199847 (q->is_user) ? UID : CN); 646479ac375Sdm199847 if (val != NULL && *val != NULL) { 647479ac375Sdm199847 *q->unixname = strdup(*val); 648479ac375Sdm199847 if (*q->unixname == NULL) { 649479ac375Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY; 650479ac375Sdm199847 goto out; 651479ac375Sdm199847 } 652479ac375Sdm199847 } 653479ac375Sdm199847 } 654479ac375Sdm199847 /* Get DN for how info */ 655479ac375Sdm199847 if (q->dn != NULL) { 656479ac375Sdm199847 val = __ns_ldap_getAttr(entry, DN); 657479ac375Sdm199847 if (val != NULL && *val != NULL) { 658479ac375Sdm199847 *q->dn = strdup(*val); 659479ac375Sdm199847 if (*q->dn == NULL) { 660479ac375Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY; 661479ac375Sdm199847 goto out; 662479ac375Sdm199847 } 663479ac375Sdm199847 } 664479ac375Sdm199847 } 665479ac375Sdm199847 /* Get nldap name mapping attr name for how info */ 666479ac375Sdm199847 if (q->attr != NULL) { 667479ac375Sdm199847 *q->attr = strdup(qs->nldap_winname_attr); 668479ac375Sdm199847 if (*q->attr == NULL) { 669479ac375Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY; 670479ac375Sdm199847 goto out; 671479ac375Sdm199847 } 672479ac375Sdm199847 } 673479ac375Sdm199847 /* Get nldap name mapping attr value for how info */ 674479ac375Sdm199847 val = __ns_ldap_getAttr(entry, qs->nldap_winname_attr); 675479ac375Sdm199847 if (val == NULL || *val == NULL) 676479ac375Sdm199847 continue; 677479ac375Sdm199847 if (q->value != NULL) { 678479ac375Sdm199847 *q->value = strdup(*val); 679479ac375Sdm199847 if (*q->value == NULL) { 680479ac375Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY; 681479ac375Sdm199847 goto out; 682479ac375Sdm199847 } 683479ac375Sdm199847 } 684479ac375Sdm199847 685479ac375Sdm199847 /* Get winname and windomain */ 686479ac375Sdm199847 if (q->winname == NULL && q->windomain == NULL) 687479ac375Sdm199847 continue; 688479ac375Sdm199847 /* 689479ac375Sdm199847 * We need to split the value into winname and 690479ac375Sdm199847 * windomain. The value could be either in NT4 691479ac375Sdm199847 * style (i.e. dom\name) or AD-style (i.e. name@dom). 692479ac375Sdm199847 * We choose the first '\\' if it's in NT4 style and 693479ac375Sdm199847 * the last '@' if it's in AD-style for the split. 694479ac375Sdm199847 */ 695479ac375Sdm199847 name = dom = NULL; 69608f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States if (lookup_wksids_name2sid(*val, NULL, NULL, NULL, NULL, NULL, 69708f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States NULL) == IDMAP_SUCCESS) { 698479ac375Sdm199847 name = *val; 699479ac375Sdm199847 dom = NULL; 700479ac375Sdm199847 } else if ((str = strchr(*val, '\\')) != NULL) { 701479ac375Sdm199847 *str = '\0'; 702479ac375Sdm199847 name = str + 1; 703479ac375Sdm199847 dom = *val; 704479ac375Sdm199847 } else if ((str = strrchr(*val, '@')) != NULL) { 705479ac375Sdm199847 *str = '\0'; 706479ac375Sdm199847 name = *val; 707479ac375Sdm199847 dom = str + 1; 708479ac375Sdm199847 } else { 709479ac375Sdm199847 idmapdlog(LOG_INFO, "Domain-less " 710479ac375Sdm199847 "winname (%s) found in Native LDAP", *val); 711479ac375Sdm199847 *q->rc = IDMAP_ERR_NS_LDAP_BAD_WINNAME; 712479ac375Sdm199847 continue; 713479ac375Sdm199847 } 714479ac375Sdm199847 if (q->winname != NULL) { 715479ac375Sdm199847 *q->winname = strdup(name); 716479ac375Sdm199847 if (*q->winname == NULL) { 717479ac375Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY; 718479ac375Sdm199847 goto out; 719479ac375Sdm199847 } 720479ac375Sdm199847 } 721479ac375Sdm199847 if (q->windomain != NULL && dom != NULL) { 722479ac375Sdm199847 *q->windomain = strdup(dom); 723479ac375Sdm199847 if (*q->windomain == NULL) { 724479ac375Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY; 725479ac375Sdm199847 goto out; 726479ac375Sdm199847 } 727479ac375Sdm199847 } 728479ac375Sdm199847 } 729479ac375Sdm199847 730479ac375Sdm199847 out: 731479ac375Sdm199847 (void) idmap_nldap_lookup_batch_release(qs); 732479ac375Sdm199847 return (rc); 733479ac375Sdm199847 } 734e8c27ec8Sbaban 735e8c27ec8Sbaban /* ARGSUSED */ 736e8c27ec8Sbaban idmap_retcode 737e8c27ec8Sbaban nldap_lookup_batch(lookup_state_t *state, idmap_mapping_batch *batch, 738e8c27ec8Sbaban idmap_ids_res *result) 739e8c27ec8Sbaban { 740479ac375Sdm199847 idmap_retcode retcode, rc1; 741148c5f43SAlan Wright int i, add; 742479ac375Sdm199847 idmap_mapping *req; 743479ac375Sdm199847 idmap_id_res *res; 744479ac375Sdm199847 idmap_nldap_query_state_t *qs = NULL; 745479ac375Sdm199847 idmap_how *how; 746479ac375Sdm199847 747479ac375Sdm199847 if (state->nldap_nqueries == 0) 748479ac375Sdm199847 return (IDMAP_SUCCESS); 749479ac375Sdm199847 750479ac375Sdm199847 /* Create nldap lookup batch */ 751479ac375Sdm199847 retcode = idmap_nldap_lookup_batch_start(state->nldap_nqueries, &qs); 752479ac375Sdm199847 if (retcode != IDMAP_SUCCESS) { 753479ac375Sdm199847 idmapdlog(LOG_ERR, 754479ac375Sdm199847 "Failed to create batch for native LDAP lookup"); 755479ac375Sdm199847 goto out; 756479ac375Sdm199847 } 757479ac375Sdm199847 758479ac375Sdm199847 qs->nldap_winname_attr = state->nldap_winname_attr; 759479ac375Sdm199847 qs->defdom = state->defdom; 760479ac375Sdm199847 761479ac375Sdm199847 /* Add requests to the batch */ 762479ac375Sdm199847 for (i = 0, add = 0; i < batch->idmap_mapping_batch_len; i++) { 763479ac375Sdm199847 req = &batch->idmap_mapping_batch_val[i]; 764479ac375Sdm199847 res = &result->ids.ids_val[i]; 765479ac375Sdm199847 retcode = IDMAP_SUCCESS; 766479ac375Sdm199847 767479ac375Sdm199847 /* Skip if not marked for nldap lookup */ 768479ac375Sdm199847 if (!(req->direction & _IDMAP_F_LOOKUP_NLDAP)) 769479ac375Sdm199847 continue; 770479ac375Sdm199847 771148c5f43SAlan Wright if (IS_ID_SID(req->id1)) { 772479ac375Sdm199847 773479ac375Sdm199847 /* win2unix request: */ 774479ac375Sdm199847 775e8c27ec8Sbaban /* 776479ac375Sdm199847 * When processing a win2unix request, nldap lookup 777479ac375Sdm199847 * is performed after AD lookup or a successful 778479ac375Sdm199847 * name-cache lookup. Therefore we should already 779479ac375Sdm199847 * have sid, winname and sidtype. Note that 780479ac375Sdm199847 * windomain could be NULL e.g. well-known SIDs. 781e8c27ec8Sbaban */ 782479ac375Sdm199847 assert(req->id1name != NULL && 783479ac375Sdm199847 (res->id.idtype == IDMAP_UID || 784479ac375Sdm199847 res->id.idtype == IDMAP_GID)); 785479ac375Sdm199847 786479ac375Sdm199847 /* Skip if we already have pid and unixname */ 787479ac375Sdm199847 if (req->id2name != NULL && 7889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States res->id.idmap_id_u.uid != IDMAP_SENTINEL_PID) { 789479ac375Sdm199847 res->retcode = IDMAP_SUCCESS; 790479ac375Sdm199847 continue; 791479ac375Sdm199847 } 792479ac375Sdm199847 793479ac375Sdm199847 /* Clear leftover value */ 794479ac375Sdm199847 free(req->id2name); 795479ac375Sdm199847 req->id2name = NULL; 796479ac375Sdm199847 797479ac375Sdm199847 /* Lookup nldap by winname to get pid and unixname */ 798479ac375Sdm199847 add = 1; 799148c5f43SAlan Wright idmap_how_clear(&res->info.how); 800479ac375Sdm199847 res->info.src = IDMAP_MAP_SRC_NEW; 801479ac375Sdm199847 how = &res->info.how; 802479ac375Sdm199847 how->map_type = IDMAP_MAP_TYPE_DS_NLDAP; 803479ac375Sdm199847 retcode = idmap_nldap_bywinname_batch_add( 804479ac375Sdm199847 qs, req->id1name, req->id1domain, 805479ac375Sdm199847 (res->id.idtype == IDMAP_UID) ? 1 : 0, 806479ac375Sdm199847 &how->idmap_how_u.nldap.dn, 807479ac375Sdm199847 &how->idmap_how_u.nldap.attr, 808479ac375Sdm199847 &how->idmap_how_u.nldap.value, 809479ac375Sdm199847 &req->id2name, &res->id.idmap_id_u.uid, 810479ac375Sdm199847 &res->retcode); 811479ac375Sdm199847 812148c5f43SAlan Wright } else if (IS_ID_UID(req->id1) || IS_ID_GID(req->id1)) { 813479ac375Sdm199847 814479ac375Sdm199847 /* unix2win request: */ 815479ac375Sdm199847 816479ac375Sdm199847 /* Skip if we already have winname */ 817479ac375Sdm199847 if (req->id2name != NULL) { 818479ac375Sdm199847 res->retcode = IDMAP_SUCCESS; 819479ac375Sdm199847 continue; 820479ac375Sdm199847 } 821479ac375Sdm199847 822479ac375Sdm199847 /* Clear old value */ 823479ac375Sdm199847 free(req->id2domain); 824479ac375Sdm199847 req->id2domain = NULL; 825479ac375Sdm199847 826479ac375Sdm199847 /* Set how info */ 827148c5f43SAlan Wright idmap_how_clear(&res->info.how); 828479ac375Sdm199847 res->info.src = IDMAP_MAP_SRC_NEW; 829479ac375Sdm199847 how = &res->info.how; 830479ac375Sdm199847 how->map_type = IDMAP_MAP_TYPE_DS_NLDAP; 831479ac375Sdm199847 832479ac375Sdm199847 /* Lookup nldap by pid or unixname to get winname */ 8339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (req->id1.idmap_id_u.uid != IDMAP_SENTINEL_PID) { 834479ac375Sdm199847 add = 1; 835479ac375Sdm199847 retcode = idmap_nldap_bypid_batch_add( 836479ac375Sdm199847 qs, req->id1.idmap_id_u.uid, 837479ac375Sdm199847 (req->id1.idtype == IDMAP_UID) ? 1 : 0, 838479ac375Sdm199847 &how->idmap_how_u.nldap.dn, 839479ac375Sdm199847 &how->idmap_how_u.nldap.attr, 840479ac375Sdm199847 &how->idmap_how_u.nldap.value, 841479ac375Sdm199847 &req->id2name, &req->id2domain, 842479ac375Sdm199847 (req->id1name == NULL) ? 843479ac375Sdm199847 &req->id1name : NULL, 844479ac375Sdm199847 &res->retcode); 845479ac375Sdm199847 } else if (req->id1name != NULL) { 846479ac375Sdm199847 add = 1; 847479ac375Sdm199847 retcode = idmap_nldap_byunixname_batch_add( 848479ac375Sdm199847 qs, req->id1name, 849479ac375Sdm199847 (req->id1.idtype == IDMAP_UID) ? 1 : 0, 850479ac375Sdm199847 &how->idmap_how_u.nldap.dn, 851479ac375Sdm199847 &how->idmap_how_u.nldap.attr, 852479ac375Sdm199847 &how->idmap_how_u.nldap.value, 853479ac375Sdm199847 &req->id2name, &req->id2domain, 854479ac375Sdm199847 &req->id1.idmap_id_u.uid, &res->retcode); 855479ac375Sdm199847 } 856479ac375Sdm199847 857479ac375Sdm199847 } 858479ac375Sdm199847 859479ac375Sdm199847 /* 860479ac375Sdm199847 * nldap_batch_add API returns error only on fatal failures 861479ac375Sdm199847 * otherwise it returns success and the actual status 862479ac375Sdm199847 * is stored in the individual request (res->retcode). 863479ac375Sdm199847 * Stop adding requests to this batch on fatal failures 864479ac375Sdm199847 * (i.e. if retcode != success) 865479ac375Sdm199847 */ 866479ac375Sdm199847 if (retcode != IDMAP_SUCCESS) 867479ac375Sdm199847 break; 868479ac375Sdm199847 } 869479ac375Sdm199847 870479ac375Sdm199847 if (!add) 871479ac375Sdm199847 idmap_nldap_lookup_batch_release(qs); 872479ac375Sdm199847 else if (retcode != IDMAP_SUCCESS) 873479ac375Sdm199847 idmap_nldap_lookup_batch_release(qs); 874479ac375Sdm199847 else 875479ac375Sdm199847 retcode = idmap_nldap_lookup_batch_end(qs); 876479ac375Sdm199847 877479ac375Sdm199847 out: 878479ac375Sdm199847 for (i = 0; i < batch->idmap_mapping_batch_len; i++) { 879479ac375Sdm199847 req = &batch->idmap_mapping_batch_val[i]; 880479ac375Sdm199847 res = &result->ids.ids_val[i]; 881479ac375Sdm199847 if (!(req->direction & _IDMAP_F_LOOKUP_NLDAP)) 882479ac375Sdm199847 continue; 883479ac375Sdm199847 884479ac375Sdm199847 /* Reset nldap flag */ 885479ac375Sdm199847 req->direction &= ~(_IDMAP_F_LOOKUP_NLDAP); 886479ac375Sdm199847 887479ac375Sdm199847 /* 888479ac375Sdm199847 * As noted earlier retcode != success if there were fatal 889479ac375Sdm199847 * errors during batch_start and batch_adds. If so then set 890479ac375Sdm199847 * the status of each nldap request to that error. 891479ac375Sdm199847 */ 892479ac375Sdm199847 if (retcode != IDMAP_SUCCESS) { 893479ac375Sdm199847 res->retcode = retcode; 894479ac375Sdm199847 continue; 895479ac375Sdm199847 } 896479ac375Sdm199847 if (!add) 897479ac375Sdm199847 continue; 898479ac375Sdm199847 899479ac375Sdm199847 /* 900479ac375Sdm199847 * If we successfully retrieved winname from nldap entry 901479ac375Sdm199847 * then lookup winname2sid locally. If not found locally 902479ac375Sdm199847 * then mark this request for AD lookup. 903479ac375Sdm199847 */ 904479ac375Sdm199847 if (res->retcode == IDMAP_SUCCESS && 905479ac375Sdm199847 req->id2name != NULL && 906479ac375Sdm199847 res->id.idmap_id_u.sid.prefix == NULL && 907148c5f43SAlan Wright (IS_ID_UID(req->id1) || IS_ID_GID(req->id1))) { 908479ac375Sdm199847 909479ac375Sdm199847 rc1 = lookup_name2sid(state->cache, 910148c5f43SAlan Wright req->id2name, req->id2domain, -1, 91108f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States NULL, NULL, 912479ac375Sdm199847 &res->id.idmap_id_u.sid.prefix, 913148c5f43SAlan Wright &res->id.idmap_id_u.sid.rid, 914148c5f43SAlan Wright &res->id.idtype, 915148c5f43SAlan Wright req, 1); 916148c5f43SAlan Wright if (rc1 == IDMAP_ERR_NOTFOUND) { 917479ac375Sdm199847 req->direction |= _IDMAP_F_LOOKUP_AD; 918479ac375Sdm199847 state->ad_nqueries++; 919479ac375Sdm199847 } else 920479ac375Sdm199847 res->retcode = rc1; 921479ac375Sdm199847 } 922479ac375Sdm199847 923479ac375Sdm199847 /* 924479ac375Sdm199847 * Unset non-fatal errors in individual request. This allows 925479ac375Sdm199847 * the next pass to process other mapping mechanisms for 926479ac375Sdm199847 * this request. 927479ac375Sdm199847 */ 928479ac375Sdm199847 if (res->retcode != IDMAP_SUCCESS && 929479ac375Sdm199847 res->retcode != IDMAP_ERR_NS_LDAP_BAD_WINNAME && 930479ac375Sdm199847 !(IDMAP_FATAL_ERROR(res->retcode))) { 931148c5f43SAlan Wright idmap_how_clear(&res->info.how); 932479ac375Sdm199847 res->retcode = IDMAP_SUCCESS; 933479ac375Sdm199847 } 934479ac375Sdm199847 } 935479ac375Sdm199847 936479ac375Sdm199847 state->nldap_nqueries = 0; 937479ac375Sdm199847 return (retcode); 938e8c27ec8Sbaban } 939