xref: /illumos-gate/usr/src/lib/libsecdb/common/getexecattr.c (revision f998c95e3b7029fe5f7542e115f7474ddb8024d7)
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 2008 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 = NULL;
78 	execattr_t	*prev = 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 (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 = 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 = NULL;
133 	execattr_t	*prev =  NULL;
134 	execattr_t	*new = NULL;
135 
136 	if ((search_flag != GET_ONE) && (search_flag != GET_ALL)) {
137 		return (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 = 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 = 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 != 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 = NULL;
244 	char		*profname = 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 = NULL;
252 	execattr_t	*prev = 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 		user_attr = _str2kva(user.attr, KV_ASSIGN, KV_DELIMITER);
269 		if ((proflist = kva_match(user_attr, "profiles")) != NULL) {
270 			/* Get the list of profiles for this user */
271 			for (profname = _strtok_escape(proflist, sep, &last);
272 			    profname != NULL;
273 			    profname = _strtok_escape(NULL, sep, &last)) {
274 				getproflist(profname, profArray, &profcnt);
275 			}
276 		}
277 	}
278 
279 	/* Get the list of default profiles */
280 	proflist = NULL;
281 	(void) _get_user_defs(username, NULL, &proflist);
282 	if (proflist != NULL) {
283 		for (profname = _strtok_escape(proflist, sep, &last);
284 		    profname != NULL;
285 		    profname = _strtok_escape(NULL, sep, &last)) {
286 			getproflist(profname, profArray, &profcnt);
287 		}
288 		_free_user_defs(NULL, proflist);
289 	}
290 
291 	if (profcnt == 0) {
292 		return (head);
293 	}
294 
295 	/* Get execs from the list of profiles */
296 	for (i = 0; i < profcnt; i++) {
297 		profname = profArray[i];
298 		if ((exec = getexecprof(profname, type, id, search_flag)) !=
299 		    NULL) {
300 			if (search_flag == GET_ONE) {
301 				head = exec;
302 				break;
303 			} else if (search_flag == GET_ALL) {
304 				if (head == NULL) {
305 					head = exec;
306 					prev = get_tail(head);
307 				} else {
308 					prev->next = exec;
309 					prev = get_tail(exec);
310 				}
311 			}
312 		}
313 	}
314 	free_proflist(profArray, profcnt);
315 	return (head);
316 }
317 
318 
319 static execattr_t *
320 get_tail(execattr_t *exec)
321 {
322 	execattr_t *i_exec = NULL;
323 	execattr_t *j_exec = NULL;
324 
325 	if (exec != NULL) {
326 		if (exec->next == NULL) {
327 			j_exec = exec;
328 		} else {
329 			for (i_exec = exec->next; i_exec != NULL;
330 			    i_exec = i_exec->next) {
331 				j_exec = i_exec;
332 			}
333 		}
334 	}
335 
336 	return (j_exec);
337 }
338 
339 
340 static execattr_t *
341 execstr2attr(execstr_t *es)
342 {
343 	execattr_t	*newexec;
344 
345 	if (es == NULL) {
346 		return (NULL);
347 	}
348 	if ((newexec = malloc(sizeof (execattr_t))) == NULL) {
349 		return (NULL);
350 	}
351 
352 	newexec->name = _do_unescape(es->name);
353 	newexec->policy = _do_unescape(es->policy);
354 	newexec->type = _do_unescape(es->type);
355 	newexec->res1 =  _do_unescape(es->res1);
356 	newexec->res2 = _do_unescape(es->res2);
357 	newexec->id = _do_unescape(es->id);
358 	newexec->attr = _str2kva(es->attr, KV_ASSIGN, KV_DELIMITER);
359 	if (es->next) {
360 		newexec->next = execstr2attr((execstr_t *)(es->next));
361 	} else {
362 		newexec->next = NULL;
363 	}
364 	return (newexec);
365 }
366 
367 #ifdef DEBUG
368 void
369 print_execattr(execattr_t *exec)
370 {
371 	extern void print_kva(kva_t *);
372 	char *empty = "empty";
373 
374 	if (exec != NULL) {
375 		printf("name=%s\n", exec->name ? exec->name : empty);
376 		printf("policy=%s\n", exec->policy ? exec->policy : empty);
377 		printf("type=%s\n", exec->type ? exec->type : empty);
378 		printf("res1=%s\n", exec->res1 ? exec->res1 : empty);
379 		printf("res2=%s\n", exec->res2 ? exec->res2 : empty);
380 		printf("id=%s\n", exec->id ? exec->id : empty);
381 		printf("attr=\n");
382 		print_kva(exec->attr);
383 		fflush(stdout);
384 		if (exec->next) {
385 			print_execattr(exec->next);
386 		}
387 	} else {
388 		printf("NULL\n");
389 	}
390 }
391 #endif  /* DEBUG */
392