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