xref: /illumos-gate/usr/src/lib/libsecdb/common/getuserattr.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 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/types.h>
30 #include <sys/mman.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <nss_dbdefs.h>
35 #include <user_attr.h>
36 #include <getxby_door.h>
37 #include <pwd.h>
38 
39 
40 /* Externs from libnsl */
41 extern userstr_t *_getusernam(const char *, userstr_t *, char *, int, int *);
42 extern userstr_t *_getuserattr(userstr_t *, char *, int, int *);
43 extern userstr_t *_fgetuserattr(FILE *, userstr_t *, char *, int);
44 extern void _setuserattr(void);
45 extern void _enduserattr(void);
46 
47 
48 static userattr_t *userstr2attr(userstr_t *);
49 static userstr_t *process_getuser(userstr_t *, char *, int, nsc_data_t *);
50 
51 
52 userattr_t *
53 getuserattr()
54 {
55 	int		err = 0;
56 	char		buf[NSS_BUFLEN_USERATTR];
57 	userstr_t	user;
58 	userstr_t	*tmp;
59 
60 	(void) memset(&user, 0, sizeof (userattr_t));
61 	tmp = _getuserattr(&user, buf, NSS_BUFLEN_USERATTR, &err);
62 	return (userstr2attr(tmp));
63 }
64 
65 
66 userattr_t *
67 fgetuserattr(FILE *f)
68 {
69 	char		buf[NSS_BUFLEN_USERATTR];
70 	userstr_t	user;
71 	userstr_t	*tmp;
72 
73 	(void) memset(&user, 0, sizeof (userattr_t));
74 	tmp = _fgetuserattr(f, &user, buf, NSS_BUFLEN_USERATTR);
75 	return (userstr2attr(tmp));
76 }
77 
78 
79 userattr_t *
80 getusernam(const char *name)
81 {
82 	int		err = 0;
83 	int		ndata;
84 	int		adata;
85 	char		buf[NSS_BUFLEN_USERATTR];
86 	userstr_t	user;
87 	union {
88 		nsc_data_t 	s_d;
89 		char		s_b[1024];
90 	} space;
91 	nsc_data_t	*sptr;
92 	userstr_t	*resptr = (userstr_t *)NULL;
93 
94 #ifdef	PIC
95 	if ((name == NULL) ||
96 	    (strlen(name) >= (sizeof (space) - sizeof (nsc_data_t)))) {
97 		errno = ERANGE;
98 		return ((userattr_t *)NULL);
99 	}
100 	ndata = sizeof (space);
101 	adata = strlen(name) + sizeof (nsc_call_t) + 1;
102 	space.s_d.nsc_call.nsc_callnumber = GETUSERNAM;
103 	(void) strcpy(space.s_d.nsc_call.nsc_u.name, name);
104 	sptr = &space.s_d;
105 
106 	switch (_nsc_trydoorcall(&sptr, &ndata, &adata)) {
107 	case SUCCESS:	/* positive cache hit */
108 		break;
109 	case NOTFOUND:	/* negative cache hit */
110 		return ((userattr_t *)NULL);
111 	default:
112 		(void) memset(&user, 0, sizeof (userattr_t));
113 		resptr = _getusernam(name, &user, buf,
114 		    NSS_BUFLEN_USERATTR, &err);
115 		return (userstr2attr(resptr));
116 	}
117 	resptr = process_getuser(&user, buf, NSS_BUFLEN_USERATTR, sptr);
118 
119 	/*
120 	 * check if doors reallocated the memory underneath us
121 	 * if they did munmap it or suffer a memory leak
122 	 */
123 	if (sptr != &space.s_d)
124 		(void) munmap((void *)sptr, ndata);
125 #else	/* !PIC */
126 	resptr = _getusernam(name, &user, buf, NSS_BUFLEN_USERATTR, &err);
127 #endif	/* PIC */
128 
129 	return (userstr2attr(resptr));
130 
131 }
132 
133 
134 userattr_t *
135 getuseruid(uid_t u)
136 {
137 	struct	passwd pwd;
138 	char	buf[NSS_BUFLEN_PASSWD];
139 
140 	if (getpwuid_r(u, &pwd, buf, NSS_BUFLEN_PASSWD) == NULL)
141 		return ((userattr_t *)NULL);
142 	return (getusernam(pwd.pw_name));
143 }
144 
145 
146 void
147 setuserattr()
148 {
149 	_setuserattr();
150 }
151 
152 
153 void
154 enduserattr()
155 {
156 	_enduserattr();
157 }
158 
159 
160 void
161 free_userattr(userattr_t *user)
162 {
163 	if (user) {
164 		free(user->name);
165 		free(user->qualifier);
166 		free(user->res1);
167 		free(user->res2);
168 		_kva_free(user->attr);
169 		free(user);
170 	}
171 }
172 
173 
174 static userattr_t *
175 userstr2attr(userstr_t *user)
176 {
177 	userattr_t *newuser;
178 
179 	if (user == NULL)
180 		return ((userattr_t *)NULL);
181 
182 	if ((newuser = (userattr_t *)malloc(sizeof (userattr_t))) == NULL)
183 		return ((userattr_t *)NULL);
184 
185 	newuser->name = _do_unescape(user->name);
186 	newuser->qualifier = _do_unescape(user->qualifier);
187 	newuser->res1 = _do_unescape(user->res1);
188 	newuser->res2 = _do_unescape(user->res2);
189 	newuser->attr = _str2kva(user->attr, KV_ASSIGN, KV_DELIMITER);
190 	return (newuser);
191 }
192 
193 
194 static userstr_t *
195 process_getuser(
196 	userstr_t *result,
197 	char *buffer,
198 	int buflen,
199 	nsc_data_t *sptr)
200 {
201 	char *fixed;
202 #ifdef	_LP64
203 	userstr_t user64;
204 
205 	fixed = (char *)(((uintptr_t)buffer + 7) & ~7);
206 #else
207 	fixed = (char *)(((uintptr_t)buffer + 3) & ~3);
208 #endif
209 	buflen -= fixed - buffer;
210 	buffer = fixed;
211 
212 	if (sptr->nsc_ret.nsc_return_code != SUCCESS)
213 		return ((userstr_t *)NULL);
214 
215 #ifdef	_LP64
216 	if (sptr->nsc_ret.nsc_bufferbytesused - (int)sizeof (userstr32_t)
217 	    > buflen)
218 #else
219 	if (sptr->nsc_ret.nsc_bufferbytesused - (int)sizeof (userstr_t)
220 	    > buflen)
221 #endif
222 	{
223 		errno = ERANGE;
224 		return ((userstr_t *)NULL);
225 	}
226 
227 #ifdef	_LP64
228 	(void) memcpy(buffer, (sptr->nsc_ret.nsc_u.buff + sizeof (userstr32_t)),
229 	    (sptr->nsc_ret.nsc_bufferbytesused - sizeof (userstr32_t)));
230 	user64.name = (char *)(sptr->nsc_ret.nsc_u.user.name +
231 	    (uintptr_t)buffer);
232 	user64.qualifier = (char *)(sptr->nsc_ret.nsc_u.user.qualifier +
233 	    (uintptr_t)buffer);
234 	user64.res1 = (char *)(sptr->nsc_ret.nsc_u.user.res1 +
235 	    (uintptr_t)buffer);
236 	user64.res2 = (char *)(sptr->nsc_ret.nsc_u.user.res2 +
237 	    (uintptr_t)buffer);
238 	user64.attr = (char *)(sptr->nsc_ret.nsc_u.user.attr +
239 	    (uintptr_t)buffer);
240 	*result = user64;
241 #else
242 	sptr->nsc_ret.nsc_u.user.name += (uintptr_t)buffer;
243 	sptr->nsc_ret.nsc_u.user.qualifier += (uintptr_t)buffer;
244 	sptr->nsc_ret.nsc_u.user.res1 += (uintptr_t)buffer;
245 	sptr->nsc_ret.nsc_u.user.res2 += (uintptr_t)buffer;
246 	sptr->nsc_ret.nsc_u.user.attr += (uintptr_t)buffer;
247 	*result = sptr->nsc_ret.nsc_u.user;
248 	(void) memcpy(buffer, (sptr->nsc_ret.nsc_u.buff + sizeof (userstr_t)),
249 	    (sptr->nsc_ret.nsc_bufferbytesused - sizeof (userstr_t)));
250 #endif
251 	return (result);
252 }
253 
254 
255 #ifdef DEBUG
256 void
257 print_userattr(userattr_t *user)
258 {
259 	extern void print_kva(kva_t *);
260 	char *empty = "empty";
261 
262 	if (user == NULL) {
263 		printf("NULL\n");
264 		return;
265 	}
266 
267 	printf("name=%s\n", user->name ? user->name : empty);
268 	printf("qualifier=%s\n", user->qualifier ? user->qualifier : empty);
269 	printf("res1=%s\n", user->res1 ? user->res1 : empty);
270 	printf("res2=%s\n", user->res2 ? user->res2 : empty);
271 	printf("attr=\n");
272 	print_kva(user->attr);
273 	fflush(stdout);
274 }
275 #endif  /* DEBUG */
276