dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / auths / auths.c
blob5a4d7ddba7901d8c03573c0e76f69e1acf7d3f11
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
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>
37 #define EXIT_OK 0
38 #define EXIT_FATAL 1
39 #define EXIT_NON_FATAL 2
41 #ifndef TEXT_DOMAIN /* Should be defined by cc -D */
42 #define TEXT_DOMAIN "SYS_TEST"
43 #endif
45 #define INCRAUTHS 512
47 typedef struct cbs {
48 int auth_cnt;
49 int auth_max;
50 char **auths;
51 } cbs_t;
53 static int show_auths(char *, int);
54 static int add_auth(const char *, void *, void *);
55 static void free_auths(cbs_t *);
56 static void simplify(cbs_t *);
58 static char *progname = "auths";
60 int
61 main(int argc, char *argv[])
63 int status = EXIT_OK;
65 (void) setlocale(LC_ALL, "");
66 (void) textdomain(TEXT_DOMAIN);
68 switch (argc) {
69 case 1:
70 status = show_auths(NULL, 0);
71 break;
72 case 2:
73 status = show_auths(argv[argc-1], 0);
74 break;
75 default:
76 while (*++argv) {
77 status = show_auths(*argv, 1);
78 if (status == EXIT_FATAL) {
79 break;
82 break;
85 status = (status == EXIT_OK) ? status : EXIT_FATAL;
86 return (status);
89 static int
90 show_auths(char *username, int print_name)
92 int status = EXIT_OK;
93 struct passwd *pw;
94 int i;
95 cbs_t cbs = { 0, 0, NULL };
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);
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);
112 (void) _enum_auths(username, add_auth, NULL, &cbs);
114 if (cbs.auth_cnt == 0)
115 status = EXIT_NON_FATAL;
117 if (status == EXIT_NON_FATAL) {
118 (void) fprintf(stderr, "%s: %s: ", progname, username);
119 (void) fprintf(stderr, gettext("No authorizations\n"));
120 } else {
121 simplify(&cbs);
123 if (print_name)
124 (void) printf("%s: ", username);
126 /* print out the auths */
127 for (i = 0; i < cbs.auth_cnt - 1; i++)
128 (void) printf("%s,", cbs.auths[i]);
130 /* print out the last entry, without the comma */
131 (void) printf("%s\n", cbs.auths[cbs.auth_cnt - 1]);
133 /* free memory allocated for authorizations */
134 free_auths(&cbs);
137 return (status);
140 /*ARGSUSED*/
141 static int
142 add_auth(const char *authname, void *ctxt, void *res)
144 cbs_t *cbs = res;
146 if (cbs->auth_cnt >= cbs->auth_max) {
147 cbs->auth_max += INCRAUTHS;
148 cbs->auths = reallocarray(cbs->auths, cbs->auth_max,
149 sizeof (char *));
151 if (cbs->auths == NULL) {
152 (void) fprintf(stderr, "%s: ", progname);
153 (void) fprintf(stderr, gettext("Out of memory\n"));
154 exit(1);
158 cbs->auths[cbs->auth_cnt] = strdup(authname);
159 cbs->auth_cnt++;
161 return (0);
164 static void
165 free_auths(cbs_t *cbs)
167 int i;
169 for (i = 0; i < cbs->auth_cnt; i++)
170 free(cbs->auths[i]);
172 free(cbs->auths);
175 /* We have always ignored .grant in auths(1) */
176 static boolean_t
177 auth_match(const char *pattern, const char *auth)
179 size_t len = strlen(pattern);
181 if (pattern[len - 1] != KV_WILDCHAR)
182 return (B_FALSE);
184 return (strncmp(pattern, auth, len - 1) == 0);
187 static int
188 mstrptr(const void *a, const void *b)
190 char *const *ap = a;
191 char *const *bp = b;
193 return (strcmp(*ap, *bp));
197 * Simplify the returned authorizations: sort and match wildcards;
198 * we're using here that "*" sorts before any other character.
200 static void
201 simplify(cbs_t *cbs)
203 int rem, i;
205 /* First we sort */
206 qsort(cbs->auths, cbs->auth_cnt, sizeof (cbs->auths[0]), mstrptr);
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.
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];
227 cbs->auth_cnt -= rem;