10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51891Sbubbva * Common Development and Distribution License (the "License").
61891Sbubbva * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*12273SCasper.Dik@Sun.COM * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate #include <stdio.h>
260Sstevel@tonic-gate #include <stdlib.h>
270Sstevel@tonic-gate #include <unistd.h>
280Sstevel@tonic-gate #include <pwd.h>
290Sstevel@tonic-gate #include <string.h>
300Sstevel@tonic-gate #include <libintl.h>
310Sstevel@tonic-gate #include <locale.h>
320Sstevel@tonic-gate #include <deflt.h>
330Sstevel@tonic-gate #include <user_attr.h>
340Sstevel@tonic-gate #include <prof_attr.h>
350Sstevel@tonic-gate #include <exec_attr.h>
360Sstevel@tonic-gate #include <auth_attr.h>
370Sstevel@tonic-gate
380Sstevel@tonic-gate
390Sstevel@tonic-gate #define EXIT_OK 0
400Sstevel@tonic-gate #define EXIT_FATAL 1
410Sstevel@tonic-gate #define EXIT_NON_FATAL 2
420Sstevel@tonic-gate
430Sstevel@tonic-gate #define TMP_BUF_LEN 2048 /* size of temp string buffer */
440Sstevel@tonic-gate
450Sstevel@tonic-gate #define PRINT_DEFAULT 0x0000
460Sstevel@tonic-gate #define PRINT_NAME 0x0010
470Sstevel@tonic-gate #define PRINT_LONG 0x0020
480Sstevel@tonic-gate
490Sstevel@tonic-gate #ifndef TEXT_DOMAIN /* Should be defined by cc -D */
500Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
510Sstevel@tonic-gate #endif
520Sstevel@tonic-gate
530Sstevel@tonic-gate static void usage();
540Sstevel@tonic-gate static int show_profs(char *, int);
559134SJoep.Vesseur@Sun.COM static void print_profs_long(execattr_t *);
56*12273SCasper.Dik@Sun.COM static void print_profile_privs(kva_t *);
570Sstevel@tonic-gate
580Sstevel@tonic-gate static char *progname = "profiles";
590Sstevel@tonic-gate
600Sstevel@tonic-gate int
main(int argc,char * argv[])610Sstevel@tonic-gate main(int argc, char *argv[])
620Sstevel@tonic-gate {
630Sstevel@tonic-gate extern int optind;
647134Sgww int c;
657134Sgww int status = EXIT_OK;
660Sstevel@tonic-gate int print_flag = PRINT_DEFAULT;
670Sstevel@tonic-gate
680Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
690Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
700Sstevel@tonic-gate
710Sstevel@tonic-gate while ((c = getopt(argc, argv, "l")) != EOF) {
720Sstevel@tonic-gate switch (c) {
730Sstevel@tonic-gate case 'l':
740Sstevel@tonic-gate print_flag |= PRINT_LONG;
750Sstevel@tonic-gate break;
760Sstevel@tonic-gate default:
770Sstevel@tonic-gate usage();
780Sstevel@tonic-gate return (EXIT_FATAL);
790Sstevel@tonic-gate }
800Sstevel@tonic-gate }
810Sstevel@tonic-gate argc -= optind;
820Sstevel@tonic-gate argv += optind;
830Sstevel@tonic-gate
840Sstevel@tonic-gate if (*argv == NULL) {
856059Sgww status = show_profs(NULL, print_flag);
860Sstevel@tonic-gate } else {
870Sstevel@tonic-gate do {
889134SJoep.Vesseur@Sun.COM (void) printf("%s:\n", *argv);
897134Sgww status = show_profs((char *)*argv,
907134Sgww (print_flag | PRINT_NAME));
910Sstevel@tonic-gate if (status == EXIT_FATAL) {
920Sstevel@tonic-gate break;
930Sstevel@tonic-gate }
949134SJoep.Vesseur@Sun.COM if (argv[1] != NULL) {
959134SJoep.Vesseur@Sun.COM /* seperate users with empty line */
969134SJoep.Vesseur@Sun.COM (void) printf("\n");
979134SJoep.Vesseur@Sun.COM }
980Sstevel@tonic-gate } while (*++argv);
990Sstevel@tonic-gate }
1000Sstevel@tonic-gate status = (status == EXIT_OK) ? status : EXIT_FATAL;
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate return (status);
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate
105*12273SCasper.Dik@Sun.COM static int
show_profs_callback(const char * prof,kva_t * pa,void * pflag,void * vcnt)106*12273SCasper.Dik@Sun.COM show_profs_callback(const char *prof, kva_t *pa, void *pflag, void *vcnt)
107*12273SCasper.Dik@Sun.COM {
108*12273SCasper.Dik@Sun.COM char *indent = "";
109*12273SCasper.Dik@Sun.COM const int *print_flag = pflag;
110*12273SCasper.Dik@Sun.COM int *pcnt = vcnt;
111*12273SCasper.Dik@Sun.COM
112*12273SCasper.Dik@Sun.COM (*pcnt)++;
113*12273SCasper.Dik@Sun.COM
114*12273SCasper.Dik@Sun.COM if ((*print_flag) & PRINT_NAME) {
115*12273SCasper.Dik@Sun.COM indent = " ";
116*12273SCasper.Dik@Sun.COM }
117*12273SCasper.Dik@Sun.COM
118*12273SCasper.Dik@Sun.COM (void) printf("%s%s", indent, prof);
119*12273SCasper.Dik@Sun.COM print_profile_privs(pa);
120*12273SCasper.Dik@Sun.COM (void) printf("\n");
121*12273SCasper.Dik@Sun.COM
122*12273SCasper.Dik@Sun.COM return (0);
123*12273SCasper.Dik@Sun.COM }
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate static int
show_profs(char * username,int print_flag)1260Sstevel@tonic-gate show_profs(char *username, int print_flag)
1270Sstevel@tonic-gate {
1287134Sgww int status = EXIT_OK;
1297134Sgww struct passwd *pw;
1307134Sgww execattr_t *exec;
1310Sstevel@tonic-gate
1320Sstevel@tonic-gate if (username == NULL) {
1330Sstevel@tonic-gate if ((pw = getpwuid(getuid())) == NULL) {
1340Sstevel@tonic-gate status = EXIT_NON_FATAL;
1350Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", progname);
1360Sstevel@tonic-gate (void) fprintf(stderr, gettext("No passwd entry\n"));
1370Sstevel@tonic-gate return (status);
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate username = pw->pw_name;
1401891Sbubbva } else if (getpwnam(username) == NULL) {
1410Sstevel@tonic-gate status = EXIT_NON_FATAL;
1429134SJoep.Vesseur@Sun.COM (void) fprintf(stderr, "%s: %s: ", progname, username);
1430Sstevel@tonic-gate (void) fprintf(stderr, gettext("No such user\n"));
1440Sstevel@tonic-gate return (status);
1450Sstevel@tonic-gate }
146*12273SCasper.Dik@Sun.COM
147*12273SCasper.Dik@Sun.COM if (print_flag & PRINT_LONG) {
148*12273SCasper.Dik@Sun.COM exec = getexecuser(username, KV_COMMAND, NULL,
149*12273SCasper.Dik@Sun.COM GET_ALL|__SEARCH_ALL_POLS);
150*12273SCasper.Dik@Sun.COM if (exec != NULL) {
151*12273SCasper.Dik@Sun.COM print_profs_long(exec);
152*12273SCasper.Dik@Sun.COM free_execattr(exec);
1530Sstevel@tonic-gate } else {
154*12273SCasper.Dik@Sun.COM status = EXIT_NON_FATAL;
1550Sstevel@tonic-gate }
156*12273SCasper.Dik@Sun.COM } else {
157*12273SCasper.Dik@Sun.COM int cnt = 0;
158*12273SCasper.Dik@Sun.COM (void) _enum_profs(username, show_profs_callback, &print_flag,
159*12273SCasper.Dik@Sun.COM &cnt);
160*12273SCasper.Dik@Sun.COM
161*12273SCasper.Dik@Sun.COM if (cnt == 0)
162*12273SCasper.Dik@Sun.COM status = EXIT_NON_FATAL;
1630Sstevel@tonic-gate }
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate if (status == EXIT_NON_FATAL) {
1669134SJoep.Vesseur@Sun.COM (void) fprintf(stderr, "%s: %s: ", progname, username);
1670Sstevel@tonic-gate (void) fprintf(stderr, gettext("No profiles\n"));
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate return (status);
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate
1739134SJoep.Vesseur@Sun.COM /*
1749134SJoep.Vesseur@Sun.COM * print extended profile information.
1759134SJoep.Vesseur@Sun.COM *
1769134SJoep.Vesseur@Sun.COM * output is "pretty printed" like
1779134SJoep.Vesseur@Sun.COM * [6spaces]Profile Name1[ possible profile privileges]
1789134SJoep.Vesseur@Sun.COM * [10spaces ]execname1 [skip to ATTR_COL]exec1 attributes1
1799134SJoep.Vesseur@Sun.COM * [ spaces to ATTR_COL ]exec1 attributes2
1809134SJoep.Vesseur@Sun.COM * [10spaces ]execname2 [skip to ATTR_COL]exec2 attributes1
1819134SJoep.Vesseur@Sun.COM * [ spaces to ATTR_COL ]exec2 attributes2
1829134SJoep.Vesseur@Sun.COM * [6spaces]Profile Name2[ possible profile privileges]
1839134SJoep.Vesseur@Sun.COM * etc
1849134SJoep.Vesseur@Sun.COM */
1859134SJoep.Vesseur@Sun.COM /*
1869134SJoep.Vesseur@Sun.COM * ATTR_COL is based on
1879134SJoep.Vesseur@Sun.COM * 10 leading spaces +
1889134SJoep.Vesseur@Sun.COM * 25 positions for the executable +
1899134SJoep.Vesseur@Sun.COM * 1 space seperating the execname from the attributes
1909134SJoep.Vesseur@Sun.COM * so attribute printing starts at column 37 (36 whitespaces)
1919134SJoep.Vesseur@Sun.COM *
1929134SJoep.Vesseur@Sun.COM * 25 spaces for the execname seems reasonable since currently
1939134SJoep.Vesseur@Sun.COM * less than 3% of the shipped exec_attr would overflow this
1949134SJoep.Vesseur@Sun.COM */
1959134SJoep.Vesseur@Sun.COM #define ATTR_COL 37
1960Sstevel@tonic-gate
1979134SJoep.Vesseur@Sun.COM static void
print_profs_long(execattr_t * exec)1989134SJoep.Vesseur@Sun.COM print_profs_long(execattr_t *exec)
1999134SJoep.Vesseur@Sun.COM {
2009134SJoep.Vesseur@Sun.COM char *curprofile;
2019134SJoep.Vesseur@Sun.COM int len;
2029134SJoep.Vesseur@Sun.COM kv_t *kv_pair;
2039134SJoep.Vesseur@Sun.COM char *key;
2049134SJoep.Vesseur@Sun.COM char *val;
2059134SJoep.Vesseur@Sun.COM int i;
2069134SJoep.Vesseur@Sun.COM
2079134SJoep.Vesseur@Sun.COM for (curprofile = ""; exec != NULL; exec = exec->next) {
2089134SJoep.Vesseur@Sun.COM /* print profile name if it is a new one */
2099134SJoep.Vesseur@Sun.COM if (strcmp(curprofile, exec->name) != 0) {
210*12273SCasper.Dik@Sun.COM profattr_t *pa;
2119134SJoep.Vesseur@Sun.COM curprofile = exec->name;
212*12273SCasper.Dik@Sun.COM
2139134SJoep.Vesseur@Sun.COM (void) printf(" %s", curprofile);
214*12273SCasper.Dik@Sun.COM
215*12273SCasper.Dik@Sun.COM pa = getprofnam(curprofile);
216*12273SCasper.Dik@Sun.COM if (pa != NULL) {
217*12273SCasper.Dik@Sun.COM print_profile_privs(pa->attr);
218*12273SCasper.Dik@Sun.COM free_profattr(pa);
219*12273SCasper.Dik@Sun.COM }
2209134SJoep.Vesseur@Sun.COM (void) printf("\n");
2210Sstevel@tonic-gate }
2229134SJoep.Vesseur@Sun.COM len = printf(" %s ", exec->id);
2239134SJoep.Vesseur@Sun.COM
2249134SJoep.Vesseur@Sun.COM if ((exec->attr == NULL || exec->attr->data == NULL)) {
2250Sstevel@tonic-gate (void) printf("\n");
2260Sstevel@tonic-gate continue;
2270Sstevel@tonic-gate }
2289134SJoep.Vesseur@Sun.COM
2299134SJoep.Vesseur@Sun.COM /*
2309134SJoep.Vesseur@Sun.COM * if printing the name of the executable got us past the
2319134SJoep.Vesseur@Sun.COM * ATTR_COLth column, skip to ATTR_COL on a new line to
2329134SJoep.Vesseur@Sun.COM * print the attribues.
2339134SJoep.Vesseur@Sun.COM * else, just skip to ATTR_COL column.
2349134SJoep.Vesseur@Sun.COM */
2359134SJoep.Vesseur@Sun.COM if (len >= ATTR_COL)
2369134SJoep.Vesseur@Sun.COM (void) printf("\n%*s", ATTR_COL, " ");
2379134SJoep.Vesseur@Sun.COM else
2389134SJoep.Vesseur@Sun.COM (void) printf("%*s", ATTR_COL-len, " ");
2399134SJoep.Vesseur@Sun.COM len = ATTR_COL;
2409134SJoep.Vesseur@Sun.COM
2419134SJoep.Vesseur@Sun.COM /* print all attributes of this profile */
2429134SJoep.Vesseur@Sun.COM kv_pair = exec->attr->data;
2430Sstevel@tonic-gate for (i = 0; i < exec->attr->length; i++) {
2440Sstevel@tonic-gate key = kv_pair[i].key;
2450Sstevel@tonic-gate val = kv_pair[i].value;
2469134SJoep.Vesseur@Sun.COM if (key == NULL || val == NULL)
2470Sstevel@tonic-gate break;
2489134SJoep.Vesseur@Sun.COM /* align subsequent attributes on the same column */
2499134SJoep.Vesseur@Sun.COM if (i > 0)
2509134SJoep.Vesseur@Sun.COM (void) printf("%*s", len, " ");
2519134SJoep.Vesseur@Sun.COM (void) printf("%s=%s\n", key, val);
2520Sstevel@tonic-gate }
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate }
2550Sstevel@tonic-gate
2560Sstevel@tonic-gate static void
usage()2570Sstevel@tonic-gate usage()
2580Sstevel@tonic-gate {
2590Sstevel@tonic-gate (void) fprintf(stderr,
2600Sstevel@tonic-gate gettext(" usage: profiles [-l] [user1 user2 ...]\n"));
2610Sstevel@tonic-gate }
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate static void
print_profile_privs(kva_t * attr)264*12273SCasper.Dik@Sun.COM print_profile_privs(kva_t *attr)
2659134SJoep.Vesseur@Sun.COM {
2669134SJoep.Vesseur@Sun.COM char *privs;
2679134SJoep.Vesseur@Sun.COM
268*12273SCasper.Dik@Sun.COM if (attr) {
269*12273SCasper.Dik@Sun.COM privs = kva_match(attr, PROFATTR_PRIVS_KW);
2709134SJoep.Vesseur@Sun.COM if (privs)
2719134SJoep.Vesseur@Sun.COM (void) printf(" privs=%s", privs);
2729134SJoep.Vesseur@Sun.COM }
2739134SJoep.Vesseur@Sun.COM }
274