getexecattr.c revision 2830:5228d1267a01
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 */
43extern execstr_t *_getexecattr(execstr_t *, char *, int, int *);
44extern void _setexecattr(void);
45extern void _endexecattr(void);
46extern execstr_t *_getexecprof(const char *, const char *, const char *, int,
47    execstr_t *, char *, int, int *);
48extern userstr_t *_getusernam(const char *, userstr_t *, char *, int, int *);
49extern userstr_t *_getuserattr(userstr_t *, char *, int, int *);
50extern char *_strtok_escape(char *, char *, char **);
51extern char *_strdup_null(char *);
52
53static execattr_t *userprof(const char *, const char *, const char *, int);
54static execattr_t *get_tail(execattr_t *);
55static execattr_t *execstr2attr(execstr_t *);
56
57execattr_t *
58getexecattr()
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
71execattr_t *
72getexecprof(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
124execattr_t *
125getexecuser(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
186execattr_t *
187match_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
204void
205setexecattr()
206{
207	_setexecattr();
208}
209
210
211void
212endexecattr()
213{
214	_endexecattr();
215}
216
217
218void
219free_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
235static execattr_t *
236userprof(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
321static execattr_t *
322get_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
342static execattr_t *
343execstr2attr(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
370void
371print_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