Home | History | Annotate | Download | only in common
      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