14520Snw141292 /* 24520Snw141292 * CDDL HEADER START 34520Snw141292 * 44520Snw141292 * The contents of this file are subject to the terms of the 54520Snw141292 * Common Development and Distribution License (the "License"). 64520Snw141292 * You may not use this file except in compliance with the License. 74520Snw141292 * 84520Snw141292 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 94520Snw141292 * or http://www.opensolaris.org/os/licensing. 104520Snw141292 * See the License for the specific language governing permissions 114520Snw141292 * and limitations under the License. 124520Snw141292 * 134520Snw141292 * When distributing Covered Code, include this CDDL HEADER in each 144520Snw141292 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 154520Snw141292 * If applicable, add the following below this CDDL HEADER, with the 164520Snw141292 * fields enclosed by brackets "[]" replaced with your own identifying 174520Snw141292 * information: Portions Copyright [yyyy] [name of copyright owner] 184520Snw141292 * 194520Snw141292 * CDDL HEADER END 204520Snw141292 */ 214520Snw141292 224520Snw141292 /* 2310122SJordan.Brown@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 244520Snw141292 * Use is subject to license terms. 254520Snw141292 */ 264520Snw141292 274520Snw141292 /* 284520Snw141292 * Processes name2sid & sid2name batched lookups for a given user or 294520Snw141292 * computer from an AD Directory server using GSSAPI authentication 304520Snw141292 */ 314520Snw141292 324520Snw141292 #include <stdio.h> 334520Snw141292 #include <stdlib.h> 344520Snw141292 #include <alloca.h> 354520Snw141292 #include <string.h> 364520Snw141292 #include <strings.h> 374520Snw141292 #include <lber.h> 384520Snw141292 #include <ldap.h> 394520Snw141292 #include <sasl/sasl.h> 404520Snw141292 #include <string.h> 414520Snw141292 #include <ctype.h> 424520Snw141292 #include <pthread.h> 434520Snw141292 #include <synch.h> 444520Snw141292 #include <atomic.h> 454520Snw141292 #include <errno.h> 464520Snw141292 #include <assert.h> 474520Snw141292 #include <limits.h> 488040SBaban.Kenkre@Sun.COM #include <time.h> 495696Snw141292 #include <sys/u8_textprep.h> 508040SBaban.Kenkre@Sun.COM #include "libadutils.h" 516616Sdm199847 #include "nldaputils.h" 524520Snw141292 #include "idmapd.h" 534520Snw141292 544520Snw141292 /* Attribute names and filter format strings */ 555447Snw141292 #define SAN "sAMAccountName" 565447Snw141292 #define OBJSID "objectSid" 575447Snw141292 #define OBJCLASS "objectClass" 58*10504SKeyur.Desai@Sun.COM #define UIDNUMBER "uidNumber" 59*10504SKeyur.Desai@Sun.COM #define GIDNUMBER "gidNumber" 60*10504SKeyur.Desai@Sun.COM #define UIDNUMBERFILTER "(&(objectclass=user)(uidNumber=%u))" 61*10504SKeyur.Desai@Sun.COM #define GIDNUMBERFILTER "(&(objectclass=group)(gidNumber=%u))" 62*10504SKeyur.Desai@Sun.COM #define SANFILTER "(sAMAccountName=%s)" 635447Snw141292 #define OBJSIDFILTER "(objectSid=%s)" 644520Snw141292 658040SBaban.Kenkre@Sun.COM void idmap_ldap_res_search_cb(LDAP *ld, LDAPMessage **res, int rc, 668040SBaban.Kenkre@Sun.COM int qid, void *argp); 674520Snw141292 684520Snw141292 /* 694520Snw141292 * A place to put the results of a batched (async) query 704520Snw141292 * 714520Snw141292 * There is one of these for every query added to a batch object 724520Snw141292 * (idmap_query_state, see below). 734520Snw141292 */ 744520Snw141292 typedef struct idmap_q { 755447Snw141292 /* 765447Snw141292 * data used for validating search result entries for name->SID 775731Sbaban * lookups 785447Snw141292 */ 795696Snw141292 char *ecanonname; /* expected canon name */ 805696Snw141292 char *edomain; /* expected domain name */ 815731Sbaban int eunixtype; /* expected unix type */ 825447Snw141292 /* results */ 835696Snw141292 char **canonname; /* actual canon name */ 844520Snw141292 char **domain; /* name of domain of object */ 855731Sbaban char **sid; /* stringified SID */ 865731Sbaban rid_t *rid; /* RID */ 875731Sbaban int *sid_type; /* user or group SID? */ 885731Sbaban char **unixname; /* unixname for name mapping */ 896386Sjp151216 char **dn; /* DN of entry */ 906386Sjp151216 char **attr; /* Attr for name mapping */ 916386Sjp151216 char **value; /* value for name mapping */ 92*10504SKeyur.Desai@Sun.COM posix_id_t *pid; /* Posix ID found via IDMU */ 934520Snw141292 idmap_retcode *rc; 948040SBaban.Kenkre@Sun.COM adutils_rc ad_rc; 958040SBaban.Kenkre@Sun.COM adutils_result_t *result; 965447Snw141292 976531Sjp151216 /* 986531Sjp151216 * The LDAP search entry result is placed here to be processed 996531Sjp151216 * when the search done result is received. 1006531Sjp151216 */ 1016531Sjp151216 LDAPMessage *search_res; /* The LDAP search result */ 1024520Snw141292 } idmap_q_t; 1034520Snw141292 1044520Snw141292 /* Batch context structure; typedef is in header file */ 1054520Snw141292 struct idmap_query_state { 1068040SBaban.Kenkre@Sun.COM adutils_query_state_t *qs; 1078361SJulian.Pullen@Sun.COM int qsize; /* Queue size */ 1088361SJulian.Pullen@Sun.COM uint32_t qcount; /* Number of queued requests */ 1095731Sbaban const char *ad_unixuser_attr; 1105731Sbaban const char *ad_unixgroup_attr; 111*10504SKeyur.Desai@Sun.COM int directory_based_mapping; /* enum */ 112*10504SKeyur.Desai@Sun.COM char *default_domain; 1134520Snw141292 idmap_q_t queries[1]; /* array of query results */ 1144520Snw141292 }; 1154520Snw141292 1164644Sbaban static pthread_t reaperid = 0; 1174520Snw141292 1184520Snw141292 /* 1194520Snw141292 * Keep connection management simple for now, extend or replace later 1204520Snw141292 * with updated libsldap code. 1214520Snw141292 */ 1224520Snw141292 #define ADREAPERSLEEP 60 1234520Snw141292 1244520Snw141292 /* 1254520Snw141292 * Idle connection reaping side of connection management 1264520Snw141292 * 1274520Snw141292 * Every minute wake up and look for connections that have been idle for 1284520Snw141292 * five minutes or more and close them. 1294520Snw141292 */ 1304520Snw141292 /*ARGSUSED*/ 1314520Snw141292 static 1324520Snw141292 void 1334520Snw141292 adreaper(void *arg) 1344520Snw141292 { 1354520Snw141292 timespec_t ts; 1364520Snw141292 1374520Snw141292 ts.tv_sec = ADREAPERSLEEP; 1384520Snw141292 ts.tv_nsec = 0; 1394520Snw141292 1404520Snw141292 for (;;) { 1414520Snw141292 /* 1424520Snw141292 * nanosleep(3RT) is thead-safe (no SIGALRM) and more 1434520Snw141292 * portable than usleep(3C) 1444520Snw141292 */ 1454520Snw141292 (void) nanosleep(&ts, NULL); 1468040SBaban.Kenkre@Sun.COM adutils_reap_idle_connections(); 1474520Snw141292 } 1484520Snw141292 } 1494520Snw141292 1504520Snw141292 /* 1514520Snw141292 * Take ad_host_config_t information, create a ad_host_t, 1524520Snw141292 * populate it and add it to the list of hosts. 1534520Snw141292 */ 1544520Snw141292 1554520Snw141292 int 1568040SBaban.Kenkre@Sun.COM idmap_add_ds(adutils_ad_t *ad, const char *host, int port) 1574520Snw141292 { 1588040SBaban.Kenkre@Sun.COM int ret = -1; 1594520Snw141292 1608040SBaban.Kenkre@Sun.COM if (adutils_add_ds(ad, host, port) == ADUTILS_SUCCESS) 1618040SBaban.Kenkre@Sun.COM ret = 0; 1624520Snw141292 1634520Snw141292 /* Start reaper if it doesn't exist */ 1648040SBaban.Kenkre@Sun.COM if (ret == 0 && reaperid == 0) 1654520Snw141292 (void) pthread_create(&reaperid, NULL, 1664520Snw141292 (void *(*)(void *))adreaper, (void *)NULL); 1674520Snw141292 return (ret); 1684520Snw141292 } 1694520Snw141292 1704520Snw141292 static 1718040SBaban.Kenkre@Sun.COM idmap_retcode 1728040SBaban.Kenkre@Sun.COM map_adrc2idmaprc(adutils_rc adrc) 1734520Snw141292 { 1748040SBaban.Kenkre@Sun.COM switch (adrc) { 1758040SBaban.Kenkre@Sun.COM case ADUTILS_SUCCESS: 1768040SBaban.Kenkre@Sun.COM return (IDMAP_SUCCESS); 1778040SBaban.Kenkre@Sun.COM case ADUTILS_ERR_NOTFOUND: 1788040SBaban.Kenkre@Sun.COM return (IDMAP_ERR_NOTFOUND); 1798040SBaban.Kenkre@Sun.COM case ADUTILS_ERR_MEMORY: 1808040SBaban.Kenkre@Sun.COM return (IDMAP_ERR_MEMORY); 1818040SBaban.Kenkre@Sun.COM case ADUTILS_ERR_DOMAIN: 1828040SBaban.Kenkre@Sun.COM return (IDMAP_ERR_DOMAIN); 1838040SBaban.Kenkre@Sun.COM case ADUTILS_ERR_OTHER: 1848040SBaban.Kenkre@Sun.COM return (IDMAP_ERR_OTHER); 1858040SBaban.Kenkre@Sun.COM case ADUTILS_ERR_RETRIABLE_NET_ERR: 1868040SBaban.Kenkre@Sun.COM return (IDMAP_ERR_RETRIABLE_NET_ERR); 1878040SBaban.Kenkre@Sun.COM default: 1888040SBaban.Kenkre@Sun.COM return (IDMAP_ERR_INTERNAL); 1894520Snw141292 } 1908040SBaban.Kenkre@Sun.COM /* NOTREACHED */ 1914520Snw141292 } 1924520Snw141292 1938040SBaban.Kenkre@Sun.COM idmap_retcode 1948040SBaban.Kenkre@Sun.COM idmap_lookup_batch_start(adutils_ad_t *ad, int nqueries, 195*10504SKeyur.Desai@Sun.COM int directory_based_mapping, const char *default_domain, 1968040SBaban.Kenkre@Sun.COM idmap_query_state_t **state) 1974520Snw141292 { 1988040SBaban.Kenkre@Sun.COM idmap_query_state_t *new_state; 1998040SBaban.Kenkre@Sun.COM adutils_rc rc; 2004520Snw141292 2014520Snw141292 *state = NULL; 2024520Snw141292 2038361SJulian.Pullen@Sun.COM assert(ad != NULL); 2044520Snw141292 2054520Snw141292 new_state = calloc(1, sizeof (idmap_query_state_t) + 2064520Snw141292 (nqueries - 1) * sizeof (idmap_q_t)); 2074520Snw141292 if (new_state == NULL) 2084520Snw141292 return (IDMAP_ERR_MEMORY); 2094520Snw141292 2108040SBaban.Kenkre@Sun.COM if ((rc = adutils_lookup_batch_start(ad, nqueries, 2118040SBaban.Kenkre@Sun.COM idmap_ldap_res_search_cb, new_state, &new_state->qs)) 2128040SBaban.Kenkre@Sun.COM != ADUTILS_SUCCESS) { 213*10504SKeyur.Desai@Sun.COM idmap_lookup_release_batch(&new_state); 2148040SBaban.Kenkre@Sun.COM return (map_adrc2idmaprc(rc)); 2158040SBaban.Kenkre@Sun.COM } 2164520Snw141292 217*10504SKeyur.Desai@Sun.COM new_state->default_domain = strdup(default_domain); 218*10504SKeyur.Desai@Sun.COM if (new_state->default_domain == NULL) { 219*10504SKeyur.Desai@Sun.COM idmap_lookup_release_batch(&new_state); 220*10504SKeyur.Desai@Sun.COM return (IDMAP_ERR_MEMORY); 221*10504SKeyur.Desai@Sun.COM } 222*10504SKeyur.Desai@Sun.COM 223*10504SKeyur.Desai@Sun.COM new_state->directory_based_mapping = directory_based_mapping; 2248361SJulian.Pullen@Sun.COM new_state->qsize = nqueries; 2254520Snw141292 *state = new_state; 2264520Snw141292 return (IDMAP_SUCCESS); 2274520Snw141292 } 2284520Snw141292 2294520Snw141292 /* 2305731Sbaban * Set unixuser_attr and unixgroup_attr for AD-based name mapping 2315731Sbaban */ 2325731Sbaban void 2335731Sbaban idmap_lookup_batch_set_unixattr(idmap_query_state_t *state, 2345908Sjp151216 const char *unixuser_attr, const char *unixgroup_attr) 2355908Sjp151216 { 2365731Sbaban state->ad_unixuser_attr = unixuser_attr; 2375731Sbaban state->ad_unixgroup_attr = unixgroup_attr; 2385731Sbaban } 2395731Sbaban 2405731Sbaban /* 2415696Snw141292 * Take parsed attribute values from a search result entry and check if 2425696Snw141292 * it is the result that was desired and, if so, set the result fields 2435696Snw141292 * of the given idmap_q_t. 2445696Snw141292 * 245*10504SKeyur.Desai@Sun.COM * Except for dn and attr, all strings are consumed, either by transferring 246*10504SKeyur.Desai@Sun.COM * them over into the request results (where the caller will eventually free 247*10504SKeyur.Desai@Sun.COM * them) or by freeing them here. Note that this aligns with the "const" 248*10504SKeyur.Desai@Sun.COM * declarations below. 2494520Snw141292 */ 2504520Snw141292 static 2515696Snw141292 void 252*10504SKeyur.Desai@Sun.COM idmap_setqresults( 253*10504SKeyur.Desai@Sun.COM idmap_q_t *q, 254*10504SKeyur.Desai@Sun.COM char *san, 255*10504SKeyur.Desai@Sun.COM const char *dn, 256*10504SKeyur.Desai@Sun.COM const char *attr, 257*10504SKeyur.Desai@Sun.COM char *value, 258*10504SKeyur.Desai@Sun.COM char *sid, 259*10504SKeyur.Desai@Sun.COM rid_t rid, 260*10504SKeyur.Desai@Sun.COM int sid_type, 261*10504SKeyur.Desai@Sun.COM char *unixname, 262*10504SKeyur.Desai@Sun.COM posix_id_t pid) 2634520Snw141292 { 2645696Snw141292 char *domain; 26510122SJordan.Brown@Sun.COM int err1; 2665696Snw141292 2675696Snw141292 assert(dn != NULL); 2685696Snw141292 2698040SBaban.Kenkre@Sun.COM if ((domain = adutils_dn2dns(dn)) == NULL) 2705696Snw141292 goto out; 2715696Snw141292 2725731Sbaban if (q->ecanonname != NULL && san != NULL) { 2735731Sbaban /* Check that this is the canonname that we were looking for */ 2745696Snw141292 if (u8_strcmp(q->ecanonname, san, 0, 2755696Snw141292 U8_STRCMP_CI_LOWER, /* no normalization, for now */ 2765731Sbaban U8_UNICODE_LATEST, &err1) != 0 || err1 != 0) 2775731Sbaban goto out; 2785731Sbaban } 2795731Sbaban 2805731Sbaban if (q->edomain != NULL) { 2815731Sbaban /* Check that this is the domain that we were looking for */ 28210122SJordan.Brown@Sun.COM if (!domain_eq(q->edomain, domain)) 2835696Snw141292 goto out; 2845696Snw141292 } 2855696Snw141292 2866386Sjp151216 /* Copy the DN and attr and value */ 2876386Sjp151216 if (q->dn != NULL) 2886386Sjp151216 *q->dn = strdup(dn); 2896386Sjp151216 2906386Sjp151216 if (q->attr != NULL && attr != NULL) 2916386Sjp151216 *q->attr = strdup(attr); 2926386Sjp151216 293*10504SKeyur.Desai@Sun.COM if (q->value != NULL && value != NULL) { 294*10504SKeyur.Desai@Sun.COM *q->value = value; 295*10504SKeyur.Desai@Sun.COM value = NULL; 296*10504SKeyur.Desai@Sun.COM } 2976386Sjp151216 2985731Sbaban /* Set results */ 2995731Sbaban if (q->sid) { 3005731Sbaban *q->sid = sid; 3015731Sbaban sid = NULL; 3025731Sbaban } 3035731Sbaban if (q->rid) 3045731Sbaban *q->rid = rid; 3055731Sbaban if (q->sid_type) 3065731Sbaban *q->sid_type = sid_type; 3075731Sbaban if (q->unixname) { 3085731Sbaban *q->unixname = unixname; 3095731Sbaban unixname = NULL; 3105731Sbaban } 3115731Sbaban if (q->domain != NULL) { 3125731Sbaban *q->domain = domain; 3135731Sbaban domain = NULL; 3145731Sbaban } 3155731Sbaban if (q->canonname != NULL) { 3166616Sdm199847 /* 3176616Sdm199847 * The caller may be replacing the given winname by its 3186616Sdm199847 * canonical name and therefore free any old name before 3196616Sdm199847 * overwriting the field by the canonical name. 3206616Sdm199847 */ 3216616Sdm199847 free(*q->canonname); 3225731Sbaban *q->canonname = san; 3235731Sbaban san = NULL; 3245731Sbaban } 3255731Sbaban 326*10504SKeyur.Desai@Sun.COM if (q->pid != NULL && pid != SENTINEL_PID) { 327*10504SKeyur.Desai@Sun.COM *q->pid = pid; 328*10504SKeyur.Desai@Sun.COM } 329*10504SKeyur.Desai@Sun.COM 3308040SBaban.Kenkre@Sun.COM q->ad_rc = ADUTILS_SUCCESS; 3315696Snw141292 3325696Snw141292 out: 3335696Snw141292 /* Free unused attribute values */ 3345696Snw141292 free(san); 3355696Snw141292 free(sid); 3365696Snw141292 free(domain); 3375731Sbaban free(unixname); 338*10504SKeyur.Desai@Sun.COM free(value); 3394520Snw141292 } 3404520Snw141292 3414520Snw141292 #define BVAL_CASEEQ(bv, str) \ 3424520Snw141292 (((*(bv))->bv_len == (sizeof (str) - 1)) && \ 3434520Snw141292 strncasecmp((*(bv))->bv_val, str, (*(bv))->bv_len) == 0) 3444520Snw141292 3454520Snw141292 /* 3465696Snw141292 * Extract the class of the result entry. Returns 1 on success, 0 on 3475696Snw141292 * failure. 3484520Snw141292 */ 3494520Snw141292 static 3505447Snw141292 int 3515696Snw141292 idmap_bv_objclass2sidtype(BerValue **bvalues, int *sid_type) 3524520Snw141292 { 3534520Snw141292 BerValue **cbval; 3544520Snw141292 3555696Snw141292 *sid_type = _IDMAP_T_OTHER; 3564520Snw141292 if (bvalues == NULL) 3575447Snw141292 return (0); 3584520Snw141292 3595696Snw141292 /* 360*10504SKeyur.Desai@Sun.COM * We consider Computer to be a subclass of User, so we can just 361*10504SKeyur.Desai@Sun.COM * ignore Computer entries and pay attention to the accompanying 362*10504SKeyur.Desai@Sun.COM * User entries. 3635696Snw141292 */ 3644520Snw141292 for (cbval = bvalues; *cbval != NULL; cbval++) { 365*10504SKeyur.Desai@Sun.COM if (BVAL_CASEEQ(cbval, "group")) { 3665696Snw141292 *sid_type = _IDMAP_T_GROUP; 3675696Snw141292 break; 368*10504SKeyur.Desai@Sun.COM } else if (BVAL_CASEEQ(cbval, "user")) { 3695696Snw141292 *sid_type = _IDMAP_T_USER; 370*10504SKeyur.Desai@Sun.COM break; 3715696Snw141292 } 3725696Snw141292 /* 3735696Snw141292 * "else if (*sid_type = _IDMAP_T_USER)" then this is a 3745696Snw141292 * new sub-class of user -- what to do with it?? 3755696Snw141292 */ 3764520Snw141292 } 3775447Snw141292 3785447Snw141292 return (1); 3794520Snw141292 } 3804520Snw141292 3814520Snw141292 /* 3824520Snw141292 * Handle a given search result entry 3834520Snw141292 */ 3844520Snw141292 static 3854520Snw141292 void 3868040SBaban.Kenkre@Sun.COM idmap_extract_object(idmap_query_state_t *state, idmap_q_t *q, 3878040SBaban.Kenkre@Sun.COM LDAPMessage *res, LDAP *ld) 3884520Snw141292 { 3894520Snw141292 BerValue **bvalues; 390*10504SKeyur.Desai@Sun.COM const char *attr = NULL; 391*10504SKeyur.Desai@Sun.COM char *value = NULL; 392*10504SKeyur.Desai@Sun.COM char *unix_name = NULL; 393*10504SKeyur.Desai@Sun.COM char *dn; 3945696Snw141292 char *san = NULL; 3955696Snw141292 char *sid = NULL; 3965696Snw141292 rid_t rid = 0; 397*10504SKeyur.Desai@Sun.COM int sid_type; 398*10504SKeyur.Desai@Sun.COM int ok; 399*10504SKeyur.Desai@Sun.COM posix_id_t pid = SENTINEL_PID; 4005447Snw141292 4015731Sbaban assert(q->rc != NULL); 402*10504SKeyur.Desai@Sun.COM assert(q->domain == NULL || *q->domain == NULL); 4035731Sbaban 4048040SBaban.Kenkre@Sun.COM if ((dn = ldap_get_dn(ld, res)) == NULL) 4054520Snw141292 return; 4064520Snw141292 407*10504SKeyur.Desai@Sun.COM bvalues = ldap_get_values_len(ld, res, OBJCLASS); 408*10504SKeyur.Desai@Sun.COM if (bvalues == NULL) { 4095731Sbaban /* 4105731Sbaban * Didn't find objectclass. Something's wrong with our 4115731Sbaban * AD data. 4125731Sbaban */ 413*10504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, "%s has no %s", dn, OBJCLASS); 414*10504SKeyur.Desai@Sun.COM goto out; 415*10504SKeyur.Desai@Sun.COM } 416*10504SKeyur.Desai@Sun.COM ok = idmap_bv_objclass2sidtype(bvalues, &sid_type); 417*10504SKeyur.Desai@Sun.COM ldap_value_free_len(bvalues); 418*10504SKeyur.Desai@Sun.COM if (!ok) { 4195731Sbaban /* 420*10504SKeyur.Desai@Sun.COM * Didn't understand objectclass. Something's wrong with our 421*10504SKeyur.Desai@Sun.COM * AD data. 4225731Sbaban */ 423*10504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, "%s has unexpected %s", dn, OBJCLASS); 424*10504SKeyur.Desai@Sun.COM goto out; 425*10504SKeyur.Desai@Sun.COM } 426*10504SKeyur.Desai@Sun.COM 427*10504SKeyur.Desai@Sun.COM if (state->directory_based_mapping == DIRECTORY_MAPPING_IDMU && 428*10504SKeyur.Desai@Sun.COM q->pid != NULL) { 429*10504SKeyur.Desai@Sun.COM if (sid_type == _IDMAP_T_USER) 430*10504SKeyur.Desai@Sun.COM attr = UIDNUMBER; 431*10504SKeyur.Desai@Sun.COM else if (sid_type == _IDMAP_T_GROUP) 432*10504SKeyur.Desai@Sun.COM attr = GIDNUMBER; 433*10504SKeyur.Desai@Sun.COM if (attr != NULL) { 434*10504SKeyur.Desai@Sun.COM bvalues = ldap_get_values_len(ld, res, attr); 435*10504SKeyur.Desai@Sun.COM if (bvalues != NULL) { 436*10504SKeyur.Desai@Sun.COM value = adutils_bv_str(bvalues[0]); 437*10504SKeyur.Desai@Sun.COM if (!adutils_bv_uint(bvalues[0], &pid)) { 438*10504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, 439*10504SKeyur.Desai@Sun.COM "%s has Invalid %s value \"%s\"", 440*10504SKeyur.Desai@Sun.COM dn, attr, value); 441*10504SKeyur.Desai@Sun.COM } 442*10504SKeyur.Desai@Sun.COM ldap_value_free_len(bvalues); 443*10504SKeyur.Desai@Sun.COM } 444*10504SKeyur.Desai@Sun.COM } 4455731Sbaban } 4465731Sbaban 447*10504SKeyur.Desai@Sun.COM if (state->directory_based_mapping == DIRECTORY_MAPPING_NAME && 448*10504SKeyur.Desai@Sun.COM q->unixname != NULL) { 449*10504SKeyur.Desai@Sun.COM /* 450*10504SKeyur.Desai@Sun.COM * If the caller has requested unixname then determine the 451*10504SKeyur.Desai@Sun.COM * AD attribute name that will have the unixname, and retrieve 452*10504SKeyur.Desai@Sun.COM * its value. 453*10504SKeyur.Desai@Sun.COM */ 454*10504SKeyur.Desai@Sun.COM int unix_type; 455*10504SKeyur.Desai@Sun.COM /* 456*10504SKeyur.Desai@Sun.COM * Determine the target UNIX type. 457*10504SKeyur.Desai@Sun.COM * 458*10504SKeyur.Desai@Sun.COM * If the caller specified one, use that. Otherwise, give the 459*10504SKeyur.Desai@Sun.COM * same type that as we found for the Windows user. 460*10504SKeyur.Desai@Sun.COM */ 461*10504SKeyur.Desai@Sun.COM unix_type = q->eunixtype; 462*10504SKeyur.Desai@Sun.COM if (unix_type == _IDMAP_T_UNDEF) { 463*10504SKeyur.Desai@Sun.COM if (sid_type == _IDMAP_T_USER) 464*10504SKeyur.Desai@Sun.COM unix_type = _IDMAP_T_USER; 465*10504SKeyur.Desai@Sun.COM else if (sid_type == _IDMAP_T_GROUP) 466*10504SKeyur.Desai@Sun.COM unix_type = _IDMAP_T_GROUP; 467*10504SKeyur.Desai@Sun.COM } 468*10504SKeyur.Desai@Sun.COM 469*10504SKeyur.Desai@Sun.COM if (unix_type == _IDMAP_T_USER) 470*10504SKeyur.Desai@Sun.COM attr = state->ad_unixuser_attr; 471*10504SKeyur.Desai@Sun.COM else if (unix_type == _IDMAP_T_GROUP) 472*10504SKeyur.Desai@Sun.COM attr = state->ad_unixgroup_attr; 4734520Snw141292 474*10504SKeyur.Desai@Sun.COM if (attr != NULL) { 475*10504SKeyur.Desai@Sun.COM bvalues = ldap_get_values_len(ld, res, attr); 476*10504SKeyur.Desai@Sun.COM if (bvalues != NULL) { 477*10504SKeyur.Desai@Sun.COM unix_name = adutils_bv_str(bvalues[0]); 478*10504SKeyur.Desai@Sun.COM ldap_value_free_len(bvalues); 479*10504SKeyur.Desai@Sun.COM value = strdup(unix_name); 480*10504SKeyur.Desai@Sun.COM } 481*10504SKeyur.Desai@Sun.COM } 482*10504SKeyur.Desai@Sun.COM } 483*10504SKeyur.Desai@Sun.COM 484*10504SKeyur.Desai@Sun.COM bvalues = ldap_get_values_len(ld, res, SAN); 485*10504SKeyur.Desai@Sun.COM if (bvalues != NULL) { 486*10504SKeyur.Desai@Sun.COM san = adutils_bv_str(bvalues[0]); 487*10504SKeyur.Desai@Sun.COM ldap_value_free_len(bvalues); 488*10504SKeyur.Desai@Sun.COM } 489*10504SKeyur.Desai@Sun.COM 490*10504SKeyur.Desai@Sun.COM if (q->sid != NULL) { 491*10504SKeyur.Desai@Sun.COM bvalues = ldap_get_values_len(ld, res, OBJSID); 492*10504SKeyur.Desai@Sun.COM if (bvalues != NULL) { 493*10504SKeyur.Desai@Sun.COM sid = adutils_bv_objsid2sidstr(bvalues[0], &rid); 494*10504SKeyur.Desai@Sun.COM ldap_value_free_len(bvalues); 495*10504SKeyur.Desai@Sun.COM } 496*10504SKeyur.Desai@Sun.COM } 497*10504SKeyur.Desai@Sun.COM 498*10504SKeyur.Desai@Sun.COM idmap_setqresults(q, san, dn, 499*10504SKeyur.Desai@Sun.COM attr, value, 500*10504SKeyur.Desai@Sun.COM sid, rid, sid_type, 501*10504SKeyur.Desai@Sun.COM unix_name, pid); 502*10504SKeyur.Desai@Sun.COM 503*10504SKeyur.Desai@Sun.COM out: 5044520Snw141292 ldap_memfree(dn); 5054520Snw141292 } 5064520Snw141292 5078040SBaban.Kenkre@Sun.COM void 5088040SBaban.Kenkre@Sun.COM idmap_ldap_res_search_cb(LDAP *ld, LDAPMessage **res, int rc, int qid, 5098040SBaban.Kenkre@Sun.COM void *argp) 5104520Snw141292 { 5118040SBaban.Kenkre@Sun.COM idmap_query_state_t *state = (idmap_query_state_t *)argp; 5128040SBaban.Kenkre@Sun.COM idmap_q_t *q = &(state->queries[qid]); 5134520Snw141292 5144520Snw141292 switch (rc) { 5154520Snw141292 case LDAP_RES_SEARCH_RESULT: 5168040SBaban.Kenkre@Sun.COM if (q->search_res != NULL) { 5178040SBaban.Kenkre@Sun.COM idmap_extract_object(state, q, q->search_res, ld); 5188040SBaban.Kenkre@Sun.COM (void) ldap_msgfree(q->search_res); 5198040SBaban.Kenkre@Sun.COM q->search_res = NULL; 5208040SBaban.Kenkre@Sun.COM } else 5218040SBaban.Kenkre@Sun.COM q->ad_rc = ADUTILS_ERR_NOTFOUND; 5224520Snw141292 break; 5238040SBaban.Kenkre@Sun.COM case LDAP_RES_SEARCH_ENTRY: 5248040SBaban.Kenkre@Sun.COM if (q->search_res == NULL) { 5258040SBaban.Kenkre@Sun.COM q->search_res = *res; 5268040SBaban.Kenkre@Sun.COM *res = NULL; 5278040SBaban.Kenkre@Sun.COM } 5284520Snw141292 break; 5294520Snw141292 default: 5304520Snw141292 break; 5314520Snw141292 } 5324884Sjp151216 } 5334884Sjp151216 5345447Snw141292 static 5355447Snw141292 void 5365447Snw141292 idmap_cleanup_batch(idmap_query_state_t *batch) 5375447Snw141292 { 5385447Snw141292 int i; 5395447Snw141292 5405447Snw141292 for (i = 0; i < batch->qcount; i++) { 5415696Snw141292 if (batch->queries[i].ecanonname != NULL) 5425696Snw141292 free(batch->queries[i].ecanonname); 5435696Snw141292 batch->queries[i].ecanonname = NULL; 5445696Snw141292 if (batch->queries[i].edomain != NULL) 5455696Snw141292 free(batch->queries[i].edomain); 5465696Snw141292 batch->queries[i].edomain = NULL; 5475447Snw141292 } 5485447Snw141292 } 5495447Snw141292 5504884Sjp151216 /* 5514884Sjp151216 * This routine frees the idmap_query_state_t structure 5524884Sjp151216 */ 5534520Snw141292 void 5544884Sjp151216 idmap_lookup_release_batch(idmap_query_state_t **state) 5554520Snw141292 { 5568040SBaban.Kenkre@Sun.COM if (state == NULL || *state == NULL) 5578040SBaban.Kenkre@Sun.COM return; 5588040SBaban.Kenkre@Sun.COM adutils_lookup_batch_release(&(*state)->qs); 5595447Snw141292 idmap_cleanup_batch(*state); 560*10504SKeyur.Desai@Sun.COM free((*state)->default_domain); 5614520Snw141292 free(*state); 5624520Snw141292 *state = NULL; 5634520Snw141292 } 5644520Snw141292 5654520Snw141292 idmap_retcode 5665968Snw141292 idmap_lookup_batch_end(idmap_query_state_t **state) 5674520Snw141292 { 5688040SBaban.Kenkre@Sun.COM adutils_rc ad_rc; 5698040SBaban.Kenkre@Sun.COM int i; 5708040SBaban.Kenkre@Sun.COM idmap_query_state_t *id_qs = *state; 5714520Snw141292 5728040SBaban.Kenkre@Sun.COM ad_rc = adutils_lookup_batch_end(&id_qs->qs); 5734520Snw141292 5748040SBaban.Kenkre@Sun.COM /* 5758040SBaban.Kenkre@Sun.COM * Map adutils rc to idmap_retcode in each 5768040SBaban.Kenkre@Sun.COM * query because consumers in dbutils.c 5778040SBaban.Kenkre@Sun.COM * expects idmap_retcode. 5788040SBaban.Kenkre@Sun.COM */ 5798040SBaban.Kenkre@Sun.COM for (i = 0; i < id_qs->qcount; i++) { 5808040SBaban.Kenkre@Sun.COM *id_qs->queries[i].rc = 5818040SBaban.Kenkre@Sun.COM map_adrc2idmaprc(id_qs->queries[i].ad_rc); 5824520Snw141292 } 5834884Sjp151216 idmap_lookup_release_batch(state); 5848040SBaban.Kenkre@Sun.COM return (map_adrc2idmaprc(ad_rc)); 5854520Snw141292 } 5864520Snw141292 5874520Snw141292 /* 5884520Snw141292 * Send one prepared search, queue up msgid, process what results are 5894520Snw141292 * available 5904520Snw141292 */ 5914520Snw141292 static 5924520Snw141292 idmap_retcode 5936386Sjp151216 idmap_batch_add1(idmap_query_state_t *state, const char *filter, 5946386Sjp151216 char *ecanonname, char *edomain, int eunixtype, 5956386Sjp151216 char **dn, char **attr, char **value, 5966386Sjp151216 char **canonname, char **dname, 5976386Sjp151216 char **sid, rid_t *rid, int *sid_type, char **unixname, 598*10504SKeyur.Desai@Sun.COM posix_id_t *pid, 5996386Sjp151216 idmap_retcode *rc) 6004520Snw141292 { 6018040SBaban.Kenkre@Sun.COM adutils_rc ad_rc; 6028040SBaban.Kenkre@Sun.COM int qid, i; 6034520Snw141292 idmap_q_t *q; 604*10504SKeyur.Desai@Sun.COM char *attrs[20]; /* Plenty */ 6054520Snw141292 6068361SJulian.Pullen@Sun.COM qid = atomic_inc_32_nv(&state->qcount) - 1; 6074520Snw141292 q = &(state->queries[qid]); 6084520Snw141292 6098361SJulian.Pullen@Sun.COM assert(qid < state->qsize); 6108361SJulian.Pullen@Sun.COM 6115696Snw141292 /* 6128040SBaban.Kenkre@Sun.COM * Remember the expected canonname, domainname and unix type 6138040SBaban.Kenkre@Sun.COM * so we can check the results * against it 6145696Snw141292 */ 6155696Snw141292 q->ecanonname = ecanonname; 6165696Snw141292 q->edomain = edomain; 6175731Sbaban q->eunixtype = eunixtype; 6185447Snw141292 6194520Snw141292 /* Remember where to put the results */ 6205696Snw141292 q->canonname = canonname; 6215731Sbaban q->sid = sid; 6224520Snw141292 q->domain = dname; 6234520Snw141292 q->rid = rid; 6244520Snw141292 q->sid_type = sid_type; 6254520Snw141292 q->rc = rc; 6265731Sbaban q->unixname = unixname; 6276386Sjp151216 q->dn = dn; 6286386Sjp151216 q->attr = attr; 6296386Sjp151216 q->value = value; 630*10504SKeyur.Desai@Sun.COM q->pid = pid; 6315731Sbaban 632*10504SKeyur.Desai@Sun.COM /* Add attributes that are not always needed */ 633*10504SKeyur.Desai@Sun.COM i = 0; 634*10504SKeyur.Desai@Sun.COM attrs[i++] = SAN; 635*10504SKeyur.Desai@Sun.COM attrs[i++] = OBJSID; 636*10504SKeyur.Desai@Sun.COM attrs[i++] = OBJCLASS; 637*10504SKeyur.Desai@Sun.COM 6385731Sbaban if (unixname != NULL) { 639*10504SKeyur.Desai@Sun.COM /* Add unixuser/unixgroup attribute names to the attrs list */ 6405731Sbaban if (eunixtype != _IDMAP_T_GROUP && 6415731Sbaban state->ad_unixuser_attr != NULL) 6425731Sbaban attrs[i++] = (char *)state->ad_unixuser_attr; 6435731Sbaban if (eunixtype != _IDMAP_T_USER && 6445731Sbaban state->ad_unixgroup_attr != NULL) 645*10504SKeyur.Desai@Sun.COM attrs[i++] = (char *)state->ad_unixgroup_attr; 6465731Sbaban } 6474520Snw141292 648*10504SKeyur.Desai@Sun.COM if (pid != NULL) { 649*10504SKeyur.Desai@Sun.COM if (eunixtype != _IDMAP_T_GROUP) 650*10504SKeyur.Desai@Sun.COM attrs[i++] = UIDNUMBER; 651*10504SKeyur.Desai@Sun.COM if (eunixtype != _IDMAP_T_USER) 652*10504SKeyur.Desai@Sun.COM attrs[i++] = GIDNUMBER; 653*10504SKeyur.Desai@Sun.COM } 654*10504SKeyur.Desai@Sun.COM 655*10504SKeyur.Desai@Sun.COM attrs[i] = NULL; 656*10504SKeyur.Desai@Sun.COM 6574520Snw141292 /* 6584520Snw141292 * Provide sane defaults for the results in case we never hear 6594520Snw141292 * back from the DS before closing the connection. 6605447Snw141292 * 6615447Snw141292 * In particular we default the result to indicate a retriable 6625447Snw141292 * error. The first complete matching result entry will cause 6635447Snw141292 * this to be set to IDMAP_SUCCESS, and the end of the results 6645447Snw141292 * for this search will cause this to indicate "not found" if no 6655447Snw141292 * result entries arrived or no complete ones matched the lookup 6665447Snw141292 * we were doing. 6674520Snw141292 */ 6684520Snw141292 *rc = IDMAP_ERR_RETRIABLE_NET_ERR; 6695731Sbaban if (sid_type != NULL) 6705731Sbaban *sid_type = _IDMAP_T_OTHER; 6715731Sbaban if (sid != NULL) 6725731Sbaban *sid = NULL; 6734520Snw141292 if (dname != NULL) 6744520Snw141292 *dname = NULL; 6754520Snw141292 if (rid != NULL) 6764520Snw141292 *rid = 0; 6776386Sjp151216 if (dn != NULL) 6786386Sjp151216 *dn = NULL; 6796386Sjp151216 if (attr != NULL) 6806386Sjp151216 *attr = NULL; 6816386Sjp151216 if (value != NULL) 6826386Sjp151216 *value = NULL; 6834520Snw141292 6846616Sdm199847 /* 6856616Sdm199847 * Don't set *canonname to NULL because it may be pointing to the 6866616Sdm199847 * given winname. Later on if we get a canonical name from AD the 6876616Sdm199847 * old name if any will be freed before assigning the new name. 6886616Sdm199847 */ 6896616Sdm199847 6904520Snw141292 /* 6918040SBaban.Kenkre@Sun.COM * Invoke the mother of all APIs i.e. the adutils API 6924520Snw141292 */ 6938040SBaban.Kenkre@Sun.COM ad_rc = adutils_lookup_batch_add(state->qs, filter, 6948040SBaban.Kenkre@Sun.COM (const char **)attrs, 6958040SBaban.Kenkre@Sun.COM edomain, &q->result, &q->ad_rc); 6968040SBaban.Kenkre@Sun.COM return (map_adrc2idmaprc(ad_rc)); 6974520Snw141292 } 6984520Snw141292 6994520Snw141292 idmap_retcode 7004520Snw141292 idmap_name2sid_batch_add1(idmap_query_state_t *state, 7015731Sbaban const char *name, const char *dname, int eunixtype, 7026386Sjp151216 char **dn, char **attr, char **value, 7036386Sjp151216 char **canonname, char **sid, rid_t *rid, 704*10504SKeyur.Desai@Sun.COM int *sid_type, char **unixname, 705*10504SKeyur.Desai@Sun.COM posix_id_t *pid, idmap_retcode *rc) 7064520Snw141292 { 7074520Snw141292 idmap_retcode retcode; 708*10504SKeyur.Desai@Sun.COM char *filter, *s_name; 7095696Snw141292 char *ecanonname, *edomain; /* expected canonname */ 7104520Snw141292 7114520Snw141292 /* 7125447Snw141292 * Strategy: search the global catalog for user/group by 7135447Snw141292 * sAMAccountName = user/groupname with "" as the base DN and by 7145447Snw141292 * userPrincipalName = user/groupname@domain. The result 7155447Snw141292 * entries will be checked to conform to the name and domain 7165447Snw141292 * name given here. The DN, sAMAccountName, userPrincipalName, 7175447Snw141292 * objectSid and objectClass of the result entries are all we 7185447Snw141292 * need to figure out which entries match the lookup, the SID of 7195447Snw141292 * the user/group and whether it is a user or a group. 7204520Snw141292 */ 7214520Snw141292 7225696Snw141292 if ((ecanonname = strdup(name)) == NULL) 7235696Snw141292 return (IDMAP_ERR_MEMORY); 7244520Snw141292 7255447Snw141292 if (dname == NULL || *dname == '\0') { 726*10504SKeyur.Desai@Sun.COM /* 'name' not qualified and dname not given */ 727*10504SKeyur.Desai@Sun.COM dname = state->default_domain; 728*10504SKeyur.Desai@Sun.COM edomain = strdup(dname); 729*10504SKeyur.Desai@Sun.COM if (edomain == NULL) { 730*10504SKeyur.Desai@Sun.COM free(ecanonname); 731*10504SKeyur.Desai@Sun.COM return (IDMAP_ERR_MEMORY); 7325696Snw141292 } 7335696Snw141292 } else { 7345696Snw141292 if ((edomain = strdup(dname)) == NULL) { 7355696Snw141292 free(ecanonname); 7365447Snw141292 return (IDMAP_ERR_MEMORY); 7375696Snw141292 } 7385447Snw141292 } 7394520Snw141292 7408361SJulian.Pullen@Sun.COM if (!adutils_lookup_check_domain(state->qs, dname)) { 7418361SJulian.Pullen@Sun.COM free(ecanonname); 7428361SJulian.Pullen@Sun.COM free(edomain); 7438361SJulian.Pullen@Sun.COM return (IDMAP_ERR_DOMAIN_NOTFOUND); 7448361SJulian.Pullen@Sun.COM } 7458361SJulian.Pullen@Sun.COM 7466616Sdm199847 s_name = sanitize_for_ldap_filter(name); 7476616Sdm199847 if (s_name == NULL) { 7486616Sdm199847 free(ecanonname); 7496616Sdm199847 free(edomain); 7506616Sdm199847 return (IDMAP_ERR_MEMORY); 7516616Sdm199847 } 7526616Sdm199847 7534520Snw141292 /* Assemble filter */ 754*10504SKeyur.Desai@Sun.COM (void) asprintf(&filter, SANFILTER, s_name); 755*10504SKeyur.Desai@Sun.COM if (s_name != name) 756*10504SKeyur.Desai@Sun.COM free(s_name); 757*10504SKeyur.Desai@Sun.COM if (filter == NULL) { 7585696Snw141292 free(ecanonname); 7596616Sdm199847 free(edomain); 7604520Snw141292 return (IDMAP_ERR_MEMORY); 7614520Snw141292 } 7624520Snw141292 7635696Snw141292 retcode = idmap_batch_add1(state, filter, ecanonname, edomain, 7646386Sjp151216 eunixtype, dn, attr, value, canonname, NULL, sid, rid, sid_type, 765*10504SKeyur.Desai@Sun.COM unixname, pid, rc); 7664520Snw141292 7674520Snw141292 free(filter); 7684520Snw141292 7694520Snw141292 return (retcode); 7704520Snw141292 } 7714520Snw141292 7724520Snw141292 idmap_retcode 7734520Snw141292 idmap_sid2name_batch_add1(idmap_query_state_t *state, 7745731Sbaban const char *sid, const rid_t *rid, int eunixtype, 7756386Sjp151216 char **dn, char **attr, char **value, 7766386Sjp151216 char **name, char **dname, int *sid_type, 777*10504SKeyur.Desai@Sun.COM char **unixname, posix_id_t *pid, idmap_retcode *rc) 7784520Snw141292 { 7794520Snw141292 idmap_retcode retcode; 780*10504SKeyur.Desai@Sun.COM int ret; 781*10504SKeyur.Desai@Sun.COM char *filter; 7828040SBaban.Kenkre@Sun.COM char cbinsid[ADUTILS_MAXHEXBINSID + 1]; 7834520Snw141292 7844520Snw141292 /* 7854520Snw141292 * Strategy: search [the global catalog] for user/group by 7864520Snw141292 * objectSid = SID with empty base DN. The DN, sAMAccountName 7874520Snw141292 * and objectClass of the result are all we need to figure out 7884520Snw141292 * the name of the SID and whether it is a user, a group or a 7894520Snw141292 * computer. 7904520Snw141292 */ 7914520Snw141292 7928361SJulian.Pullen@Sun.COM if (!adutils_lookup_check_sid_prefix(state->qs, sid)) 7938361SJulian.Pullen@Sun.COM return (IDMAP_ERR_DOMAIN_NOTFOUND); 7948361SJulian.Pullen@Sun.COM 7958040SBaban.Kenkre@Sun.COM ret = adutils_txtsid2hexbinsid(sid, rid, &cbinsid[0], sizeof (cbinsid)); 7964520Snw141292 if (ret != 0) 7974520Snw141292 return (IDMAP_ERR_SID); 7984520Snw141292 7994520Snw141292 /* Assemble filter */ 800*10504SKeyur.Desai@Sun.COM (void) asprintf(&filter, OBJSIDFILTER, cbinsid); 801*10504SKeyur.Desai@Sun.COM if (filter == NULL) 8024520Snw141292 return (IDMAP_ERR_MEMORY); 8034520Snw141292 8045731Sbaban retcode = idmap_batch_add1(state, filter, NULL, NULL, eunixtype, 805*10504SKeyur.Desai@Sun.COM dn, attr, value, name, dname, NULL, NULL, sid_type, unixname, 806*10504SKeyur.Desai@Sun.COM pid, rc); 8074520Snw141292 8084520Snw141292 free(filter); 8094520Snw141292 8104520Snw141292 return (retcode); 8114520Snw141292 } 8125731Sbaban 8135731Sbaban idmap_retcode 8145731Sbaban idmap_unixname2sid_batch_add1(idmap_query_state_t *state, 8155731Sbaban const char *unixname, int is_user, int is_wuser, 8166386Sjp151216 char **dn, char **attr, char **value, 8176386Sjp151216 char **sid, rid_t *rid, char **name, 8186386Sjp151216 char **dname, int *sid_type, idmap_retcode *rc) 8195731Sbaban { 8205731Sbaban idmap_retcode retcode; 821*10504SKeyur.Desai@Sun.COM char *filter, *s_unixname; 822*10504SKeyur.Desai@Sun.COM const char *attrname; 8235731Sbaban 8245731Sbaban /* Get unixuser or unixgroup AD attribute name */ 8255731Sbaban attrname = (is_user) ? 8265731Sbaban state->ad_unixuser_attr : state->ad_unixgroup_attr; 8275731Sbaban if (attrname == NULL) 8285731Sbaban return (IDMAP_ERR_NOTFOUND); 8295731Sbaban 8306616Sdm199847 s_unixname = sanitize_for_ldap_filter(unixname); 8316616Sdm199847 if (s_unixname == NULL) 8326616Sdm199847 return (IDMAP_ERR_MEMORY); 8336616Sdm199847 8345731Sbaban /* Assemble filter */ 835*10504SKeyur.Desai@Sun.COM (void) asprintf(&filter, "(&(objectclass=%s)(%s=%s))", 836*10504SKeyur.Desai@Sun.COM is_wuser ? "user" : "group", attrname, s_unixname); 837*10504SKeyur.Desai@Sun.COM if (s_unixname != unixname) 838*10504SKeyur.Desai@Sun.COM free(s_unixname); 839*10504SKeyur.Desai@Sun.COM if (filter == NULL) { 8405731Sbaban return (IDMAP_ERR_MEMORY); 8416616Sdm199847 } 8425731Sbaban 8435731Sbaban retcode = idmap_batch_add1(state, filter, NULL, NULL, 8446386Sjp151216 _IDMAP_T_UNDEF, dn, NULL, NULL, name, dname, sid, rid, sid_type, 845*10504SKeyur.Desai@Sun.COM NULL, NULL, rc); 8466386Sjp151216 8476386Sjp151216 if (retcode == IDMAP_SUCCESS && attr != NULL) { 8486386Sjp151216 if ((*attr = strdup(attrname)) == NULL) 8496386Sjp151216 retcode = IDMAP_ERR_MEMORY; 8506386Sjp151216 } 8516386Sjp151216 8526386Sjp151216 if (retcode == IDMAP_SUCCESS && value != NULL) { 853*10504SKeyur.Desai@Sun.COM if ((*value = strdup(unixname)) == NULL) 854*10504SKeyur.Desai@Sun.COM retcode = IDMAP_ERR_MEMORY; 8556386Sjp151216 } 8565731Sbaban 8575731Sbaban free(filter); 8585731Sbaban 8595731Sbaban return (retcode); 8605731Sbaban } 861*10504SKeyur.Desai@Sun.COM 862*10504SKeyur.Desai@Sun.COM idmap_retcode 863*10504SKeyur.Desai@Sun.COM idmap_pid2sid_batch_add1(idmap_query_state_t *state, 864*10504SKeyur.Desai@Sun.COM posix_id_t pid, int is_user, 865*10504SKeyur.Desai@Sun.COM char **dn, char **attr, char **value, 866*10504SKeyur.Desai@Sun.COM char **sid, rid_t *rid, char **name, 867*10504SKeyur.Desai@Sun.COM char **dname, int *sid_type, idmap_retcode *rc) 868*10504SKeyur.Desai@Sun.COM { 869*10504SKeyur.Desai@Sun.COM idmap_retcode retcode; 870*10504SKeyur.Desai@Sun.COM char *filter; 871*10504SKeyur.Desai@Sun.COM const char *attrname; 872*10504SKeyur.Desai@Sun.COM 873*10504SKeyur.Desai@Sun.COM /* Assemble filter */ 874*10504SKeyur.Desai@Sun.COM if (is_user) { 875*10504SKeyur.Desai@Sun.COM (void) asprintf(&filter, UIDNUMBERFILTER, pid); 876*10504SKeyur.Desai@Sun.COM attrname = UIDNUMBER; 877*10504SKeyur.Desai@Sun.COM } else { 878*10504SKeyur.Desai@Sun.COM (void) asprintf(&filter, GIDNUMBERFILTER, pid); 879*10504SKeyur.Desai@Sun.COM attrname = GIDNUMBER; 880*10504SKeyur.Desai@Sun.COM } 881*10504SKeyur.Desai@Sun.COM if (filter == NULL) 882*10504SKeyur.Desai@Sun.COM return (IDMAP_ERR_MEMORY); 883*10504SKeyur.Desai@Sun.COM 884*10504SKeyur.Desai@Sun.COM retcode = idmap_batch_add1(state, filter, NULL, NULL, 885*10504SKeyur.Desai@Sun.COM _IDMAP_T_UNDEF, dn, NULL, NULL, name, dname, sid, rid, sid_type, 886*10504SKeyur.Desai@Sun.COM NULL, NULL, rc); 887*10504SKeyur.Desai@Sun.COM 888*10504SKeyur.Desai@Sun.COM if (retcode == IDMAP_SUCCESS && attr != NULL) { 889*10504SKeyur.Desai@Sun.COM if ((*attr = strdup(attrname)) == NULL) 890*10504SKeyur.Desai@Sun.COM retcode = IDMAP_ERR_MEMORY; 891*10504SKeyur.Desai@Sun.COM } 892*10504SKeyur.Desai@Sun.COM 893*10504SKeyur.Desai@Sun.COM if (retcode == IDMAP_SUCCESS && value != NULL) { 894*10504SKeyur.Desai@Sun.COM (void) asprintf(value, "%u", pid); 895*10504SKeyur.Desai@Sun.COM if (*value == NULL) 896*10504SKeyur.Desai@Sun.COM retcode = IDMAP_ERR_MEMORY; 897*10504SKeyur.Desai@Sun.COM } 898*10504SKeyur.Desai@Sun.COM 899*10504SKeyur.Desai@Sun.COM free(filter); 900*10504SKeyur.Desai@Sun.COM 901*10504SKeyur.Desai@Sun.COM return (retcode); 902*10504SKeyur.Desai@Sun.COM } 903