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.
23cb5caa98Sdjl  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  *
257c478bd9Sstevel@tonic-gate  *	nis/getpwnam.c -- "nis" backend for nsswitch "passwd" database
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <pwd.h>
297c478bd9Sstevel@tonic-gate #include "nis_common.h"
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate static nss_status_t
getbyname(be,a)327c478bd9Sstevel@tonic-gate getbyname(be, a)
337c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
347c478bd9Sstevel@tonic-gate 	void			*a;
357c478bd9Sstevel@tonic-gate {
36cb5caa98Sdjl 	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *)a;
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate 	return (_nss_nis_lookup(be, argp, 0,
397c478bd9Sstevel@tonic-gate 				"passwd.byname", argp->key.name, 0));
407c478bd9Sstevel@tonic-gate }
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate static nss_status_t
getbyuid(be,a)437c478bd9Sstevel@tonic-gate getbyuid(be, a)
447c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
457c478bd9Sstevel@tonic-gate 	void			*a;
467c478bd9Sstevel@tonic-gate {
47cb5caa98Sdjl 	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *)a;
487c478bd9Sstevel@tonic-gate 	char			uidstr[12];	/* More than enough */
497c478bd9Sstevel@tonic-gate 
50*2b4a7802SBaban Kenkre 	if (argp->key.uid > MAXUID)
51*2b4a7802SBaban Kenkre 		return (NSS_NOTFOUND);
52*2b4a7802SBaban Kenkre 	(void) snprintf(uidstr, 12, "%u", argp->key.uid);
537c478bd9Sstevel@tonic-gate 	return (_nss_nis_lookup(be, argp, 0, "passwd.byuid", uidstr, 0));
547c478bd9Sstevel@tonic-gate }
557c478bd9Sstevel@tonic-gate 
56*2b4a7802SBaban Kenkre /*
57*2b4a7802SBaban Kenkre  * Validates passwd entry replacing uid/gid > MAXUID by ID_NOBODY.
58*2b4a7802SBaban Kenkre  */
59*2b4a7802SBaban Kenkre int
validate_passwd_ids(char ** linepp,int * linelenp,int allocbuf)60*2b4a7802SBaban Kenkre validate_passwd_ids(char **linepp, int *linelenp, int allocbuf)
61*2b4a7802SBaban Kenkre {
62*2b4a7802SBaban Kenkre 	char	*linep, *limit, *uidp, *gidp, *newline;
63*2b4a7802SBaban Kenkre 	uid_t	uid;
64*2b4a7802SBaban Kenkre 	gid_t	gid;
65*2b4a7802SBaban Kenkre 	ulong_t	uidl, gidl;
66*2b4a7802SBaban Kenkre 	int	olduidlen, oldgidlen, idlen;
67*2b4a7802SBaban Kenkre 	int	linelen = *linelenp, newlinelen;
68*2b4a7802SBaban Kenkre 
69*2b4a7802SBaban Kenkre 	linep = *linepp;
70*2b4a7802SBaban Kenkre 	limit = linep + linelen;
71*2b4a7802SBaban Kenkre 
72*2b4a7802SBaban Kenkre 	/* +/- entries valid for compat source only */
73*2b4a7802SBaban Kenkre 	if (linelen == 0 || *linep == '+' || *linep == '-')
74*2b4a7802SBaban Kenkre 		return (NSS_STR_PARSE_SUCCESS);
75*2b4a7802SBaban Kenkre 
76*2b4a7802SBaban Kenkre 	while (linep < limit && *linep++ != ':') /* skip username */
77*2b4a7802SBaban Kenkre 		continue;
78*2b4a7802SBaban Kenkre 	while (linep < limit && *linep++ != ':') /* skip password */
79*2b4a7802SBaban Kenkre 		continue;
80*2b4a7802SBaban Kenkre 	if (linep == limit)
81*2b4a7802SBaban Kenkre 		return (NSS_STR_PARSE_PARSE);
82*2b4a7802SBaban Kenkre 
83*2b4a7802SBaban Kenkre 	uidp = linep;
84*2b4a7802SBaban Kenkre 	uidl = strtoul(uidp, (char **)&linep, 10); /* grab uid */
85*2b4a7802SBaban Kenkre 	olduidlen = linep - uidp;
86*2b4a7802SBaban Kenkre 	if (++linep >= limit || olduidlen == 0)
87*2b4a7802SBaban Kenkre 		return (NSS_STR_PARSE_PARSE);
88*2b4a7802SBaban Kenkre 
89*2b4a7802SBaban Kenkre 	gidp = linep;
90*2b4a7802SBaban Kenkre 	gidl = strtoul(gidp, (char **)&linep, 10); /* grab gid */
91*2b4a7802SBaban Kenkre 	oldgidlen = linep - gidp;
92*2b4a7802SBaban Kenkre 	if (linep >= limit || oldgidlen == 0)
93*2b4a7802SBaban Kenkre 		return (NSS_STR_PARSE_PARSE);
94*2b4a7802SBaban Kenkre 
95*2b4a7802SBaban Kenkre 	if (uidl <= MAXUID && gidl <= MAXUID)
96*2b4a7802SBaban Kenkre 		return (NSS_STR_PARSE_SUCCESS);
97*2b4a7802SBaban Kenkre 	uid = (uidl > MAXUID) ? UID_NOBODY : (uid_t)uidl;
98*2b4a7802SBaban Kenkre 	gid = (gidl > MAXUID) ? GID_NOBODY : (gid_t)gidl;
99*2b4a7802SBaban Kenkre 
100*2b4a7802SBaban Kenkre 	/* Check if we have enough space in the buffer */
101*2b4a7802SBaban Kenkre 	idlen = snprintf(NULL, 0, "%u:%u", uid, gid);
102*2b4a7802SBaban Kenkre 	newlinelen = linelen + idlen - olduidlen - oldgidlen - 1;
103*2b4a7802SBaban Kenkre 	if (newlinelen > linelen) {
104*2b4a7802SBaban Kenkre 		/* need a larger buffer */
105*2b4a7802SBaban Kenkre 		if (!allocbuf || (newline = malloc(newlinelen + 1)) == NULL)
106*2b4a7802SBaban Kenkre 			return (NSS_STR_PARSE_ERANGE);
107*2b4a7802SBaban Kenkre 		/* Replace ephemeral ids by ID_NOBODY in the new buffer */
108*2b4a7802SBaban Kenkre 		*(uidp - 1) = '\0';
109*2b4a7802SBaban Kenkre 		(void) snprintf(newline, newlinelen + 1, "%s:%u:%u%s",
110*2b4a7802SBaban Kenkre 		    *linepp, uid, gid, linep);
111*2b4a7802SBaban Kenkre 		free(*linepp);
112*2b4a7802SBaban Kenkre 		*linepp = newline;
113*2b4a7802SBaban Kenkre 		*linelenp = newlinelen;
114*2b4a7802SBaban Kenkre 		return (NSS_STR_PARSE_SUCCESS);
115*2b4a7802SBaban Kenkre 	}
116*2b4a7802SBaban Kenkre 
117*2b4a7802SBaban Kenkre 	/* Replace ephemeral ids by ID_NOBODY in the same buffer */
118*2b4a7802SBaban Kenkre 	(void) bcopy(linep, uidp + idlen, limit - linep + 1);
119*2b4a7802SBaban Kenkre 	(void) snprintf(uidp, idlen + 1, "%u:%u", uid, gid);
120*2b4a7802SBaban Kenkre 	*(uidp + idlen) = ':'; /* restore : that was overwritten by snprintf */
121*2b4a7802SBaban Kenkre 	*linelenp = newlinelen;
122*2b4a7802SBaban Kenkre 	return (NSS_STR_PARSE_SUCCESS);
123*2b4a7802SBaban Kenkre }
124*2b4a7802SBaban Kenkre 
1257c478bd9Sstevel@tonic-gate static nis_backend_op_t passwd_ops[] = {
1267c478bd9Sstevel@tonic-gate 	_nss_nis_destr,
1277c478bd9Sstevel@tonic-gate 	_nss_nis_endent,
1287c478bd9Sstevel@tonic-gate 	_nss_nis_setent,
1297c478bd9Sstevel@tonic-gate 	_nss_nis_getent_rigid,
1307c478bd9Sstevel@tonic-gate 	getbyname,
1317c478bd9Sstevel@tonic-gate 	getbyuid
1327c478bd9Sstevel@tonic-gate };
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1357c478bd9Sstevel@tonic-gate nss_backend_t *
_nss_nis_passwd_constr(dummy1,dummy2,dummy3)1367c478bd9Sstevel@tonic-gate _nss_nis_passwd_constr(dummy1, dummy2, dummy3)
1377c478bd9Sstevel@tonic-gate 	const char	*dummy1, *dummy2, dummy3;
1387c478bd9Sstevel@tonic-gate {
1397c478bd9Sstevel@tonic-gate 	return (_nss_nis_constr(passwd_ops,
1407c478bd9Sstevel@tonic-gate 				sizeof (passwd_ops) / sizeof (passwd_ops[0]),
1417c478bd9Sstevel@tonic-gate 				"passwd.byname"));
1427c478bd9Sstevel@tonic-gate }
143