15731Sbaban /*
25731Sbaban * CDDL HEADER START
35731Sbaban *
45731Sbaban * The contents of this file are subject to the terms of the
55731Sbaban * Common Development and Distribution License (the "License").
65731Sbaban * You may not use this file except in compliance with the License.
75731Sbaban *
85731Sbaban * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95731Sbaban * or http://www.opensolaris.org/os/licensing.
105731Sbaban * See the License for the specific language governing permissions
115731Sbaban * and limitations under the License.
125731Sbaban *
135731Sbaban * When distributing Covered Code, include this CDDL HEADER in each
145731Sbaban * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155731Sbaban * If applicable, add the following below this CDDL HEADER, with the
165731Sbaban * fields enclosed by brackets "[]" replaced with your own identifying
175731Sbaban * information: Portions Copyright [yyyy] [name of copyright owner]
185731Sbaban *
195731Sbaban * CDDL HEADER END
205731Sbaban */
215731Sbaban
225731Sbaban /*
23*12508Samw@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
245731Sbaban */
255731Sbaban
265731Sbaban /*
275731Sbaban * native LDAP related utility routines
285731Sbaban */
295731Sbaban
305731Sbaban #include "idmapd.h"
316616Sdm199847 #include "idmap_priv.h"
326616Sdm199847 #include "ns_sldap.h"
336616Sdm199847 #include "nldaputils.h"
346616Sdm199847 #include <assert.h>
356616Sdm199847
366616Sdm199847 /*
376616Sdm199847 * The following are format strings used to construct LDAP search filters
386616Sdm199847 * when looking up Native LDAP directory service. The _F_XXX_SSD format
396616Sdm199847 * is used by the libsldap API if a corresponding SSD is defined in
406616Sdm199847 * Native LDAP configuration. The SSD contains a string that replaces
416616Sdm199847 * the first %s in _F_XXX_SSD. If no SSD is defined then the regular
426616Sdm199847 * _F_XXX format is used.
436616Sdm199847 *
446616Sdm199847 * Note that '\\' needs to be represented as "\\5c" in LDAP filters.
456616Sdm199847 */
466616Sdm199847
476616Sdm199847 /* Native LDAP lookup using UNIX username */
486616Sdm199847 #define _F_GETPWNAM "(&(objectClass=posixAccount)(uid=%s))"
496616Sdm199847 #define _F_GETPWNAM_SSD "(&(%%s)(uid=%s))"
506616Sdm199847
516616Sdm199847 /*
526616Sdm199847 * Native LDAP user lookup using names of well-known SIDs
536616Sdm199847 * Note the use of 1$, 2$ in the format string which basically
546616Sdm199847 * allows snprintf to re-use its first two arguments.
556616Sdm199847 */
566616Sdm199847 #define _F_GETPWWNAMWK \
576616Sdm199847 "(&(objectClass=posixAccount)(|(%s=%s)(%1$s=BUILTIN\\5c%2$s)))"
586616Sdm199847 #define _F_GETPWWNAMWK_SSD "(&(%%s)(|(%s=%s)(%1$s=BUILTIN\\5c%2$s)))"
596616Sdm199847
606616Sdm199847 /* Native LDAP user lookup using winname@windomain OR windomain\winname */
616616Sdm199847 #define _F_GETPWWNAMDOM \
626616Sdm199847 "(&(objectClass=posixAccount)(|(%s=%s@%s)(%1$s=%3$s\\5c%2$s)))"
636616Sdm199847 #define _F_GETPWWNAMDOM_SSD "(&(%%s)(|(%s=%s@%s)(%1$s=%3$s\\5c%2$s)))"
646616Sdm199847
656616Sdm199847 /* Native LDAP lookup using UID */
666616Sdm199847 #define _F_GETPWUID "(&(objectClass=posixAccount)(uidNumber=%u))"
676616Sdm199847 #define _F_GETPWUID_SSD "(&(%%s)(uidNumber=%u))"
686616Sdm199847
696616Sdm199847 /* Native LDAP lookup using UNIX groupname */
706616Sdm199847 #define _F_GETGRNAM "(&(objectClass=posixGroup)(cn=%s))"
716616Sdm199847 #define _F_GETGRNAM_SSD "(&(%%s)(cn=%s))"
726616Sdm199847
736616Sdm199847 /* Native LDAP group lookup using names of well-known SIDs */
746616Sdm199847 #define _F_GETGRWNAMWK \
756616Sdm199847 "(&(objectClass=posixGroup)(|(%s=%s)(%1$s=BUILTIN\\5c%2$s)))"
766616Sdm199847 #define _F_GETGRWNAMWK_SSD "(&(%%s)(|(%s=%s)(%1$s=BUILTIN\\5c%2$s)))"
776616Sdm199847
786616Sdm199847 /* Native LDAP group lookup using winname@windomain OR windomain\winname */
796616Sdm199847 #define _F_GETGRWNAMDOM \
806616Sdm199847 "(&(objectClass=posixGroup)(|(%s=%s@%s)(%1$s=%3$s\\5c%2$s)))"
816616Sdm199847 #define _F_GETGRWNAMDOM_SSD "(&(%%s)(|(%s=%s@%s)(%1$s=%3$s\\5c%2$s)))"
826616Sdm199847
836616Sdm199847 /* Native LDAP lookup using GID */
846616Sdm199847 #define _F_GETGRGID "(&(objectClass=posixGroup)(gidNumber=%u))"
856616Sdm199847 #define _F_GETGRGID_SSD "(&(%%s)(gidNumber=%u))"
866616Sdm199847
876616Sdm199847 /* Native LDAP attribute names */
886616Sdm199847 #define UID "uid"
896616Sdm199847 #define CN "cn"
906616Sdm199847 #define UIDNUMBER "uidnumber"
916616Sdm199847 #define GIDNUMBER "gidnumber"
926616Sdm199847 #define DN "dn"
936616Sdm199847
946616Sdm199847 #define IS_NLDAP_RC_FATAL(x) ((x == NS_LDAP_MEMORY) ? 1 : 0)
956616Sdm199847
966616Sdm199847 typedef struct idmap_nldap_q {
976616Sdm199847 char **winname;
986616Sdm199847 char **windomain;
996616Sdm199847 char **unixname;
1006616Sdm199847 uid_t *pid;
1016616Sdm199847 char **dn;
1026616Sdm199847 char **attr;
1036616Sdm199847 char **value;
1046616Sdm199847 int is_user;
1056616Sdm199847 idmap_retcode *rc;
1066616Sdm199847 int lrc;
1076616Sdm199847 ns_ldap_result_t *result;
1086616Sdm199847 ns_ldap_error_t *errorp;
1096616Sdm199847 char *filter;
1106616Sdm199847 char *udata;
1116616Sdm199847 } idmap_nldap_q_t;
1126616Sdm199847
1136616Sdm199847 typedef struct idmap_nldap_query_state {
1146616Sdm199847 const char *nldap_winname_attr;
1156616Sdm199847 const char *defdom;
1166616Sdm199847 int nqueries;
1176616Sdm199847 int qid;
1186616Sdm199847 int flag;
1196616Sdm199847 ns_ldap_list_batch_t *batch;
1206616Sdm199847 idmap_nldap_q_t queries[1];
1216616Sdm199847 } idmap_nldap_query_state_t;
1226616Sdm199847
1236616Sdm199847 /*
1246616Sdm199847 * This routine has been copied from lib/nsswitch/ldap/common/ldap_utils.c
1256616Sdm199847 * after removing the debug statements.
1266616Sdm199847 *
1276616Sdm199847 * This is a generic filter callback function for merging the filter
1286616Sdm199847 * from service search descriptor with an existing search filter. This
1296616Sdm199847 * routine expects userdata to contain a format string with a single %s
1306616Sdm199847 * in it, and will use the format string with sprintf() to insert the
1316616Sdm199847 * SSD filter.
1326616Sdm199847 *
1336616Sdm199847 * This routine and userdata are passed to the __ns_ldap_list_batch_add()
1346616Sdm199847 * API.
1356616Sdm199847 *
1366616Sdm199847 * Consider an example that uses __ns_ldap_list_batch_add() to lookup
1376616Sdm199847 * native LDAP directory using a given userid 'xy12345'. In this
1386616Sdm199847 * example the userdata will contain the filter "(&(%s)(cn=xy1234))".
1396616Sdm199847 * If a SSD is defined to replace the rfc2307bis specified filter
1406616Sdm199847 * i.e. (objectClass=posixAccount) by a site-specific filter
1416616Sdm199847 * say (department=sds) then this routine when called will produce
1426616Sdm199847 * "(&(department=sds)(uid=xy1234))" as the real search filter.
1436616Sdm199847 */
1446616Sdm199847 static
1456616Sdm199847 int
merge_SSD_filter(const ns_ldap_search_desc_t * desc,char ** realfilter,const void * userdata)1466616Sdm199847 merge_SSD_filter(const ns_ldap_search_desc_t *desc,
1476616Sdm199847 char **realfilter, const void *userdata)
1486616Sdm199847 {
1496616Sdm199847 int len;
1506616Sdm199847 if (realfilter == NULL)
1516616Sdm199847 return (NS_LDAP_INVALID_PARAM);
1526616Sdm199847 *realfilter = NULL;
1536616Sdm199847 if (desc == NULL || desc->filter == NULL || userdata == NULL)
1546616Sdm199847 return (NS_LDAP_INVALID_PARAM);
1556616Sdm199847 len = strlen(userdata) + strlen(desc->filter) + 1;
1566616Sdm199847 *realfilter = (char *)malloc(len);
1576616Sdm199847 if (*realfilter == NULL)
1586616Sdm199847 return (NS_LDAP_MEMORY);
1596616Sdm199847 (void) sprintf(*realfilter, (char *)userdata, desc->filter);
1606616Sdm199847 return (NS_LDAP_SUCCESS);
1616616Sdm199847 }
1626616Sdm199847
1636616Sdm199847 static
1646616Sdm199847 char
hex_char(int n)1656616Sdm199847 hex_char(int n)
1666616Sdm199847 {
1676616Sdm199847 return ("0123456789abcdef"[n & 0xf]);
1686616Sdm199847 }
1696616Sdm199847
1706616Sdm199847 /*
1716616Sdm199847 * If the input string contains special characters that needs to be
1726616Sdm199847 * escaped before the string can be used in a LDAP filter then this
1736616Sdm199847 * function will return a new sanitized string. Otherwise this function
1746616Sdm199847 * returns the input string (This saves us un-necessary memory allocations
1756616Sdm199847 * especially when processing a batch of requests). The caller must free
1766616Sdm199847 * the returned string if it isn't the input string.
1776616Sdm199847 *
1786616Sdm199847 * The escape mechanism for LDAP filter is described in RFC2254 basically
1796616Sdm199847 * it's \hh where hh are the two hexadecimal digits representing the ASCII
1806616Sdm199847 * value of the encoded character (case of hh is not significant).
1816616Sdm199847 * Example: * -> \2a, ( -> \28, ) -> \29, \ -> \5c,
1826616Sdm199847 *
1836616Sdm199847 * outstring = sanitize_for_ldap_filter(instring);
1846616Sdm199847 * if (outstring == NULL)
1856616Sdm199847 * Out of memory
1866616Sdm199847 * else
1876616Sdm199847 * Use outstring
1886616Sdm199847 * if (outstring != instring)
1896616Sdm199847 * free(outstring);
1906616Sdm199847 * done
1916616Sdm199847 */
1926616Sdm199847 char *
sanitize_for_ldap_filter(const char * str)1936616Sdm199847 sanitize_for_ldap_filter(const char *str)
1946616Sdm199847 {
1956616Sdm199847 const char *p;
1966616Sdm199847 char *q, *s_str = NULL;
1976616Sdm199847 int n;
1986616Sdm199847
1996616Sdm199847 /* Get a count of special characters */
2006616Sdm199847 for (p = str, n = 0; *p; p++)
2016616Sdm199847 if (*p == '*' || *p == '(' || *p == ')' ||
2026616Sdm199847 *p == '\\' || *p == '%')
2036616Sdm199847 n++;
2046616Sdm199847 /* If count is zero then no need to sanitize */
2056616Sdm199847 if (n == 0)
2066616Sdm199847 return ((char *)str);
2076616Sdm199847 /* Create output buffer that will contain the sanitized value */
2086616Sdm199847 s_str = calloc(1, n * 2 + strlen(str) + 1);
2096616Sdm199847 if (s_str == NULL)
2106616Sdm199847 return (NULL);
2116616Sdm199847 for (p = str, q = s_str; *p; p++) {
2126616Sdm199847 if (*p == '*' || *p == '(' || *p == ')' ||
2136616Sdm199847 *p == '\\' || *p == '%') {
2146616Sdm199847 *q++ = '\\';
2156616Sdm199847 *q++ = hex_char(*p >> 4);
2166616Sdm199847 *q++ = hex_char(*p & 0xf);
2176616Sdm199847 } else
2186616Sdm199847 *q++ = *p;
2196616Sdm199847 }
2206616Sdm199847 return (s_str);
2216616Sdm199847 }
2226616Sdm199847
2236616Sdm199847 /*
2246616Sdm199847 * Map libsldap status to idmap status
2256616Sdm199847 */
2266616Sdm199847 static
2276616Sdm199847 idmap_retcode
nldaprc2retcode(int rc)2286616Sdm199847 nldaprc2retcode(int rc)
2296616Sdm199847 {
2306616Sdm199847 switch (rc) {
2316616Sdm199847 case NS_LDAP_SUCCESS:
2326616Sdm199847 case NS_LDAP_SUCCESS_WITH_INFO:
2336616Sdm199847 return (IDMAP_SUCCESS);
2346616Sdm199847 case NS_LDAP_NOTFOUND:
2356616Sdm199847 return (IDMAP_ERR_NOTFOUND);
2366616Sdm199847 case NS_LDAP_MEMORY:
2376616Sdm199847 return (IDMAP_ERR_MEMORY);
2386616Sdm199847 case NS_LDAP_CONFIG:
2396616Sdm199847 return (IDMAP_ERR_NS_LDAP_CFG);
2406616Sdm199847 case NS_LDAP_OP_FAILED:
2416616Sdm199847 return (IDMAP_ERR_NS_LDAP_OP_FAILED);
2426616Sdm199847 case NS_LDAP_PARTIAL:
2436616Sdm199847 return (IDMAP_ERR_NS_LDAP_PARTIAL);
2446616Sdm199847 case NS_LDAP_INTERNAL:
2456616Sdm199847 return (IDMAP_ERR_INTERNAL);
2466616Sdm199847 case NS_LDAP_INVALID_PARAM:
2476616Sdm199847 return (IDMAP_ERR_ARG);
2486616Sdm199847 default:
2496616Sdm199847 return (IDMAP_ERR_OTHER);
2506616Sdm199847 }
2516616Sdm199847 /*NOTREACHED*/
2526616Sdm199847 }
2536616Sdm199847
2546616Sdm199847 /*
2556616Sdm199847 * Create a batch for native LDAP lookup.
2566616Sdm199847 */
2576616Sdm199847 static
2586616Sdm199847 idmap_retcode
idmap_nldap_lookup_batch_start(int nqueries,idmap_nldap_query_state_t ** qs)2596616Sdm199847 idmap_nldap_lookup_batch_start(int nqueries, idmap_nldap_query_state_t **qs)
2606616Sdm199847 {
2616616Sdm199847 idmap_nldap_query_state_t *s;
2626616Sdm199847
2636616Sdm199847 s = calloc(1, sizeof (*s) +
2646616Sdm199847 (nqueries - 1) * sizeof (idmap_nldap_q_t));
2656616Sdm199847 if (s == NULL)
2666616Sdm199847 return (IDMAP_ERR_MEMORY);
2676616Sdm199847 if (__ns_ldap_list_batch_start(&s->batch) != NS_LDAP_SUCCESS) {
2686616Sdm199847 free(s);
2696616Sdm199847 return (IDMAP_ERR_MEMORY);
2706616Sdm199847 }
2716616Sdm199847 s->nqueries = nqueries;
2726616Sdm199847 s->flag = NS_LDAP_KEEP_CONN;
2736616Sdm199847 *qs = s;
2746616Sdm199847 return (IDMAP_SUCCESS);
2756616Sdm199847 }
2766616Sdm199847
2776616Sdm199847 /*
2786616Sdm199847 * Add a lookup by winname request to the batch.
2796616Sdm199847 */
2806616Sdm199847 static
2816616Sdm199847 idmap_retcode
idmap_nldap_bywinname_batch_add(idmap_nldap_query_state_t * qs,const char * winname,const char * windomain,int is_user,char ** dn,char ** attr,char ** value,char ** unixname,uid_t * pid,idmap_retcode * rc)2826616Sdm199847 idmap_nldap_bywinname_batch_add(idmap_nldap_query_state_t *qs,
2836616Sdm199847 const char *winname, const char *windomain, int is_user,
2846616Sdm199847 char **dn, char **attr, char **value,
2856616Sdm199847 char **unixname, uid_t *pid, idmap_retcode *rc)
2866616Sdm199847 {
2876616Sdm199847 idmap_nldap_q_t *q;
2886616Sdm199847 const char *db, *filter, *udata;
2896616Sdm199847 int flen, ulen, wksid = 0;
2906616Sdm199847 char *s_winname, *s_windomain;
2916616Sdm199847 const char **attrs;
2926616Sdm199847 const char *pwd_attrs[] = {UID, UIDNUMBER, NULL, NULL};
2936616Sdm199847 const char *grp_attrs[] = {CN, GIDNUMBER, NULL, NULL};
2946616Sdm199847
2956616Sdm199847 s_winname = s_windomain = NULL;
2966616Sdm199847 q = &(qs->queries[qs->qid++]);
2976616Sdm199847 q->unixname = unixname;
2986616Sdm199847 q->pid = pid;
2996616Sdm199847 q->rc = rc;
3006616Sdm199847 q->is_user = is_user;
3016616Sdm199847 q->dn = dn;
3026616Sdm199847 q->attr = attr;
3036616Sdm199847 q->value = value;
3046616Sdm199847
3056616Sdm199847 if (is_user) {
3066616Sdm199847 db = "passwd";
3079422SAfshin.Ardakani@Sun.COM if (lookup_wksids_name2sid(winname, NULL, NULL, NULL, NULL,
3089422SAfshin.Ardakani@Sun.COM NULL, NULL) == IDMAP_SUCCESS) {
3096616Sdm199847 filter = _F_GETPWWNAMWK;
3106616Sdm199847 udata = _F_GETPWWNAMWK_SSD;
3116616Sdm199847 wksid = 1;
3126616Sdm199847 } else if (windomain != NULL) {
3136616Sdm199847 filter = _F_GETPWWNAMDOM;
3146616Sdm199847 udata = _F_GETPWWNAMDOM_SSD;
3156616Sdm199847 } else {
3166616Sdm199847 *q->rc = IDMAP_ERR_DOMAIN_NOTFOUND;
3176616Sdm199847 goto errout;
3186616Sdm199847 }
3196616Sdm199847 pwd_attrs[2] = qs->nldap_winname_attr;
3206616Sdm199847 attrs = pwd_attrs;
3216616Sdm199847 } else {
3226616Sdm199847 db = "group";
3239422SAfshin.Ardakani@Sun.COM if (lookup_wksids_name2sid(winname, NULL, NULL, NULL, NULL,
3249422SAfshin.Ardakani@Sun.COM NULL, NULL) == IDMAP_SUCCESS) {
3256616Sdm199847 filter = _F_GETGRWNAMWK;
3266616Sdm199847 udata = _F_GETGRWNAMWK_SSD;
3276616Sdm199847 wksid = 1;
3286616Sdm199847 } else if (windomain != NULL) {
3296616Sdm199847 filter = _F_GETGRWNAMDOM;
3306616Sdm199847 udata = _F_GETGRWNAMDOM_SSD;
3316616Sdm199847 } else {
3326616Sdm199847 *q->rc = IDMAP_ERR_DOMAIN_NOTFOUND;
3336616Sdm199847 goto errout;
3346616Sdm199847 }
3356616Sdm199847 grp_attrs[2] = qs->nldap_winname_attr;
3366616Sdm199847 attrs = grp_attrs;
3376616Sdm199847 }
3386616Sdm199847
3396616Sdm199847 /*
3406616Sdm199847 * Sanitize names. No need to sanitize qs->nldap_winname_attr
3416616Sdm199847 * because if it contained any of the special characters then
3426616Sdm199847 * it would have been rejected by the function that reads it
3436616Sdm199847 * from the SMF config. LDAP attribute names can only contain
3446616Sdm199847 * letters, digits or hyphens.
3456616Sdm199847 */
3466616Sdm199847 s_winname = sanitize_for_ldap_filter(winname);
3476616Sdm199847 if (s_winname == NULL) {
3486616Sdm199847 *q->rc = IDMAP_ERR_MEMORY;
3496616Sdm199847 goto errout;
3506616Sdm199847 }
3516616Sdm199847 /* windomain could be NULL for names of well-known SIDs */
3526616Sdm199847 if (windomain != NULL) {
3536616Sdm199847 s_windomain = sanitize_for_ldap_filter(windomain);
3546616Sdm199847 if (s_windomain == NULL) {
3556616Sdm199847 *q->rc = IDMAP_ERR_MEMORY;
3566616Sdm199847 goto errout;
3576616Sdm199847 }
3586616Sdm199847 }
3596616Sdm199847
3606616Sdm199847 /* Construct the filter and udata using snprintf. */
3616616Sdm199847 if (wksid) {
3626616Sdm199847 flen = snprintf(NULL, 0, filter, qs->nldap_winname_attr,
3636616Sdm199847 s_winname) + 1;
3646616Sdm199847 ulen = snprintf(NULL, 0, udata, qs->nldap_winname_attr,
3656616Sdm199847 s_winname) + 1;
3666616Sdm199847 } else {
3676616Sdm199847 flen = snprintf(NULL, 0, filter, qs->nldap_winname_attr,
3686616Sdm199847 s_winname, s_windomain) + 1;
3696616Sdm199847 ulen = snprintf(NULL, 0, udata, qs->nldap_winname_attr,
3706616Sdm199847 s_winname, s_windomain) + 1;
3716616Sdm199847 }
3726616Sdm199847
3736616Sdm199847 q->filter = malloc(flen);
3746616Sdm199847 if (q->filter == NULL) {
3756616Sdm199847 *q->rc = IDMAP_ERR_MEMORY;
3766616Sdm199847 goto errout;
3776616Sdm199847 }
3786616Sdm199847 q->udata = malloc(ulen);
3796616Sdm199847 if (q->udata == NULL) {
3806616Sdm199847 *q->rc = IDMAP_ERR_MEMORY;
3816616Sdm199847 goto errout;
3826616Sdm199847 }
3836616Sdm199847
3846616Sdm199847 if (wksid) {
3856616Sdm199847 (void) snprintf(q->filter, flen, filter,
3866616Sdm199847 qs->nldap_winname_attr, s_winname);
3876616Sdm199847 (void) snprintf(q->udata, ulen, udata,
3886616Sdm199847 qs->nldap_winname_attr, s_winname);
3896616Sdm199847 } else {
3906616Sdm199847 (void) snprintf(q->filter, flen, filter,
3916616Sdm199847 qs->nldap_winname_attr, s_winname, s_windomain);
3926616Sdm199847 (void) snprintf(q->udata, ulen, udata,
3936616Sdm199847 qs->nldap_winname_attr, s_winname, s_windomain);
3946616Sdm199847 }
3956616Sdm199847
3966616Sdm199847 if (s_winname != winname)
3976616Sdm199847 free(s_winname);
3986616Sdm199847 if (s_windomain != windomain)
3996616Sdm199847 free(s_windomain);
4006616Sdm199847
4016616Sdm199847 q->lrc = __ns_ldap_list_batch_add(qs->batch, db, q->filter,
4026616Sdm199847 merge_SSD_filter, attrs, NULL, qs->flag, &q->result,
4036616Sdm199847 &q->errorp, &q->lrc, NULL, q->udata);
4046616Sdm199847
4056616Sdm199847 if (IS_NLDAP_RC_FATAL(q->lrc))
4066616Sdm199847 return (nldaprc2retcode(q->lrc));
4076616Sdm199847 return (IDMAP_SUCCESS);
4086616Sdm199847
4096616Sdm199847 errout:
4106616Sdm199847 /* query q and its content will be freed by batch_release */
4116616Sdm199847 if (s_winname != winname)
4126616Sdm199847 free(s_winname);
4136616Sdm199847 if (s_windomain != windomain)
4146616Sdm199847 free(s_windomain);
4156616Sdm199847 return (*q->rc);
4166616Sdm199847 }
4176616Sdm199847
4186616Sdm199847 /*
4196616Sdm199847 * Add a lookup by uid/gid request to the batch.
4206616Sdm199847 */
4216616Sdm199847 static
4226616Sdm199847 idmap_retcode
idmap_nldap_bypid_batch_add(idmap_nldap_query_state_t * qs,uid_t pid,int is_user,char ** dn,char ** attr,char ** value,char ** winname,char ** windomain,char ** unixname,idmap_retcode * rc)4236616Sdm199847 idmap_nldap_bypid_batch_add(idmap_nldap_query_state_t *qs,
4246616Sdm199847 uid_t pid, int is_user, char **dn, char **attr, char **value,
4256616Sdm199847 char **winname, char **windomain,
4266616Sdm199847 char **unixname, idmap_retcode *rc)
4276616Sdm199847 {
4286616Sdm199847 idmap_nldap_q_t *q;
4296616Sdm199847 const char *db, *filter, *udata;
4306616Sdm199847 int len;
4316616Sdm199847 const char **attrs;
4326616Sdm199847 const char *pwd_attrs[] = {UID, NULL, NULL};
4336616Sdm199847 const char *grp_attrs[] = {CN, NULL, NULL};
4346616Sdm199847
4356616Sdm199847 q = &(qs->queries[qs->qid++]);
4366616Sdm199847 q->winname = winname;
4376616Sdm199847 q->windomain = windomain;
4386616Sdm199847 q->unixname = unixname;
4396616Sdm199847 q->rc = rc;
4406616Sdm199847 q->is_user = is_user;
4416616Sdm199847 q->dn = dn;
4426616Sdm199847 q->attr = attr;
4436616Sdm199847 q->value = value;
4446616Sdm199847
4456616Sdm199847 if (is_user) {
4466616Sdm199847 db = "passwd";
4476616Sdm199847 filter = _F_GETPWUID;
4486616Sdm199847 udata = _F_GETPWUID_SSD;
4496616Sdm199847 pwd_attrs[1] = qs->nldap_winname_attr;
4506616Sdm199847 attrs = pwd_attrs;
4516616Sdm199847 } else {
4526616Sdm199847 db = "group";
4536616Sdm199847 filter = _F_GETGRGID;
4546616Sdm199847 udata = _F_GETGRGID_SSD;
4556616Sdm199847 grp_attrs[1] = qs->nldap_winname_attr;
4566616Sdm199847 attrs = grp_attrs;
4576616Sdm199847 }
4586616Sdm199847
4596616Sdm199847 len = snprintf(NULL, 0, filter, pid) + 1;
4606616Sdm199847 q->filter = malloc(len);
4616616Sdm199847 if (q->filter == NULL) {
4626616Sdm199847 *q->rc = IDMAP_ERR_MEMORY;
4636616Sdm199847 return (IDMAP_ERR_MEMORY);
4646616Sdm199847 }
4656616Sdm199847 (void) snprintf(q->filter, len, filter, pid);
4666616Sdm199847
4676616Sdm199847 len = snprintf(NULL, 0, udata, pid) + 1;
4686616Sdm199847 q->udata = malloc(len);
4696616Sdm199847 if (q->udata == NULL) {
4706616Sdm199847 *q->rc = IDMAP_ERR_MEMORY;
4716616Sdm199847 return (IDMAP_ERR_MEMORY);
4726616Sdm199847 }
4736616Sdm199847 (void) snprintf(q->udata, len, udata, pid);
4746616Sdm199847
4756616Sdm199847 q->lrc = __ns_ldap_list_batch_add(qs->batch, db, q->filter,
4766616Sdm199847 merge_SSD_filter, attrs, NULL, qs->flag, &q->result,
4776616Sdm199847 &q->errorp, &q->lrc, NULL, q->udata);
4786616Sdm199847
4796616Sdm199847 if (IS_NLDAP_RC_FATAL(q->lrc))
4806616Sdm199847 return (nldaprc2retcode(q->lrc));
4816616Sdm199847 return (IDMAP_SUCCESS);
4826616Sdm199847 }
4836616Sdm199847
4846616Sdm199847 /*
4856616Sdm199847 * Add a lookup by user/group name request to the batch.
4866616Sdm199847 */
4876616Sdm199847 static
4886616Sdm199847 idmap_retcode
idmap_nldap_byunixname_batch_add(idmap_nldap_query_state_t * qs,const char * unixname,int is_user,char ** dn,char ** attr,char ** value,char ** winname,char ** windomain,uid_t * pid,idmap_retcode * rc)4896616Sdm199847 idmap_nldap_byunixname_batch_add(idmap_nldap_query_state_t *qs,
4906616Sdm199847 const char *unixname, int is_user,
4916616Sdm199847 char **dn, char **attr, char **value,
4926616Sdm199847 char **winname, char **windomain, uid_t *pid, idmap_retcode *rc)
4936616Sdm199847 {
4946616Sdm199847 idmap_nldap_q_t *q;
4956616Sdm199847 const char *db, *filter, *udata;
4966616Sdm199847 int len;
4976616Sdm199847 char *s_unixname = NULL;
4986616Sdm199847 const char **attrs;
4996616Sdm199847 const char *pwd_attrs[] = {UIDNUMBER, NULL, NULL};
5006616Sdm199847 const char *grp_attrs[] = {GIDNUMBER, NULL, NULL};
5016616Sdm199847
5026616Sdm199847 q = &(qs->queries[qs->qid++]);
5036616Sdm199847 q->winname = winname;
5046616Sdm199847 q->windomain = windomain;
5056616Sdm199847 q->pid = pid;
5066616Sdm199847 q->rc = rc;
5076616Sdm199847 q->is_user = is_user;
5086616Sdm199847 q->dn = dn;
5096616Sdm199847 q->attr = attr;
5106616Sdm199847 q->value = value;
5116616Sdm199847
5126616Sdm199847 if (is_user) {
5136616Sdm199847 db = "passwd";
5146616Sdm199847 filter = _F_GETPWNAM;
5156616Sdm199847 udata = _F_GETPWNAM_SSD;
5166616Sdm199847 pwd_attrs[1] = qs->nldap_winname_attr;
5176616Sdm199847 attrs = pwd_attrs;
5186616Sdm199847 } else {
5196616Sdm199847 db = "group";
5206616Sdm199847 filter = _F_GETGRNAM;
5216616Sdm199847 udata = _F_GETGRNAM_SSD;
5226616Sdm199847 grp_attrs[1] = qs->nldap_winname_attr;
5236616Sdm199847 attrs = grp_attrs;
5246616Sdm199847 }
5256616Sdm199847
5266616Sdm199847 s_unixname = sanitize_for_ldap_filter(unixname);
5276616Sdm199847 if (s_unixname == NULL) {
5286616Sdm199847 *q->rc = IDMAP_ERR_MEMORY;
5296616Sdm199847 return (IDMAP_ERR_MEMORY);
5306616Sdm199847 }
5316616Sdm199847
5326616Sdm199847 len = snprintf(NULL, 0, filter, s_unixname) + 1;
5336616Sdm199847 q->filter = malloc(len);
5346616Sdm199847 if (q->filter == NULL) {
5356616Sdm199847 if (s_unixname != unixname)
5366616Sdm199847 free(s_unixname);
5376616Sdm199847 *q->rc = IDMAP_ERR_MEMORY;
5386616Sdm199847 return (IDMAP_ERR_MEMORY);
5396616Sdm199847 }
5406616Sdm199847 (void) snprintf(q->filter, len, filter, s_unixname);
5416616Sdm199847
5426616Sdm199847 len = snprintf(NULL, 0, udata, s_unixname) + 1;
5436616Sdm199847 q->udata = malloc(len);
5446616Sdm199847 if (q->udata == NULL) {
5456616Sdm199847 if (s_unixname != unixname)
5466616Sdm199847 free(s_unixname);
5476616Sdm199847 *q->rc = IDMAP_ERR_MEMORY;
5486616Sdm199847 return (IDMAP_ERR_MEMORY);
5496616Sdm199847 }
5506616Sdm199847 (void) snprintf(q->udata, len, udata, s_unixname);
5516616Sdm199847
5526616Sdm199847 if (s_unixname != unixname)
5536616Sdm199847 free(s_unixname);
5546616Sdm199847
5556616Sdm199847 q->lrc = __ns_ldap_list_batch_add(qs->batch, db, q->filter,
5566616Sdm199847 merge_SSD_filter, attrs, NULL, qs->flag, &q->result,
5576616Sdm199847 &q->errorp, &q->lrc, NULL, q->udata);
5586616Sdm199847
5596616Sdm199847 if (IS_NLDAP_RC_FATAL(q->lrc))
5606616Sdm199847 return (nldaprc2retcode(q->lrc));
5616616Sdm199847 return (IDMAP_SUCCESS);
5626616Sdm199847 }
5636616Sdm199847
5646616Sdm199847 /*
5656616Sdm199847 * Free the batch
5666616Sdm199847 */
5676616Sdm199847 static
5686616Sdm199847 void
idmap_nldap_lookup_batch_release(idmap_nldap_query_state_t * qs)5696616Sdm199847 idmap_nldap_lookup_batch_release(idmap_nldap_query_state_t *qs)
5706616Sdm199847 {
5716616Sdm199847 idmap_nldap_q_t *q;
5726616Sdm199847 int i;
5736616Sdm199847
5746616Sdm199847 if (qs->batch != NULL)
5756616Sdm199847 (void) __ns_ldap_list_batch_release(qs->batch);
5766616Sdm199847 for (i = 0; i < qs->qid; i++) {
5776616Sdm199847 q = &(qs->queries[i]);
5786616Sdm199847 free(q->filter);
5796616Sdm199847 free(q->udata);
5806616Sdm199847 if (q->errorp != NULL)
5816616Sdm199847 (void) __ns_ldap_freeError(&q->errorp);
5826616Sdm199847 if (q->result != NULL)
5836616Sdm199847 (void) __ns_ldap_freeResult(&q->result);
5846616Sdm199847 }
5856616Sdm199847 free(qs);
5866616Sdm199847 }
5876616Sdm199847
5886616Sdm199847 /*
5896616Sdm199847 * Process all requests added to the batch and then free the batch.
5906616Sdm199847 * The results for individual requests will be accessible using the
5916616Sdm199847 * pointers passed during idmap_nldap_lookup_batch_end.
5926616Sdm199847 */
5936616Sdm199847 static
5946616Sdm199847 idmap_retcode
idmap_nldap_lookup_batch_end(idmap_nldap_query_state_t * qs)5956616Sdm199847 idmap_nldap_lookup_batch_end(idmap_nldap_query_state_t *qs)
5966616Sdm199847 {
5976616Sdm199847 idmap_nldap_q_t *q;
5986616Sdm199847 int i;
5996616Sdm199847 ns_ldap_entry_t *entry;
6006616Sdm199847 char **val, *end, *str, *name, *dom;
6016616Sdm199847 idmap_retcode rc = IDMAP_SUCCESS;
6026616Sdm199847
6036616Sdm199847 (void) __ns_ldap_list_batch_end(qs->batch);
6046616Sdm199847 qs->batch = NULL;
6056616Sdm199847 for (i = 0; i < qs->qid; i++) {
6066616Sdm199847 q = &(qs->queries[i]);
6076616Sdm199847 *q->rc = nldaprc2retcode(q->lrc);
6086616Sdm199847 if (*q->rc != IDMAP_SUCCESS)
6096616Sdm199847 continue;
6106616Sdm199847 if (q->result == NULL ||
6116616Sdm199847 !q->result->entries_count ||
6126616Sdm199847 (entry = q->result->entry) == NULL ||
6136616Sdm199847 !entry->attr_count) {
6146616Sdm199847 *q->rc = IDMAP_ERR_NOTFOUND;
6156616Sdm199847 continue;
6166616Sdm199847 }
6176616Sdm199847 /* Get uid/gid */
6186616Sdm199847 if (q->pid != NULL) {
6196616Sdm199847 val = __ns_ldap_getAttr(entry,
6206616Sdm199847 (q->is_user) ? UIDNUMBER : GIDNUMBER);
6216616Sdm199847 if (val != NULL && *val != NULL)
6226616Sdm199847 *q->pid = strtoul(*val, &end, 10);
6236616Sdm199847 }
6246616Sdm199847 /* Get unixname */
6256616Sdm199847 if (q->unixname != NULL) {
6266616Sdm199847 val = __ns_ldap_getAttr(entry,
6276616Sdm199847 (q->is_user) ? UID : CN);
6286616Sdm199847 if (val != NULL && *val != NULL) {
6296616Sdm199847 *q->unixname = strdup(*val);
6306616Sdm199847 if (*q->unixname == NULL) {
6316616Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY;
6326616Sdm199847 goto out;
6336616Sdm199847 }
6346616Sdm199847 }
6356616Sdm199847 }
6366616Sdm199847 /* Get DN for how info */
6376616Sdm199847 if (q->dn != NULL) {
6386616Sdm199847 val = __ns_ldap_getAttr(entry, DN);
6396616Sdm199847 if (val != NULL && *val != NULL) {
6406616Sdm199847 *q->dn = strdup(*val);
6416616Sdm199847 if (*q->dn == NULL) {
6426616Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY;
6436616Sdm199847 goto out;
6446616Sdm199847 }
6456616Sdm199847 }
6466616Sdm199847 }
6476616Sdm199847 /* Get nldap name mapping attr name for how info */
6486616Sdm199847 if (q->attr != NULL) {
6496616Sdm199847 *q->attr = strdup(qs->nldap_winname_attr);
6506616Sdm199847 if (*q->attr == NULL) {
6516616Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY;
6526616Sdm199847 goto out;
6536616Sdm199847 }
6546616Sdm199847 }
6556616Sdm199847 /* Get nldap name mapping attr value for how info */
6566616Sdm199847 val = __ns_ldap_getAttr(entry, qs->nldap_winname_attr);
6576616Sdm199847 if (val == NULL || *val == NULL)
6586616Sdm199847 continue;
6596616Sdm199847 if (q->value != NULL) {
6606616Sdm199847 *q->value = strdup(*val);
6616616Sdm199847 if (*q->value == NULL) {
6626616Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY;
6636616Sdm199847 goto out;
6646616Sdm199847 }
6656616Sdm199847 }
6666616Sdm199847
6676616Sdm199847 /* Get winname and windomain */
6686616Sdm199847 if (q->winname == NULL && q->windomain == NULL)
6696616Sdm199847 continue;
6706616Sdm199847 /*
6716616Sdm199847 * We need to split the value into winname and
6726616Sdm199847 * windomain. The value could be either in NT4
6736616Sdm199847 * style (i.e. dom\name) or AD-style (i.e. name@dom).
6746616Sdm199847 * We choose the first '\\' if it's in NT4 style and
6756616Sdm199847 * the last '@' if it's in AD-style for the split.
6766616Sdm199847 */
6776616Sdm199847 name = dom = NULL;
6789422SAfshin.Ardakani@Sun.COM if (lookup_wksids_name2sid(*val, NULL, NULL, NULL, NULL, NULL,
6799422SAfshin.Ardakani@Sun.COM NULL) == IDMAP_SUCCESS) {
6806616Sdm199847 name = *val;
6816616Sdm199847 dom = NULL;
6826616Sdm199847 } else if ((str = strchr(*val, '\\')) != NULL) {
6836616Sdm199847 *str = '\0';
6846616Sdm199847 name = str + 1;
6856616Sdm199847 dom = *val;
6866616Sdm199847 } else if ((str = strrchr(*val, '@')) != NULL) {
6876616Sdm199847 *str = '\0';
6886616Sdm199847 name = *val;
6896616Sdm199847 dom = str + 1;
6906616Sdm199847 } else {
6916616Sdm199847 idmapdlog(LOG_INFO, "Domain-less "
6926616Sdm199847 "winname (%s) found in Native LDAP", *val);
6936616Sdm199847 *q->rc = IDMAP_ERR_NS_LDAP_BAD_WINNAME;
6946616Sdm199847 continue;
6956616Sdm199847 }
6966616Sdm199847 if (q->winname != NULL) {
6976616Sdm199847 *q->winname = strdup(name);
6986616Sdm199847 if (*q->winname == NULL) {
6996616Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY;
7006616Sdm199847 goto out;
7016616Sdm199847 }
7026616Sdm199847 }
7036616Sdm199847 if (q->windomain != NULL && dom != NULL) {
7046616Sdm199847 *q->windomain = strdup(dom);
7056616Sdm199847 if (*q->windomain == NULL) {
7066616Sdm199847 rc = *q->rc = IDMAP_ERR_MEMORY;
7076616Sdm199847 goto out;
7086616Sdm199847 }
7096616Sdm199847 }
7106616Sdm199847 }
7116616Sdm199847
7126616Sdm199847 out:
7136616Sdm199847 (void) idmap_nldap_lookup_batch_release(qs);
7146616Sdm199847 return (rc);
7156616Sdm199847 }
7165731Sbaban
7175731Sbaban /* ARGSUSED */
7185731Sbaban idmap_retcode
nldap_lookup_batch(lookup_state_t * state,idmap_mapping_batch * batch,idmap_ids_res * result)7195731Sbaban nldap_lookup_batch(lookup_state_t *state, idmap_mapping_batch *batch,
7205731Sbaban idmap_ids_res *result)
7215731Sbaban {
7226616Sdm199847 idmap_retcode retcode, rc1;
723*12508Samw@Sun.COM int i, add;
7246616Sdm199847 idmap_mapping *req;
7256616Sdm199847 idmap_id_res *res;
7266616Sdm199847 idmap_nldap_query_state_t *qs = NULL;
7276616Sdm199847 idmap_how *how;
7286616Sdm199847
7296616Sdm199847 if (state->nldap_nqueries == 0)
7306616Sdm199847 return (IDMAP_SUCCESS);
7316616Sdm199847
7326616Sdm199847 /* Create nldap lookup batch */
7336616Sdm199847 retcode = idmap_nldap_lookup_batch_start(state->nldap_nqueries, &qs);
7346616Sdm199847 if (retcode != IDMAP_SUCCESS) {
7356616Sdm199847 idmapdlog(LOG_ERR,
7366616Sdm199847 "Failed to create batch for native LDAP lookup");
7376616Sdm199847 goto out;
7386616Sdm199847 }
7396616Sdm199847
7406616Sdm199847 qs->nldap_winname_attr = state->nldap_winname_attr;
7416616Sdm199847 qs->defdom = state->defdom;
7426616Sdm199847
7436616Sdm199847 /* Add requests to the batch */
7446616Sdm199847 for (i = 0, add = 0; i < batch->idmap_mapping_batch_len; i++) {
7456616Sdm199847 req = &batch->idmap_mapping_batch_val[i];
7466616Sdm199847 res = &result->ids.ids_val[i];
7476616Sdm199847 retcode = IDMAP_SUCCESS;
7486616Sdm199847
7496616Sdm199847 /* Skip if not marked for nldap lookup */
7506616Sdm199847 if (!(req->direction & _IDMAP_F_LOOKUP_NLDAP))
7516616Sdm199847 continue;
7526616Sdm199847
753*12508Samw@Sun.COM if (IS_ID_SID(req->id1)) {
7546616Sdm199847
7556616Sdm199847 /* win2unix request: */
7566616Sdm199847
7576616Sdm199847 /*
7586616Sdm199847 * When processing a win2unix request, nldap lookup
7596616Sdm199847 * is performed after AD lookup or a successful
7606616Sdm199847 * name-cache lookup. Therefore we should already
7616616Sdm199847 * have sid, winname and sidtype. Note that
7626616Sdm199847 * windomain could be NULL e.g. well-known SIDs.
7636616Sdm199847 */
7646616Sdm199847 assert(req->id1name != NULL &&
7656616Sdm199847 (res->id.idtype == IDMAP_UID ||
7666616Sdm199847 res->id.idtype == IDMAP_GID));
7676616Sdm199847
7686616Sdm199847 /* Skip if we already have pid and unixname */
7696616Sdm199847 if (req->id2name != NULL &&
77011963SAfshin.Ardakani@Sun.COM res->id.idmap_id_u.uid != IDMAP_SENTINEL_PID) {
7716616Sdm199847 res->retcode = IDMAP_SUCCESS;
7726616Sdm199847 continue;
7736616Sdm199847 }
7746616Sdm199847
7756616Sdm199847 /* Clear leftover value */
7766616Sdm199847 free(req->id2name);
7776616Sdm199847 req->id2name = NULL;
7786616Sdm199847
7796616Sdm199847 /* Lookup nldap by winname to get pid and unixname */
7806616Sdm199847 add = 1;
781*12508Samw@Sun.COM idmap_how_clear(&res->info.how);
7826616Sdm199847 res->info.src = IDMAP_MAP_SRC_NEW;
7836616Sdm199847 how = &res->info.how;
7846616Sdm199847 how->map_type = IDMAP_MAP_TYPE_DS_NLDAP;
7856616Sdm199847 retcode = idmap_nldap_bywinname_batch_add(
7866616Sdm199847 qs, req->id1name, req->id1domain,
7876616Sdm199847 (res->id.idtype == IDMAP_UID) ? 1 : 0,
7886616Sdm199847 &how->idmap_how_u.nldap.dn,
7896616Sdm199847 &how->idmap_how_u.nldap.attr,
7906616Sdm199847 &how->idmap_how_u.nldap.value,
7916616Sdm199847 &req->id2name, &res->id.idmap_id_u.uid,
7926616Sdm199847 &res->retcode);
7936616Sdm199847
794*12508Samw@Sun.COM } else if (IS_ID_UID(req->id1) || IS_ID_GID(req->id1)) {
7956616Sdm199847
7966616Sdm199847 /* unix2win request: */
7976616Sdm199847
7986616Sdm199847 /* Skip if we already have winname */
7996616Sdm199847 if (req->id2name != NULL) {
8006616Sdm199847 res->retcode = IDMAP_SUCCESS;
8016616Sdm199847 continue;
8026616Sdm199847 }
8036616Sdm199847
8046616Sdm199847 /* Clear old value */
8056616Sdm199847 free(req->id2domain);
8066616Sdm199847 req->id2domain = NULL;
8076616Sdm199847
8086616Sdm199847 /* Set how info */
809*12508Samw@Sun.COM idmap_how_clear(&res->info.how);
8106616Sdm199847 res->info.src = IDMAP_MAP_SRC_NEW;
8116616Sdm199847 how = &res->info.how;
8126616Sdm199847 how->map_type = IDMAP_MAP_TYPE_DS_NLDAP;
8136616Sdm199847
8146616Sdm199847 /* Lookup nldap by pid or unixname to get winname */
81511963SAfshin.Ardakani@Sun.COM if (req->id1.idmap_id_u.uid != IDMAP_SENTINEL_PID) {
8166616Sdm199847 add = 1;
8176616Sdm199847 retcode = idmap_nldap_bypid_batch_add(
8186616Sdm199847 qs, req->id1.idmap_id_u.uid,
8196616Sdm199847 (req->id1.idtype == IDMAP_UID) ? 1 : 0,
8206616Sdm199847 &how->idmap_how_u.nldap.dn,
8216616Sdm199847 &how->idmap_how_u.nldap.attr,
8226616Sdm199847 &how->idmap_how_u.nldap.value,
8236616Sdm199847 &req->id2name, &req->id2domain,
8246616Sdm199847 (req->id1name == NULL) ?
8256616Sdm199847 &req->id1name : NULL,
8266616Sdm199847 &res->retcode);
8276616Sdm199847 } else if (req->id1name != NULL) {
8286616Sdm199847 add = 1;
8296616Sdm199847 retcode = idmap_nldap_byunixname_batch_add(
8306616Sdm199847 qs, req->id1name,
8316616Sdm199847 (req->id1.idtype == IDMAP_UID) ? 1 : 0,
8326616Sdm199847 &how->idmap_how_u.nldap.dn,
8336616Sdm199847 &how->idmap_how_u.nldap.attr,
8346616Sdm199847 &how->idmap_how_u.nldap.value,
8356616Sdm199847 &req->id2name, &req->id2domain,
8366616Sdm199847 &req->id1.idmap_id_u.uid, &res->retcode);
8376616Sdm199847 }
8386616Sdm199847
8396616Sdm199847 }
8406616Sdm199847
8416616Sdm199847 /*
8426616Sdm199847 * nldap_batch_add API returns error only on fatal failures
8436616Sdm199847 * otherwise it returns success and the actual status
8446616Sdm199847 * is stored in the individual request (res->retcode).
8456616Sdm199847 * Stop adding requests to this batch on fatal failures
8466616Sdm199847 * (i.e. if retcode != success)
8476616Sdm199847 */
8486616Sdm199847 if (retcode != IDMAP_SUCCESS)
8496616Sdm199847 break;
8506616Sdm199847 }
8516616Sdm199847
8526616Sdm199847 if (!add)
8536616Sdm199847 idmap_nldap_lookup_batch_release(qs);
8546616Sdm199847 else if (retcode != IDMAP_SUCCESS)
8556616Sdm199847 idmap_nldap_lookup_batch_release(qs);
8566616Sdm199847 else
8576616Sdm199847 retcode = idmap_nldap_lookup_batch_end(qs);
8586616Sdm199847
8596616Sdm199847 out:
8606616Sdm199847 for (i = 0; i < batch->idmap_mapping_batch_len; i++) {
8616616Sdm199847 req = &batch->idmap_mapping_batch_val[i];
8626616Sdm199847 res = &result->ids.ids_val[i];
8636616Sdm199847 if (!(req->direction & _IDMAP_F_LOOKUP_NLDAP))
8646616Sdm199847 continue;
8656616Sdm199847
8666616Sdm199847 /* Reset nldap flag */
8676616Sdm199847 req->direction &= ~(_IDMAP_F_LOOKUP_NLDAP);
8686616Sdm199847
8696616Sdm199847 /*
8706616Sdm199847 * As noted earlier retcode != success if there were fatal
8716616Sdm199847 * errors during batch_start and batch_adds. If so then set
8726616Sdm199847 * the status of each nldap request to that error.
8736616Sdm199847 */
8746616Sdm199847 if (retcode != IDMAP_SUCCESS) {
8756616Sdm199847 res->retcode = retcode;
8766616Sdm199847 continue;
8776616Sdm199847 }
8786616Sdm199847 if (!add)
8796616Sdm199847 continue;
8806616Sdm199847
8816616Sdm199847 /*
8826616Sdm199847 * If we successfully retrieved winname from nldap entry
8836616Sdm199847 * then lookup winname2sid locally. If not found locally
8846616Sdm199847 * then mark this request for AD lookup.
8856616Sdm199847 */
8866616Sdm199847 if (res->retcode == IDMAP_SUCCESS &&
8876616Sdm199847 req->id2name != NULL &&
8886616Sdm199847 res->id.idmap_id_u.sid.prefix == NULL &&
889*12508Samw@Sun.COM (IS_ID_UID(req->id1) || IS_ID_GID(req->id1))) {
8906616Sdm199847
8916616Sdm199847 rc1 = lookup_name2sid(state->cache,
892*12508Samw@Sun.COM req->id2name, req->id2domain, -1,
8939422SAfshin.Ardakani@Sun.COM NULL, NULL,
8946616Sdm199847 &res->id.idmap_id_u.sid.prefix,
895*12508Samw@Sun.COM &res->id.idmap_id_u.sid.rid,
896*12508Samw@Sun.COM &res->id.idtype,
897*12508Samw@Sun.COM req, 1);
898*12508Samw@Sun.COM if (rc1 == IDMAP_ERR_NOTFOUND) {
8996616Sdm199847 req->direction |= _IDMAP_F_LOOKUP_AD;
9006616Sdm199847 state->ad_nqueries++;
9016616Sdm199847 } else
9026616Sdm199847 res->retcode = rc1;
9036616Sdm199847 }
9046616Sdm199847
9056616Sdm199847 /*
9066616Sdm199847 * Unset non-fatal errors in individual request. This allows
9076616Sdm199847 * the next pass to process other mapping mechanisms for
9086616Sdm199847 * this request.
9096616Sdm199847 */
9106616Sdm199847 if (res->retcode != IDMAP_SUCCESS &&
9116616Sdm199847 res->retcode != IDMAP_ERR_NS_LDAP_BAD_WINNAME &&
9126616Sdm199847 !(IDMAP_FATAL_ERROR(res->retcode))) {
913*12508Samw@Sun.COM idmap_how_clear(&res->info.how);
9146616Sdm199847 res->retcode = IDMAP_SUCCESS;
9156616Sdm199847 }
9166616Sdm199847 }
9176616Sdm199847
9186616Sdm199847 state->nldap_nqueries = 0;
9196616Sdm199847 return (retcode);
9205731Sbaban }
921