12b4a7802SBaban Kenkre /* 22b4a7802SBaban Kenkre * CDDL HEADER START 32b4a7802SBaban Kenkre * 42b4a7802SBaban Kenkre * The contents of this file are subject to the terms of the 52b4a7802SBaban Kenkre * Common Development and Distribution License (the "License"). 62b4a7802SBaban Kenkre * You may not use this file except in compliance with the License. 72b4a7802SBaban Kenkre * 82b4a7802SBaban Kenkre * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92b4a7802SBaban Kenkre * or http://www.opensolaris.org/os/licensing. 102b4a7802SBaban Kenkre * See the License for the specific language governing permissions 112b4a7802SBaban Kenkre * and limitations under the License. 122b4a7802SBaban Kenkre * 132b4a7802SBaban Kenkre * When distributing Covered Code, include this CDDL HEADER in each 142b4a7802SBaban Kenkre * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152b4a7802SBaban Kenkre * If applicable, add the following below this CDDL HEADER, with the 162b4a7802SBaban Kenkre * fields enclosed by brackets "[]" replaced with your own identifying 172b4a7802SBaban Kenkre * information: Portions Copyright [yyyy] [name of copyright owner] 182b4a7802SBaban Kenkre * 192b4a7802SBaban Kenkre * CDDL HEADER END 202b4a7802SBaban Kenkre */ 212b4a7802SBaban Kenkre /* 22*1fdeec65Sjoyce mcintosh * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 232b4a7802SBaban Kenkre */ 242b4a7802SBaban Kenkre 252b4a7802SBaban Kenkre #include <pwd.h> 262b4a7802SBaban Kenkre #include <idmap.h> 272b4a7802SBaban Kenkre #include <ctype.h> 282b4a7802SBaban Kenkre #include "ad_common.h" 292b4a7802SBaban Kenkre 302b4a7802SBaban Kenkre /* passwd attributes and filters */ 312b4a7802SBaban Kenkre #define _PWD_DN "dn" 322b4a7802SBaban Kenkre #define _PWD_SAN "sAMAccountName" 332b4a7802SBaban Kenkre #define _PWD_OBJSID "objectSid" 342b4a7802SBaban Kenkre #define _PWD_PRIMARYGROUPID "primaryGroupID" 352b4a7802SBaban Kenkre #define _PWD_CN "cn" 362b4a7802SBaban Kenkre #define _PWD_HOMEDIRECTORY "homedirectory" 372b4a7802SBaban Kenkre #define _PWD_LOGINSHELL "loginshell" 382b4a7802SBaban Kenkre #define _PWD_OBJCLASS "objectClass" 392b4a7802SBaban Kenkre 402b4a7802SBaban Kenkre #define _F_GETPWNAM "(sAMAccountName=%.*s)" 412b4a7802SBaban Kenkre #define _F_GETPWUID "(objectSid=%s)" 422b4a7802SBaban Kenkre 432b4a7802SBaban Kenkre static const char *pwd_attrs[] = { 442b4a7802SBaban Kenkre _PWD_SAN, 452b4a7802SBaban Kenkre _PWD_OBJSID, 462b4a7802SBaban Kenkre _PWD_PRIMARYGROUPID, 472b4a7802SBaban Kenkre _PWD_CN, 482b4a7802SBaban Kenkre _PWD_HOMEDIRECTORY, 492b4a7802SBaban Kenkre _PWD_LOGINSHELL, 502b4a7802SBaban Kenkre _PWD_OBJCLASS, 512b4a7802SBaban Kenkre (char *)NULL 522b4a7802SBaban Kenkre }; 532b4a7802SBaban Kenkre 542b4a7802SBaban Kenkre static int 552b4a7802SBaban Kenkre update_buffer(ad_backend_ptr be, nss_XbyY_args_t *argp, 562b4a7802SBaban Kenkre const char *name, const char *domain, 572b4a7802SBaban Kenkre uid_t uid, gid_t gid, const char *gecos, 582b4a7802SBaban Kenkre const char *homedir, const char *shell) 592b4a7802SBaban Kenkre { 602b4a7802SBaban Kenkre int buflen; 612b4a7802SBaban Kenkre char *buffer; 622b4a7802SBaban Kenkre 632b4a7802SBaban Kenkre if (be->db_type == NSS_AD_DB_PASSWD_BYNAME) { 642b4a7802SBaban Kenkre /* 652b4a7802SBaban Kenkre * The canonical name obtained from AD lookup may not match 662b4a7802SBaban Kenkre * the case of the name (i.e. key) in the request. Therefore, 672b4a7802SBaban Kenkre * use the name from the request to construct the result. 682b4a7802SBaban Kenkre */ 692b4a7802SBaban Kenkre buflen = snprintf(NULL, 0, "%s:%s:%u:%u:%s:%s:%s", 702b4a7802SBaban Kenkre argp->key.name, "x", uid, gid, gecos, homedir, shell) + 1; 712b4a7802SBaban Kenkre } else { 722b4a7802SBaban Kenkre if (domain == NULL) 732b4a7802SBaban Kenkre domain = WK_DOMAIN; 742b4a7802SBaban Kenkre buflen = snprintf(NULL, 0, "%s@%s:%s:%u:%u:%s:%s:%s", 752b4a7802SBaban Kenkre name, domain, "x", uid, gid, gecos, homedir, shell) + 1; 762b4a7802SBaban Kenkre } 772b4a7802SBaban Kenkre 782b4a7802SBaban Kenkre 792b4a7802SBaban Kenkre if (argp->buf.result != NULL) { 802b4a7802SBaban Kenkre buffer = be->buffer = malloc(buflen); 812b4a7802SBaban Kenkre if (be->buffer == NULL) 822b4a7802SBaban Kenkre return (-1); 832b4a7802SBaban Kenkre be->buflen = buflen; 842b4a7802SBaban Kenkre } else { 852b4a7802SBaban Kenkre if (buflen > argp->buf.buflen) 862b4a7802SBaban Kenkre return (-1); 872b4a7802SBaban Kenkre buflen = argp->buf.buflen; 882b4a7802SBaban Kenkre buffer = argp->buf.buffer; 892b4a7802SBaban Kenkre } 902b4a7802SBaban Kenkre 912b4a7802SBaban Kenkre if (be->db_type == NSS_AD_DB_PASSWD_BYNAME) 922b4a7802SBaban Kenkre (void) snprintf(buffer, buflen, "%s:%s:%u:%u:%s:%s:%s", 932b4a7802SBaban Kenkre argp->key.name, "x", uid, gid, gecos, homedir, shell); 942b4a7802SBaban Kenkre else 952b4a7802SBaban Kenkre (void) snprintf(buffer, buflen, "%s@%s:%s:%u:%u:%s:%s:%s", 962b4a7802SBaban Kenkre name, domain, "x", uid, gid, gecos, homedir, shell); 972b4a7802SBaban Kenkre return (0); 982b4a7802SBaban Kenkre } 992b4a7802SBaban Kenkre 1002b4a7802SBaban Kenkre 1012b4a7802SBaban Kenkre #define NET_SCHEME "/net" 1022b4a7802SBaban Kenkre 1032b4a7802SBaban Kenkre /* 1042b4a7802SBaban Kenkre * 1) If the homeDirectory string is in UNC format then convert it into 1052b4a7802SBaban Kenkre * a /net format. This needs to be revisited later but is fine for now 1062b4a7802SBaban Kenkre * because Solaris does not support -hosts automount map for CIFS yet. 1072b4a7802SBaban Kenkre * 1082b4a7802SBaban Kenkre * 2) If homeDirectory contains ':' then return NULL because ':' is the 1092b4a7802SBaban Kenkre * delimiter in passwd entries and may break apps that parse these entries. 1102b4a7802SBaban Kenkre * 1112b4a7802SBaban Kenkre * 3) For all other cases return the same string that was passed to 1122b4a7802SBaban Kenkre * this function. 1132b4a7802SBaban Kenkre */ 1142b4a7802SBaban Kenkre static 1152b4a7802SBaban Kenkre char * 1162b4a7802SBaban Kenkre process_homedir(char *homedir) 1172b4a7802SBaban Kenkre { 1182b4a7802SBaban Kenkre size_t len, smb_len; 1192b4a7802SBaban Kenkre char *smb_homedir; 1202b4a7802SBaban Kenkre int i, slash = 0; 1212b4a7802SBaban Kenkre 1222b4a7802SBaban Kenkre len = strlen(homedir); 1232b4a7802SBaban Kenkre 1242b4a7802SBaban Kenkre if (strchr(homedir, ':') != NULL) 1252b4a7802SBaban Kenkre /* 1262b4a7802SBaban Kenkre * Ignore paths that have colon ':' because ':' is a 1272b4a7802SBaban Kenkre * delimiter for the passwd entry. 1282b4a7802SBaban Kenkre */ 1292b4a7802SBaban Kenkre return (NULL); 1302b4a7802SBaban Kenkre 1312b4a7802SBaban Kenkre if (!(len > 1 && homedir[0] == '\\' && homedir[1] == '\\')) 1322b4a7802SBaban Kenkre /* Keep homedir intact if not in UNC format */ 1332b4a7802SBaban Kenkre return (homedir); 1342b4a7802SBaban Kenkre 1352b4a7802SBaban Kenkre /* 1362b4a7802SBaban Kenkre * Convert UNC string into /net format 1372b4a7802SBaban Kenkre * Example: \\server\abc -> /net/server/abc 1382b4a7802SBaban Kenkre */ 1392b4a7802SBaban Kenkre smb_len = len + 1 + sizeof (NET_SCHEME); 1402b4a7802SBaban Kenkre if ((smb_homedir = calloc(1, smb_len)) == NULL) 1412b4a7802SBaban Kenkre return (NULL); 1422b4a7802SBaban Kenkre (void) strlcpy(smb_homedir, NET_SCHEME, smb_len); 1432b4a7802SBaban Kenkre for (i = strlen(smb_homedir); *homedir != '\0'; homedir++) { 1442b4a7802SBaban Kenkre if (*homedir == '\\') { 1452b4a7802SBaban Kenkre /* Reduce double backslashes into one */ 1462b4a7802SBaban Kenkre if (slash) 1472b4a7802SBaban Kenkre slash = 0; 1482b4a7802SBaban Kenkre else { 1492b4a7802SBaban Kenkre slash = 1; 1502b4a7802SBaban Kenkre smb_homedir[i++] = '/'; 1512b4a7802SBaban Kenkre } 1522b4a7802SBaban Kenkre } else { 1532b4a7802SBaban Kenkre smb_homedir[i++] = *homedir; 1542b4a7802SBaban Kenkre slash = 0; 1552b4a7802SBaban Kenkre } 1562b4a7802SBaban Kenkre } 1572b4a7802SBaban Kenkre return (smb_homedir); 1582b4a7802SBaban Kenkre } 1592b4a7802SBaban Kenkre 1602b4a7802SBaban Kenkre /* 1612b4a7802SBaban Kenkre * _nss_ad_passwd2str is the data marshaling method for the passwd getXbyY 1622b4a7802SBaban Kenkre * (e.g., getbyuid(), getbyname(), getpwent()) backend processes. This method is 1632b4a7802SBaban Kenkre * called after a successful AD search has been performed. This method will 1642b4a7802SBaban Kenkre * parse the AD search values into the file format. 1652b4a7802SBaban Kenkre * e.g. 1662b4a7802SBaban Kenkre * 1672b4a7802SBaban Kenkre * blue@whale:x:123456:10:Blue Whale:/: 1682b4a7802SBaban Kenkre * 1692b4a7802SBaban Kenkre */ 1702b4a7802SBaban Kenkre static int 1712b4a7802SBaban Kenkre _nss_ad_passwd2str(ad_backend_ptr be, nss_XbyY_args_t *argp) 1722b4a7802SBaban Kenkre { 1732b4a7802SBaban Kenkre int nss_result; 1742b4a7802SBaban Kenkre adutils_result_t *result = be->result; 1752b4a7802SBaban Kenkre const adutils_entry_t *entry; 1762b4a7802SBaban Kenkre char **sid_v, *ptr, **pgid_v, *end; 1772b4a7802SBaban Kenkre ulong_t tmp; 1782b4a7802SBaban Kenkre uint32_t urid, grid; 1792b4a7802SBaban Kenkre uid_t uid; 1802b4a7802SBaban Kenkre gid_t gid; 1812b4a7802SBaban Kenkre idmap_stat gstat; 1822b4a7802SBaban Kenkre idmap_get_handle_t *ig = NULL; 1832b4a7802SBaban Kenkre char **name_v, **dn_v, *domain = NULL; 1842b4a7802SBaban Kenkre char **gecos_v, **shell_v; 1852b4a7802SBaban Kenkre char **homedir_v = NULL, *homedir = NULL; 1862b4a7802SBaban Kenkre char *NULL_STR = ""; 1872b4a7802SBaban Kenkre 1882b4a7802SBaban Kenkre if (result == NULL) 1892b4a7802SBaban Kenkre return (NSS_STR_PARSE_PARSE); 1902b4a7802SBaban Kenkre entry = adutils_getfirstentry(result); 1912b4a7802SBaban Kenkre nss_result = NSS_STR_PARSE_PARSE; 1922b4a7802SBaban Kenkre 1932b4a7802SBaban Kenkre /* Create handles for idmap service */ 194*1fdeec65Sjoyce mcintosh if (idmap_get_create(&ig) != 0) 1952b4a7802SBaban Kenkre goto result_pwd2str; 1962b4a7802SBaban Kenkre 1972b4a7802SBaban Kenkre /* Get name */ 1982b4a7802SBaban Kenkre name_v = adutils_getattr(entry, _PWD_SAN); 1992b4a7802SBaban Kenkre if (name_v == NULL || name_v[0] == NULL || *name_v[0] == '\0') 2002b4a7802SBaban Kenkre goto result_pwd2str; 2012b4a7802SBaban Kenkre 2022b4a7802SBaban Kenkre /* Get domain */ 2032b4a7802SBaban Kenkre dn_v = adutils_getattr(entry, _PWD_DN); 2042b4a7802SBaban Kenkre if (dn_v == NULL || dn_v[0] == NULL || *dn_v[0] == '\0') 2052b4a7802SBaban Kenkre goto result_pwd2str; 2062b4a7802SBaban Kenkre domain = adutils_dn2dns(dn_v[0]); 2072b4a7802SBaban Kenkre 2082b4a7802SBaban Kenkre /* Get objectSID (in text format) */ 2092b4a7802SBaban Kenkre sid_v = adutils_getattr(entry, _PWD_OBJSID); 2102b4a7802SBaban Kenkre if (sid_v == NULL || sid_v[0] == NULL || *sid_v[0] == '\0') 2112b4a7802SBaban Kenkre goto result_pwd2str; 2122b4a7802SBaban Kenkre 2132b4a7802SBaban Kenkre /* Break SID into prefix and rid */ 2142b4a7802SBaban Kenkre if ((ptr = strrchr(sid_v[0], '-')) == NULL) 2152b4a7802SBaban Kenkre goto result_pwd2str; 2162b4a7802SBaban Kenkre *ptr = '\0'; 2172b4a7802SBaban Kenkre end = ++ptr; 2182b4a7802SBaban Kenkre tmp = strtoul(ptr, &end, 10); 2192b4a7802SBaban Kenkre if (end == ptr || tmp > UINT32_MAX) 2202b4a7802SBaban Kenkre goto result_pwd2str; 2212b4a7802SBaban Kenkre urid = (uint32_t)tmp; 2222b4a7802SBaban Kenkre 2232b4a7802SBaban Kenkre /* We already have uid -- no need to call idmapd */ 2242b4a7802SBaban Kenkre if (be->db_type == NSS_AD_DB_PASSWD_BYUID) 2252b4a7802SBaban Kenkre uid = argp->key.uid; 2262b4a7802SBaban Kenkre else 2272b4a7802SBaban Kenkre uid = be->uid; 2282b4a7802SBaban Kenkre 2292b4a7802SBaban Kenkre /* Get primaryGroupID */ 2302b4a7802SBaban Kenkre pgid_v = adutils_getattr(entry, _PWD_PRIMARYGROUPID); 2312b4a7802SBaban Kenkre if (pgid_v == NULL || pgid_v[0] == NULL || *pgid_v[0] == '\0') 2322b4a7802SBaban Kenkre /* 2332b4a7802SBaban Kenkre * If primaryGroupID is not found then we request 2342b4a7802SBaban Kenkre * a GID to be mapped to the given user's objectSID 2352b4a7802SBaban Kenkre * (diagonal mapping) and use this GID as the primary 2362b4a7802SBaban Kenkre * GID for the entry. 2372b4a7802SBaban Kenkre */ 2382b4a7802SBaban Kenkre grid = urid; 2392b4a7802SBaban Kenkre else { 2402b4a7802SBaban Kenkre end = pgid_v[0]; 2412b4a7802SBaban Kenkre tmp = strtoul(pgid_v[0], &end, 10); 2422b4a7802SBaban Kenkre if (end == pgid_v[0] || tmp > UINT32_MAX) 2432b4a7802SBaban Kenkre goto result_pwd2str; 2442b4a7802SBaban Kenkre grid = (uint32_t)tmp; 2452b4a7802SBaban Kenkre } 2462b4a7802SBaban Kenkre 2472b4a7802SBaban Kenkre /* Map group SID to GID using idmap service */ 2482b4a7802SBaban Kenkre if (idmap_get_gidbysid(ig, sid_v[0], grid, 0, &gid, &gstat) != 0) 2492b4a7802SBaban Kenkre goto result_pwd2str; 2502b4a7802SBaban Kenkre if (idmap_get_mappings(ig) != 0 || gstat != 0) { 2512b4a7802SBaban Kenkre RESET_ERRNO(); 2522b4a7802SBaban Kenkre goto result_pwd2str; 2532b4a7802SBaban Kenkre } 2542b4a7802SBaban Kenkre 2552b4a7802SBaban Kenkre /* Get gecos, homedirectory and shell information if available */ 2562b4a7802SBaban Kenkre gecos_v = adutils_getattr(entry, _PWD_CN); 2572b4a7802SBaban Kenkre if (gecos_v == NULL || gecos_v[0] == NULL || *gecos_v[0] == '\0') 2582b4a7802SBaban Kenkre gecos_v = &NULL_STR; 2592b4a7802SBaban Kenkre 2602b4a7802SBaban Kenkre homedir_v = adutils_getattr(entry, _PWD_HOMEDIRECTORY); 2612b4a7802SBaban Kenkre if (homedir_v == NULL || homedir_v[0] == NULL || *homedir_v[0] == '\0') 2622b4a7802SBaban Kenkre homedir = NULL_STR; 2632b4a7802SBaban Kenkre else if ((homedir = process_homedir(homedir_v[0])) == NULL) 2642b4a7802SBaban Kenkre homedir = NULL_STR; 2652b4a7802SBaban Kenkre 2662b4a7802SBaban Kenkre shell_v = adutils_getattr(entry, _PWD_LOGINSHELL); 2672b4a7802SBaban Kenkre if (shell_v == NULL || shell_v[0] == NULL || *shell_v[0] == '\0') 2682b4a7802SBaban Kenkre shell_v = &NULL_STR; 2692b4a7802SBaban Kenkre 2702b4a7802SBaban Kenkre if (update_buffer(be, argp, name_v[0], domain, uid, gid, 2712b4a7802SBaban Kenkre gecos_v[0], homedir, shell_v[0]) < 0) 2722b4a7802SBaban Kenkre nss_result = NSS_STR_PARSE_ERANGE; 2732b4a7802SBaban Kenkre else 2742b4a7802SBaban Kenkre nss_result = NSS_STR_PARSE_SUCCESS; 2752b4a7802SBaban Kenkre 2762b4a7802SBaban Kenkre result_pwd2str: 2772b4a7802SBaban Kenkre idmap_get_destroy(ig); 2782b4a7802SBaban Kenkre (void) adutils_freeresult(&be->result); 2792b4a7802SBaban Kenkre free(domain); 2802b4a7802SBaban Kenkre if (homedir != NULL_STR && homedir_v != NULL && 2812b4a7802SBaban Kenkre homedir != homedir_v[0]) 2822b4a7802SBaban Kenkre free(homedir); 2832b4a7802SBaban Kenkre return ((int)nss_result); 2842b4a7802SBaban Kenkre } 2852b4a7802SBaban Kenkre 2862b4a7802SBaban Kenkre /* 2872b4a7802SBaban Kenkre * getbyname gets a passwd entry by winname. This function constructs an ldap 2882b4a7802SBaban Kenkre * search filter using the name invocation parameter and the getpwnam search 2892b4a7802SBaban Kenkre * filter defined. Once the filter is constructed, we search for a matching 2902b4a7802SBaban Kenkre * entry and marshal the data results into struct passwd for the frontend 2912b4a7802SBaban Kenkre * process. The function _nss_ad_passwd2ent performs the data marshaling. 2922b4a7802SBaban Kenkre */ 2932b4a7802SBaban Kenkre 2942b4a7802SBaban Kenkre static nss_status_t 2952b4a7802SBaban Kenkre getbyname(ad_backend_ptr be, void *a) 2962b4a7802SBaban Kenkre { 2972b4a7802SBaban Kenkre nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 2982b4a7802SBaban Kenkre char *searchfilter; 2992b4a7802SBaban Kenkre char name[SEARCHFILTERLEN]; 3002b4a7802SBaban Kenkre char *dname; 3012b4a7802SBaban Kenkre int filterlen, namelen; 3022b4a7802SBaban Kenkre int flag; 3032b4a7802SBaban Kenkre nss_status_t stat; 3042b4a7802SBaban Kenkre idmap_stat idmaprc; 3052b4a7802SBaban Kenkre uid_t uid; 3062b4a7802SBaban Kenkre gid_t gid; 3072b4a7802SBaban Kenkre int is_user, is_wuser, try_idmap; 3082b4a7802SBaban Kenkre 3092b4a7802SBaban Kenkre be->db_type = NSS_AD_DB_PASSWD_BYNAME; 3102b4a7802SBaban Kenkre 3112b4a7802SBaban Kenkre /* Sanitize name so that it can be used in our LDAP filter */ 3122b4a7802SBaban Kenkre if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0) 3132b4a7802SBaban Kenkre return ((nss_status_t)NSS_NOTFOUND); 3142b4a7802SBaban Kenkre 3152b4a7802SBaban Kenkre if ((dname = strchr(name, '@')) == NULL) 3162b4a7802SBaban Kenkre return ((nss_status_t)NSS_NOTFOUND); 3172b4a7802SBaban Kenkre 3182b4a7802SBaban Kenkre *dname = '\0'; 3192b4a7802SBaban Kenkre dname++; 3202b4a7802SBaban Kenkre 3212b4a7802SBaban Kenkre /* 3222b4a7802SBaban Kenkre * Map the given name to UID using idmap service. If idmap 3232b4a7802SBaban Kenkre * call fails then this will save us doing AD discovery and 3242b4a7802SBaban Kenkre * AD lookup here. 3252b4a7802SBaban Kenkre */ 3262b4a7802SBaban Kenkre flag = (strcasecmp(dname, WK_DOMAIN) == 0) ? 3272b4a7802SBaban Kenkre IDMAP_REQ_FLG_WK_OR_LOCAL_SIDS_ONLY : 0; 3282b4a7802SBaban Kenkre is_wuser = -1; 3292b4a7802SBaban Kenkre is_user = 1; 330*1fdeec65Sjoyce mcintosh if (idmap_get_w2u_mapping(NULL, NULL, name, 3312b4a7802SBaban Kenkre dname, flag, &is_user, &is_wuser, &be->uid, NULL, 3322b4a7802SBaban Kenkre NULL, NULL) != IDMAP_SUCCESS) { 3332b4a7802SBaban Kenkre RESET_ERRNO(); 3342b4a7802SBaban Kenkre return ((nss_status_t)NSS_NOTFOUND); 3352b4a7802SBaban Kenkre } 3362b4a7802SBaban Kenkre 3372b4a7802SBaban Kenkre /* If this is not a Well-Known SID then try AD lookup. */ 3382b4a7802SBaban Kenkre if (strcasecmp(dname, WK_DOMAIN) != 0) { 3392b4a7802SBaban Kenkre /* Assemble filter using the given name */ 3402b4a7802SBaban Kenkre namelen = strlen(name); 3412b4a7802SBaban Kenkre filterlen = snprintf(NULL, 0, _F_GETPWNAM, namelen, name) + 1; 3422b4a7802SBaban Kenkre if ((searchfilter = (char *)malloc(filterlen)) == NULL) 3432b4a7802SBaban Kenkre return ((nss_status_t)NSS_NOTFOUND); 3442b4a7802SBaban Kenkre (void) snprintf(searchfilter, filterlen, _F_GETPWNAM, 3452b4a7802SBaban Kenkre namelen, name); 3462b4a7802SBaban Kenkre stat = _nss_ad_lookup(be, argp, _PASSWD, searchfilter, 3472b4a7802SBaban Kenkre dname, &try_idmap); 3482b4a7802SBaban Kenkre free(searchfilter); 3492b4a7802SBaban Kenkre 350*1fdeec65Sjoyce mcintosh if (!try_idmap) 3512b4a7802SBaban Kenkre return (stat); 3522b4a7802SBaban Kenkre 3532b4a7802SBaban Kenkre } 3542b4a7802SBaban Kenkre 3552b4a7802SBaban Kenkre /* 3562b4a7802SBaban Kenkre * Either this is a Well-Known SID or AD lookup failed. Map 3572b4a7802SBaban Kenkre * the given name to GID using idmap service and construct 3582b4a7802SBaban Kenkre * the passwd entry. 3592b4a7802SBaban Kenkre */ 3602b4a7802SBaban Kenkre is_wuser = -1; 3612b4a7802SBaban Kenkre is_user = 0; /* Map name to primary gid */ 362*1fdeec65Sjoyce mcintosh idmaprc = idmap_get_w2u_mapping(NULL, NULL, name, dname, 3632b4a7802SBaban Kenkre flag, &is_user, &is_wuser, &gid, NULL, NULL, NULL); 3642b4a7802SBaban Kenkre if (idmaprc != IDMAP_SUCCESS) { 3652b4a7802SBaban Kenkre RESET_ERRNO(); 3662b4a7802SBaban Kenkre return ((nss_status_t)NSS_NOTFOUND); 3672b4a7802SBaban Kenkre } 3682b4a7802SBaban Kenkre 3692b4a7802SBaban Kenkre /* Create passwd(4) style string */ 3702b4a7802SBaban Kenkre if (update_buffer(be, argp, name, dname, 3712b4a7802SBaban Kenkre be->uid, gid, "", "", "") < 0) 3722b4a7802SBaban Kenkre return ((nss_status_t)NSS_NOTFOUND); 3732b4a7802SBaban Kenkre 3742b4a7802SBaban Kenkre /* Marshall the data, sanitize the return status and return */ 3752b4a7802SBaban Kenkre stat = _nss_ad_marshall_data(be, argp); 3762b4a7802SBaban Kenkre return (_nss_ad_sanitize_status(be, argp, stat)); 3772b4a7802SBaban Kenkre } 3782b4a7802SBaban Kenkre 3792b4a7802SBaban Kenkre 3802b4a7802SBaban Kenkre /* 3812b4a7802SBaban Kenkre * getbyuid gets a passwd entry by uid number. This function constructs an ldap 3822b4a7802SBaban Kenkre * search filter using the uid invocation parameter and the getpwuid search 3832b4a7802SBaban Kenkre * filter defined. Once the filter is constructed, we search for a matching 3842b4a7802SBaban Kenkre * entry and marshal the data results into struct passwd for the frontend 3852b4a7802SBaban Kenkre * process. The function _nss_ad_passwd2ent performs the data marshaling. 3862b4a7802SBaban Kenkre */ 3872b4a7802SBaban Kenkre 3882b4a7802SBaban Kenkre static nss_status_t 3892b4a7802SBaban Kenkre getbyuid(ad_backend_ptr be, void *a) 3902b4a7802SBaban Kenkre { 3912b4a7802SBaban Kenkre nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 3922b4a7802SBaban Kenkre char searchfilter[ADUTILS_MAXHEXBINSID + 14]; 3932b4a7802SBaban Kenkre char *sidprefix = NULL; 3942b4a7802SBaban Kenkre idmap_rid_t rid; 3952b4a7802SBaban Kenkre char cbinsid[ADUTILS_MAXHEXBINSID + 1]; 3962b4a7802SBaban Kenkre char *winname = NULL, *windomain = NULL; 3972b4a7802SBaban Kenkre int is_user, is_wuser; 3982b4a7802SBaban Kenkre gid_t gid; 3992b4a7802SBaban Kenkre idmap_stat idmaprc; 4002b4a7802SBaban Kenkre int ret, try_idmap; 4012b4a7802SBaban Kenkre nss_status_t stat; 4022b4a7802SBaban Kenkre 4032b4a7802SBaban Kenkre be->db_type = NSS_AD_DB_PASSWD_BYUID; 4042b4a7802SBaban Kenkre 4052b4a7802SBaban Kenkre stat = (nss_status_t)NSS_NOTFOUND; 4062b4a7802SBaban Kenkre 4072b4a7802SBaban Kenkre /* nss_ad does not support non ephemeral uids */ 4082b4a7802SBaban Kenkre if (argp->key.uid <= MAXUID) 4092b4a7802SBaban Kenkre goto out; 4102b4a7802SBaban Kenkre 4112b4a7802SBaban Kenkre /* Map the given UID to a SID using the idmap service */ 412*1fdeec65Sjoyce mcintosh if (idmap_get_u2w_mapping(&argp->key.uid, NULL, 0, 4132b4a7802SBaban Kenkre 1, NULL, &sidprefix, &rid, &winname, &windomain, 4142b4a7802SBaban Kenkre NULL, NULL) != 0) { 4152b4a7802SBaban Kenkre RESET_ERRNO(); 4162b4a7802SBaban Kenkre goto out; 4172b4a7802SBaban Kenkre } 4182b4a7802SBaban Kenkre 4192b4a7802SBaban Kenkre /* 4202b4a7802SBaban Kenkre * NULL winname implies a local SID or unresolvable SID both of 4212b4a7802SBaban Kenkre * which cannot be used to generated passwd(4) entry 4222b4a7802SBaban Kenkre */ 4232b4a7802SBaban Kenkre if (winname == NULL) 4242b4a7802SBaban Kenkre goto out; 4252b4a7802SBaban Kenkre 4262b4a7802SBaban Kenkre /* If this is not a Well-Known SID try AD lookup */ 4272b4a7802SBaban Kenkre if (windomain != NULL && strcasecmp(windomain, WK_DOMAIN) != 0) { 4282b4a7802SBaban Kenkre if (adutils_txtsid2hexbinsid(sidprefix, &rid, 4292b4a7802SBaban Kenkre &cbinsid[0], sizeof (cbinsid)) != 0) 4302b4a7802SBaban Kenkre goto out; 4312b4a7802SBaban Kenkre 4322b4a7802SBaban Kenkre ret = snprintf(searchfilter, sizeof (searchfilter), 4332b4a7802SBaban Kenkre _F_GETPWUID, cbinsid); 4342b4a7802SBaban Kenkre if (ret >= sizeof (searchfilter) || ret < 0) 4352b4a7802SBaban Kenkre goto out; 4362b4a7802SBaban Kenkre 4372b4a7802SBaban Kenkre stat = _nss_ad_lookup(be, argp, _PASSWD, searchfilter, 4382b4a7802SBaban Kenkre windomain, &try_idmap); 4392b4a7802SBaban Kenkre 4402b4a7802SBaban Kenkre if (!try_idmap) 4412b4a7802SBaban Kenkre goto out; 4422b4a7802SBaban Kenkre } 4432b4a7802SBaban Kenkre 4442b4a7802SBaban Kenkre /* Map winname to primary gid using idmap service */ 4452b4a7802SBaban Kenkre is_user = 0; 4462b4a7802SBaban Kenkre is_wuser = -1; 447*1fdeec65Sjoyce mcintosh idmaprc = idmap_get_w2u_mapping(NULL, NULL, 4482b4a7802SBaban Kenkre winname, windomain, 0, &is_user, &is_wuser, &gid, 4492b4a7802SBaban Kenkre NULL, NULL, NULL); 4502b4a7802SBaban Kenkre 4512b4a7802SBaban Kenkre if (idmaprc != IDMAP_SUCCESS) { 4522b4a7802SBaban Kenkre RESET_ERRNO(); 4532b4a7802SBaban Kenkre goto out; 4542b4a7802SBaban Kenkre } 4552b4a7802SBaban Kenkre 4562b4a7802SBaban Kenkre /* Create passwd(4) style string */ 4572b4a7802SBaban Kenkre if (update_buffer(be, argp, winname, windomain, 4582b4a7802SBaban Kenkre argp->key.uid, gid, "", "", "") < 0) 4592b4a7802SBaban Kenkre goto out; 4602b4a7802SBaban Kenkre 4612b4a7802SBaban Kenkre /* Marshall the data, sanitize the return status and return */ 4622b4a7802SBaban Kenkre stat = _nss_ad_marshall_data(be, argp); 4632b4a7802SBaban Kenkre stat = _nss_ad_sanitize_status(be, argp, stat); 4642b4a7802SBaban Kenkre 4652b4a7802SBaban Kenkre out: 4662b4a7802SBaban Kenkre idmap_free(sidprefix); 4672b4a7802SBaban Kenkre idmap_free(winname); 4682b4a7802SBaban Kenkre idmap_free(windomain); 4692b4a7802SBaban Kenkre return (stat); 4702b4a7802SBaban Kenkre } 4712b4a7802SBaban Kenkre 4722b4a7802SBaban Kenkre static ad_backend_op_t passwd_ops[] = { 4732b4a7802SBaban Kenkre _nss_ad_destr, 4742b4a7802SBaban Kenkre _nss_ad_endent, 4752b4a7802SBaban Kenkre _nss_ad_setent, 4762b4a7802SBaban Kenkre _nss_ad_getent, 4772b4a7802SBaban Kenkre getbyname, 4782b4a7802SBaban Kenkre getbyuid 4792b4a7802SBaban Kenkre }; 4802b4a7802SBaban Kenkre 4812b4a7802SBaban Kenkre /* 4822b4a7802SBaban Kenkre * _nss_ad_passwd_constr is where life begins. This function calls the 4832b4a7802SBaban Kenkre * generic AD constructor function to define and build the abstract 4842b4a7802SBaban Kenkre * data types required to support AD operations. 4852b4a7802SBaban Kenkre */ 4862b4a7802SBaban Kenkre 4872b4a7802SBaban Kenkre /*ARGSUSED0*/ 4882b4a7802SBaban Kenkre nss_backend_t * 4892b4a7802SBaban Kenkre _nss_ad_passwd_constr(const char *dummy1, const char *dummy2, 4902b4a7802SBaban Kenkre const char *dummy3) 4912b4a7802SBaban Kenkre { 4922b4a7802SBaban Kenkre 4932b4a7802SBaban Kenkre return ((nss_backend_t *)_nss_ad_constr(passwd_ops, 4942b4a7802SBaban Kenkre sizeof (passwd_ops)/sizeof (passwd_ops[0]), 4952b4a7802SBaban Kenkre _PASSWD, pwd_attrs, _nss_ad_passwd2str)); 4962b4a7802SBaban Kenkre } 497