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