summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2020-09-30 21:42:51 +0000
committerAndy Fiddaman <omnios@citrus-it.co.uk>2020-10-12 15:56:16 +0000
commit9e678d632bda8e6911719d88b7c2d44a886aba5b (patch)
tree1d4297eea37f7514f587da567e190a82c2673f6f
parentaefb332f5664b51526fd3e7d0b3cb6bdda1e1758 (diff)
downloadillumos-gate-9e678d632bda8e6911719d88b7c2d44a886aba5b.tar.gz
13195 would like roleauth user_attr
Reviewed by: Jason King <jason.king@joyent.com> Reviewed by: Marco van Wieringen <mvw@planets.elm.net> Approved by: Robert Mustacchi <rm@fingolfin.org>
-rw-r--r--usr/src/cmd/oamuser/user/funcs.c25
-rw-r--r--usr/src/cmd/oamuser/user/userdefs.c47
-rw-r--r--usr/src/cmd/oamuser/user/userdisp.h10
-rw-r--r--usr/src/cmd/passmgmt/Makefile13
-rw-r--r--usr/src/cmd/passmgmt/passmgmt.c6
-rw-r--r--usr/src/cmd/su/Makefile12
-rw-r--r--usr/src/cmd/su/su.c92
-rw-r--r--usr/src/head/user_attr.h4
-rw-r--r--usr/src/head/userdefs.h7
-rw-r--r--usr/src/man/man4/user_attr.447
10 files changed, 159 insertions, 104 deletions
diff --git a/usr/src/cmd/oamuser/user/funcs.c b/usr/src/cmd/oamuser/user/funcs.c
index ac9cdfa580..5231f0d94c 100644
--- a/usr/src/cmd/oamuser/user/funcs.c
+++ b/usr/src/cmd/oamuser/user/funcs.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 RackTop Systems.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
#include <stdio.h>
@@ -58,6 +59,7 @@ static const char priv[] = "privilege set";
static const char auth[] = "authorization";
static const char type[] = "user type";
static const char lock[] = "lock_after_retries value";
+static const char roleauth[] = "roleauth";
static const char label[] = "label";
static const char auditflags[] = "audit mask";
static char auditerr[256];
@@ -70,6 +72,7 @@ static const char *check_proj(const char *);
static const char *check_privset(const char *);
static const char *check_type(const char *);
static const char *check_lock_after_retries(const char *);
+static const char *check_roleauth(const char *);
static const char *check_label(const char *);
static const char *check_auditflags(const char *);
@@ -84,7 +87,8 @@ static ua_key_t keys[] = {
{ USERATTR_DEFAULTPROJ_KW, check_proj, proj },
{ USERATTR_LIMPRIV_KW, check_privset, priv },
{ USERATTR_DFLTPRIV_KW, check_privset, priv },
- { USERATTR_LOCK_AFTER_RETRIES_KW, check_lock_after_retries, lock },
+ { USERATTR_LOCK_AFTER_RETRIES_KW, check_lock_after_retries, lock },
+ { USERATTR_ROLEAUTH_KW, check_roleauth, roleauth },
{ USERATTR_CLEARANCE, check_label, label },
{ USERATTR_MINLABEL, check_label, label },
{ USERATTR_AUDIT_FLAGS_KW, check_auditflags, auditflags },
@@ -414,9 +418,22 @@ static const char *
check_lock_after_retries(const char *keyval)
{
if (keyval != NULL) {
- if ((strcasecmp(keyval, "no") != 0) &&
- (strcasecmp(keyval, "yes") != 0) &&
- (*keyval != '\0')) {
+ if (strcasecmp(keyval, USERATTR_LOCK_NO) != 0 &&
+ strcasecmp(keyval, USERATTR_LOCK_YES) != 0 &&
+ *keyval != '\0') {
+ return (keyval);
+ }
+ }
+ return (NULL);
+}
+
+static const char *
+check_roleauth(const char *keyval)
+{
+ if (keyval != NULL) {
+ if (strcasecmp(keyval, USERATTR_ROLEAUTH_USER) != 0 &&
+ strcasecmp(keyval, USERATTR_ROLEAUTH_ROLE) != 0 &&
+ *keyval != '\0') {
return (keyval);
}
}
diff --git a/usr/src/cmd/oamuser/user/userdefs.c b/usr/src/cmd/oamuser/user/userdefs.c
index 5845179d77..749b6f578a 100644
--- a/usr/src/cmd/oamuser/user/userdefs.c
+++ b/usr/src/cmd/oamuser/user/userdefs.c
@@ -26,14 +26,13 @@
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
+/* All Rights Reserved */
/*
* Copyright (c) 2013 RackTop Systems.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
-/*LINTLIBRARY*/
-
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
@@ -55,7 +54,7 @@
(void) fprintf(fptr, "\n"); \
}
-#define SKIPWS(ptr) while (*ptr && (*ptr == ' ' || *ptr == '\t')) ptr++
+#define SKIPWS(ptr) while (*(ptr) == ' ' || *(ptr) == '\t') (ptr)++
static char *dup_to_nl(char *);
@@ -63,7 +62,7 @@ static struct userdefs defaults = {
DEFRID, DEFGROUP, DEFGNAME, DEFPARENT, DEFSKL,
DEFSHL, DEFINACT, DEFEXPIRE, DEFAUTH, DEFPROF,
DEFROLE, DEFPROJ, DEFPROJNAME, DEFLIMPRIV,
- DEFDFLTPRIV, DEFLOCK_AFTER_RETRIES
+ DEFDFLTPRIV, DEFLOCK_AFTER_RETRIES, DEFROLEAUTH
};
#define INT 0
@@ -104,6 +103,8 @@ static const parsent_t tab[] = {
{ LOCK_AFTER_RETRIESSTR, sizeof (LOCK_AFTER_RETRIESSTR) - 1,
STR, DEFOFF(deflock_after_retries),
USERATTR_LOCK_AFTER_RETRIES_KW },
+ { ROLEAUTHSTR, sizeof (ROLEAUTHSTR) - 1, STR, DEFOFF(defroleauth),
+ USERATTR_ROLEAUTH_KW },
};
#define NDEF (sizeof (tab) / sizeof (parsent_t))
@@ -152,12 +153,13 @@ scan(char **start_p)
* defauth = 0
* defprof = 0
* defrole = 0
+ * defroleauth = role
*
* If getusrdef() is unable to access the defaults file, it
* returns a NULL pointer.
*
- * If user defaults file exists, then getusrdef uses values
- * in it to override the above values.
+ * If user defaults file exists, then getusrdef uses values
+ * in it to override the above values.
*/
struct userdefs *
@@ -170,6 +172,7 @@ getusrdef(char *usertype)
if ((defptr = fopen(DEFROLEFILE, "r")) == NULL) {
defaults.defshell = DEFROLESHL;
defaults.defprof = DEFROLEPROF;
+ defaults.defroleauth = DEFROLEROLEAUTH;
return (&defaults);
}
} else {
@@ -191,11 +194,11 @@ getusrdef(char *usertype)
switch (pe->type) {
case INT:
FIELD(&defaults, pe, int) =
- (int)strtol(ptr, NULL, 10);
+ (int)strtol(ptr, NULL, 10);
break;
case PROJID:
FIELD(&defaults, pe, projid_t) =
- (projid_t)strtol(ptr, NULL, 10);
+ (projid_t)strtol(ptr, NULL, 10);
break;
case STR:
FIELD(&defaults, pe, char *) = dup_to_nl(ptr);
@@ -231,7 +234,7 @@ dispusrdef(FILE *fptr, unsigned flags, char *usertype)
if (flags & D_GROUP) {
outcount += fprintf(fptr, "group=%s,%ld ",
- deflts->defgname, deflts->defgroup);
+ deflts->defgname, deflts->defgroup);
PRINTNL();
}
@@ -288,20 +291,25 @@ dispusrdef(FILE *fptr, unsigned flags, char *usertype)
}
if (flags & D_LPRIV) {
- outcount += fprintf(fptr, "limitpriv=%s ",
- deflts->deflimpriv);
+ outcount += fprintf(fptr, "limitpriv=%s ", deflts->deflimpriv);
PRINTNL();
}
if (flags & D_DPRIV) {
outcount += fprintf(fptr, "defaultpriv=%s ",
- deflts->defdfltpriv);
+ deflts->defdfltpriv);
PRINTNL();
}
if (flags & D_LOCK) {
outcount += fprintf(fptr, "lock_after_retries=%s ",
deflts->deflock_after_retries);
+ PRINTNL();
+ }
+
+ if ((flags & D_ROLEAUTH) && is_role(usertype)) {
+ outcount += fprintf(fptr, "roleauth=%s ",
+ deflts->defroleauth);
}
if (outcount > 0)
@@ -310,7 +318,7 @@ dispusrdef(FILE *fptr, unsigned flags, char *usertype)
/*
* putusrdef -
- * changes default values in defadduser file
+ * changes default values in defadduser file
*/
int
putusrdef(struct userdefs *defs, char *usertype)
@@ -353,10 +361,11 @@ putusrdef(struct userdefs *defs, char *usertype)
if (is_role(usertype)) {
/* If it's a role, we must skip the defrole field */
- skip = offsetof(struct userdefs, defrole);
+ skip = DEFOFF(defrole);
hdr = FHEADER_ROLE;
} else {
- skip = -1;
+ /* If it's a user, we must skip the defroleauth field */
+ skip = DEFOFF(defroleauth);
hdr = FHEADER;
}
@@ -378,15 +387,15 @@ putusrdef(struct userdefs *defs, char *usertype)
switch (tab[i].type) {
case INT:
res = fprintf(defptr, "%s%d\n", tab[i].name,
- FIELD(defs, &tab[i], int));
+ FIELD(defs, &tab[i], int));
break;
case STR:
res = fprintf(defptr, "%s%s\n", tab[i].name,
- FIELD(defs, &tab[i], char *));
+ FIELD(defs, &tab[i], char *));
break;
case PROJID:
res = fprintf(defptr, "%s%d\n", tab[i].name,
- (int)FIELD(defs, &tab[i], projid_t));
+ (int)FIELD(defs, &tab[i], projid_t));
break;
}
diff --git a/usr/src/cmd/oamuser/user/userdisp.h b/usr/src/cmd/oamuser/user/userdisp.h
index 5fa676ddf7..b9fe58012b 100644
--- a/usr/src/cmd/oamuser/user/userdisp.h
+++ b/usr/src/cmd/oamuser/user/userdisp.h
@@ -25,14 +25,15 @@
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
+/* All Rights Reserved */
+/*
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
+ */
#ifndef _USERDISP_H
#define _USERDISP_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -52,10 +53,11 @@ extern "C" {
#define D_LPRIV 0x0800
#define D_DPRIV 0x1000
#define D_LOCK 0x2000
+#define D_ROLEAUTH 0x4000
#define D_ALL (D_GROUP | D_BASEDIR | D_RID | D_SKEL | D_SHELL \
| D_INACT | D_EXPIRE | D_AUTH | D_PROF | D_ROLE | D_PROJ | \
- D_LPRIV | D_DPRIV | D_LOCK)
+ D_LPRIV | D_DPRIV | D_LOCK | D_ROLEAUTH)
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/passmgmt/Makefile b/usr/src/cmd/passmgmt/Makefile
index 21fd15a65f..3845239b4b 100644
--- a/usr/src/cmd/passmgmt/Makefile
+++ b/usr/src/cmd/passmgmt/Makefile
@@ -22,15 +22,16 @@
# Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
#
# Copyright (c) 2018, Joyent, Inc.
+# Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
-PROG= passmgmt
-FILE= datemsk
-TXTS= $(FILE)
+PROG= passmgmt
+FILE= datemsk
+TXTS= $(FILE)
include ../Makefile.cmd
-FILEMODE= 0555
+FILEMODE= 0555
ROOTFILE= $(ROOTETC)/$(FILE)
# conditional assignment
@@ -48,7 +49,7 @@ SMATCH=off
all: $(PROG) $(TXTS)
-XGETFLAGS= -a -x $(PROG).xcl
+XGETFLAGS= -a -x $(PROG).xcl
install: all $(ROOTLIBPROG) $(ROOTFILE)
@@ -64,6 +65,4 @@ datemsk: datemsk.template
clean:
$(RM) datemsk
-lint: lint_PROG
-
include ../Makefile.targ
diff --git a/usr/src/cmd/passmgmt/passmgmt.c b/usr/src/cmd/passmgmt/passmgmt.c
index 2b4f34e8db..2af2fa9075 100644
--- a/usr/src/cmd/passmgmt/passmgmt.c
+++ b/usr/src/cmd/passmgmt/passmgmt.c
@@ -20,10 +20,11 @@
*/
/*
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
+/* All Rights Reserved */
#include <stdio.h>
#include <sys/types.h>
@@ -90,6 +91,7 @@ kvopts_t ua_opts[] = {
{ '\0', USERATTR_LIMPRIV_KW },
{ '\0', USERATTR_DFLTPRIV_KW },
{ '\0', USERATTR_LOCK_AFTER_RETRIES_KW },
+{ '\0', USERATTR_ROLEAUTH_KW },
{ '\0', USERATTR_LABELVIEW },
{ '\0', USERATTR_CLEARANCE },
{ '\0', USERATTR_MINLABEL },
@@ -346,7 +348,7 @@ main(int argc, char **argv)
shadow_st.sp_lstchg = -1; /* no lastchanged date */
shadow_st.sp_min = -1; /* no min */
shadow_st.sp_max = -1; /* no max */
- shadow_st.sp_warn = -1; /* no warn */
+ shadow_st.sp_warn = -1; /* no warn */
shadow_st.sp_inact = -1; /* no inactive */
shadow_st.sp_expire = -1; /* no expire */
shadow_st.sp_flag = 0; /* no flag */
diff --git a/usr/src/cmd/su/Makefile b/usr/src/cmd/su/Makefile
index 031ebc0740..89de951933 100644
--- a/usr/src/cmd/su/Makefile
+++ b/usr/src/cmd/su/Makefile
@@ -22,6 +22,8 @@
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
+# Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
+#
# build two versions, su and su.static
# su.static is dynamically linked; the .static suffix is historical.
@@ -44,20 +46,14 @@ $(PROG_STATIC) := FILEMODE = 0555
# A reduced su.static is created, with just enough functionality
# to satisfy the needs of a single-user login with /usr not mounted.
# In particular, nss_files.so.1 may be dlopen()'ed at runtime.
-$(ROOTFS_PROG) := LDLIBS += -lbsm -lpam -lsecdb
+$(ROOTFS_PROG) := LDLIBS += -lbsm -lpam
# The standard su is fully functional.
$(PROG) := CPPFLAGS += -DDYNAMIC_SU
$(PROG) := LDLIBS += -lbsm -lpam -lsecdb
-LINTFLAGS += -DDYNAMIC_SU
-
CLOBBERFILES += $(ROOTFS_PROG) $(EMB_PROG)
-CERRWARN += -_gcc=-Wno-parentheses
-
-lint := LDLIBS += -lbsm -lpam -lsecdb
-
.KEEP_STATE:
all: $(PROG) $(ROOTFS_PROG) $(EMB_PROG)
@@ -85,6 +81,4 @@ $(EMB_PROG):
clean:
-lint: lint_PROG
-
include ../Makefile.targ
diff --git a/usr/src/cmd/su/su.c b/usr/src/cmd/su/su.c
index 5d8f6da20a..08635d482b 100644
--- a/usr/src/cmd/su/su.c
+++ b/usr/src/cmd/su/su.c
@@ -22,6 +22,7 @@
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Milan Jurik. All rights reserved.
* Copyright 2014 Nexenta Systems, Inc.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
@@ -120,12 +121,12 @@ static void message(enum messagemode, char *, ...);
static char *alloc_vsprintf(const char *, va_list);
static char *tail(char *);
-static void audit_success(int, struct passwd *);
+static void audit_success(int, struct passwd *, boolean_t);
static void audit_logout(adt_session_data_t *, au_event_t);
-static void audit_failure(int, struct passwd *, char *, int);
+static void audit_failure(int, struct passwd *, char *, int, boolean_t);
#ifdef DYNAMIC_SU
-static void validate(char *, int *);
+static void validate(char *, int *, boolean_t);
static int legalenvvar(char *);
static int su_conv(int, struct pam_message **, struct pam_response **, void *);
static int emb_su_conv(int, struct pam_message **, struct pam_response **,
@@ -190,8 +191,11 @@ main(int argc, char **argv)
int flags = 0;
int retcode;
int idx = 0;
+ userattr_t *user_entry;
+ char *authname;
#endif /* DYNAMIC_SU */
int pw_change = PW_FALSE;
+ boolean_t isrole = B_FALSE;
(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
@@ -245,13 +249,13 @@ main(int argc, char **argv)
if (defopen(DEFFILE) == 0) {
- if (Sulog = defread("SULOG="))
+ if ((Sulog = defread("SULOG=")) != NULL)
Sulog = strdup(Sulog);
- if (Console = defread("CONSOLE="))
+ if ((Console = defread("CONSOLE=")) != NULL)
Console = strdup(Console);
- if (Path = defread("PATH="))
+ if ((Path = defread("PATH=")) != NULL)
Path = strdup(Path);
- if (Supath = defread("SUPATH="))
+ if ((Supath = defread("SUPATH=")) != NULL)
Supath = strdup(Supath);
if ((ptr = defread("SYSLOG=")) != NULL)
dosyslog = strcmp(ptr, "YES") == 0;
@@ -279,7 +283,31 @@ main(int argc, char **argv)
}
#ifdef DYNAMIC_SU
- if (pam_start(embedded ? EMBEDDED_NAME : "su", nptr,
+ authname = nptr;
+
+ if (((user_entry = getusernam(authname)) != NULL)) {
+ kva_t *attr = user_entry->attr;
+ char *kv;
+
+ if ((kv = kva_match(attr, USERATTR_TYPE_KW)) != NULL &&
+ ((strcmp(kv, USERATTR_TYPE_NONADMIN_KW) == 0) ||
+ (strcmp(kv, USERATTR_TYPE_ADMIN_KW) == 0))) {
+ isrole = B_TRUE;
+
+ if ((kv = kva_match(attr,
+ USERATTR_ROLEAUTH_KW)) != NULL &&
+ strcmp(kv, USERATTR_ROLEAUTH_USER) == 0) {
+ authname = cuserid(NULL);
+ }
+
+ }
+ free_userattr(user_entry);
+ }
+
+ if (authname == NULL)
+ exit(1);
+
+ if (pam_start(embedded ? EMBEDDED_NAME : "su", authname,
embedded ? &emb_pam_conv : &pam_conv, &pamh) != PAM_SUCCESS)
exit(1);
if (pam_set_item(pamh, PAM_TTY, ttyn) != PAM_SUCCESS)
@@ -333,7 +361,7 @@ main(int argc, char **argv)
* 3rd step: print out message to user.
*/
/* don't let audit_failure distinguish a role here */
- audit_failure(PW_FALSE, NULL, nptr, retcode);
+ audit_failure(PW_FALSE, NULL, nptr, retcode, B_FALSE);
switch (retcode) {
case PAM_USER_UNKNOWN:
closelog();
@@ -368,7 +396,7 @@ main(int argc, char **argv)
exit(1);
}
if (flags)
- validate(username, &pw_change);
+ validate(username, &pw_change, isrole);
if (pam_setcred(pamh, PAM_REINITIALIZE_CRED) != PAM_SUCCESS) {
message(ERR, gettext("unable to set credentials"));
exit(2);
@@ -384,7 +412,7 @@ main(int argc, char **argv)
if ((getpwnam_r(nptr, &pwd, pwdbuf, sizeof (pwdbuf)) == NULL) ||
(getspnam_r(nptr, &sp, spbuf, sizeof (spbuf)) == NULL)) {
message(ERR, gettext("Unknown id: %s"), nptr);
- audit_failure(PW_FALSE, NULL, nptr, PAM_USER_UNKNOWN);
+ audit_failure(PW_FALSE, NULL, nptr, PAM_USER_UNKNOWN, B_FALSE);
closelog();
exit(1);
}
@@ -403,7 +431,7 @@ main(int argc, char **argv)
if (Sulog != NULL)
log(Sulog, nptr, 0); /* log entry */
message(ERR, gettext("Sorry"));
- audit_failure(PW_FALSE, NULL, nptr, PAM_AUTH_ERR);
+ audit_failure(PW_FALSE, NULL, nptr, PAM_AUTH_ERR, B_FALSE);
if (dosyslog)
syslog(LOG_CRIT, "'su %s' failed for %s on %s",
pwd.pw_name, username, ttyn);
@@ -421,7 +449,7 @@ ok:
pwd.pw_name, username, ttyn);
#endif /* DYNAMIC_SU */
- audit_success(pw_change, &pwd);
+ audit_success(pw_change, &pwd, isrole);
uid = pwd.pw_uid;
gid = pwd.pw_gid;
dir = strdup(pwd.pw_dir);
@@ -489,7 +517,7 @@ ok:
}
(void) strlcat(homedir, dir, sizeof (homedir));
(void) strlcat(logname, name, sizeof (logname));
- if (hz = getenv("HZ"))
+ if ((hz = getenv("HZ")) != NULL)
(void) strlcat(hzname, hz, sizeof (hzname));
(void) strlcat(shelltyp, pshell, sizeof (shelltyp));
@@ -522,7 +550,7 @@ ok:
*/
tznam[0] = '\0';
for (j = 0; initenv[j] != 0; j++) {
- if (initvar = getenv(initenv[j])) {
+ if ((initvar = getenv(initenv[j])) != NULL) {
/*
* Skip over values beginning with '/' for
@@ -558,7 +586,7 @@ ok:
*/
if (tznam[0] == '\0') {
if (defopen(DEFAULT_LOGIN) == 0) {
- if (initvar = defread("TIMEZONE=")) {
+ if ((initvar = defread("TIMEZONE=")) != NULL) {
(void) strcpy(tznam, "TZ=");
(void) strlcat(tznam, initvar,
sizeof (tznam));
@@ -783,27 +811,19 @@ to(int sig)
*/
static void
-audit_success(int pw_change, struct passwd *pwd)
+audit_success(int pw_change, struct passwd *pwd, boolean_t isrole)
{
adt_session_data_t *ah = NULL;
adt_event_data_t *event;
au_event_t event_id = ADT_su;
- userattr_t *user_entry;
- char *kva_value;
if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
syslog(LOG_AUTH | LOG_ALERT,
"adt_start_session(ADT_su): %m");
return;
}
- if (((user_entry = getusernam(pwd->pw_name)) != NULL) &&
- ((kva_value = kva_match((kva_t *)user_entry->attr,
- USERATTR_TYPE_KW)) != NULL) &&
- ((strcmp(kva_value, USERATTR_TYPE_NONADMIN_KW) == 0) ||
- (strcmp(kva_value, USERATTR_TYPE_ADMIN_KW) == 0))) {
+ if (isrole)
event_id = ADT_role_login;
- }
- free_userattr(user_entry); /* OK to use, checks for NULL */
/* since proc uid/gid not yet updated */
if (adt_set_user(ah, pwd->pw_uid, pwd->pw_gid, pwd->pw_uid,
@@ -1004,13 +1024,12 @@ audit_logout(adt_session_data_t *ah, au_event_t event_id)
*/
static void
-audit_failure(int pw_change, struct passwd *pwd, char *user, int pamerr)
+audit_failure(int pw_change, struct passwd *pwd, char *user, int pamerr,
+ boolean_t isrole)
{
adt_session_data_t *ah; /* audit session handle */
adt_event_data_t *event; /* event to generate */
au_event_t event_id = ADT_su;
- userattr_t *user_entry;
- char *kva_value;
if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
syslog(LOG_AUTH | LOG_ALERT,
@@ -1025,14 +1044,8 @@ audit_failure(int pw_change, struct passwd *pwd, char *user, int pamerr)
syslog(LOG_AUTH | LOG_ERR,
"adt_set_user(ADT_su, ADT_FAILURE): %m");
}
- if (((user_entry = getusernam(pwd->pw_name)) != NULL) &&
- ((kva_value = kva_match((kva_t *)user_entry->attr,
- USERATTR_TYPE_KW)) != NULL) &&
- ((strcmp(kva_value, USERATTR_TYPE_NONADMIN_KW) == 0) ||
- (strcmp(kva_value, USERATTR_TYPE_ADMIN_KW) == 0))) {
+ if (isrole)
event_id = ADT_role_login;
- }
- free_userattr(user_entry); /* OK to use, checks for NULL */
}
if ((event = adt_alloc_event(ah, event_id)) == NULL) {
syslog(LOG_AUTH | LOG_ALERT,
@@ -1320,7 +1333,7 @@ quotemsg(char *fmt, ...)
* validate - Check that the account is valid for switching to.
*/
static void
-validate(char *usernam, int *pw_change)
+validate(char *usernam, int *pw_change, boolean_t isrole)
{
int error;
int tries;
@@ -1340,7 +1353,8 @@ validate(char *usernam, int *pw_change)
continue;
}
message(ERR, gettext("Sorry"));
- audit_failure(PW_FAILED, &pwd, NULL, error);
+ audit_failure(PW_FAILED, &pwd, NULL, error,
+ isrole);
if (dosyslog)
syslog(LOG_CRIT,
"'su %s' failed for %s on %s",
@@ -1352,7 +1366,7 @@ validate(char *usernam, int *pw_change)
return;
} else {
message(ERR, gettext("Sorry"));
- audit_failure(PW_FALSE, &pwd, NULL, error);
+ audit_failure(PW_FALSE, &pwd, NULL, error, isrole);
if (dosyslog)
syslog(LOG_CRIT, "'su %s' failed for %s on %s",
pwd.pw_name, usernam, ttyn);
diff --git a/usr/src/head/user_attr.h b/usr/src/head/user_attr.h
index 4a65465c4b..15169c0656 100644
--- a/usr/src/head/user_attr.h
+++ b/usr/src/head/user_attr.h
@@ -21,6 +21,7 @@
/*
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
#ifndef _USER_ATTR_H
@@ -102,6 +103,9 @@ struct __FILE; /* structure tag for type FILE defined in stdio.h */
#define USERATTR_PASSWD_MANUAL "manual"
#define USERATTR_TYPE_ROLE USERATTR_TYPE_NONADMIN_KW
#define USERATTR_AUDIT_FLAGS_KW "audit_flags"
+#define USERATTR_ROLEAUTH_KW "roleauth"
+#define USERATTR_ROLEAUTH_USER "user"
+#define USERATTR_ROLEAUTH_ROLE "role"
/*
diff --git a/usr/src/head/userdefs.h b/usr/src/head/userdefs.h
index 9e012fc812..39608f06da 100644
--- a/usr/src/head/userdefs.h
+++ b/usr/src/head/userdefs.h
@@ -27,6 +27,9 @@
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
+/*
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
+ */
#ifndef _USERDEFS_H
#define _USERDEFS_H
@@ -62,6 +65,8 @@ extern "C" {
#define DEFLIMPRIV ""
#define DEFDFLTPRIV ""
#define DEFLOCK_AFTER_RETRIES ""
+#define DEFROLEAUTH ""
+#define DEFROLEROLEAUTH "role"
/* Defaults file keywords */
#define RIDSTR "defrid="
@@ -82,6 +87,7 @@ extern "C" {
#define FHEADER "# Default values for useradd. Changed "
#define FHEADER_ROLE "# Default values for roleadd. Changed "
#define LOCK_AFTER_RETRIESSTR "deflock_after_retries="
+#define ROLEAUTHSTR "defroleauth="
/* Defaults file */
#define DEFFILE "/usr/sadm/defadduser"
@@ -110,6 +116,7 @@ struct userdefs {
char *deflimpriv; /* default limitpriv */
char *defdfltpriv; /* default defaultpriv */
char *deflock_after_retries; /* default lock_after_retries */
+ char *defroleauth; /* default roleauth */
};
diff --git a/usr/src/man/man4/user_attr.4 b/usr/src/man/man4/user_attr.4
index 4f2872e7ed..ab19073461 100644
--- a/usr/src/man/man4/user_attr.4
+++ b/usr/src/man/man4/user_attr.4
@@ -1,19 +1,18 @@
'\" te
+.\" Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
.\" Copyright (C) 2008 Sun Microsystems, Inc. All Rights Reserved
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH USER_ATTR 4 "Aug 3, 2017"
+.TH USER_ATTR 4 "Oct 1, 2020"
.SH NAME
user_attr \- extended user attributes database
.SH SYNOPSIS
-.LP
.nf
\fB/etc/user_attr\fR
.fi
.SH DESCRIPTION
-.LP
\fB/etc/user_attr\fR is a local source of extended attributes associated with
users and roles. \fBuser_attr\fR can be used with other user attribute sources,
including the LDAP people container and the \fBuser_attr\fR \fBNIS\fR map.
@@ -90,7 +89,7 @@ system:
.sp
.ne 2
.na
-\fB\fBauths\fR\fR
+\fBauths\fR
.ad
.sp .6
.RS 4n
@@ -103,7 +102,7 @@ specified using the asterisk (\fB*\fR) character as a wildcard. For example,
.sp
.ne 2
.na
-\fB\fBprofiles\fR\fR
+\fBprofiles\fR
.ad
.sp .6
.RS 4n
@@ -117,7 +116,20 @@ are assigned, the profile shells do not allow the user to execute any commands.
.sp
.ne 2
.na
-\fB\fBroles\fR\fR
+\fBroleauth\fR
+.ad
+.sp .6
+.RS 4n
+Specifies whether a user assuming a role is required to use the role password
+or their own password.
+If the \fBroleauth\fR key value is not specified, the role password is required
+for users assuming the role.
+.RE
+
+.sp
+.ne 2
+.na
+\fBroles\fR
.ad
.sp .6
.RS 4n
@@ -130,7 +142,7 @@ to assume any role.
.sp
.ne 2
.na
-\fB\fBtype\fR\fR
+\fBtype\fR
.ad
.sp .6
.RS 4n
@@ -143,7 +155,7 @@ the user has logged in.
.sp
.ne 2
.na
-\fB\fBproject\fR\fR
+\fBproject\fR
.ad
.sp .6
.RS 4n
@@ -155,7 +167,7 @@ information, see \fBgetdefaultproj\fR(3PROJECT).
.sp
.ne 2
.na
-\fB\fBdefaultpriv\fR\fR
+\fBdefaultpriv\fR
.ad
.sp .6
.RS 4n
@@ -166,7 +178,7 @@ See "Privileges Keywords," below.
.sp
.ne 2
.na
-\fB\fBlimitpriv\fR\fR
+\fBlimitpriv\fR
.ad
.sp .6
.RS 4n
@@ -181,7 +193,7 @@ requiring privileges to malfunction. See "Privileges Keywords," below.
.sp
.ne 2
.na
-\fB\fBlock_after_retries\fR\fR
+\fBlock_after_retries\fR
.ad
.sp .6
.RS 4n
@@ -197,7 +209,7 @@ Trusted Extensions feature:
.sp
.ne 2
.na
-\fB\fBclearance\fR\fR
+\fBclearance\fR
.ad
.sp .6
.RS 4n
@@ -210,7 +222,7 @@ specified in \fBlabel_encodings\fR(4) (see \fBlabel_encodings\fR(4) and
.sp
.ne 2
.na
-\fB\fBmin_label\fR\fR
+\fBmin_label\fR
.ad
.sp .6
.RS 4n
@@ -231,7 +243,6 @@ modify \fB\fIkey\fR=\fIvalue\fR\fR fields in \fB/etc/user_attr\fR. Modification
of the \fBtype\fR key is restricted as described in \fBrolemod\fR and
\fBusermod\fR.
.SS "Privileges Keywords"
-.LP
The \fBdefaultpriv\fR and \fBlimitpriv\fR are the privileges-related keywords
and are described above.
.sp
@@ -248,7 +259,6 @@ privileges. Note that you specify privileges as they are displayed by
See \fBusermod\fR(1M) for examples of commands that
modify privileges and their subsequent effect on \fBuser_attr\fR.
.SH EXAMPLES
-.LP
\fBExample 1 \fRAssigning a Profile to Root
.sp
.LP
@@ -274,7 +284,7 @@ authorizations.
.SH FILES
.ne 2
.na
-\fB\fB/etc/nsswitch.conf\fR\fR
+\fB/etc/nsswitch.conf\fR
.ad
.sp .6
.RS 4n
@@ -284,7 +294,7 @@ See \fBnsswitch.conf\fR(4).
.sp
.ne 2
.na
-\fB\fB/etc/user_attr\fR\fR
+\fB/etc/user_attr\fR
.ad
.sp .6
.RS 4n
@@ -292,7 +302,6 @@ Described here.
.RE
.SH ATTRIBUTES
-.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -312,7 +321,6 @@ Interface Stability See below
.LP
The command-line syntax is Committed. The output is Uncommitted.
.SH SEE ALSO
-.LP
\fBauths\fR(1), \fBpfcsh\fR(1), \fBpfksh\fR(1), \fBpfsh\fR(1), \fBppriv\fR(1),
\fBprofiles\fR(1), \fBroles\fR(1), \fBroleadd\fR(1M), \fBrolemod\fR(1M),
\fBuseradd\fR(1M), \fBusermod\fR(1M), \fBgetdefaultproj\fR(3PROJECT),
@@ -323,7 +331,6 @@ The command-line syntax is Committed. The output is Uncommitted.
.LP
\fISystem Administration Guide: Security Services\fR
.SH NOTES
-.LP
The root user is usually defined in local databases for a number of reasons,
including the fact that root needs to be able to log in and do system
maintenance in single-user mode, before the network name service databases are