xref: /illumos-gate/usr/src/cmd/profiles/profiles.c (revision 257873cfc1dd3337766407f80397db60a56f2f5a)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <pwd.h>
32 #include <string.h>
33 #include <libintl.h>
34 #include <locale.h>
35 #include <deflt.h>
36 #include <user_attr.h>
37 #include <prof_attr.h>
38 #include <exec_attr.h>
39 #include <auth_attr.h>
40 
41 
42 #define	EXIT_OK		0
43 #define	EXIT_FATAL	1
44 #define	EXIT_NON_FATAL	2
45 
46 #define	MAX_LINE_LEN	80		/* max 80 chars per line of output */
47 #define	TMP_BUF_LEN	2048		/* size of temp string buffer */
48 
49 #define	PRINT_DEFAULT	0x0000
50 #define	PRINT_NAME	0x0010
51 #define	PRINT_LONG	0x0020
52 
53 #ifndef TEXT_DOMAIN			/* Should be defined by cc -D */
54 #define	TEXT_DOMAIN	"SYS_TEST"
55 #endif
56 
57 #define	PROFLIST_SEP	","
58 
59 
60 static void usage();
61 static int show_profs(char *, int);
62 static int list_profs(userattr_t *, int);
63 static void print_profs_long(void *, int);
64 static void print_profs(char **, int, int);
65 static void format_attr(int *, int, char *);
66 static void getProfiles(char *, char **, int *);
67 static void getDefaultProfiles(char *, char **, int *);
68 
69 static char *progname = "profiles";
70 
71 int
72 main(int argc, char *argv[])
73 {
74 	extern int	optind;
75 	int		c;
76 	int		status = EXIT_OK;
77 	int		print_flag = PRINT_DEFAULT;
78 
79 	(void) setlocale(LC_ALL, "");
80 	(void) textdomain(TEXT_DOMAIN);
81 
82 	while ((c = getopt(argc, argv, "l")) != EOF) {
83 		switch (c) {
84 		case 'l':
85 			print_flag |= PRINT_LONG;
86 			break;
87 		default:
88 			usage();
89 			return (EXIT_FATAL);
90 		}
91 	}
92 	argc -= optind;
93 	argv += optind;
94 
95 	if (*argv == NULL) {
96 		status = show_profs(NULL, print_flag);
97 	} else {
98 		do {
99 			(void) printf("\n%s :\n", *argv);
100 			status = show_profs((char *)*argv,
101 			    (print_flag | PRINT_NAME));
102 			if (status == EXIT_FATAL) {
103 				break;
104 			}
105 		} while (*++argv);
106 	}
107 	status = (status == EXIT_OK) ? status : EXIT_FATAL;
108 
109 	return (status);
110 }
111 
112 
113 static int
114 show_profs(char *username, int print_flag)
115 {
116 	int		status = EXIT_OK;
117 	struct passwd	*pw;
118 	userattr_t	*user;
119 	char		*profArray[MAXPROFS];
120 	int		profcnt = 0;
121 	execattr_t	*exec;
122 
123 	if (username == NULL) {
124 		if ((pw = getpwuid(getuid())) == NULL) {
125 			status = EXIT_NON_FATAL;
126 			(void) fprintf(stderr, "%s: ", progname);
127 			(void) fprintf(stderr, gettext("No passwd entry\n"));
128 			return (status);
129 		}
130 		username = pw->pw_name;
131 	} else if (getpwnam(username) == NULL) {
132 		status = EXIT_NON_FATAL;
133 		(void) fprintf(stderr, "%s: %s : ", progname, username);
134 		(void) fprintf(stderr, gettext("No such user\n"));
135 		return (status);
136 	}
137 	if (username != NULL) {
138 		if ((user = getusernam(username)) != NULL) {
139 			status = list_profs(user, print_flag);
140 		} else {
141 			getDefaultProfiles(username, profArray, &profcnt);
142 			if (profcnt == 0) {
143 				status = EXIT_NON_FATAL;
144 			} else {
145 				if (print_flag & PRINT_LONG) {
146 					exec = getexecuser(username, KV_COMMAND,
147 					    NULL, GET_ALL);
148 					print_profs_long(exec, print_flag);
149 					free_execattr(exec);
150 				} else {
151 					print_profs(profArray, print_flag,
152 					    profcnt);
153 				}
154 			}
155 		}
156 	}
157 
158 	if (status == EXIT_NON_FATAL) {
159 		(void) fprintf(stderr, "%s: %s : ", progname, username);
160 		(void) fprintf(stderr, gettext("No profiles\n"));
161 	}
162 
163 	return (status);
164 }
165 
166 
167 static int
168 list_profs(userattr_t *user, int print_flag)
169 {
170 	int		status = EXIT_OK;
171 	char		*proflist = (char *)NULL;
172 	execattr_t	*exec = (execattr_t *)NULL;
173 	char		*profArray[MAXPROFS];
174 	int		profcnt = 0;
175 
176 	if (print_flag & PRINT_LONG) {
177 		exec = getexecuser(user->name, KV_COMMAND, NULL, GET_ALL);
178 		if (exec == NULL) {
179 			status = EXIT_NON_FATAL;
180 		}
181 	} else {
182 		proflist = kva_match(user->attr, USERATTR_PROFILES_KW);
183 		if (proflist != NULL) {
184 			getProfiles(proflist, profArray, &profcnt);
185 		}
186 		/* Also get any default profiles */
187 		getDefaultProfiles(user->name, profArray, &profcnt);
188 		if (profcnt == 0) {
189 			status = EXIT_NON_FATAL;
190 		}
191 	}
192 	if (status == EXIT_OK) {
193 		if (print_flag & PRINT_LONG) {
194 			print_profs_long(exec, print_flag);
195 			free_execattr(exec);
196 		} else {
197 			print_profs(profArray, print_flag, profcnt);
198 		}
199 	}
200 	free_userattr(user);
201 
202 	return (status);
203 }
204 
205 
206 static void
207 print_profs_long(void *data, int print_flag)
208 {
209 
210 	int		i;
211 	int		len;
212 	int		outlen;
213 	char		tmpstr[TMP_BUF_LEN];
214 	char		*lastname = "";
215 	char		*key;
216 	char		*val;
217 	kv_t		*kv_pair;
218 	execattr_t	*exec;
219 
220 	if (!(print_flag & PRINT_NAME)) {
221 		(void) printf("\n");
222 	}
223 	exec = (execattr_t *)data;
224 	while (exec != (execattr_t *)NULL) {
225 		if (strcmp(exec->name, lastname) != NULL) {
226 			(void) snprintf(tmpstr, sizeof (tmpstr),
227 			    "      %s:", exec->name);
228 			(void) printf("%s\n", tmpstr);
229 		}
230 		(void) snprintf(tmpstr, sizeof (tmpstr),
231 		    "          %s    ", exec->id);
232 		outlen = strlen(tmpstr);
233 		len = outlen;
234 		(void) printf("%s", tmpstr);
235 		if ((exec->attr == NULL) ||
236 		    (kv_pair = exec->attr->data) == NULL) {
237 			(void) printf("\n");
238 			lastname = exec->name;
239 			exec = exec->next;
240 			continue;
241 		}
242 		for (i = 0; i < exec->attr->length; i++) {
243 			key = kv_pair[i].key;
244 			val = kv_pair[i].value;
245 			if ((key == NULL) || (val == NULL)) {
246 				break;
247 			}
248 			if (i > 0) {
249 				(void) strlcpy(tmpstr, ", ", TMP_BUF_LEN);
250 				format_attr(&outlen, len, tmpstr);
251 			}
252 			(void) snprintf(tmpstr, sizeof (tmpstr), "%s=%s",
253 			    key, val);
254 			format_attr(&outlen, len, tmpstr);
255 		}
256 		(void) printf("\n");
257 		lastname = exec->name;
258 		exec = exec->next;
259 	}
260 }
261 
262 
263 static void
264 format_attr(int *outlen, int len, char *str)
265 {
266 	int newline = 0;
267 
268 	if ((MAX_LINE_LEN - *outlen) < strlen(str)) {
269 		newline = 1;
270 	}
271 	if (newline) {
272 		(void) printf("\n");
273 		len += strlen(str);
274 		(void) printf("%*s", len, str);
275 		*outlen = len;
276 	} else {
277 		*outlen += strlen(str);
278 		(void) printf("%s", str);
279 	}
280 }
281 
282 static void
283 usage()
284 {
285 	(void) fprintf(stderr,
286 	    gettext("  usage: profiles [-l] [user1 user2 ...]\n"));
287 }
288 
289 static void
290 getProfiles(char *profiles, char **profArray, int *profcnt) {
291 
292 	char		*prof;
293 	char		*lasts;
294 
295 	for (prof = (char *)strtok_r(profiles, PROFLIST_SEP, &lasts);
296 	    prof != NULL;
297 	    prof = (char *)strtok_r(NULL, PROFLIST_SEP, &lasts)) {
298 
299 		getproflist(prof, profArray, profcnt);
300 
301 	}
302 }
303 
304 static void
305 print_profs(char **profnames, int print_flag, int profcnt)
306 {
307 
308 	int i;
309 	char *indent = "";
310 
311 	if (print_flag & PRINT_NAME) {
312 		indent = "          ";
313 	}
314 
315 	for (i = 0; i < profcnt; i++) {
316 		(void) printf("%s%s\n", indent, profnames[i]);
317 	}
318 
319 	free_proflist(profnames, profcnt);
320 }
321 
322 /*
323  * Get the list of default profiles from /etc/security/policy.conf
324  */
325 static void
326 getDefaultProfiles(char *user, char **profArray, int *profcnt)
327 {
328 	char *profs = NULL;
329 
330 	if (_get_user_defs(user, NULL, &profs) == 0) {
331 		if (profs != NULL) {
332 			getProfiles(profs, profArray, profcnt);
333 			_free_user_defs(NULL, profs);
334 		}
335 	}
336 }
337