10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 52830Sdjl * Common Development and Distribution License (the "License"). 62830Sdjl * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*8040SBaban.Kenkre@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #include <pwd.h> 270Sstevel@tonic-gate #include "ldap_common.h" 280Sstevel@tonic-gate 290Sstevel@tonic-gate /* passwd attributes filters */ 300Sstevel@tonic-gate #define _PWD_CN "cn" 310Sstevel@tonic-gate #define _PWD_UID "uid" 320Sstevel@tonic-gate #define _PWD_USERPASSWORD "userpassword" 330Sstevel@tonic-gate #define _PWD_UIDNUMBER "uidnumber" 340Sstevel@tonic-gate #define _PWD_GIDNUMBER "gidnumber" 350Sstevel@tonic-gate #define _PWD_GECOS "gecos" 360Sstevel@tonic-gate #define _PWD_DESCRIPTION "description" 370Sstevel@tonic-gate #define _PWD_HOMEDIRECTORY "homedirectory" 380Sstevel@tonic-gate #define _PWD_LOGINSHELL "loginshell" 390Sstevel@tonic-gate 400Sstevel@tonic-gate 410Sstevel@tonic-gate #define _F_GETPWNAM "(&(objectClass=posixAccount)(uid=%s))" 420Sstevel@tonic-gate #define _F_GETPWNAM_SSD "(&(%%s)(uid=%s))" 430Sstevel@tonic-gate #define _F_GETPWUID "(&(objectClass=posixAccount)(uidNumber=%ld))" 440Sstevel@tonic-gate #define _F_GETPWUID_SSD "(&(%%s)(uidNumber=%ld))" 450Sstevel@tonic-gate 460Sstevel@tonic-gate static const char *pwd_attrs[] = { 470Sstevel@tonic-gate _PWD_CN, 480Sstevel@tonic-gate _PWD_UID, 490Sstevel@tonic-gate _PWD_UIDNUMBER, 500Sstevel@tonic-gate _PWD_GIDNUMBER, 510Sstevel@tonic-gate _PWD_GECOS, 520Sstevel@tonic-gate _PWD_DESCRIPTION, 530Sstevel@tonic-gate _PWD_HOMEDIRECTORY, 540Sstevel@tonic-gate _PWD_LOGINSHELL, 550Sstevel@tonic-gate (char *)NULL 560Sstevel@tonic-gate }; 570Sstevel@tonic-gate 580Sstevel@tonic-gate /* 592830Sdjl * _nss_ldap_passwd2str is the data marshaling method for the passwd getXbyY 600Sstevel@tonic-gate * (e.g., getbyuid(), getbyname(), getpwent()) backend processes. This method is 610Sstevel@tonic-gate * called after a successful ldap search has been performed. This method will 622830Sdjl * parse the ldap search values into the file format. 632830Sdjl * e.g. 642830Sdjl * 652830Sdjl * nobody:x:60001:60001:Nobody:/: 662830Sdjl * 670Sstevel@tonic-gate */ 680Sstevel@tonic-gate static int 692830Sdjl _nss_ldap_passwd2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) 700Sstevel@tonic-gate { 710Sstevel@tonic-gate int nss_result; 722830Sdjl int buflen = 0; 732830Sdjl unsigned long str_len = 0L; 742830Sdjl char *buffer = NULL; 750Sstevel@tonic-gate ns_ldap_result_t *result = be->result; 762830Sdjl ns_ldap_entry_t *entry; 772830Sdjl char **uid_v, **uidn_v, **gidn_v; 782830Sdjl char **gecos_v, **homedir_v, **shell_v; 792830Sdjl char *NULL_STR = ""; 80*8040SBaban.Kenkre@Sun.COM char uid_nobody[NOBODY_STR_LEN]; 81*8040SBaban.Kenkre@Sun.COM char gid_nobody[NOBODY_STR_LEN], *end; 82*8040SBaban.Kenkre@Sun.COM char *uid_nobody_v[1], *gid_nobody_v[1]; 83*8040SBaban.Kenkre@Sun.COM 84*8040SBaban.Kenkre@Sun.COM (void) snprintf(uid_nobody, sizeof (uid_nobody), "%u", UID_NOBODY); 85*8040SBaban.Kenkre@Sun.COM uid_nobody_v[0] = uid_nobody; 86*8040SBaban.Kenkre@Sun.COM (void) snprintf(gid_nobody, sizeof (gid_nobody), "%u", GID_NOBODY); 87*8040SBaban.Kenkre@Sun.COM gid_nobody_v[0] = gid_nobody; 880Sstevel@tonic-gate 892830Sdjl if (result == NULL) 902830Sdjl return (NSS_STR_PARSE_PARSE); 910Sstevel@tonic-gate 922830Sdjl entry = result->entry; 932830Sdjl 942830Sdjl buflen = argp->buf.buflen; 950Sstevel@tonic-gate buffer = argp->buf.buffer; 960Sstevel@tonic-gate 972830Sdjl nss_result = NSS_STR_PARSE_SUCCESS; 980Sstevel@tonic-gate (void) memset(buffer, 0, buflen); 990Sstevel@tonic-gate 1002830Sdjl /* 8 = 6 ':' + 1 '\0' + 1 'x' */ 1012830Sdjl buflen -= 8; 1020Sstevel@tonic-gate 1032830Sdjl uid_v = __ns_ldap_getAttr(entry, _PWD_UID); 1042830Sdjl uidn_v = __ns_ldap_getAttr(entry, _PWD_UIDNUMBER); 1052830Sdjl gidn_v = __ns_ldap_getAttr(entry, _PWD_GIDNUMBER); 1062830Sdjl if (uid_v == NULL || uidn_v == NULL || gidn_v == NULL || 107*8040SBaban.Kenkre@Sun.COM uid_v[0] == NULL || uidn_v[0] == NULL || gidn_v[0] == NULL) { 1082830Sdjl nss_result = NSS_STR_PARSE_PARSE; 1092830Sdjl goto result_pwd2str; 1102830Sdjl } 111*8040SBaban.Kenkre@Sun.COM /* Validate UID and GID */ 112*8040SBaban.Kenkre@Sun.COM if (strtoul(uidn_v[0], &end, 10) > MAXUID) 113*8040SBaban.Kenkre@Sun.COM uidn_v = uid_nobody_v; 114*8040SBaban.Kenkre@Sun.COM if (strtoul(gidn_v[0], &end, 10) > MAXUID) 115*8040SBaban.Kenkre@Sun.COM gidn_v = gid_nobody_v; 1162830Sdjl str_len = strlen(uid_v[0]) + strlen(uidn_v[0]) + strlen(gidn_v[0]); 1172830Sdjl if (str_len > buflen) { 1182830Sdjl nss_result = NSS_STR_PARSE_ERANGE; 1192830Sdjl goto result_pwd2str; 1200Sstevel@tonic-gate } 1210Sstevel@tonic-gate 1222830Sdjl gecos_v = __ns_ldap_getAttr(entry, _PWD_GECOS); 1232830Sdjl if (gecos_v == NULL || gecos_v[0] == NULL || *gecos_v[0] == '\0') 1242830Sdjl gecos_v = &NULL_STR; 1252830Sdjl else 1262830Sdjl str_len += strlen(gecos_v[0]); 1270Sstevel@tonic-gate 1282830Sdjl homedir_v = __ns_ldap_getAttr(entry, _PWD_HOMEDIRECTORY); 1292830Sdjl if (homedir_v == NULL || homedir_v[0] == NULL || *homedir_v[0] == '\0') 1302830Sdjl homedir_v = &NULL_STR; 1312830Sdjl else 1322830Sdjl str_len += strlen(homedir_v[0]); 1332830Sdjl 1342830Sdjl shell_v = __ns_ldap_getAttr(entry, _PWD_LOGINSHELL); 1352830Sdjl if (shell_v == NULL || shell_v[0] == NULL || *shell_v[0] == '\0') 1362830Sdjl shell_v = &NULL_STR; 1372830Sdjl else 1382830Sdjl str_len += strlen(shell_v[0]); 1392830Sdjl 1402830Sdjl if (str_len > buflen) { 1412830Sdjl nss_result = NSS_STR_PARSE_ERANGE; 1422830Sdjl goto result_pwd2str; 1430Sstevel@tonic-gate } 1440Sstevel@tonic-gate 1452830Sdjl if (argp->buf.result != NULL) { 1462830Sdjl be->buflen = str_len + 8; 1472830Sdjl be->buffer = malloc(be->buflen); 1482830Sdjl if (be->buffer == NULL) { 1492830Sdjl nss_result = (int)NSS_STR_PARSE_ERANGE; 1502830Sdjl goto result_pwd2str; 1512830Sdjl } 1522830Sdjl 1532830Sdjl (void) snprintf(be->buffer, be->buflen, 154*8040SBaban.Kenkre@Sun.COM "%s:%s:%s:%s:%s:%s:%s", 155*8040SBaban.Kenkre@Sun.COM uid_v[0], "x", uidn_v[0], gidn_v[0], 156*8040SBaban.Kenkre@Sun.COM gecos_v[0], homedir_v[0], shell_v[0]); 1572830Sdjl } else { 1582830Sdjl (void) snprintf(argp->buf.buffer, (str_len + 8), 159*8040SBaban.Kenkre@Sun.COM "%s:%s:%s:%s:%s:%s:%s", 160*8040SBaban.Kenkre@Sun.COM uid_v[0], "x", uidn_v[0], gidn_v[0], 161*8040SBaban.Kenkre@Sun.COM gecos_v[0], homedir_v[0], shell_v[0]); 1620Sstevel@tonic-gate } 1630Sstevel@tonic-gate 1642830Sdjl result_pwd2str: 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 1670Sstevel@tonic-gate return ((int)nss_result); 1680Sstevel@tonic-gate } 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate /* 1710Sstevel@tonic-gate * getbyname gets a passwd entry by uid name. This function constructs an ldap 1720Sstevel@tonic-gate * search filter using the name invocation parameter and the getpwnam search 1730Sstevel@tonic-gate * filter defined. Once the filter is constructed, we search for a matching 1740Sstevel@tonic-gate * entry and marshal the data results into struct passwd for the frontend 1750Sstevel@tonic-gate * process. The function _nss_ldap_passwd2ent performs the data marshaling. 1760Sstevel@tonic-gate */ 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate static nss_status_t 1790Sstevel@tonic-gate getbyname(ldap_backend_ptr be, void *a) 1800Sstevel@tonic-gate { 1810Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 1820Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 1830Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 1840Sstevel@tonic-gate char name[SEARCHFILTERLEN]; 1850Sstevel@tonic-gate int ret; 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0) 1880Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETPWNAM, name); 1910Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 1920Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate ret = snprintf(userdata, sizeof (userdata), _F_GETPWNAM_SSD, name); 1950Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 1960Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate return ((nss_status_t)_nss_ldap_lookup(be, argp, 199*8040SBaban.Kenkre@Sun.COM _PASSWD, searchfilter, NULL, _merge_SSD_filter, userdata)); 2000Sstevel@tonic-gate } 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate 2030Sstevel@tonic-gate /* 2040Sstevel@tonic-gate * getbyuid gets a passwd entry by uid number. This function constructs an ldap 2050Sstevel@tonic-gate * search filter using the uid invocation parameter and the getpwuid search 2060Sstevel@tonic-gate * filter defined. Once the filter is constructed, we search for a matching 2070Sstevel@tonic-gate * entry and marshal the data results into struct passwd for the frontend 2080Sstevel@tonic-gate * process. The function _nss_ldap_passwd2ent performs the data marshaling. 2090Sstevel@tonic-gate */ 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate static nss_status_t 2120Sstevel@tonic-gate getbyuid(ldap_backend_ptr be, void *a) 2130Sstevel@tonic-gate { 2140Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 2150Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 2160Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 2170Sstevel@tonic-gate int ret; 2180Sstevel@tonic-gate 219*8040SBaban.Kenkre@Sun.COM if (argp->key.uid > MAXUID) 220*8040SBaban.Kenkre@Sun.COM return ((nss_status_t)NSS_NOTFOUND); 221*8040SBaban.Kenkre@Sun.COM 2220Sstevel@tonic-gate ret = snprintf(searchfilter, sizeof (searchfilter), 2230Sstevel@tonic-gate _F_GETPWUID, (long)argp->key.uid); 2240Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 2250Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate ret = snprintf(userdata, sizeof (userdata), 2280Sstevel@tonic-gate _F_GETPWUID_SSD, (long)argp->key.uid); 2290Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 2300Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate return ((nss_status_t)_nss_ldap_lookup(be, argp, 233*8040SBaban.Kenkre@Sun.COM _PASSWD, searchfilter, NULL, _merge_SSD_filter, userdata)); 2340Sstevel@tonic-gate } 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate static ldap_backend_op_t passwd_ops[] = { 2370Sstevel@tonic-gate _nss_ldap_destr, 2380Sstevel@tonic-gate _nss_ldap_endent, 2390Sstevel@tonic-gate _nss_ldap_setent, 2400Sstevel@tonic-gate _nss_ldap_getent, 2410Sstevel@tonic-gate getbyname, 2420Sstevel@tonic-gate getbyuid 2430Sstevel@tonic-gate }; 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate /* 2470Sstevel@tonic-gate * _nss_ldap_passwd_constr is where life begins. This function calls the 2480Sstevel@tonic-gate * generic ldap constructor function to define and build the abstract 2490Sstevel@tonic-gate * data types required to support ldap operations. 2500Sstevel@tonic-gate */ 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate /*ARGSUSED0*/ 2530Sstevel@tonic-gate nss_backend_t * 2540Sstevel@tonic-gate _nss_ldap_passwd_constr(const char *dummy1, const char *dummy2, 2550Sstevel@tonic-gate const char *dummy3) 2560Sstevel@tonic-gate { 2570Sstevel@tonic-gate 2580Sstevel@tonic-gate return ((nss_backend_t *)_nss_ldap_constr(passwd_ops, 259*8040SBaban.Kenkre@Sun.COM sizeof (passwd_ops)/sizeof (passwd_ops[0]), 260*8040SBaban.Kenkre@Sun.COM _PASSWD, pwd_attrs, _nss_ldap_passwd2str)); 2610Sstevel@tonic-gate } 262