xref: /illumos-gate/usr/src/lib/libsecdb/common/getexecattr.c (revision cb6207858a9fcc2feaee22e626912fba281ac969)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/types.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <nss_dbdefs.h>
33 #include <deflt.h>
34 #include <exec_attr.h>
35 #include <user_attr.h>
36 #include <auth_attr.h>
37 #include <prof_attr.h>
38 #include <getxby_door.h>
39 #include <sys/mman.h>
40 
41 
42 /* Externs from libnsl */
43 extern execstr_t *_getexecattr(execstr_t *, char *, int, int *);
44 extern void _setexecattr(void);
45 extern void _endexecattr(void);
46 extern execstr_t *_getexecprof(const char *, const char *, const char *, int,
47     execstr_t *, char *, int, int *);
48 extern userstr_t *_getusernam(const char *, userstr_t *, char *, int, int *);
49 extern userstr_t *_getuserattr(userstr_t *, char *, int, int *);
50 extern char *_strtok_escape(char *, char *, char **);
51 extern char *_strdup_null(char *);
52 
53 static execattr_t *userprof(const char *, const char *, const char *, int);
54 static execattr_t *get_tail(execattr_t *);
55 static execattr_t *execstr2attr(execstr_t *);
56 
57 execattr_t *
58 getexecattr()
59 {
60 	int		err = 0;
61 	char		buf[NSS_BUFLEN_EXECATTR];
62 	execstr_t	exec;
63 	execstr_t	*tmp;
64 
65 	tmp = _getexecattr(&exec, buf, NSS_BUFLEN_EXECATTR, &err);
66 
67 	return (execstr2attr(tmp));
68 }
69 
70 
71 execattr_t *
72 getexecprof(const char *name, const char *type, const char *id, int search_flag)
73 {
74 	int		err = 0;
75 	char		unique[NSS_BUFLEN_EXECATTR];
76 	char		buf[NSS_BUFLEN_EXECATTR];
77 	execattr_t	*head = (execattr_t *)NULL;
78 	execattr_t	*prev = (execattr_t *)NULL;
79 	execstr_t	exec;
80 	execstr_t	*tmp;
81 
82 	(void) memset(unique, 0, NSS_BUFLEN_EXECATTR);
83 	(void) memset(&exec, 0, sizeof (execstr_t));
84 
85 	if ((search_flag != GET_ONE) && (search_flag != GET_ALL)) {
86 		return ((execattr_t *)NULL);
87 	}
88 
89 	if ((name == NULL) && (type == NULL) && (id == NULL)) {
90 		setexecattr();
91 		switch (search_flag) {
92 		case GET_ONE:
93 			head = getexecattr();
94 			break;
95 		case GET_ALL:
96 			head = getexecattr();
97 			prev = head;
98 			while (prev != NULL) {
99 				prev->next = getexecattr();
100 				prev = prev->next;
101 			};
102 			break;
103 		default:
104 			head = (execattr_t *)NULL;
105 			break;
106 		}
107 		endexecattr();
108 		return (head);
109 	}
110 
111 	tmp = _getexecprof(name,
112 	    type,
113 	    id,
114 	    search_flag,
115 	    &exec,
116 	    buf,
117 	    NSS_BUFLEN_EXECATTR,
118 	    &err);
119 
120 	return (execstr2attr(tmp));
121 }
122 
123 
124 execattr_t *
125 getexecuser(const char *username, const char *type, const char *id,
126     int search_flag)
127 {
128 	int		err = 0;
129 	char		buf[NSS_BUFLEN_USERATTR];
130 	userstr_t	user;
131 	userstr_t	*utmp;
132 	execattr_t	*head = (execattr_t *)NULL;
133 	execattr_t	*prev = (execattr_t *)NULL;
134 	execattr_t	*new = (execattr_t *)NULL;
135 
136 	if ((search_flag != GET_ONE) && (search_flag != GET_ALL)) {
137 		return ((execattr_t *)NULL);
138 	}
139 
140 	if (username == NULL) {
141 		setuserattr();
142 		/* avoid userstr2attr mallocs by calling libnsl directly */
143 		utmp = _getuserattr(&user, buf, NSS_BUFLEN_USERATTR, &err);
144 		if (utmp == NULL) {
145 			return (head);
146 		}
147 		switch (search_flag) {
148 		case GET_ONE:
149 			head = userprof((const char *)(utmp->name), type, id,
150 			    search_flag);
151 			break;
152 		case GET_ALL:
153 			head = userprof((const char *)(utmp->name), type, id,
154 			    search_flag);
155 			if (head != NULL) {
156 				prev = get_tail(head);
157 			}
158 			while ((utmp = _getuserattr(&user,
159 				    buf, NSS_BUFLEN_USERATTR, &err)) != NULL) {
160 				if ((new =
161 				    userprof((const char *)(utmp->name),
162 				    type, id, search_flag)) != NULL) {
163 					if (prev != NULL) {
164 						prev->next = new;
165 						prev = get_tail(prev->next);
166 					} else {
167 						head = new;
168 						prev = get_tail(head);
169 					}
170 				}
171 			}
172 			break;
173 		default:
174 			head = (execattr_t *)NULL;
175 			break;
176 		}
177 		enduserattr();
178 	} else {
179 		head = userprof(username, type, id, search_flag);
180 	}
181 
182 	return (head);
183 }
184 
185 
186 execattr_t *
187 match_execattr(execattr_t *exec, const char *profname, const char *type,
188     const char *id)
189 {
190 	execattr_t	*execp = (execattr_t *)NULL;
191 
192 	for (execp = exec; execp != NULL; execp = execp->next) {
193 		if ((profname && execp->name &&
194 		    (strcmp(profname, execp->name) != 0)) ||
195 		    (type && execp->type && (strcmp(type, execp->type) != 0)) ||
196 		    (id && execp->id && (strcmp(id, execp->id) != 0)))
197 			continue;
198 	}
199 
200 	return (execp);
201 }
202 
203 
204 void
205 setexecattr()
206 {
207 	_setexecattr();
208 }
209 
210 
211 void
212 endexecattr()
213 {
214 	_endexecattr();
215 }
216 
217 
218 void
219 free_execattr(execattr_t *exec)
220 {
221 	if (exec != (execattr_t *)NULL) {
222 		free(exec->name);
223 		free(exec->type);
224 		free(exec->policy);
225 		free(exec->res1);
226 		free(exec->res2);
227 		free(exec->id);
228 		_kva_free(exec->attr);
229 		free_execattr(exec->next);
230 		free(exec);
231 	}
232 }
233 
234 
235 static execattr_t *
236 userprof(const char *username, const char *type, const char *id,
237     int search_flag)
238 {
239 
240 	int		err = 0;
241 	char		*last;
242 	char		*sep = ",";
243 	char		*proflist = (char *)NULL;
244 	char		*profname = (char *)NULL;
245 	char		buf[NSS_BUFLEN_USERATTR];
246 	char		pwdb[NSS_BUFLEN_PASSWD];
247 	kva_t		*user_attr;
248 	userstr_t	user;
249 	userstr_t	*utmp;
250 	execattr_t	*exec;
251 	execattr_t	*head = (execattr_t *)NULL;
252 	execattr_t	*prev = (execattr_t *)NULL;
253 	struct passwd	pwd;
254 
255 	char		*profArray[MAXPROFS];
256 	int		profcnt = 0;
257 	int		i;
258 
259 	/*
260 	 * Check if specified username is valid user
261 	 */
262 	if (getpwnam_r(username, &pwd, pwdb, sizeof (pwdb)) == NULL) {
263 		return (head);
264 	}
265 
266 	utmp = _getusernam(username, &user, buf, NSS_BUFLEN_USERATTR, &err);
267 	if (utmp != NULL) {
268 		proflist = NULL;
269 		user_attr = _str2kva(user.attr, KV_ASSIGN, KV_DELIMITER);
270 		if ((proflist = kva_match(user_attr, "profiles")) != NULL) {
271 			/* Get the list of profiles for this user */
272 			for (profname = _strtok_escape(proflist, sep, &last);
273 			    profname != NULL;
274 			    profname = _strtok_escape(NULL, sep, &last)) {
275 				getproflist(profname, profArray, &profcnt);
276 			}
277 		}
278 	}
279 
280 	/* Get the list of default profiles */
281 	if (defopen(AUTH_POLICY) == NULL) {
282 		proflist = defread(DEF_PROF);
283 		(void) defopen(NULL);
284 	}
285 	if (proflist != NULL) {
286 		for (profname = _strtok_escape(proflist, sep, &last);
287 		    profname != NULL;
288 		    profname = _strtok_escape(NULL, sep, &last)) {
289 			getproflist(profname, profArray, &profcnt);
290 		}
291 	}
292 
293 	if (profcnt == 0) {
294 		return (head);
295 	}
296 
297 	/* Get execs from the list of profiles */
298 	for (i = 0; i < profcnt; i++) {
299 		profname = profArray[i];
300 		if ((exec = getexecprof(profname, type, id, search_flag)) !=
301 		    NULL) {
302 			if (search_flag == GET_ONE) {
303 				head = exec;
304 				break;
305 			} else if (search_flag == GET_ALL) {
306 				if (head == NULL) {
307 					head = exec;
308 					prev = get_tail(head);
309 				} else {
310 					prev->next = exec;
311 					prev = get_tail(exec);
312 				}
313 			}
314 		}
315 	}
316 	free_proflist(profArray, profcnt);
317 	return (head);
318 }
319 
320 
321 static execattr_t *
322 get_tail(execattr_t *exec)
323 {
324 	execattr_t *i_exec = (execattr_t *)NULL;
325 	execattr_t *j_exec = (execattr_t *)NULL;
326 
327 	if (exec != NULL) {
328 		if (exec->next == NULL) {
329 			j_exec = exec;
330 		} else {
331 			for (i_exec = exec->next; i_exec != NULL;
332 			    i_exec = i_exec->next) {
333 				j_exec = i_exec;
334 			}
335 		}
336 	}
337 
338 	return (j_exec);
339 }
340 
341 
342 static execattr_t *
343 execstr2attr(execstr_t *es)
344 {
345 	execattr_t	*newexec;
346 
347 	if (es == NULL) {
348 		return ((execattr_t *)NULL);
349 	}
350 	if ((newexec = (execattr_t *)malloc(sizeof (execattr_t))) == NULL) {
351 		return ((execattr_t *)NULL);
352 	}
353 
354 	newexec->name = _do_unescape(es->name);
355 	newexec->policy = _do_unescape(es->policy);
356 	newexec->type = _do_unescape(es->type);
357 	newexec->res1 =  _do_unescape(es->res1);
358 	newexec->res2 = _do_unescape(es->res2);
359 	newexec->id = _do_unescape(es->id);
360 	newexec->attr = _str2kva(es->attr, KV_ASSIGN, KV_DELIMITER);
361 	if (es->next) {
362 		newexec->next = execstr2attr((execstr_t *)(es->next));
363 	} else {
364 		newexec->next = (execattr_t *)NULL;
365 	}
366 	return (newexec);
367 }
368 
369 #ifdef DEBUG
370 void
371 print_execattr(execattr_t *exec)
372 {
373 	extern void print_kva(kva_t *);
374 	char *empty = "empty";
375 
376 	if (exec != NULL) {
377 		printf("name=%s\n", exec->name ? exec->name : empty);
378 		printf("policy=%s\n", exec->policy ? exec->policy : empty);
379 		printf("type=%s\n", exec->type ? exec->type : empty);
380 		printf("res1=%s\n", exec->res1 ? exec->res1 : empty);
381 		printf("res2=%s\n", exec->res2 ? exec->res2 : empty);
382 		printf("id=%s\n", exec->id ? exec->id : empty);
383 		printf("attr=\n");
384 		print_kva(exec->attr);
385 		fflush(stdout);
386 		if (exec->next) {
387 			print_execattr(exec->next);
388 		}
389 	} else {
390 		printf("NULL\n");
391 	}
392 }
393 #endif  /* DEBUG */
394