xref: /onnv-gate/usr/src/cmd/profiles/profiles.c (revision 12273:63678502e95e)
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