auths.c (49a66a682b5ea524222294a1268bb1a9e7ac3af5) auths.c (134a1f4e3289b54e0f980e9cf05352e419a60bee)
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

--- 5 unchanged lines hidden (view full) ---

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/*
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

--- 5 unchanged lines hidden (view full) ---

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.
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
23 */
24
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
25#include <stdio.h>
26#include <stdlib.h>
27#include <unistd.h>
28#include <pwd.h>
29#include <string.h>
30#include <deflt.h>
31#include <libintl.h>
32#include <locale.h>
33#include <user_attr.h>
34#include <prof_attr.h>
35#include <auth_attr.h>
36
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
37#define EXIT_OK 0
38#define EXIT_FATAL 1
39#define EXIT_NON_FATAL 2
40
41#ifndef TEXT_DOMAIN /* Should be defined by cc -D */
42#define TEXT_DOMAIN "SYS_TEST"
43#endif
44
52#define PROFLIST_SEP ","
53#define AUTH_SEP ","
54#define MAXAUTHS 4096
45#define INCRAUTHS 512
55
46
47typedef struct cbs {
48 int auth_cnt;
49 int auth_max;
50 char **auths;
51} cbs_t;
56
52
57static int show_auths(char *, char **, int, int);
58static int list_auths(userattr_t *, char **, int *);
59static void get_default_auths(char *, char **, int *);
60static void getProfiles(char *, char **, int *, char **, int *);
61static void add_auths(char *, char **, int *);
62static void free_auths(char **, int *);
53static int show_auths(char *, int);
54static int add_auth(const char *, void *, void *);
55static void free_auths(cbs_t *);
56static void simplify(cbs_t *);
63
64static char *progname = "auths";
65
57
58static char *progname = "auths";
59
66
67int
68main(int argc, char *argv[])
69{
70 int status = EXIT_OK;
60int
61main(int argc, char *argv[])
62{
63 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:
64
65 (void) setlocale(LC_ALL, "");
66 (void) textdomain(TEXT_DOMAIN);
67
68 switch (argc) {
69 case 1:
79 get_default_auths(NULL, defauths, &defauth_cnt);
80 status = show_auths(NULL, defauths, defauth_cnt, 0);
70 status = show_auths(NULL, 0);
81 break;
82 case 2:
71 break;
72 case 2:
83 get_default_auths(argv[argc-1], defauths, &defauth_cnt);
84 status = show_auths(argv[argc-1], defauths, defauth_cnt, 0);
73 status = show_auths(argv[argc-1], 0);
85 break;
86 default:
87 while (*++argv) {
74 break;
75 default:
76 while (*++argv) {
88 get_default_auths(*argv, defauths, &defauth_cnt);
89 status = show_auths(*argv, defauths, defauth_cnt, 1);
77 status = show_auths(*argv, 1);
90 if (status == EXIT_FATAL) {
91 break;
92 }
78 if (status == EXIT_FATAL) {
79 break;
80 }
93 /* free memory allocated for default authorizations */
94 free_auths(defauths, &defauth_cnt);
95 (void) printf("\n");
96 }
97 break;
98 }
99
81 }
82 break;
83 }
84
100 /* free memory allocated for default authorizations */
101 free_auths(defauths, &defauth_cnt);
102 status = (status == EXIT_OK) ? status : EXIT_FATAL;
85 status = (status == EXIT_OK) ? status : EXIT_FATAL;
103
104 return (status);
105}
106
86 return (status);
87}
88
107
108static int
89static int
109show_auths(char *username, char **defauths, int defauth_cnt, int print_name)
90show_auths(char *username, int print_name)
110{
111 int status = EXIT_OK;
112 struct passwd *pw;
91{
92 int status = EXIT_OK;
93 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;
94 int i;
95 cbs_t cbs = { 0, 0, NULL };
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
96
97 if (username == NULL) {
98 if ((pw = getpwuid(getuid())) == NULL) {
99 status = EXIT_NON_FATAL;
100 (void) fprintf(stderr, "%s: ", progname);
101 (void) fprintf(stderr, gettext("No passwd entry\n"));
102 return (status);
103 }
104 username = pw->pw_name;
105 } else if (getpwnam(username) == NULL) {
106 status = EXIT_NON_FATAL;
107 (void) fprintf(stderr, "%s: %s : ", progname, username);
108 (void) fprintf(stderr, gettext("No such user\n"));
109 return (status);
110 }
111
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 }
112 (void) _enum_auths(username, add_auth, NULL, &cbs);
113
114 if (cbs.auth_cnt == 0)
115 status = EXIT_NON_FATAL;
116
158 if (status == EXIT_NON_FATAL) {
117 if (status == EXIT_NON_FATAL) {
159 (void) fprintf(stderr, "%s: %s : ", progname, username);
118 (void) fprintf(stderr, "%s: %s: ", progname, username);
160 (void) fprintf(stderr, gettext("No authorizations\n"));
161 } else {
119 (void) fprintf(stderr, gettext("No authorizations\n"));
120 } else {
162 if (print_name) {
163 (void) printf("%s : ", username);
164 }
121 simplify(&cbs);
165
122
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 }
123 if (print_name)
124 (void) printf("%s: ", username);
189
125
190 /* print out the auths */
191 for (i = 0; i < (userauth_cnt - 1); i++) {
192 (void) printf("%s,", userauths[i]);
193 }
126 /* print out the auths */
127 for (i = 0; i < cbs.auth_cnt - 1; i++)
128 (void) printf("%s,", cbs.auths[i]);
194
129
195 /* print out the last entry, without the comma */
196 (void) printf("%s\n", userauths[userauth_cnt - 1]);
197 }
130 /* print out the last entry, without the comma */
131 (void) printf("%s\n", cbs.auths[cbs.auth_cnt - 1]);
132
133 /* free memory allocated for authorizations */
134 free_auths(&cbs);
198 }
199
135 }
136
200 /* free memory allocated for authorizations */
201 free_auths(userauths, &userauth_cnt);
202
203 return (status);
204}
205
137 return (status);
138}
139
206
140/*ARGSUSED*/
207static int
141static int
208list_auths(userattr_t *user, char **authArray, int *authcnt)
142add_auth(const char *authname, void *ctxt, void *res)
209{
143{
210 int status = EXIT_OK;
211 char *authlist = NULL;
212 char *proflist = NULL;
213 char *profArray[MAXPROFS];
214 int profcnt = 0;
144 cbs_t *cbs = res;
215
145
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;
146 if (cbs->auth_cnt >= cbs->auth_max) {
147 cbs->auth_max += INCRAUTHS;
148 cbs->auths = realloc(cbs->auths,
149 cbs->auth_max * sizeof (char *));
150
151 if (cbs->auths == NULL) {
152 (void) fprintf(stderr, "%s: ", progname);
153 (void) fprintf(stderr, gettext("Out of memory\n"));
154 exit(1);
223 }
155 }
224 } else {
225 getProfiles(proflist, profArray, &profcnt,
226 authArray, authcnt);
227 free_proflist(profArray, profcnt);
228 }
156 }
229 if (authcnt == 0) {
230 status = EXIT_NON_FATAL;
231 }
232 free_userattr(user);
233
157
234 return (status);
158 cbs->auths[cbs->auth_cnt] = strdup(authname);
159 cbs->auth_cnt++;
160
161 return (0);
235}
236
162}
163
237
238static void
164static void
239get_default_auths(char *user, char **authArray, int *authcnt)
165free_auths(cbs_t *cbs)
240{
166{
241 char *auths = NULL;
242 char *profs = NULL;
243 char *profArray[MAXPROFS];
244 int profcnt = 0;
167 int i;
245
168
246 if (user == NULL) {
247 struct passwd *pw;
169 for (i = 0; i < cbs->auth_cnt; i++)
170 free(cbs->auths[i]);
248
171
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 }
172 free(cbs->auths);
267}
268
173}
174
269void
270add_auths(char *auths, char **authArray, int *authcnt)
175/* We have always ignored .grant in auths(1) */
176static boolean_t
177auth_match(const char *pattern, const char *auth)
271{
178{
272 char *authname, *lasts, *real_authname;
273 int i;
179 size_t len = strlen(pattern);
274
180
275 for (authname = (char *)strtok_r(auths, AUTH_SEP, &lasts);
276 authname != NULL;
277 authname = (char *)strtok_r(NULL, AUTH_SEP, &lasts)) {
181 if (pattern[len - 1] != KV_WILDCHAR)
182 return (B_FALSE);
278
183
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
184 return (strncmp(pattern, auth, len - 1) == 0);
300}
301
185}
186
302static void
303free_auths(char *auths[], int *auth_cnt)
187static int
188mstrptr(const void *a, const void *b)
304{
189{
305 int i;
190 char *const *ap = a;
191 char *const *bp = b;
306
192
307 for (i = 0; i < *auth_cnt; i++) {
308 free(auths[i]);
309 }
310 *auth_cnt = 0;
193 return (strcmp(*ap, *bp));
311}
312
194}
195
196/*
197 * Simplify the returned authorizations: sort and match wildcards;
198 * we're using here that "*" sorts before any other character.
199 */
313static void
200static void
314getProfiles(char *profiles, char **profArray, int *profcnt,
315 char **authArray, int *authcnt)
201simplify(cbs_t *cbs)
316{
202{
203 int rem, i;
317
204
318 char *prof;
319 char *lasts;
320 profattr_t *pa;
321 char *auths;
322 int i;
205 /* First we sort */
206 qsort(cbs->auths, cbs->auth_cnt, sizeof (cbs->auths[0]), mstrptr);
323
207
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;
208 /*
209 * Then we remove the entries which match a later entry.
210 * We walk the list, with "i + rem + 1" the cursor for the possible
211 * candidate for removal. With "rem" we count the removed entries
212 * and we copy while we're looking for duplicate/superfluous entries.
213 */
214 for (i = 0, rem = 0; i < cbs->auth_cnt - rem - 1; ) {
215 if (strcmp(cbs->auths[i], cbs->auths[i + rem + 1]) == 0 ||
216 strchr(cbs->auths[i], KV_WILDCHAR) != NULL &&
217 auth_match(cbs->auths[i], cbs->auths[i + rem + 1])) {
218 free(cbs->auths[i + rem + 1]);
219 rem++;
220 } else {
221 i++;
222 if (rem > 0)
223 cbs->auths[i] = cbs->auths[i + rem];
340 }
224 }
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 }
225 }
226
227 cbs->auth_cnt -= rem;
350}
228}