xref: /illumos-gate/usr/src/cmd/auths/auths.c (revision bfed486ad8de8b8ebc6345a8e10accae08bf2f45)
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 <deflt.h>
34 #include <libintl.h>
35 #include <locale.h>
36 #include <user_attr.h>
37 #include <prof_attr.h>
38 #include <auth_attr.h>
39 
40 
41 #define	ALL_AUTHS	"All"
42 #define	ALL_SUN_AUTHS	"solaris.*"
43 
44 #define	EXIT_OK		0
45 #define	EXIT_FATAL	1
46 #define	EXIT_NON_FATAL	2
47 
48 #ifndef	TEXT_DOMAIN			/* Should be defined by cc -D */
49 #define	TEXT_DOMAIN	"SYS_TEST"
50 #endif
51 
52 #define	PROFLIST_SEP	","
53 #define	AUTH_SEP	","
54 #define	MAXAUTHS	4096
55 
56 
57 static int show_auths(char *, char **, int, int);
58 static int list_auths(userattr_t *, char **, int *);
59 static void get_default_auths(char *, char **, int *);
60 static void getProfiles(char *, char **, int *, char **, int *);
61 static void add_auths(char *, char **, int *);
62 static void free_auths(char **, int *);
63 
64 static char *progname = "auths";
65 
66 
67 int
68 main(int argc, char *argv[])
69 {
70 	int		status = EXIT_OK;
71 	char		*defauths[MAXAUTHS];
72 	int		defauth_cnt = 0;
73 
74 	(void) setlocale(LC_ALL, "");
75 	(void) textdomain(TEXT_DOMAIN);
76 
77 	switch (argc) {
78 	case 1:
79 		get_default_auths(NULL, defauths, &defauth_cnt);
80 		status = show_auths(NULL, defauths, defauth_cnt, 0);
81 		break;
82 	case 2:
83 		get_default_auths(argv[argc-1], defauths, &defauth_cnt);
84 		status = show_auths(argv[argc-1], defauths, defauth_cnt, 0);
85 		break;
86 	default:
87 		while (*++argv) {
88 			get_default_auths(*argv, defauths, &defauth_cnt);
89 			status = show_auths(*argv, defauths, defauth_cnt, 1);
90 			if (status == EXIT_FATAL) {
91 				break;
92 			}
93 			/* free memory allocated for default authorizations */
94 			free_auths(defauths, &defauth_cnt);
95 			(void) printf("\n");
96 		}
97 		break;
98 	}
99 
100 	/* free memory allocated for default authorizations */
101 	free_auths(defauths, &defauth_cnt);
102 	status = (status == EXIT_OK) ? status : EXIT_FATAL;
103 
104 	return (status);
105 }
106 
107 
108 static int
109 show_auths(char *username, char **defauths, int defauth_cnt, int print_name)
110 {
111 	int		status = EXIT_OK;
112 	struct passwd	*pw;
113 	userattr_t	*user;
114 	char		*userauths[MAXAUTHS];
115 	int		userauth_cnt = 0, old_userauth_cnt;
116 	int		i, j, have_allauths, duplicate;
117 
118 	if (username == NULL) {
119 		if ((pw = getpwuid(getuid())) == NULL) {
120 			status = EXIT_NON_FATAL;
121 			(void) fprintf(stderr, "%s: ", progname);
122 			(void) fprintf(stderr, gettext("No passwd entry\n"));
123 			return (status);
124 		}
125 		username = pw->pw_name;
126 	} else if (getpwnam(username) == NULL) {
127 		status = EXIT_NON_FATAL;
128 		(void) fprintf(stderr, "%s: %s : ", progname, username);
129 		(void) fprintf(stderr, gettext("No such user\n"));
130 		return (status);
131 	}
132 
133 	have_allauths = 0;
134 	if (username != NULL) {
135 		/* if ALL_AUTHS is default, don't need to look at other auths */
136 		for (i = 0; i < defauth_cnt; i++) {
137 			if (strcmp(defauths[i], ALL_AUTHS) == 0) {
138 				have_allauths = 1;
139 				break;
140 			}
141 		}
142 		if (have_allauths) {
143 			status = EXIT_OK;
144 		} else if ((user = getusernam(username)) != NULL) {
145 			status = list_auths(user, userauths, &userauth_cnt);
146 			/* check if any profiles have ALL_AUTHS */
147 			for (i = 0; i < userauth_cnt; i++) {
148 				if (strcmp(userauths[i], ALL_AUTHS) == 0) {
149 					have_allauths = 1;
150 					break;
151 				}
152 			}
153 		}
154 		if ((defauth_cnt + userauth_cnt) == 0) {
155 			status = EXIT_NON_FATAL;
156 		}
157 	}
158 	if (status == EXIT_NON_FATAL) {
159 		(void) fprintf(stderr, "%s: %s : ", progname, username);
160 		(void) fprintf(stderr, gettext("No authorizations\n"));
161 	} else {
162 		if (print_name) {
163 			(void) printf("%s : ", username);
164 		}
165 
166 		if (have_allauths) {
167 			(void) printf("%s\n", ALL_SUN_AUTHS);
168 		} else {
169 			/*
170 			 * combine the user auths and default auths,
171 			 * and eliminate duplicates from the two
172 			 */
173 			old_userauth_cnt = userauth_cnt;
174 			for (i = 0; i < defauth_cnt; i++) {
175 				duplicate = 0;
176 				for (j = 0; j < old_userauth_cnt; j++) {
177 					if (strcmp(userauths[j], defauths[i]) ==
178 					    0) {
179 						duplicate = 1;
180 						break;
181 					}
182 				}
183 				if (!duplicate) {
184 					userauths[userauth_cnt] =
185 					    strdup(defauths[i]);
186 					userauth_cnt++;
187 				}
188 			}
189 
190 			/* print out the auths */
191 			for (i = 0; i < (userauth_cnt - 1); i++) {
192 				(void) printf("%s,", userauths[i]);
193 			}
194 
195 			/* print out the last entry, without the comma */
196 			(void) printf("%s\n", userauths[userauth_cnt - 1]);
197 		}
198 	}
199 
200 	/* free memory allocated for authorizations */
201 	free_auths(userauths, &userauth_cnt);
202 
203 	return (status);
204 }
205 
206 
207 static int
208 list_auths(userattr_t *user, char **authArray, int *authcnt)
209 {
210 	int		status = EXIT_OK;
211 	char		*authlist = NULL;
212 	char		*proflist = NULL;
213 	char		*profArray[MAXPROFS];
214 	int		profcnt = 0;
215 
216 	authlist = kva_match(user->attr, USERATTR_AUTHS_KW);
217 	if (authlist != NULL) {
218 		add_auths(authlist, authArray, authcnt);
219 	}
220 	if ((proflist = kva_match(user->attr, USERATTR_PROFILES_KW)) == NULL) {
221 		if (authcnt == 0) {
222 			status = EXIT_NON_FATAL;
223 		}
224 	} else {
225 		getProfiles(proflist, profArray, &profcnt,
226 		    authArray, authcnt);
227 		free_proflist(profArray, profcnt);
228 	}
229 	if (authcnt == 0) {
230 		status = EXIT_NON_FATAL;
231 	}
232 	free_userattr(user);
233 
234 	return (status);
235 }
236 
237 
238 static void
239 get_default_auths(char *user, char **authArray, int *authcnt)
240 {
241 	char *auths = NULL;
242 	char *profs = NULL;
243 	char *profArray[MAXPROFS];
244 	int profcnt = 0;
245 
246 	if (user == NULL) {
247 		struct passwd *pw;
248 
249 		if ((pw = getpwuid(getuid())) != NULL) {
250 			user = pw->pw_name;
251 		}
252 	}
253 
254 	if (_get_user_defs(user, &auths, &profs) == 0) {
255 		if (auths != NULL) {
256 			add_auths(auths, authArray, authcnt);
257 		}
258 
259 		/* get authorizations from default profiles */
260 		if (profs != NULL) {
261 			getProfiles(profs, profArray, &profcnt,
262 			    authArray, authcnt);
263 			free_proflist(profArray, profcnt);
264 		}
265 		_free_user_defs(auths, profs);
266 	}
267 }
268 
269 void
270 add_auths(char *auths, char **authArray, int *authcnt)
271 {
272 	char	*authname, *lasts, *real_authname;
273 	int	i;
274 
275 	for (authname = (char *)strtok_r(auths, AUTH_SEP, &lasts);
276 	    authname != NULL;
277 	    authname = (char *)strtok_r(NULL, AUTH_SEP, &lasts)) {
278 
279 		if ((strcmp(authname, KV_WILDCARD) == 0) ||
280 		    (strcmp(authname, ALL_SUN_AUTHS) == 0)) {
281 			real_authname = ALL_AUTHS;
282 		} else {
283 			real_authname = authname;
284 		}
285 
286 		/* check to see if authorization is already in list */
287 		for (i = 0; i < *authcnt; i++) {
288 			if (strcmp(real_authname, authArray[i]) == 0) {
289 				break;	/* already in list */
290 			}
291 		}
292 
293 		/* not in list, add it in */
294 		if (i == *authcnt) {
295 			authArray[i] = strdup(real_authname);
296 			*authcnt = i + 1;
297 		}
298 	}
299 
300 }
301 
302 static void
303 free_auths(char *auths[], int *auth_cnt)
304 {
305 	int i;
306 
307 	for (i = 0; i < *auth_cnt; i++) {
308 		free(auths[i]);
309 	}
310 	*auth_cnt = 0;
311 }
312 
313 static void
314 getProfiles(char *profiles, char **profArray, int *profcnt,
315 	char **authArray, int *authcnt)
316 {
317 
318 	char		*prof;
319 	char		*lasts;
320 	profattr_t	*pa;
321 	char		*auths;
322 	int		i;
323 
324 	for (prof = (char *)strtok_r(profiles, PROFLIST_SEP, &lasts);
325 	    prof != NULL;
326 	    prof = (char *)strtok_r(NULL, PROFLIST_SEP, &lasts)) {
327 
328 		getproflist(prof, profArray, profcnt);
329 	}
330 
331 	/* get authorizations from list of profiles */
332 	for (i = 0; i < *profcnt; i++) {
333 
334 		if ((pa = getprofnam(profArray[i])) == NULL) {
335 			/*
336 			 *  this should never happen.
337 			 *  unless the database has an undefined profile
338 			 */
339 			continue;
340 		}
341 
342 		/* get auths this profile */
343 		auths = kva_match(pa->attr, PROFATTR_AUTHS_KW);
344 		if (auths != NULL) {
345 			add_auths(auths, authArray, authcnt);
346 		}
347 
348 		free_profattr(pa);
349 	}
350 }
351