/* * 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 #define EXIT_OK 0 #define EXIT_FATAL 1 #define EXIT_NON_FATAL 2 #define TMP_BUF_LEN 2048 /* size of temp string buffer */ #define PRINT_DEFAULT 0x0000 #define PRINT_NAME 0x0010 #define PRINT_LONG 0x0020 #ifndef TEXT_DOMAIN /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" #endif static void usage(); static int show_profs(char *, int); static void print_profs_long(execattr_t *); static void print_profile_privs(kva_t *); static char *progname = "profiles"; int main(int argc, char *argv[]) { extern int optind; int c; int status = EXIT_OK; int print_flag = PRINT_DEFAULT; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); while ((c = getopt(argc, argv, "l")) != EOF) { switch (c) { case 'l': print_flag |= PRINT_LONG; break; default: usage(); return (EXIT_FATAL); } } argc -= optind; argv += optind; if (*argv == NULL) { status = show_profs(NULL, print_flag); } else { do { (void) printf("%s:\n", *argv); status = show_profs((char *)*argv, (print_flag | PRINT_NAME)); if (status == EXIT_FATAL) { break; } if (argv[1] != NULL) { /* seperate users with empty line */ (void) printf("\n"); } } while (*++argv); } status = (status == EXIT_OK) ? status : EXIT_FATAL; return (status); } static int show_profs_callback(const char *prof, kva_t *pa, void *pflag, void *vcnt) { char *indent = ""; const int *print_flag = pflag; int *pcnt = vcnt; (*pcnt)++; if ((*print_flag) & PRINT_NAME) { indent = " "; } (void) printf("%s%s", indent, prof); print_profile_privs(pa); (void) printf("\n"); return (0); } static int show_profs(char *username, int print_flag) { int status = EXIT_OK; struct passwd *pw; execattr_t *exec; if (username == NULL) { if ((pw = getpwuid(getuid())) == NULL) { status = EXIT_NON_FATAL; (void) fprintf(stderr, "%s: ", progname); (void) fprintf(stderr, gettext("No passwd entry\n")); return (status); } username = pw->pw_name; } else if (getpwnam(username) == NULL) { status = EXIT_NON_FATAL; (void) fprintf(stderr, "%s: %s: ", progname, username); (void) fprintf(stderr, gettext("No such user\n")); return (status); } if (print_flag & PRINT_LONG) { exec = getexecuser(username, KV_COMMAND, NULL, GET_ALL|__SEARCH_ALL_POLS); if (exec != NULL) { print_profs_long(exec); free_execattr(exec); } else { status = EXIT_NON_FATAL; } } else { int cnt = 0; (void) _enum_profs(username, show_profs_callback, &print_flag, &cnt); if (cnt == 0) status = EXIT_NON_FATAL; } if (status == EXIT_NON_FATAL) { (void) fprintf(stderr, "%s: %s: ", progname, username); (void) fprintf(stderr, gettext("No profiles\n")); } return (status); } /* * print extended profile information. * * output is "pretty printed" like * [6spaces]Profile Name1[ possible profile privileges] * [10spaces ]execname1 [skip to ATTR_COL]exec1 attributes1 * [ spaces to ATTR_COL ]exec1 attributes2 * [10spaces ]execname2 [skip to ATTR_COL]exec2 attributes1 * [ spaces to ATTR_COL ]exec2 attributes2 * [6spaces]Profile Name2[ possible profile privileges] * etc */ /* * ATTR_COL is based on * 10 leading spaces + * 25 positions for the executable + * 1 space seperating the execname from the attributes * so attribute printing starts at column 37 (36 whitespaces) * * 25 spaces for the execname seems reasonable since currently * less than 3% of the shipped exec_attr would overflow this */ #define ATTR_COL 37 static void print_profs_long(execattr_t *exec) { char *curprofile; int len; kv_t *kv_pair; char *key; char *val; int i; for (curprofile = ""; exec != NULL; exec = exec->next) { /* print profile name if it is a new one */ if (strcmp(curprofile, exec->name) != 0) { profattr_t *pa; curprofile = exec->name; (void) printf(" %s", curprofile); pa = getprofnam(curprofile); if (pa != NULL) { print_profile_privs(pa->attr); free_profattr(pa); } (void) printf("\n"); } len = printf(" %s ", exec->id); if ((exec->attr == NULL || exec->attr->data == NULL)) { (void) printf("\n"); continue; } /* * if printing the name of the executable got us past the * ATTR_COLth column, skip to ATTR_COL on a new line to * print the attribues. * else, just skip to ATTR_COL column. */ if (len >= ATTR_COL) (void) printf("\n%*s", ATTR_COL, " "); else (void) printf("%*s", ATTR_COL-len, " "); len = ATTR_COL; /* print all attributes of this profile */ kv_pair = exec->attr->data; for (i = 0; i < exec->attr->length; i++) { key = kv_pair[i].key; val = kv_pair[i].value; if (key == NULL || val == NULL) break; /* align subsequent attributes on the same column */ if (i > 0) (void) printf("%*s", len, " "); (void) printf("%s=%s\n", key, val); } } } static void usage() { (void) fprintf(stderr, gettext(" usage: profiles [-l] [user1 user2 ...]\n")); } static void print_profile_privs(kva_t *attr) { char *privs; if (attr) { privs = kva_match(attr, PROFATTR_PRIVS_KW); if (privs) (void) printf(" privs=%s", privs); } }