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} |