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]
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
33 #include <user_attr.h>
34 #include <prof_attr.h>
35 #include <auth_attr.h>
39 #define EXIT_NON_FATAL 2
41 #ifndef TEXT_DOMAIN /* Should be defined by cc -D */
42 #define TEXT_DOMAIN "SYS_TEST"
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";
61 main(int argc
, char *argv
[])
65 (void) setlocale(LC_ALL
, "");
66 (void) textdomain(TEXT_DOMAIN
);
70 status
= show_auths(NULL
, 0);
73 status
= show_auths(argv
[argc
-1], 0);
77 status
= show_auths(*argv
, 1);
78 if (status
== EXIT_FATAL
) {
85 status
= (status
== EXIT_OK
) ? status
: EXIT_FATAL
;
90 show_auths(char *username
, int print_name
)
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"));
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"));
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"));
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 */
142 add_auth(const char *authname
, void *ctxt
, void *res
)
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 *));
151 if (cbs
->auths
== NULL
) {
152 (void) fprintf(stderr
, "%s: ", progname
);
153 (void) fprintf(stderr
, gettext("Out of memory\n"));
158 cbs
->auths
[cbs
->auth_cnt
] = strdup(authname
);
165 free_auths(cbs_t
*cbs
)
169 for (i
= 0; i
< cbs
->auth_cnt
; i
++)
175 /* We have always ignored .grant in auths(1) */
177 auth_match(const char *pattern
, const char *auth
)
179 size_t len
= strlen(pattern
);
181 if (pattern
[len
- 1] != KV_WILDCHAR
)
184 return (strncmp(pattern
, auth
, len
- 1) == 0);
188 mstrptr(const void *a
, const void *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.
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]);
223 cbs
->auths
[i
] = cbs
->auths
[i
+ rem
];
227 cbs
->auth_cnt
-= rem
;