summaryrefslogtreecommitdiff
path: root/usr/src/cmd/auths/auths.c
diff options
context:
space:
mode:
authorCasper H.S. Dik <Casper.Dik@Sun.COM>2010-04-28 10:01:37 +0200
committerCasper H.S. Dik <Casper.Dik@Sun.COM>2010-04-28 10:01:37 +0200
commit134a1f4e3289b54e0f980e9cf05352e419a60bee (patch)
tree792d1e39f7d9299df1f67c1681a02daa1b734878 /usr/src/cmd/auths/auths.c
parent2e98bdabdfa935eb368c090f1cecbba5619c88ee (diff)
downloadillumos-joyent-134a1f4e3289b54e0f980e9cf05352e419a60bee.tar.gz
PSARC 2009/377 In-kernel pfexec implementation.
PSARC 2009/378 Basic File Privileges PSARC 2010/072 RBAC update: user attrs from profiles 4912090 pfzsh(1) should exist 4912093 pfbash(1) should exist 4912096 pftcsh(1) should exist 6440298 Expand the basic privilege set in order to restrict file access 6859862 Move pfexec into the kernel 6919171 cred_t sidesteps kmem_debug; we need to be able to detect bad hold/free when they occur 6923721 The new SYS_SMB privilege is not backward compatible 6937562 autofs doesn't remove its door when the zone shuts down 6937727 Zones stuck on deathrow; netstack_zone keeps a credential reference to the zone 6940159 Implement PSARC 2010/072
Diffstat (limited to 'usr/src/cmd/auths/auths.c')
-rw-r--r--usr/src/cmd/auths/auths.c314
1 files changed, 96 insertions, 218 deletions
diff --git a/usr/src/cmd/auths/auths.c b/usr/src/cmd/auths/auths.c
index 82416e0017..98141feb88 100644
--- a/usr/src/cmd/auths/auths.c
+++ b/usr/src/cmd/auths/auths.c
@@ -19,12 +19,9 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -37,10 +34,6 @@
#include <prof_attr.h>
#include <auth_attr.h>
-
-#define ALL_AUTHS "All"
-#define ALL_SUN_AUTHS "solaris.*"
-
#define EXIT_OK 0
#define EXIT_FATAL 1
#define EXIT_NON_FATAL 2
@@ -49,71 +42,57 @@
#define TEXT_DOMAIN "SYS_TEST"
#endif
-#define PROFLIST_SEP ","
-#define AUTH_SEP ","
-#define MAXAUTHS 4096
+#define INCRAUTHS 512
+typedef struct cbs {
+ int auth_cnt;
+ int auth_max;
+ char **auths;
+} cbs_t;
-static int show_auths(char *, char **, int, int);
-static int list_auths(userattr_t *, char **, int *);
-static void get_default_auths(char *, char **, int *);
-static void getProfiles(char *, char **, int *, char **, int *);
-static void add_auths(char *, char **, int *);
-static void free_auths(char **, int *);
+static int show_auths(char *, int);
+static int add_auth(const char *, void *, void *);
+static void free_auths(cbs_t *);
+static void simplify(cbs_t *);
static char *progname = "auths";
-
int
main(int argc, char *argv[])
{
int status = EXIT_OK;
- char *defauths[MAXAUTHS];
- int defauth_cnt = 0;
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
switch (argc) {
case 1:
- get_default_auths(NULL, defauths, &defauth_cnt);
- status = show_auths(NULL, defauths, defauth_cnt, 0);
+ status = show_auths(NULL, 0);
break;
case 2:
- get_default_auths(argv[argc-1], defauths, &defauth_cnt);
- status = show_auths(argv[argc-1], defauths, defauth_cnt, 0);
+ status = show_auths(argv[argc-1], 0);
break;
default:
while (*++argv) {
- get_default_auths(*argv, defauths, &defauth_cnt);
- status = show_auths(*argv, defauths, defauth_cnt, 1);
+ status = show_auths(*argv, 1);
if (status == EXIT_FATAL) {
break;
}
- /* free memory allocated for default authorizations */
- free_auths(defauths, &defauth_cnt);
- (void) printf("\n");
}
break;
}
- /* free memory allocated for default authorizations */
- free_auths(defauths, &defauth_cnt);
status = (status == EXIT_OK) ? status : EXIT_FATAL;
-
return (status);
}
-
static int
-show_auths(char *username, char **defauths, int defauth_cnt, int print_name)
+show_auths(char *username, int print_name)
{
int status = EXIT_OK;
struct passwd *pw;
- userattr_t *user;
- char *userauths[MAXAUTHS];
- int userauth_cnt = 0, old_userauth_cnt;
- int i, j, have_allauths, duplicate;
+ int i;
+ cbs_t cbs = { 0, 0, NULL };
if (username == NULL) {
if ((pw = getpwuid(getuid())) == NULL) {
@@ -130,221 +109,120 @@ show_auths(char *username, char **defauths, int defauth_cnt, int print_name)
return (status);
}
- have_allauths = 0;
- if (username != NULL) {
- /* if ALL_AUTHS is default, don't need to look at other auths */
- for (i = 0; i < defauth_cnt; i++) {
- if (strcmp(defauths[i], ALL_AUTHS) == 0) {
- have_allauths = 1;
- break;
- }
- }
- if (have_allauths) {
- status = EXIT_OK;
- } else if ((user = getusernam(username)) != NULL) {
- status = list_auths(user, userauths, &userauth_cnt);
- /* check if any profiles have ALL_AUTHS */
- for (i = 0; i < userauth_cnt; i++) {
- if (strcmp(userauths[i], ALL_AUTHS) == 0) {
- have_allauths = 1;
- break;
- }
- }
- }
- if ((defauth_cnt + userauth_cnt) == 0) {
- status = EXIT_NON_FATAL;
- }
- }
+ (void) _enum_auths(username, add_auth, NULL, &cbs);
+
+ if (cbs.auth_cnt == 0)
+ status = EXIT_NON_FATAL;
+
if (status == EXIT_NON_FATAL) {
- (void) fprintf(stderr, "%s: %s : ", progname, username);
+ (void) fprintf(stderr, "%s: %s: ", progname, username);
(void) fprintf(stderr, gettext("No authorizations\n"));
} else {
- if (print_name) {
- (void) printf("%s : ", username);
- }
-
- if (have_allauths) {
- (void) printf("%s\n", ALL_SUN_AUTHS);
- } else {
- /*
- * combine the user auths and default auths,
- * and eliminate duplicates from the two
- */
- old_userauth_cnt = userauth_cnt;
- for (i = 0; i < defauth_cnt; i++) {
- duplicate = 0;
- for (j = 0; j < old_userauth_cnt; j++) {
- if (strcmp(userauths[j], defauths[i]) ==
- 0) {
- duplicate = 1;
- break;
- }
- }
- if (!duplicate) {
- userauths[userauth_cnt] =
- strdup(defauths[i]);
- userauth_cnt++;
- }
- }
-
- /* print out the auths */
- for (i = 0; i < (userauth_cnt - 1); i++) {
- (void) printf("%s,", userauths[i]);
- }
-
- /* print out the last entry, without the comma */
- (void) printf("%s\n", userauths[userauth_cnt - 1]);
- }
- }
+ simplify(&cbs);
- /* free memory allocated for authorizations */
- free_auths(userauths, &userauth_cnt);
+ if (print_name)
+ (void) printf("%s: ", username);
- return (status);
-}
+ /* print out the auths */
+ for (i = 0; i < cbs.auth_cnt - 1; i++)
+ (void) printf("%s,", cbs.auths[i]);
+ /* print out the last entry, without the comma */
+ (void) printf("%s\n", cbs.auths[cbs.auth_cnt - 1]);
-static int
-list_auths(userattr_t *user, char **authArray, int *authcnt)
-{
- int status = EXIT_OK;
- char *authlist = NULL;
- char *proflist = NULL;
- char *profArray[MAXPROFS];
- int profcnt = 0;
-
- authlist = kva_match(user->attr, USERATTR_AUTHS_KW);
- if (authlist != NULL) {
- add_auths(authlist, authArray, authcnt);
- }
- if ((proflist = kva_match(user->attr, USERATTR_PROFILES_KW)) == NULL) {
- if (authcnt == 0) {
- status = EXIT_NON_FATAL;
- }
- } else {
- getProfiles(proflist, profArray, &profcnt,
- authArray, authcnt);
- free_proflist(profArray, profcnt);
+ /* free memory allocated for authorizations */
+ free_auths(&cbs);
}
- if (authcnt == 0) {
- status = EXIT_NON_FATAL;
- }
- free_userattr(user);
return (status);
}
-
-static void
-get_default_auths(char *user, char **authArray, int *authcnt)
+/*ARGSUSED*/
+static int
+add_auth(const char *authname, void *ctxt, void *res)
{
- char *auths = NULL;
- char *profs = NULL;
- char *profArray[MAXPROFS];
- int profcnt = 0;
+ cbs_t *cbs = res;
- if (user == NULL) {
- struct passwd *pw;
+ if (cbs->auth_cnt >= cbs->auth_max) {
+ cbs->auth_max += INCRAUTHS;
+ cbs->auths = realloc(cbs->auths,
+ cbs->auth_max * sizeof (char *));
- if ((pw = getpwuid(getuid())) != NULL) {
- user = pw->pw_name;
+ if (cbs->auths == NULL) {
+ (void) fprintf(stderr, "%s: ", progname);
+ (void) fprintf(stderr, gettext("Out of memory\n"));
+ exit(1);
}
}
- if (_get_user_defs(user, &auths, &profs) == 0) {
- if (auths != NULL) {
- add_auths(auths, authArray, authcnt);
- }
+ cbs->auths[cbs->auth_cnt] = strdup(authname);
+ cbs->auth_cnt++;
- /* get authorizations from default profiles */
- if (profs != NULL) {
- getProfiles(profs, profArray, &profcnt,
- authArray, authcnt);
- free_proflist(profArray, profcnt);
- }
- _free_user_defs(auths, profs);
- }
+ return (0);
}
-void
-add_auths(char *auths, char **authArray, int *authcnt)
+static void
+free_auths(cbs_t *cbs)
{
- char *authname, *lasts, *real_authname;
- int i;
+ int i;
- for (authname = (char *)strtok_r(auths, AUTH_SEP, &lasts);
- authname != NULL;
- authname = (char *)strtok_r(NULL, AUTH_SEP, &lasts)) {
+ for (i = 0; i < cbs->auth_cnt; i++)
+ free(cbs->auths[i]);
- if ((strcmp(authname, KV_WILDCARD) == 0) ||
- (strcmp(authname, ALL_SUN_AUTHS) == 0)) {
- real_authname = ALL_AUTHS;
- } else {
- real_authname = authname;
- }
+ free(cbs->auths);
+}
- /* check to see if authorization is already in list */
- for (i = 0; i < *authcnt; i++) {
- if (strcmp(real_authname, authArray[i]) == 0) {
- break; /* already in list */
- }
- }
+/* We have always ignored .grant in auths(1) */
+static boolean_t
+auth_match(const char *pattern, const char *auth)
+{
+ size_t len = strlen(pattern);
- /* not in list, add it in */
- if (i == *authcnt) {
- authArray[i] = strdup(real_authname);
- *authcnt = i + 1;
- }
- }
+ if (pattern[len - 1] != KV_WILDCHAR)
+ return (B_FALSE);
+ return (strncmp(pattern, auth, len - 1) == 0);
}
-static void
-free_auths(char *auths[], int *auth_cnt)
+static int
+mstrptr(const void *a, const void *b)
{
- int i;
+ char *const *ap = a;
+ char *const *bp = b;
- for (i = 0; i < *auth_cnt; i++) {
- free(auths[i]);
- }
- *auth_cnt = 0;
+ return (strcmp(*ap, *bp));
}
+/*
+ * Simplify the returned authorizations: sort and match wildcards;
+ * we're using here that "*" sorts before any other character.
+ */
static void
-getProfiles(char *profiles, char **profArray, int *profcnt,
- char **authArray, int *authcnt)
+simplify(cbs_t *cbs)
{
-
- char *prof;
- char *lasts;
- profattr_t *pa;
- char *auths;
- int i;
-
- for (prof = (char *)strtok_r(profiles, PROFLIST_SEP, &lasts);
- prof != NULL;
- prof = (char *)strtok_r(NULL, PROFLIST_SEP, &lasts)) {
-
- getproflist(prof, profArray, profcnt);
- }
-
- /* get authorizations from list of profiles */
- for (i = 0; i < *profcnt; i++) {
-
- if ((pa = getprofnam(profArray[i])) == NULL) {
- /*
- * this should never happen.
- * unless the database has an undefined profile
- */
- continue;
- }
-
- /* get auths this profile */
- auths = kva_match(pa->attr, PROFATTR_AUTHS_KW);
- if (auths != NULL) {
- add_auths(auths, authArray, authcnt);
+ int rem, i;
+
+ /* First we sort */
+ qsort(cbs->auths, cbs->auth_cnt, sizeof (cbs->auths[0]), mstrptr);
+
+ /*
+ * Then we remove the entries which match a later entry.
+ * We walk the list, with "i + rem + 1" the cursor for the possible
+ * candidate for removal. With "rem" we count the removed entries
+ * and we copy while we're looking for duplicate/superfluous entries.
+ */
+ for (i = 0, rem = 0; i < cbs->auth_cnt - rem - 1; ) {
+ if (strcmp(cbs->auths[i], cbs->auths[i + rem + 1]) == 0 ||
+ strchr(cbs->auths[i], KV_WILDCHAR) != NULL &&
+ auth_match(cbs->auths[i], cbs->auths[i + rem + 1])) {
+ free(cbs->auths[i + rem + 1]);
+ rem++;
+ } else {
+ i++;
+ if (rem > 0)
+ cbs->auths[i] = cbs->auths[i + rem];
}
-
- free_profattr(pa);
}
+
+ cbs->auth_cnt -= rem;
}