xref: /titanic_51/usr/src/lib/nsswitch/ldap/common/getpwnam.c (revision 2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1f)
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 /*
22*2b4a7802SBaban Kenkre  * 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 <pwd.h>
277c478bd9Sstevel@tonic-gate #include "ldap_common.h"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /* passwd attributes filters */
307c478bd9Sstevel@tonic-gate #define	_PWD_CN			"cn"
317c478bd9Sstevel@tonic-gate #define	_PWD_UID		"uid"
327c478bd9Sstevel@tonic-gate #define	_PWD_USERPASSWORD	"userpassword"
337c478bd9Sstevel@tonic-gate #define	_PWD_UIDNUMBER		"uidnumber"
347c478bd9Sstevel@tonic-gate #define	_PWD_GIDNUMBER		"gidnumber"
357c478bd9Sstevel@tonic-gate #define	_PWD_GECOS		"gecos"
367c478bd9Sstevel@tonic-gate #define	_PWD_DESCRIPTION	"description"
377c478bd9Sstevel@tonic-gate #define	_PWD_HOMEDIRECTORY	"homedirectory"
387c478bd9Sstevel@tonic-gate #define	_PWD_LOGINSHELL		"loginshell"
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #define	_F_GETPWNAM		"(&(objectClass=posixAccount)(uid=%s))"
427c478bd9Sstevel@tonic-gate #define	_F_GETPWNAM_SSD		"(&(%%s)(uid=%s))"
437c478bd9Sstevel@tonic-gate #define	_F_GETPWUID		"(&(objectClass=posixAccount)(uidNumber=%ld))"
447c478bd9Sstevel@tonic-gate #define	_F_GETPWUID_SSD		"(&(%%s)(uidNumber=%ld))"
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate static const char *pwd_attrs[] = {
477c478bd9Sstevel@tonic-gate 	_PWD_CN,
487c478bd9Sstevel@tonic-gate 	_PWD_UID,
497c478bd9Sstevel@tonic-gate 	_PWD_UIDNUMBER,
507c478bd9Sstevel@tonic-gate 	_PWD_GIDNUMBER,
517c478bd9Sstevel@tonic-gate 	_PWD_GECOS,
527c478bd9Sstevel@tonic-gate 	_PWD_DESCRIPTION,
537c478bd9Sstevel@tonic-gate 	_PWD_HOMEDIRECTORY,
547c478bd9Sstevel@tonic-gate 	_PWD_LOGINSHELL,
557c478bd9Sstevel@tonic-gate 	(char *)NULL
567c478bd9Sstevel@tonic-gate };
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate /*
59cb5caa98Sdjl  * _nss_ldap_passwd2str is the data marshaling method for the passwd getXbyY
607c478bd9Sstevel@tonic-gate  * (e.g., getbyuid(), getbyname(), getpwent()) backend processes. This method is
617c478bd9Sstevel@tonic-gate  * called after a successful ldap search has been performed. This method will
62cb5caa98Sdjl  * parse the ldap search values into the file format.
63cb5caa98Sdjl  * e.g.
64cb5caa98Sdjl  *
65cb5caa98Sdjl  * nobody:x:60001:60001:Nobody:/:
66cb5caa98Sdjl  *
677c478bd9Sstevel@tonic-gate  */
687c478bd9Sstevel@tonic-gate static int
69cb5caa98Sdjl _nss_ldap_passwd2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
707c478bd9Sstevel@tonic-gate {
717c478bd9Sstevel@tonic-gate 	int		nss_result;
72cb5caa98Sdjl 	int		buflen = 0;
73cb5caa98Sdjl 	unsigned long	str_len = 0L;
74cb5caa98Sdjl 	char		*buffer = NULL;
757c478bd9Sstevel@tonic-gate 	ns_ldap_result_t	*result = be->result;
76cb5caa98Sdjl 	ns_ldap_entry_t	*entry;
77cb5caa98Sdjl 	char		**uid_v, **uidn_v, **gidn_v;
78cb5caa98Sdjl 	char		**gecos_v, **homedir_v, **shell_v;
79cb5caa98Sdjl 	char		*NULL_STR = "";
80*2b4a7802SBaban Kenkre 	char		uid_nobody[NOBODY_STR_LEN];
81*2b4a7802SBaban Kenkre 	char		gid_nobody[NOBODY_STR_LEN], *end;
82*2b4a7802SBaban Kenkre 	char		*uid_nobody_v[1], *gid_nobody_v[1];
83*2b4a7802SBaban Kenkre 
84*2b4a7802SBaban Kenkre 	(void) snprintf(uid_nobody, sizeof (uid_nobody), "%u", UID_NOBODY);
85*2b4a7802SBaban Kenkre 	uid_nobody_v[0] = uid_nobody;
86*2b4a7802SBaban Kenkre 	(void) snprintf(gid_nobody, sizeof (gid_nobody), "%u", GID_NOBODY);
87*2b4a7802SBaban Kenkre 	gid_nobody_v[0] = gid_nobody;
887c478bd9Sstevel@tonic-gate 
89cb5caa98Sdjl 	if (result == NULL)
90cb5caa98Sdjl 		return (NSS_STR_PARSE_PARSE);
917c478bd9Sstevel@tonic-gate 
92cb5caa98Sdjl 	entry = result->entry;
93cb5caa98Sdjl 
94cb5caa98Sdjl 	buflen = argp->buf.buflen;
957c478bd9Sstevel@tonic-gate 	buffer = argp->buf.buffer;
967c478bd9Sstevel@tonic-gate 
97cb5caa98Sdjl 	nss_result = NSS_STR_PARSE_SUCCESS;
987c478bd9Sstevel@tonic-gate 	(void) memset(buffer, 0, buflen);
997c478bd9Sstevel@tonic-gate 
100cb5caa98Sdjl 	/* 8 = 6 ':' + 1 '\0' + 1 'x' */
101cb5caa98Sdjl 	buflen -=  8;
1027c478bd9Sstevel@tonic-gate 
103cb5caa98Sdjl 	uid_v = __ns_ldap_getAttr(entry, _PWD_UID);
104cb5caa98Sdjl 	uidn_v = __ns_ldap_getAttr(entry, _PWD_UIDNUMBER);
105cb5caa98Sdjl 	gidn_v = __ns_ldap_getAttr(entry, _PWD_GIDNUMBER);
106cb5caa98Sdjl 	if (uid_v == NULL || uidn_v == NULL || gidn_v == NULL ||
107cb5caa98Sdjl 	    uid_v[0] == NULL || uidn_v[0] == NULL || gidn_v[0] == NULL) {
108cb5caa98Sdjl 		nss_result = NSS_STR_PARSE_PARSE;
109cb5caa98Sdjl 		goto result_pwd2str;
110cb5caa98Sdjl 	}
111*2b4a7802SBaban Kenkre 	/* Validate UID and GID */
112*2b4a7802SBaban Kenkre 	if (strtoul(uidn_v[0], &end, 10) > MAXUID)
113*2b4a7802SBaban Kenkre 		uidn_v = uid_nobody_v;
114*2b4a7802SBaban Kenkre 	if (strtoul(gidn_v[0], &end, 10) > MAXUID)
115*2b4a7802SBaban Kenkre 		gidn_v = gid_nobody_v;
116cb5caa98Sdjl 	str_len = strlen(uid_v[0]) + strlen(uidn_v[0]) + strlen(gidn_v[0]);
117cb5caa98Sdjl 	if (str_len >  buflen) {
118cb5caa98Sdjl 		nss_result = NSS_STR_PARSE_ERANGE;
119cb5caa98Sdjl 		goto result_pwd2str;
1207c478bd9Sstevel@tonic-gate 	}
1217c478bd9Sstevel@tonic-gate 
122cb5caa98Sdjl 	gecos_v = __ns_ldap_getAttr(entry, _PWD_GECOS);
123cb5caa98Sdjl 	if (gecos_v == NULL || gecos_v[0] == NULL || *gecos_v[0] == '\0')
124cb5caa98Sdjl 		gecos_v = &NULL_STR;
125cb5caa98Sdjl 	else
126cb5caa98Sdjl 		str_len += strlen(gecos_v[0]);
1277c478bd9Sstevel@tonic-gate 
128cb5caa98Sdjl 	homedir_v = __ns_ldap_getAttr(entry, _PWD_HOMEDIRECTORY);
129cb5caa98Sdjl 	if (homedir_v == NULL || homedir_v[0] == NULL || *homedir_v[0] == '\0')
130cb5caa98Sdjl 		homedir_v = &NULL_STR;
131cb5caa98Sdjl 	else
132cb5caa98Sdjl 		str_len += strlen(homedir_v[0]);
133cb5caa98Sdjl 
134cb5caa98Sdjl 	shell_v = __ns_ldap_getAttr(entry, _PWD_LOGINSHELL);
135cb5caa98Sdjl 	if (shell_v == NULL || shell_v[0] == NULL || *shell_v[0] == '\0')
136cb5caa98Sdjl 		shell_v = &NULL_STR;
137cb5caa98Sdjl 	else
138cb5caa98Sdjl 		str_len += strlen(shell_v[0]);
139cb5caa98Sdjl 
140cb5caa98Sdjl 	if (str_len >  buflen) {
141cb5caa98Sdjl 		nss_result = NSS_STR_PARSE_ERANGE;
142cb5caa98Sdjl 		goto result_pwd2str;
1437c478bd9Sstevel@tonic-gate 	}
144cb5caa98Sdjl 
145cb5caa98Sdjl 	if (argp->buf.result != NULL) {
146cb5caa98Sdjl 		be->buflen = str_len + 8;
147cb5caa98Sdjl 		be->buffer = malloc(be->buflen);
148cb5caa98Sdjl 		if (be->buffer == NULL) {
1497c478bd9Sstevel@tonic-gate 			nss_result = (int)NSS_STR_PARSE_ERANGE;
150cb5caa98Sdjl 			goto result_pwd2str;
1517c478bd9Sstevel@tonic-gate 		}
152cb5caa98Sdjl 
153cb5caa98Sdjl 		(void) snprintf(be->buffer, be->buflen,
154cb5caa98Sdjl 		    "%s:%s:%s:%s:%s:%s:%s",
155cb5caa98Sdjl 		    uid_v[0], "x", uidn_v[0], gidn_v[0],
156cb5caa98Sdjl 		    gecos_v[0], homedir_v[0], shell_v[0]);
1577c478bd9Sstevel@tonic-gate 	} else {
158cb5caa98Sdjl 		(void) snprintf(argp->buf.buffer, (str_len + 8),
159cb5caa98Sdjl 		    "%s:%s:%s:%s:%s:%s:%s",
160cb5caa98Sdjl 		    uid_v[0], "x", uidn_v[0], gidn_v[0],
161cb5caa98Sdjl 		    gecos_v[0], homedir_v[0], shell_v[0]);
1627c478bd9Sstevel@tonic-gate 	}
1637c478bd9Sstevel@tonic-gate 
164cb5caa98Sdjl result_pwd2str:
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 	(void) __ns_ldap_freeResult(&be->result);
1677c478bd9Sstevel@tonic-gate 	return ((int)nss_result);
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate /*
1717c478bd9Sstevel@tonic-gate  * getbyname gets a passwd entry by uid name. This function constructs an ldap
1727c478bd9Sstevel@tonic-gate  * search filter using the name invocation parameter and the getpwnam search
1737c478bd9Sstevel@tonic-gate  * filter defined. Once the filter is constructed, we search for a matching
1747c478bd9Sstevel@tonic-gate  * entry and marshal the data results into struct passwd for the frontend
1757c478bd9Sstevel@tonic-gate  * process. The function _nss_ldap_passwd2ent performs the data marshaling.
1767c478bd9Sstevel@tonic-gate  */
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate static nss_status_t
1797c478bd9Sstevel@tonic-gate getbyname(ldap_backend_ptr be, void *a)
1807c478bd9Sstevel@tonic-gate {
1817c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
1827c478bd9Sstevel@tonic-gate 	char		searchfilter[SEARCHFILTERLEN];
1837c478bd9Sstevel@tonic-gate 	char		userdata[SEARCHFILTERLEN];
1847c478bd9Sstevel@tonic-gate 	char		name[SEARCHFILTERLEN];
1857c478bd9Sstevel@tonic-gate 	int		ret;
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 	if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0)
1887c478bd9Sstevel@tonic-gate 		return ((nss_status_t)NSS_NOTFOUND);
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 	ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETPWNAM, name);
1917c478bd9Sstevel@tonic-gate 	if (ret >= sizeof (searchfilter) || ret < 0)
1927c478bd9Sstevel@tonic-gate 		return ((nss_status_t)NSS_NOTFOUND);
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	ret = snprintf(userdata, sizeof (userdata), _F_GETPWNAM_SSD, name);
1957c478bd9Sstevel@tonic-gate 	if (ret >= sizeof (userdata) || ret < 0)
1967c478bd9Sstevel@tonic-gate 		return ((nss_status_t)NSS_NOTFOUND);
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 	return ((nss_status_t)_nss_ldap_lookup(be, argp,
199*2b4a7802SBaban Kenkre 	    _PASSWD, searchfilter, NULL, _merge_SSD_filter, userdata));
2007c478bd9Sstevel@tonic-gate }
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate /*
2047c478bd9Sstevel@tonic-gate  * getbyuid gets a passwd entry by uid number. This function constructs an ldap
2057c478bd9Sstevel@tonic-gate  * search filter using the uid invocation parameter and the getpwuid search
2067c478bd9Sstevel@tonic-gate  * filter defined. Once the filter is constructed, we search for a matching
2077c478bd9Sstevel@tonic-gate  * entry and marshal the data results into struct passwd for the frontend
2087c478bd9Sstevel@tonic-gate  * process. The function _nss_ldap_passwd2ent performs the data marshaling.
2097c478bd9Sstevel@tonic-gate  */
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate static nss_status_t
2127c478bd9Sstevel@tonic-gate getbyuid(ldap_backend_ptr be, void *a)
2137c478bd9Sstevel@tonic-gate {
2147c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
2157c478bd9Sstevel@tonic-gate 	char		searchfilter[SEARCHFILTERLEN];
2167c478bd9Sstevel@tonic-gate 	char		userdata[SEARCHFILTERLEN];
2177c478bd9Sstevel@tonic-gate 	int		ret;
2187c478bd9Sstevel@tonic-gate 
219*2b4a7802SBaban Kenkre 	if (argp->key.uid > MAXUID)
220*2b4a7802SBaban Kenkre 		return ((nss_status_t)NSS_NOTFOUND);
221*2b4a7802SBaban Kenkre 
2227c478bd9Sstevel@tonic-gate 	ret = snprintf(searchfilter, sizeof (searchfilter),
2237c478bd9Sstevel@tonic-gate 	    _F_GETPWUID, (long)argp->key.uid);
2247c478bd9Sstevel@tonic-gate 	if (ret >= sizeof (searchfilter) || ret < 0)
2257c478bd9Sstevel@tonic-gate 		return ((nss_status_t)NSS_NOTFOUND);
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	ret = snprintf(userdata, sizeof (userdata),
2287c478bd9Sstevel@tonic-gate 	    _F_GETPWUID_SSD, (long)argp->key.uid);
2297c478bd9Sstevel@tonic-gate 	if (ret >= sizeof (userdata) || ret < 0)
2307c478bd9Sstevel@tonic-gate 		return ((nss_status_t)NSS_NOTFOUND);
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	return ((nss_status_t)_nss_ldap_lookup(be, argp,
233*2b4a7802SBaban Kenkre 	    _PASSWD, searchfilter, NULL, _merge_SSD_filter, userdata));
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate static ldap_backend_op_t passwd_ops[] = {
2377c478bd9Sstevel@tonic-gate 	_nss_ldap_destr,
2387c478bd9Sstevel@tonic-gate 	_nss_ldap_endent,
2397c478bd9Sstevel@tonic-gate 	_nss_ldap_setent,
2407c478bd9Sstevel@tonic-gate 	_nss_ldap_getent,
2417c478bd9Sstevel@tonic-gate 	getbyname,
2427c478bd9Sstevel@tonic-gate 	getbyuid
2437c478bd9Sstevel@tonic-gate };
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate /*
2477c478bd9Sstevel@tonic-gate  * _nss_ldap_passwd_constr is where life begins. This function calls the
2487c478bd9Sstevel@tonic-gate  * generic ldap constructor function to define and build the abstract
2497c478bd9Sstevel@tonic-gate  * data types required to support ldap operations.
2507c478bd9Sstevel@tonic-gate  */
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate /*ARGSUSED0*/
2537c478bd9Sstevel@tonic-gate nss_backend_t *
2547c478bd9Sstevel@tonic-gate _nss_ldap_passwd_constr(const char *dummy1, const char *dummy2,
2557c478bd9Sstevel@tonic-gate 			const char *dummy3)
2567c478bd9Sstevel@tonic-gate {
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	return ((nss_backend_t *)_nss_ldap_constr(passwd_ops,
2597c478bd9Sstevel@tonic-gate 	    sizeof (passwd_ops)/sizeof (passwd_ops[0]),
260cb5caa98Sdjl 	    _PASSWD, pwd_attrs, _nss_ldap_passwd2str));
2617c478bd9Sstevel@tonic-gate }
262