xref: /titanic_41/usr/src/lib/nsswitch/nis/common/getspent.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  *	Copyright (c) 1988-1992 Sun Microsystems Inc
24  *	All Rights Reserved.
25  *
26  *	nis/getspent.c -- "nis" backend for nsswitch "shadow" database
27  */
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #include <shadow.h>
32 #include <string.h>
33 #include "nis_common.h"
34 
35 /*
36  * Most of the information in a struct spwd simply isn't available from the
37  * YP maps, we dummy out all the numeric fields and just get sp_namp and
38  * sp_pwdp (name and password) from the YP passwd map.  Thus we don't
39  * use the str2ent() routine that's passed to us, but instead have our
40  * own dummy routine:
41  *
42  * Return values: 0 = success, 1 = parse error, 2 = erange ...
43  * The structure pointer passed in is a structure in the caller's space
44  * wherein the field pointers would be set to areas in the buffer if
45  * need be. instring and buffer should be separate areas. Let's not
46  * fight over crumbs.
47  */
48 static int
49 nis_str2spent(instr, lenstr, ent, buffer, buflen)
50 	const char		*instr;
51 	int			lenstr;
52 	void	*ent; /* it is really (struct spwd *) */
53 	char	*buffer;
54 	int	buflen;
55 {
56 	struct spwd		*spwd	= (struct spwd *)ent;
57 	char			*p, *q;
58 
59 	/*
60 	 * We know that instr != 0 because we're in 'nis', not 'files'
61 	 */
62 	if ((p = memchr(instr, ':', lenstr)) == 0) {
63 		return (NSS_STR_PARSE_PARSE);
64 	}
65 	if ((q = memchr(p + 1, ':', lenstr - (p + 1 - instr))) == 0) {
66 		return (NSS_STR_PARSE_PARSE);
67 	}
68 	/* Don't bother checking the rest of the YP passwd entry... */
69 
70 	if (q + 1 - instr > buflen) {
71 		return (NSS_STR_PARSE_ERANGE);
72 	}
73 	memcpy(buffer, instr, q - instr);
74 	buffer[p - instr] = '\0';
75 	buffer[q - instr] = '\0';
76 
77 	spwd->sp_namp	= buffer;
78 	spwd->sp_pwdp	= buffer + (p + 1 - instr);
79 	spwd->sp_lstchg	= -1;
80 	spwd->sp_min	= -1;
81 	spwd->sp_max	= -1;
82 	spwd->sp_warn	= -1;
83 	spwd->sp_inact	= -1;
84 	spwd->sp_expire	= -1;
85 	spwd->sp_flag	= 0;
86 	return (NSS_STR_PARSE_SUCCESS);
87 }
88 
89 typedef int	(*cstr2ent_t)(const char *, int, void *, char *, int);
90 
91 static nss_status_t
92 getbyname(be, a)
93 	nis_backend_ptr_t	be;
94 	void			*a;
95 {
96 	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *) a;
97 	cstr2ent_t		save_c2e;
98 	nss_status_t		res;
99 	struct spwd 		*spwd;
100 
101 	save_c2e	= argp->str2ent;
102 	argp->str2ent	= nis_str2spent;
103 	res = _nss_nis_lookup(be, argp, 0, "passwd.byname", argp->key.name, 0);
104 	spwd = (struct spwd *)argp->buf.result;
105 	/*
106 	 * check for the C2 security flag "##" in the passwd field.
107 	 * If the first 2 chars in the passwd field is "##", get
108 	 * the user's passwd from passwd.adjunct.byname map.
109 	 * The lookup to this passwd.adjunct.byname map will only
110 	 * succeed if the caller's uid is 0 because only root user
111 	 * can use privilege port.
112 	 */
113 	if ((res == NSS_SUCCESS) && (spwd->sp_pwdp) &&
114 	    (*(spwd->sp_pwdp) == '#') && (*(spwd->sp_pwdp + 1) == '#')) {
115 		/* get password from passwd.adjunct.byname */
116 		res = _nss_nis_lookup_rsvdport(be, argp, 0,
117 						"passwd.adjunct.byname",
118 						argp->key.name, 0);
119 	}
120 
121 	argp->str2ent	= save_c2e;
122 	return (res);
123 }
124 
125 #define	NIS_SP_GETENT
126 
127 #ifdef	NIS_SP_GETENT
128 
129 static nss_status_t
130 getent(be, a)
131 	nis_backend_ptr_t	be;
132 	void			*a;
133 {
134 	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *) a;
135 	cstr2ent_t		save_c2e;
136 	nss_status_t		res;
137 	struct spwd 		*spwd;
138 
139 	save_c2e	= argp->str2ent;
140 	argp->str2ent	= nis_str2spent;
141 	res = _nss_nis_getent_rigid(be, argp);
142 	spwd = (struct spwd *)argp->buf.result;
143 	/*
144 	 * check for the C2 security flag "##" in the passwd field.
145 	 * If the first 2 chars in the passwd field is "##", get
146 	 * the user's passwd from passwd.adjunct.byname map.
147 	 * The lookup to this passwd.adjunct.byname map will only
148 	 * succeed if the caller's uid is 0 because only root user
149 	 * can use privilege port.
150 	 */
151 	if ((res == NSS_SUCCESS) && (spwd->sp_pwdp) &&
152 	    (*(spwd->sp_pwdp) == '#') && (*(spwd->sp_pwdp + 1) == '#')) {
153 		/* get password from passwd.adjunct.byname */
154 		res = _nss_nis_lookup_rsvdport(be, argp, 0,
155 					"passwd.adjunct.byname",
156 					spwd->sp_namp, 0);
157 	}
158 	argp->str2ent	= save_c2e;
159 	return (res);
160 }
161 
162 #endif	/* NIS_SP_GETENT */
163 
164 static nis_backend_op_t shadow_ops[] = {
165 	_nss_nis_destr,
166 	_nss_nis_endent,
167 	_nss_nis_setent,
168 #ifdef	NIS_SP_GETENT
169 	getent,
170 #else
171 	0,
172 #endif	/* NIS_SP_GETENT */
173 	getbyname
174 };
175 
176 nss_backend_t *
177 _nss_nis_shadow_constr(dummy1, dummy2, dummy3)
178 	const char	*dummy1, *dummy2, *dummy3;
179 {
180 	return (_nss_nis_constr(shadow_ops,
181 				sizeof (shadow_ops) / sizeof (shadow_ops[0]),
182 				"passwd.byname"));
183 }
184