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.
232830Sdjl * Use is subject to license terms.
240Sstevel@tonic-gate *
250Sstevel@tonic-gate * nis/getpwnam.c -- "nis" backend for nsswitch "passwd" database
260Sstevel@tonic-gate */
270Sstevel@tonic-gate
280Sstevel@tonic-gate #include <pwd.h>
290Sstevel@tonic-gate #include "nis_common.h"
300Sstevel@tonic-gate
310Sstevel@tonic-gate static nss_status_t
getbyname(be,a)320Sstevel@tonic-gate getbyname(be, a)
330Sstevel@tonic-gate nis_backend_ptr_t be;
340Sstevel@tonic-gate void *a;
350Sstevel@tonic-gate {
362830Sdjl nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
370Sstevel@tonic-gate
380Sstevel@tonic-gate return (_nss_nis_lookup(be, argp, 0,
390Sstevel@tonic-gate "passwd.byname", argp->key.name, 0));
400Sstevel@tonic-gate }
410Sstevel@tonic-gate
420Sstevel@tonic-gate static nss_status_t
getbyuid(be,a)430Sstevel@tonic-gate getbyuid(be, a)
440Sstevel@tonic-gate nis_backend_ptr_t be;
450Sstevel@tonic-gate void *a;
460Sstevel@tonic-gate {
472830Sdjl nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
480Sstevel@tonic-gate char uidstr[12]; /* More than enough */
490Sstevel@tonic-gate
50*8040SBaban.Kenkre@Sun.COM if (argp->key.uid > MAXUID)
51*8040SBaban.Kenkre@Sun.COM return (NSS_NOTFOUND);
52*8040SBaban.Kenkre@Sun.COM (void) snprintf(uidstr, 12, "%u", argp->key.uid);
530Sstevel@tonic-gate return (_nss_nis_lookup(be, argp, 0, "passwd.byuid", uidstr, 0));
540Sstevel@tonic-gate }
550Sstevel@tonic-gate
56*8040SBaban.Kenkre@Sun.COM /*
57*8040SBaban.Kenkre@Sun.COM * Validates passwd entry replacing uid/gid > MAXUID by ID_NOBODY.
58*8040SBaban.Kenkre@Sun.COM */
59*8040SBaban.Kenkre@Sun.COM int
validate_passwd_ids(char ** linepp,int * linelenp,int allocbuf)60*8040SBaban.Kenkre@Sun.COM validate_passwd_ids(char **linepp, int *linelenp, int allocbuf)
61*8040SBaban.Kenkre@Sun.COM {
62*8040SBaban.Kenkre@Sun.COM char *linep, *limit, *uidp, *gidp, *newline;
63*8040SBaban.Kenkre@Sun.COM uid_t uid;
64*8040SBaban.Kenkre@Sun.COM gid_t gid;
65*8040SBaban.Kenkre@Sun.COM ulong_t uidl, gidl;
66*8040SBaban.Kenkre@Sun.COM int olduidlen, oldgidlen, idlen;
67*8040SBaban.Kenkre@Sun.COM int linelen = *linelenp, newlinelen;
68*8040SBaban.Kenkre@Sun.COM
69*8040SBaban.Kenkre@Sun.COM linep = *linepp;
70*8040SBaban.Kenkre@Sun.COM limit = linep + linelen;
71*8040SBaban.Kenkre@Sun.COM
72*8040SBaban.Kenkre@Sun.COM /* +/- entries valid for compat source only */
73*8040SBaban.Kenkre@Sun.COM if (linelen == 0 || *linep == '+' || *linep == '-')
74*8040SBaban.Kenkre@Sun.COM return (NSS_STR_PARSE_SUCCESS);
75*8040SBaban.Kenkre@Sun.COM
76*8040SBaban.Kenkre@Sun.COM while (linep < limit && *linep++ != ':') /* skip username */
77*8040SBaban.Kenkre@Sun.COM continue;
78*8040SBaban.Kenkre@Sun.COM while (linep < limit && *linep++ != ':') /* skip password */
79*8040SBaban.Kenkre@Sun.COM continue;
80*8040SBaban.Kenkre@Sun.COM if (linep == limit)
81*8040SBaban.Kenkre@Sun.COM return (NSS_STR_PARSE_PARSE);
82*8040SBaban.Kenkre@Sun.COM
83*8040SBaban.Kenkre@Sun.COM uidp = linep;
84*8040SBaban.Kenkre@Sun.COM uidl = strtoul(uidp, (char **)&linep, 10); /* grab uid */
85*8040SBaban.Kenkre@Sun.COM olduidlen = linep - uidp;
86*8040SBaban.Kenkre@Sun.COM if (++linep >= limit || olduidlen == 0)
87*8040SBaban.Kenkre@Sun.COM return (NSS_STR_PARSE_PARSE);
88*8040SBaban.Kenkre@Sun.COM
89*8040SBaban.Kenkre@Sun.COM gidp = linep;
90*8040SBaban.Kenkre@Sun.COM gidl = strtoul(gidp, (char **)&linep, 10); /* grab gid */
91*8040SBaban.Kenkre@Sun.COM oldgidlen = linep - gidp;
92*8040SBaban.Kenkre@Sun.COM if (linep >= limit || oldgidlen == 0)
93*8040SBaban.Kenkre@Sun.COM return (NSS_STR_PARSE_PARSE);
94*8040SBaban.Kenkre@Sun.COM
95*8040SBaban.Kenkre@Sun.COM if (uidl <= MAXUID && gidl <= MAXUID)
96*8040SBaban.Kenkre@Sun.COM return (NSS_STR_PARSE_SUCCESS);
97*8040SBaban.Kenkre@Sun.COM uid = (uidl > MAXUID) ? UID_NOBODY : (uid_t)uidl;
98*8040SBaban.Kenkre@Sun.COM gid = (gidl > MAXUID) ? GID_NOBODY : (gid_t)gidl;
99*8040SBaban.Kenkre@Sun.COM
100*8040SBaban.Kenkre@Sun.COM /* Check if we have enough space in the buffer */
101*8040SBaban.Kenkre@Sun.COM idlen = snprintf(NULL, 0, "%u:%u", uid, gid);
102*8040SBaban.Kenkre@Sun.COM newlinelen = linelen + idlen - olduidlen - oldgidlen - 1;
103*8040SBaban.Kenkre@Sun.COM if (newlinelen > linelen) {
104*8040SBaban.Kenkre@Sun.COM /* need a larger buffer */
105*8040SBaban.Kenkre@Sun.COM if (!allocbuf || (newline = malloc(newlinelen + 1)) == NULL)
106*8040SBaban.Kenkre@Sun.COM return (NSS_STR_PARSE_ERANGE);
107*8040SBaban.Kenkre@Sun.COM /* Replace ephemeral ids by ID_NOBODY in the new buffer */
108*8040SBaban.Kenkre@Sun.COM *(uidp - 1) = '\0';
109*8040SBaban.Kenkre@Sun.COM (void) snprintf(newline, newlinelen + 1, "%s:%u:%u%s",
110*8040SBaban.Kenkre@Sun.COM *linepp, uid, gid, linep);
111*8040SBaban.Kenkre@Sun.COM free(*linepp);
112*8040SBaban.Kenkre@Sun.COM *linepp = newline;
113*8040SBaban.Kenkre@Sun.COM *linelenp = newlinelen;
114*8040SBaban.Kenkre@Sun.COM return (NSS_STR_PARSE_SUCCESS);
115*8040SBaban.Kenkre@Sun.COM }
116*8040SBaban.Kenkre@Sun.COM
117*8040SBaban.Kenkre@Sun.COM /* Replace ephemeral ids by ID_NOBODY in the same buffer */
118*8040SBaban.Kenkre@Sun.COM (void) bcopy(linep, uidp + idlen, limit - linep + 1);
119*8040SBaban.Kenkre@Sun.COM (void) snprintf(uidp, idlen + 1, "%u:%u", uid, gid);
120*8040SBaban.Kenkre@Sun.COM *(uidp + idlen) = ':'; /* restore : that was overwritten by snprintf */
121*8040SBaban.Kenkre@Sun.COM *linelenp = newlinelen;
122*8040SBaban.Kenkre@Sun.COM return (NSS_STR_PARSE_SUCCESS);
123*8040SBaban.Kenkre@Sun.COM }
124*8040SBaban.Kenkre@Sun.COM
1250Sstevel@tonic-gate static nis_backend_op_t passwd_ops[] = {
1260Sstevel@tonic-gate _nss_nis_destr,
1270Sstevel@tonic-gate _nss_nis_endent,
1280Sstevel@tonic-gate _nss_nis_setent,
1290Sstevel@tonic-gate _nss_nis_getent_rigid,
1300Sstevel@tonic-gate getbyname,
1310Sstevel@tonic-gate getbyuid
1320Sstevel@tonic-gate };
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate /*ARGSUSED*/
1350Sstevel@tonic-gate nss_backend_t *
_nss_nis_passwd_constr(dummy1,dummy2,dummy3)1360Sstevel@tonic-gate _nss_nis_passwd_constr(dummy1, dummy2, dummy3)
1370Sstevel@tonic-gate const char *dummy1, *dummy2, dummy3;
1380Sstevel@tonic-gate {
1390Sstevel@tonic-gate return (_nss_nis_constr(passwd_ops,
1400Sstevel@tonic-gate sizeof (passwd_ops) / sizeof (passwd_ops[0]),
1410Sstevel@tonic-gate "passwd.byname"));
1420Sstevel@tonic-gate }
143