/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include /* Externs from libnsl */ extern execstr_t *_getexecattr(execstr_t *, char *, int, int *); extern void _setexecattr(void); extern void _endexecattr(void); extern execstr_t *_getexecprof(const char *, const char *, const char *, int, execstr_t *, char *, int, int *); extern userstr_t *_getusernam(const char *, userstr_t *, char *, int, int *); extern userstr_t *_getuserattr(userstr_t *, char *, int, int *); extern char *_strtok_escape(char *, char *, char **); extern char *_strdup_null(char *); static execattr_t *userprof(const char *, const char *, const char *, int); static execattr_t *get_tail(execattr_t *); static execattr_t *execstr2attr(execstr_t *); execattr_t * getexecattr() { int err = 0; char buf[NSS_BUFLEN_EXECATTR]; execstr_t exec; execstr_t *tmp; tmp = _getexecattr(&exec, buf, NSS_BUFLEN_EXECATTR, &err); return (execstr2attr(tmp)); } execattr_t * getexecprof(const char *name, const char *type, const char *id, int search_flag) { int err = 0; char unique[NSS_BUFLEN_EXECATTR]; char buf[NSS_BUFLEN_EXECATTR]; execattr_t *head = NULL; execattr_t *prev = NULL; execstr_t exec; execstr_t *tmp; (void) memset(unique, 0, NSS_BUFLEN_EXECATTR); (void) memset(&exec, 0, sizeof (execstr_t)); if (!IS_GET_ONE(search_flag) && !IS_GET_ALL(search_flag)) { return (NULL); } if ((name == NULL) && (type == NULL) && (id == NULL)) { setexecattr(); if (IS_GET_ONE(search_flag)) { head = getexecattr(); } else if (IS_GET_ALL(search_flag)) { head = getexecattr(); prev = head; while (prev != NULL) { prev->next = getexecattr(); prev = prev->next; }; } else { head = NULL; } endexecattr(); return (head); } tmp = _getexecprof(name, type, id, search_flag, &exec, buf, NSS_BUFLEN_EXECATTR, &err); return (execstr2attr(tmp)); } execattr_t * getexecuser(const char *username, const char *type, const char *id, int search_flag) { int err = 0; char buf[NSS_BUFLEN_USERATTR]; userstr_t user; userstr_t *utmp; execattr_t *head = NULL; execattr_t *prev = NULL; execattr_t *new = NULL; if (!IS_GET_ONE(search_flag) && !IS_GET_ALL(search_flag)) { return (NULL); } if (username == NULL) { setuserattr(); /* avoid userstr2attr mallocs by calling libnsl directly */ utmp = _getuserattr(&user, buf, NSS_BUFLEN_USERATTR, &err); if (utmp == NULL) { return (head); } if (IS_GET_ONE(search_flag)) { head = userprof((const char *)(utmp->name), type, id, search_flag); } else if (IS_GET_ALL(search_flag)) { head = userprof((const char *)(utmp->name), type, id, search_flag); if (head != NULL) { prev = get_tail(head); } while ((utmp = _getuserattr(&user, buf, NSS_BUFLEN_USERATTR, &err)) != NULL) { if ((new = userprof((const char *)(utmp->name), type, id, search_flag)) != NULL) { if (prev != NULL) { prev->next = new; prev = get_tail(prev->next); } else { head = new; prev = get_tail(head); } } } } else { head = NULL; } enduserattr(); } else { head = userprof(username, type, id, search_flag); } return (head); } execattr_t * match_execattr(execattr_t *exec, const char *profname, const char *type, const char *id) { execattr_t *execp = NULL; for (execp = exec; execp != NULL; execp = execp->next) { if ((profname && execp->name && (strcmp(profname, execp->name) != 0)) || (type && execp->type && (strcmp(type, execp->type) != 0)) || (id && execp->id && (strcmp(id, execp->id) != 0))) continue; } return (execp); } void setexecattr() { _setexecattr(); } void endexecattr() { _endexecattr(); } void free_execattr(execattr_t *exec) { if (exec != NULL) { free(exec->name); free(exec->type); free(exec->policy); free(exec->res1); free(exec->res2); free(exec->id); _kva_free(exec->attr); free_execattr(exec->next); free(exec); } } typedef struct call { const char *type; const char *id; int sflag; } call; typedef struct result { execattr_t *head; execattr_t *prev; } result; /*ARGSUSED*/ static int findexecattr(const char *prof, kva_t *kva, void *ctxt, void *res) { execattr_t *exec; call *c = ctxt; result *r = res; if ((exec = getexecprof(prof, c->type, c->id, c->sflag)) != NULL) { if (IS_GET_ONE(c->sflag)) { r->head = exec; return (1); } else if (IS_GET_ALL(c->sflag)) { if (r->head == NULL) { r->head = exec; r->prev = get_tail(r->head); } else { r->prev->next = exec; r->prev = get_tail(exec); } } } return (0); } static execattr_t * userprof(const char *username, const char *type, const char *id, int search_flag) { char pwdb[NSS_BUFLEN_PASSWD]; struct passwd pwd; call call; result result; /* * Check if specified username is valid user */ if (getpwnam_r(username, &pwd, pwdb, sizeof (pwdb)) == NULL) { return (NULL); } result.head = result.prev = NULL; call.type = type; call.id = id; call.sflag = search_flag; (void) _enum_profs(username, findexecattr, &call, &result); return (result.head); } static execattr_t * get_tail(execattr_t *exec) { execattr_t *i_exec = NULL; execattr_t *j_exec = NULL; if (exec != NULL) { if (exec->next == NULL) { j_exec = exec; } else { for (i_exec = exec->next; i_exec != NULL; i_exec = i_exec->next) { j_exec = i_exec; } } } return (j_exec); } static execattr_t * execstr2attr(execstr_t *es) { execattr_t *newexec; if (es == NULL) { return (NULL); } if ((newexec = malloc(sizeof (execattr_t))) == NULL) { return (NULL); } newexec->name = _do_unescape(es->name); newexec->policy = _do_unescape(es->policy); newexec->type = _do_unescape(es->type); newexec->res1 = _do_unescape(es->res1); newexec->res2 = _do_unescape(es->res2); newexec->id = _do_unescape(es->id); newexec->attr = _str2kva(es->attr, KV_ASSIGN, KV_DELIMITER); if (es->next) { newexec->next = execstr2attr((execstr_t *)(es->next)); } else { newexec->next = NULL; } return (newexec); } #ifdef DEBUG void print_execattr(execattr_t *exec) { extern void print_kva(kva_t *); char *empty = "empty"; if (exec != NULL) { printf("name=%s\n", exec->name ? exec->name : empty); printf("policy=%s\n", exec->policy ? exec->policy : empty); printf("type=%s\n", exec->type ? exec->type : empty); printf("res1=%s\n", exec->res1 ? exec->res1 : empty); printf("res2=%s\n", exec->res2 ? exec->res2 : empty); printf("id=%s\n", exec->id ? exec->id : empty); printf("attr=\n"); print_kva(exec->attr); fflush(stdout); if (exec->next) { print_execattr(exec->next); } } else { printf("NULL\n"); } } #endif /* DEBUG */