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 * 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 * 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 * 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 * 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 193 setexecattr() 194 { 195 _setexecattr(); 196 } 197 198 199 void 200 endexecattr() 201 { 202 _endexecattr(); 203 } 204 205 206 void 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 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 * 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 * 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 * 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 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