17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5cb5caa98Sdjl * Common Development and Distribution License (the "License"). 6cb5caa98Sdjl * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 2220e6d5c5Ssc157166 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <grp.h> 277c478bd9Sstevel@tonic-gate #include "ldap_common.h" 28*4c6ae461SPaul B. Henson #include <string.h> 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* String which may need to be removed from beginning of group password */ 317c478bd9Sstevel@tonic-gate #define _CRYPT "{CRYPT}" 327c478bd9Sstevel@tonic-gate #define _NO_PASSWD_VAL "" 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate /* Group attributes filters */ 357c478bd9Sstevel@tonic-gate #define _G_NAME "cn" 367c478bd9Sstevel@tonic-gate #define _G_GID "gidnumber" 377c478bd9Sstevel@tonic-gate #define _G_PASSWD "userpassword" 387c478bd9Sstevel@tonic-gate #define _G_MEM "memberuid" 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #define _F_GETGRNAM "(&(objectClass=posixGroup)(cn=%s))" 417c478bd9Sstevel@tonic-gate #define _F_GETGRNAM_SSD "(&(%%s)(cn=%s))" 42f48205beScasper #define _F_GETGRGID "(&(objectClass=posixGroup)(gidNumber=%u))" 43f48205beScasper #define _F_GETGRGID_SSD "(&(%%s)(gidNumber=%u))" 44*4c6ae461SPaul B. Henson /* 45*4c6ae461SPaul B. Henson * Group membership can be defined by either username or DN, so when searching 46*4c6ae461SPaul B. Henson * for groups by member we need to consider both. The first parameter in the 47*4c6ae461SPaul B. Henson * filter is replaced by username, the second by DN. 48*4c6ae461SPaul B. Henson */ 49*4c6ae461SPaul B. Henson #define _F_GETGRMEM \ 50*4c6ae461SPaul B. Henson "(&(objectClass=posixGroup)(|(memberUid=%s)(memberUid=%s)))" 51*4c6ae461SPaul B. Henson #define _F_GETGRMEM_SSD "(&(%%s)(|(memberUid=%s)(memberUid=%s)))" 52*4c6ae461SPaul B. Henson 53*4c6ae461SPaul B. Henson /* 54*4c6ae461SPaul B. Henson * Copied from getpwnam.c, needed to look up user DN. 55*4c6ae461SPaul B. Henson * Would it be better to move to ldap_common.h rather than duplicate? 56*4c6ae461SPaul B. Henson */ 57*4c6ae461SPaul B. Henson #define _F_GETPWNAM "(&(objectClass=posixAccount)(uid=%s))" 58*4c6ae461SPaul B. Henson #define _F_GETPWNAM_SSD "(&(%%s)(uid=%s))" 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate static const char *gr_attrs[] = { 617c478bd9Sstevel@tonic-gate _G_NAME, 627c478bd9Sstevel@tonic-gate _G_GID, 637c478bd9Sstevel@tonic-gate _G_PASSWD, 647c478bd9Sstevel@tonic-gate _G_MEM, 657c478bd9Sstevel@tonic-gate (char *)NULL 667c478bd9Sstevel@tonic-gate }; 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate /* 70cb5caa98Sdjl * _nss_ldap_group2str is the data marshaling method for the group getXbyY 717c478bd9Sstevel@tonic-gate * (e.g., getgrnam(), getgrgid(), getgrent()) backend processes. This method 727c478bd9Sstevel@tonic-gate * is called after a successful ldap search has been performed. This method 73cb5caa98Sdjl * will parse the ldap search values into the file format. 74cb5caa98Sdjl * e.g. 75cb5caa98Sdjl * 76cb5caa98Sdjl * adm::4:root,adm,daemon 77cb5caa98Sdjl * 787c478bd9Sstevel@tonic-gate */ 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate static int 81cb5caa98Sdjl _nss_ldap_group2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) 827c478bd9Sstevel@tonic-gate { 83cb5caa98Sdjl int i; 847c478bd9Sstevel@tonic-gate int nss_result; 85cb5caa98Sdjl int buflen = 0, len; 86cb5caa98Sdjl int firstime = 1; 87cb5caa98Sdjl char *buffer = NULL; 887c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = be->result; 892b4a7802SBaban Kenkre char **gname, **passwd, **gid, *password, *end; 902b4a7802SBaban Kenkre char gid_nobody[NOBODY_STR_LEN]; 912b4a7802SBaban Kenkre char *gid_nobody_v[1]; 92*4c6ae461SPaul B. Henson char *member_str, *strtok_state; 93cb5caa98Sdjl ns_ldap_attr_t *members; 947c478bd9Sstevel@tonic-gate 952b4a7802SBaban Kenkre (void) snprintf(gid_nobody, sizeof (gid_nobody), "%u", GID_NOBODY); 962b4a7802SBaban Kenkre gid_nobody_v[0] = gid_nobody; 97cb5caa98Sdjl 98cb5caa98Sdjl if (result == NULL) 99cb5caa98Sdjl return (NSS_STR_PARSE_PARSE); 100cb5caa98Sdjl buflen = argp->buf.buflen; 101cb5caa98Sdjl 102cb5caa98Sdjl if (argp->buf.result != NULL) { 103cb5caa98Sdjl if ((be->buffer = calloc(1, buflen)) == NULL) { 104cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 105cb5caa98Sdjl goto result_grp2str; 106cb5caa98Sdjl } 107cb5caa98Sdjl buffer = be->buffer; 108cb5caa98Sdjl } else 1097c478bd9Sstevel@tonic-gate buffer = argp->buf.buffer; 1107c478bd9Sstevel@tonic-gate 111cb5caa98Sdjl nss_result = NSS_STR_PARSE_SUCCESS; 112cb5caa98Sdjl (void) memset(buffer, 0, buflen); 1137c478bd9Sstevel@tonic-gate 114cb5caa98Sdjl gname = __ns_ldap_getAttr(result->entry, _G_NAME); 115cb5caa98Sdjl if (gname == NULL || gname[0] == NULL || (strlen(gname[0]) < 1)) { 116cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 117cb5caa98Sdjl goto result_grp2str; 1187c478bd9Sstevel@tonic-gate } 119cb5caa98Sdjl passwd = __ns_ldap_getAttr(result->entry, _G_PASSWD); 120cb5caa98Sdjl if (passwd == NULL || passwd[0] == NULL || (strlen(passwd[0]) == 0)) { 121cb5caa98Sdjl /* group password could be NULL, replace it with "" */ 122cb5caa98Sdjl password = _NO_PASSWD_VAL; 123cb5caa98Sdjl } else { 1247c478bd9Sstevel@tonic-gate /* 1257c478bd9Sstevel@tonic-gate * Preen "{crypt}" if necessary. 1267c478bd9Sstevel@tonic-gate * If the password does not include the {crypt} prefix 1277c478bd9Sstevel@tonic-gate * then the password may be plain text. And thus 1287c478bd9Sstevel@tonic-gate * perhaps crypt(3c) should be used to encrypt it. 1297c478bd9Sstevel@tonic-gate * Currently the password is copied verbatim. 1307c478bd9Sstevel@tonic-gate */ 131cb5caa98Sdjl if (strncasecmp(passwd[0], _CRYPT, strlen(_CRYPT)) == 0) 132cb5caa98Sdjl password = passwd[0] + strlen(_CRYPT); 133cb5caa98Sdjl else 134cb5caa98Sdjl password = passwd[0]; 1357c478bd9Sstevel@tonic-gate } 136cb5caa98Sdjl gid = __ns_ldap_getAttr(result->entry, _G_GID); 137cb5caa98Sdjl if (gid == NULL || gid[0] == NULL || (strlen(gid[0]) < 1)) { 138cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 139cb5caa98Sdjl goto result_grp2str; 1407c478bd9Sstevel@tonic-gate } 1412b4a7802SBaban Kenkre /* Validate GID */ 1422b4a7802SBaban Kenkre if (strtoul(gid[0], &end, 10) > MAXUID) 1432b4a7802SBaban Kenkre gid = gid_nobody_v; 14418bdb8a7Smichen len = snprintf(buffer, buflen, "%s:%s:%s:", gname[0], password, gid[0]); 145cb5caa98Sdjl TEST_AND_ADJUST(len, buffer, buflen, result_grp2str); 146cb5caa98Sdjl 147cb5caa98Sdjl members = __ns_ldap_getAttrStruct(result->entry, _G_MEM); 148cb5caa98Sdjl if (members == NULL || members->attrvalue == NULL) { 149767b0abfSmichen /* no member is fine, skip processing the member list */ 150767b0abfSmichen goto nomember; 1517c478bd9Sstevel@tonic-gate } 152cb5caa98Sdjl 153cb5caa98Sdjl for (i = 0; i < members->value_count; i++) { 154cb5caa98Sdjl if (members->attrvalue[i] == NULL) { 155cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 156cb5caa98Sdjl goto result_grp2str; 1577c478bd9Sstevel@tonic-gate } 158*4c6ae461SPaul B. Henson /* 159*4c6ae461SPaul B. Henson * If we find an '=' in the member attribute value, treat it as 160*4c6ae461SPaul B. Henson * a DN, otherwise as a username. 161*4c6ae461SPaul B. Henson */ 162*4c6ae461SPaul B. Henson if (member_str = strchr(members->attrvalue[i], '=')) { 163*4c6ae461SPaul B. Henson member_str++; /* skip over the '=' */ 164*4c6ae461SPaul B. Henson /* Fail if we can't pull a username out of the RDN */ 165*4c6ae461SPaul B. Henson if (! (member_str = strtok_r(member_str, 166*4c6ae461SPaul B. Henson ",", &strtok_state))) { 167*4c6ae461SPaul B. Henson nss_result = NSS_STR_PARSE_PARSE; 168*4c6ae461SPaul B. Henson goto result_grp2str; 169*4c6ae461SPaul B. Henson } 170*4c6ae461SPaul B. Henson } else { 171*4c6ae461SPaul B. Henson member_str = members->attrvalue[i]; 172*4c6ae461SPaul B. Henson } 173*4c6ae461SPaul B. Henson if (*member_str != '\0') { 1747c478bd9Sstevel@tonic-gate if (firstime) { 175cb5caa98Sdjl len = snprintf(buffer, buflen, "%s", 176*4c6ae461SPaul B. Henson member_str); 177*4c6ae461SPaul B. Henson TEST_AND_ADJUST(len, buffer, buflen, 178*4c6ae461SPaul B. Henson result_grp2str); 179cb5caa98Sdjl firstime = 0; 180cb5caa98Sdjl } else { 181cb5caa98Sdjl len = snprintf(buffer, buflen, ",%s", 182*4c6ae461SPaul B. Henson member_str); 183*4c6ae461SPaul B. Henson TEST_AND_ADJUST(len, buffer, buflen, 184*4c6ae461SPaul B. Henson result_grp2str); 185*4c6ae461SPaul B. Henson } 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate } 188767b0abfSmichen nomember: 189cb5caa98Sdjl /* The front end marshaller doesn't need the trailing nulls */ 190cb5caa98Sdjl if (argp->buf.result != NULL) 191cb5caa98Sdjl be->buflen = strlen(be->buffer); 192cb5caa98Sdjl result_grp2str: 1937c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 194cb5caa98Sdjl return (nss_result); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate /* 1987c478bd9Sstevel@tonic-gate * getbynam gets a group entry by name. This function constructs an ldap 1997c478bd9Sstevel@tonic-gate * search filter using the name invocation parameter and the getgrnam search 2007c478bd9Sstevel@tonic-gate * filter defined. Once the filter is constructed, we searche for a matching 2017c478bd9Sstevel@tonic-gate * entry and marshal the data results into struct group for the frontend 2027c478bd9Sstevel@tonic-gate * process. The function _nss_ldap_group2ent performs the data marshaling. 2037c478bd9Sstevel@tonic-gate */ 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate static nss_status_t 2067c478bd9Sstevel@tonic-gate getbynam(ldap_backend_ptr be, void *a) 2077c478bd9Sstevel@tonic-gate { 2087c478bd9Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 2097c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 2107c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 2117c478bd9Sstevel@tonic-gate char groupname[SEARCHFILTERLEN]; 2127c478bd9Sstevel@tonic-gate int ret; 2137c478bd9Sstevel@tonic-gate 21418bdb8a7Smichen if (_ldap_filter_name(groupname, argp->key.name, sizeof (groupname)) != 21518bdb8a7Smichen 0) 2167c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate ret = snprintf(searchfilter, sizeof (searchfilter), 2197c478bd9Sstevel@tonic-gate _F_GETGRNAM, groupname); 2207c478bd9Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 2217c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate ret = snprintf(userdata, sizeof (userdata), _F_GETGRNAM_SSD, groupname); 2247c478bd9Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 2257c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate return ((nss_status_t)_nss_ldap_lookup(be, argp, 22818bdb8a7Smichen _GROUP, searchfilter, NULL, _merge_SSD_filter, userdata)); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate /* 2337c478bd9Sstevel@tonic-gate * getbygid gets a group entry by number. This function constructs an ldap 2347c478bd9Sstevel@tonic-gate * search filter using the name invocation parameter and the getgrgid search 2357c478bd9Sstevel@tonic-gate * filter defined. Once the filter is constructed, we searche for a matching 2367c478bd9Sstevel@tonic-gate * entry and marshal the data results into struct group for the frontend 2377c478bd9Sstevel@tonic-gate * process. The function _nss_ldap_group2ent performs the data marshaling. 2387c478bd9Sstevel@tonic-gate */ 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate static nss_status_t 2417c478bd9Sstevel@tonic-gate getbygid(ldap_backend_ptr be, void *a) 2427c478bd9Sstevel@tonic-gate { 2437c478bd9Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 2447c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 2457c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 2467c478bd9Sstevel@tonic-gate int ret; 2477c478bd9Sstevel@tonic-gate 2482b4a7802SBaban Kenkre if (argp->key.uid > MAXUID) 2492b4a7802SBaban Kenkre return ((nss_status_t)NSS_NOTFOUND); 2502b4a7802SBaban Kenkre 2517c478bd9Sstevel@tonic-gate ret = snprintf(searchfilter, sizeof (searchfilter), 252f48205beScasper _F_GETGRGID, argp->key.uid); 2537c478bd9Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 2547c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate ret = snprintf(userdata, sizeof (userdata), 257f48205beScasper _F_GETGRGID_SSD, argp->key.uid); 2587c478bd9Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 2597c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate return ((nss_status_t)_nss_ldap_lookup(be, argp, 26218bdb8a7Smichen _GROUP, searchfilter, NULL, _merge_SSD_filter, userdata)); 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate /* 2687c478bd9Sstevel@tonic-gate * getbymember returns all groups a user is defined in. This function 2697c478bd9Sstevel@tonic-gate * uses different architectural procedures than the other group backend 2707c478bd9Sstevel@tonic-gate * system calls because it's a private interface. This function constructs 2717c478bd9Sstevel@tonic-gate * an ldap search filter using the name invocation parameter. Once the 2727c478bd9Sstevel@tonic-gate * filter is constructed, we search for all matching groups counting 2737c478bd9Sstevel@tonic-gate * and storing each group name, gid, etc. Data marshaling is used for 2747c478bd9Sstevel@tonic-gate * group processing. The function _nss_ldap_group2ent() performs the 2757c478bd9Sstevel@tonic-gate * data marshaling. 2767c478bd9Sstevel@tonic-gate * 2777c478bd9Sstevel@tonic-gate * (const char *)argp->username; (size_t)strlen(argp->username); 2787c478bd9Sstevel@tonic-gate * (gid_t)argp->gid_array; (int)argp->maxgids; 2797c478bd9Sstevel@tonic-gate * (int)argp->numgids; 2807c478bd9Sstevel@tonic-gate */ 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate static nss_status_t 2837c478bd9Sstevel@tonic-gate getbymember(ldap_backend_ptr be, void *a) 2847c478bd9Sstevel@tonic-gate { 2857c478bd9Sstevel@tonic-gate int i, j, k; 2867c478bd9Sstevel@tonic-gate int gcnt = (int)0; 287*4c6ae461SPaul B. Henson char **groupvalue, **membervalue, *member_str; 288*4c6ae461SPaul B. Henson char *strtok_state; 2897c478bd9Sstevel@tonic-gate nss_status_t lstat; 2907c478bd9Sstevel@tonic-gate struct nss_groupsbymem *argp = (struct nss_groupsbymem *)a; 2917c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 2927c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 2937c478bd9Sstevel@tonic-gate char name[SEARCHFILTERLEN]; 2947c478bd9Sstevel@tonic-gate ns_ldap_result_t *result; 2957c478bd9Sstevel@tonic-gate ns_ldap_entry_t *curEntry; 296*4c6ae461SPaul B. Henson char *username, **dn_attr, *dn; 2977c478bd9Sstevel@tonic-gate gid_t gid; 2987c478bd9Sstevel@tonic-gate int ret; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate if (strcmp(argp->username, "") == 0 || 3017c478bd9Sstevel@tonic-gate strcmp(argp->username, "root") == 0) 3027c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate if (_ldap_filter_name(name, argp->username, sizeof (name)) != 0) 3057c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3067c478bd9Sstevel@tonic-gate 307*4c6ae461SPaul B. Henson ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETPWNAM, name); 3087c478bd9Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 3097c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3107c478bd9Sstevel@tonic-gate 311*4c6ae461SPaul B. Henson ret = snprintf(userdata, sizeof (userdata), _F_GETPWNAM_SSD, name); 3127c478bd9Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 3137c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3147c478bd9Sstevel@tonic-gate 315*4c6ae461SPaul B. Henson /* 316*4c6ae461SPaul B. Henson * Look up the user DN in ldap. If it's not found, search solely by 317*4c6ae461SPaul B. Henson * username. 318*4c6ae461SPaul B. Henson */ 319*4c6ae461SPaul B. Henson lstat = (nss_status_t)_nss_ldap_nocb_lookup(be, NULL, 320*4c6ae461SPaul B. Henson _PASSWD, searchfilter, NULL, _merge_SSD_filter, userdata); 321*4c6ae461SPaul B. Henson if (lstat != (nss_status_t)NS_LDAP_SUCCESS) 322*4c6ae461SPaul B. Henson return ((nss_status_t)lstat); 323*4c6ae461SPaul B. Henson 324*4c6ae461SPaul B. Henson if (be->result == NULL || 325*4c6ae461SPaul B. Henson !(dn_attr = __ns_ldap_getAttr(be->result->entry, "dn"))) 326*4c6ae461SPaul B. Henson dn = name; 327*4c6ae461SPaul B. Henson else 328*4c6ae461SPaul B. Henson dn = dn_attr[0]; 329*4c6ae461SPaul B. Henson 330*4c6ae461SPaul B. Henson ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETGRMEM, name, 331*4c6ae461SPaul B. Henson dn); 332*4c6ae461SPaul B. Henson if (ret >= sizeof (searchfilter) || ret < 0) 333*4c6ae461SPaul B. Henson return ((nss_status_t)NSS_NOTFOUND); 334*4c6ae461SPaul B. Henson 335*4c6ae461SPaul B. Henson ret = snprintf(userdata, sizeof (userdata), _F_GETGRMEM_SSD, name, 336*4c6ae461SPaul B. Henson dn); 337*4c6ae461SPaul B. Henson if (ret >= sizeof (userdata) || ret < 0) 338*4c6ae461SPaul B. Henson return ((nss_status_t)NSS_NOTFOUND); 339*4c6ae461SPaul B. Henson 340*4c6ae461SPaul B. Henson /* 341*4c6ae461SPaul B. Henson * Free up resources from user DN search before performing group 342*4c6ae461SPaul B. Henson * search. 343*4c6ae461SPaul B. Henson */ 344*4c6ae461SPaul B. Henson (void) __ns_ldap_freeResult((ns_ldap_result_t **)&be->result); 345*4c6ae461SPaul B. Henson 3467c478bd9Sstevel@tonic-gate gcnt = (int)argp->numgids; 34718bdb8a7Smichen lstat = (nss_status_t)_nss_ldap_nocb_lookup(be, NULL, 34818bdb8a7Smichen _GROUP, searchfilter, NULL, _merge_SSD_filter, userdata); 3497c478bd9Sstevel@tonic-gate if (lstat != (nss_status_t)NS_LDAP_SUCCESS) 3507c478bd9Sstevel@tonic-gate return ((nss_status_t)lstat); 3517c478bd9Sstevel@tonic-gate if (be->result == NULL) 3527c478bd9Sstevel@tonic-gate return (NSS_NOTFOUND); 3537c478bd9Sstevel@tonic-gate username = (char *)argp->username; 3547c478bd9Sstevel@tonic-gate result = (ns_ldap_result_t *)be->result; 3557c478bd9Sstevel@tonic-gate curEntry = (ns_ldap_entry_t *)result->entry; 3567c478bd9Sstevel@tonic-gate for (i = 0; i < result->entries_count; i++) { 3577c478bd9Sstevel@tonic-gate membervalue = __ns_ldap_getAttr(curEntry, "memberUid"); 3587c478bd9Sstevel@tonic-gate if (membervalue) { 3597c478bd9Sstevel@tonic-gate for (j = 0; membervalue[j]; j++) { 360*4c6ae461SPaul B. Henson /* 361*4c6ae461SPaul B. Henson * If we find an '=' in the member attribute 362*4c6ae461SPaul B. Henson * value, treat it as a DN, otherwise as a 363*4c6ae461SPaul B. Henson * username. 364*4c6ae461SPaul B. Henson */ 365*4c6ae461SPaul B. Henson if (member_str = strchr(membervalue[j], '=')) { 366*4c6ae461SPaul B. Henson member_str++; /* skip over the '=' */ 367*4c6ae461SPaul B. Henson member_str = strtok_r(member_str, ",", 368*4c6ae461SPaul B. Henson &strtok_state); 369*4c6ae461SPaul B. Henson } else { 370*4c6ae461SPaul B. Henson member_str = membervalue[j]; 371*4c6ae461SPaul B. Henson } 372*4c6ae461SPaul B. Henson if (member_str && 373*4c6ae461SPaul B. Henson strcmp(member_str, username) == NULL) { 3747c478bd9Sstevel@tonic-gate groupvalue = __ns_ldap_getAttr(curEntry, 3757c478bd9Sstevel@tonic-gate "gidnumber"); 3767c478bd9Sstevel@tonic-gate gid = (gid_t)strtol(groupvalue[0], 3777c478bd9Sstevel@tonic-gate (char **)NULL, 10); 3787c478bd9Sstevel@tonic-gate if (argp->numgids < argp->maxgids) { 3797c478bd9Sstevel@tonic-gate for (k = 0; k < argp->numgids; 3807c478bd9Sstevel@tonic-gate k++) { 38118bdb8a7Smichen if (argp->gid_array[k] 38218bdb8a7Smichen == gid) 3837c478bd9Sstevel@tonic-gate /* already exists */ 3847c478bd9Sstevel@tonic-gate break; 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate if (k == argp->numgids) 3877c478bd9Sstevel@tonic-gate argp->gid_array[argp->numgids++] 3887c478bd9Sstevel@tonic-gate = gid; 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate break; 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate curEntry = curEntry->next; 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 397cb5caa98Sdjl (void) __ns_ldap_freeResult((ns_ldap_result_t **)&be->result); 3987c478bd9Sstevel@tonic-gate if (gcnt == argp->numgids) 3997c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 4007c478bd9Sstevel@tonic-gate 40120e6d5c5Ssc157166 /* 40220e6d5c5Ssc157166 * Return NSS_SUCCESS only if array is full. 40320e6d5c5Ssc157166 * Explained in <nss_dbdefs.h>. 40420e6d5c5Ssc157166 */ 40520e6d5c5Ssc157166 return ((nss_status_t)((argp->numgids == argp->maxgids) 40620e6d5c5Ssc157166 ? NSS_SUCCESS 40720e6d5c5Ssc157166 : NSS_NOTFOUND)); 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate static ldap_backend_op_t gr_ops[] = { 4117c478bd9Sstevel@tonic-gate _nss_ldap_destr, 4127c478bd9Sstevel@tonic-gate _nss_ldap_endent, 4137c478bd9Sstevel@tonic-gate _nss_ldap_setent, 4147c478bd9Sstevel@tonic-gate _nss_ldap_getent, 4157c478bd9Sstevel@tonic-gate getbynam, 4167c478bd9Sstevel@tonic-gate getbygid, 4177c478bd9Sstevel@tonic-gate getbymember 4187c478bd9Sstevel@tonic-gate }; 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate /*ARGSUSED0*/ 4227c478bd9Sstevel@tonic-gate nss_backend_t * 4237c478bd9Sstevel@tonic-gate _nss_ldap_group_constr(const char *dummy1, const char *dummy2, 4247c478bd9Sstevel@tonic-gate const char *dummy3) 4257c478bd9Sstevel@tonic-gate { 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate return ((nss_backend_t *)_nss_ldap_constr(gr_ops, 4287c478bd9Sstevel@tonic-gate sizeof (gr_ops)/sizeof (gr_ops[0]), _GROUP, gr_attrs, 429cb5caa98Sdjl _nss_ldap_group2str)); 4307c478bd9Sstevel@tonic-gate } 431