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 (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25#include <sys/types.h>
26#include <stdio.h>
27#include <string.h>
28#include <stdlib.h>
29#include <nss_dbdefs.h>
30#include <deflt.h>
31#include <exec_attr.h>
32#include <user_attr.h>
33#include <auth_attr.h>
34#include <prof_attr.h>
35#include <getxby_door.h>
36#include <sys/mman.h>
37
38
39/* Externs from libnsl */
40extern execstr_t *_getexecattr(execstr_t *, char *, int, int *);
41extern void _setexecattr(void);
42extern void _endexecattr(void);
43extern execstr_t *_getexecprof(const char *, const char *, const char *, int,
44    execstr_t *, char *, int, int *);
45extern userstr_t *_getusernam(const char *, userstr_t *, char *, int, int *);
46extern userstr_t *_getuserattr(userstr_t *, char *, int, int *);
47extern char *_strtok_escape(char *, char *, char **);
48extern char *_strdup_null(char *);
49
50static execattr_t *userprof(const char *, const char *, const char *, int);
51static execattr_t *get_tail(execattr_t *);
52static execattr_t *execstr2attr(execstr_t *);
53
54execattr_t *
55getexecattr()
56{
57	int		err = 0;
58	char		buf[NSS_BUFLEN_EXECATTR];
59	execstr_t	exec;
60	execstr_t	*tmp;
61
62	tmp = _getexecattr(&exec, buf, NSS_BUFLEN_EXECATTR, &err);
63
64	return (execstr2attr(tmp));
65}
66
67
68execattr_t *
69getexecprof(const char *name, const char *type, const char *id, int search_flag)
70{
71	int		err = 0;
72	char		unique[NSS_BUFLEN_EXECATTR];
73	char		buf[NSS_BUFLEN_EXECATTR];
74	execattr_t	*head = NULL;
75	execattr_t	*prev = NULL;
76	execstr_t	exec;
77	execstr_t	*tmp;
78
79	(void) memset(unique, 0, NSS_BUFLEN_EXECATTR);
80	(void) memset(&exec, 0, sizeof (execstr_t));
81
82	if (!IS_GET_ONE(search_flag) && !IS_GET_ALL(search_flag)) {
83		return (NULL);
84	}
85
86	if ((name == NULL) && (type == NULL) && (id == NULL)) {
87		setexecattr();
88		if (IS_GET_ONE(search_flag)) {
89			head = getexecattr();
90		} else if (IS_GET_ALL(search_flag)) {
91			head = getexecattr();
92			prev = head;
93			while (prev != NULL) {
94				prev->next = getexecattr();
95				prev = prev->next;
96			};
97		} else {
98			head = NULL;
99		}
100		endexecattr();
101		return (head);
102	}
103
104	tmp = _getexecprof(name,
105	    type,
106	    id,
107	    search_flag,
108	    &exec,
109	    buf,
110	    NSS_BUFLEN_EXECATTR,
111	    &err);
112
113	return (execstr2attr(tmp));
114}
115
116execattr_t *
117getexecuser(const char *username, const char *type, const char *id,
118    int search_flag)
119{
120	int		err = 0;
121	char		buf[NSS_BUFLEN_USERATTR];
122	userstr_t	user;
123	userstr_t	*utmp;
124	execattr_t	*head = NULL;
125	execattr_t	*prev =  NULL;
126	execattr_t	*new = NULL;
127
128	if (!IS_GET_ONE(search_flag) && !IS_GET_ALL(search_flag)) {
129		return (NULL);
130	}
131
132	if (username == NULL) {
133		setuserattr();
134		/* avoid userstr2attr mallocs by calling libnsl directly */
135		utmp = _getuserattr(&user, buf, NSS_BUFLEN_USERATTR, &err);
136		if (utmp == NULL) {
137			return (head);
138		}
139		if (IS_GET_ONE(search_flag)) {
140			head = userprof((const char *)(utmp->name), type, id,
141			    search_flag);
142		} else if (IS_GET_ALL(search_flag)) {
143			head = userprof((const char *)(utmp->name), type, id,
144			    search_flag);
145			if (head != NULL) {
146				prev = get_tail(head);
147			}
148			while ((utmp = _getuserattr(&user,
149			    buf, NSS_BUFLEN_USERATTR, &err)) != NULL) {
150				if ((new =
151				    userprof((const char *)(utmp->name),
152				    type, id, search_flag)) != NULL) {
153					if (prev != NULL) {
154						prev->next = new;
155						prev = get_tail(prev->next);
156					} else {
157						head = new;
158						prev = get_tail(head);
159					}
160				}
161			}
162		} else {
163			head = NULL;
164		}
165		enduserattr();
166	} else {
167		head = userprof(username, type, id, search_flag);
168	}
169
170	return (head);
171}
172
173
174execattr_t *
175match_execattr(execattr_t *exec, const char *profname, const char *type,
176    const char *id)
177{
178	execattr_t	*execp = NULL;
179
180	for (execp = exec; execp != NULL; execp = execp->next) {
181		if ((profname && execp->name &&
182		    (strcmp(profname, execp->name) != 0)) ||
183		    (type && execp->type && (strcmp(type, execp->type) != 0)) ||
184		    (id && execp->id && (strcmp(id, execp->id) != 0)))
185			continue;
186	}
187
188	return (execp);
189}
190
191
192void
193setexecattr()
194{
195	_setexecattr();
196}
197
198
199void
200endexecattr()
201{
202	_endexecattr();
203}
204
205
206void
207free_execattr(execattr_t *exec)
208{
209	if (exec != NULL) {
210		free(exec->name);
211		free(exec->type);
212		free(exec->policy);
213		free(exec->res1);
214		free(exec->res2);
215		free(exec->id);
216		_kva_free(exec->attr);
217		free_execattr(exec->next);
218		free(exec);
219	}
220}
221
222typedef struct call {
223	const char	*type;
224	const char	*id;
225	int		sflag;
226} call;
227
228typedef struct result {
229	execattr_t *head;
230	execattr_t *prev;
231} result;
232
233/*ARGSUSED*/
234static int
235findexecattr(const char *prof, kva_t *kva, void *ctxt, void *res)
236{
237	execattr_t *exec;
238	call *c = ctxt;
239	result *r = res;
240
241	if ((exec = getexecprof(prof, c->type, c->id, c->sflag)) != NULL) {
242		if (IS_GET_ONE(c->sflag)) {
243			r->head = exec;
244			return (1);
245		} else if (IS_GET_ALL(c->sflag)) {
246			if (r->head == NULL) {
247				r->head = exec;
248				r->prev = get_tail(r->head);
249			} else {
250				r->prev->next = exec;
251				r->prev = get_tail(exec);
252			}
253		}
254	}
255	return (0);
256}
257
258
259static execattr_t *
260userprof(const char *username, const char *type, const char *id,
261    int search_flag)
262{
263
264	char		pwdb[NSS_BUFLEN_PASSWD];
265	struct passwd	pwd;
266	call		call;
267	result		result;
268
269	/*
270	 * Check if specified username is valid user
271	 */
272	if (getpwnam_r(username, &pwd, pwdb, sizeof (pwdb)) == NULL) {
273		return (NULL);
274	}
275
276	result.head = result.prev = NULL;
277	call.type = type;
278	call.id = id;
279	call.sflag = search_flag;
280
281	(void) _enum_profs(username, findexecattr, &call, &result);
282
283	return (result.head);
284}
285
286
287static execattr_t *
288get_tail(execattr_t *exec)
289{
290	execattr_t *i_exec = NULL;
291	execattr_t *j_exec = NULL;
292
293	if (exec != NULL) {
294		if (exec->next == NULL) {
295			j_exec = exec;
296		} else {
297			for (i_exec = exec->next; i_exec != NULL;
298			    i_exec = i_exec->next) {
299				j_exec = i_exec;
300			}
301		}
302	}
303
304	return (j_exec);
305}
306
307
308static execattr_t *
309execstr2attr(execstr_t *es)
310{
311	execattr_t	*newexec;
312
313	if (es == NULL) {
314		return (NULL);
315	}
316	if ((newexec = malloc(sizeof (execattr_t))) == NULL) {
317		return (NULL);
318	}
319
320	newexec->name = _do_unescape(es->name);
321	newexec->policy = _do_unescape(es->policy);
322	newexec->type = _do_unescape(es->type);
323	newexec->res1 =  _do_unescape(es->res1);
324	newexec->res2 = _do_unescape(es->res2);
325	newexec->id = _do_unescape(es->id);
326	newexec->attr = _str2kva(es->attr, KV_ASSIGN, KV_DELIMITER);
327	if (es->next) {
328		newexec->next = execstr2attr((execstr_t *)(es->next));
329	} else {
330		newexec->next = NULL;
331	}
332	return (newexec);
333}
334
335#ifdef DEBUG
336void
337print_execattr(execattr_t *exec)
338{
339	extern void print_kva(kva_t *);
340	char *empty = "empty";
341
342	if (exec != NULL) {
343		printf("name=%s\n", exec->name ? exec->name : empty);
344		printf("policy=%s\n", exec->policy ? exec->policy : empty);
345		printf("type=%s\n", exec->type ? exec->type : empty);
346		printf("res1=%s\n", exec->res1 ? exec->res1 : empty);
347		printf("res2=%s\n", exec->res2 ? exec->res2 : empty);
348		printf("id=%s\n", exec->id ? exec->id : empty);
349		printf("attr=\n");
350		print_kva(exec->attr);
351		fflush(stdout);
352		if (exec->next) {
353			print_execattr(exec->next);
354		}
355	} else {
356		printf("NULL\n");
357	}
358}
359#endif  /* DEBUG */
360