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 */
40 extern execstr_t *_getexecattr(execstr_t *, char *, int, int *);
41 extern void _setexecattr(void);
42 extern void _endexecattr(void);
43 extern execstr_t *_getexecprof(const char *, const char *, const char *, int,
44     execstr_t *, char *, int, int *);
45 extern userstr_t *_getusernam(const char *, userstr_t *, char *, int, int *);
46 extern userstr_t *_getuserattr(userstr_t *, char *, int, int *);
47 extern char *_strtok_escape(char *, char *, char **);
48 extern char *_strdup_null(char *);
49 
50 static execattr_t *userprof(const char *, const char *, const char *, int);
51 static execattr_t *get_tail(execattr_t *);
52 static execattr_t *execstr2attr(execstr_t *);
53 
54 execattr_t *
getexecattr()55 getexecattr()
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 
68 execattr_t *
getexecprof(const char * name,const char * type,const char * id,int search_flag)69 getexecprof(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 
116 execattr_t *
getexecuser(const char * username,const char * type,const char * id,int search_flag)117 getexecuser(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 
174 execattr_t *
match_execattr(execattr_t * exec,const char * profname,const char * type,const char * id)175 match_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 
192 void
setexecattr()193 setexecattr()
194 {
195 	_setexecattr();
196 }
197 
198 
199 void
endexecattr()200 endexecattr()
201 {
202 	_endexecattr();
203 }
204 
205 
206 void
free_execattr(execattr_t * exec)207 free_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 
222 typedef struct call {
223 	const char	*type;
224 	const char	*id;
225 	int		sflag;
226 } call;
227 
228 typedef struct result {
229 	execattr_t *head;
230 	execattr_t *prev;
231 } result;
232 
233 /*ARGSUSED*/
234 static int
findexecattr(const char * prof,kva_t * kva,void * ctxt,void * res)235 findexecattr(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 
259 static execattr_t *
userprof(const char * username,const char * type,const char * id,int search_flag)260 userprof(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 
287 static execattr_t *
get_tail(execattr_t * exec)288 get_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 
308 static execattr_t *
execstr2attr(execstr_t * es)309 execstr2attr(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
336 void
print_execattr(execattr_t * exec)337 print_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