summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c9
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c123
-rw-r--r--usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm4
-rw-r--r--usr/src/cmd/ptools/ppriv/ppriv.c5
-rw-r--r--usr/src/cmd/truss/print.c1
-rw-r--r--usr/src/lib/pam_modules/unix_cred/unix_cred.c19
-rw-r--r--usr/src/uts/common/os/priv.c58
-rw-r--r--usr/src/uts/common/sys/priv.h8
-rw-r--r--usr/src/uts/common/syscall/ppriv.c16
-rw-r--r--usr/src/uts/common/syscall/uid.c9
10 files changed, 154 insertions, 98 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c
index 7848dc7c85..b68c549787 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c
@@ -1,10 +1,8 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/****************************************************************************
Copyright (c) 1999,2000 WU-FTPD Development Group.
All rights reserved.
@@ -198,11 +196,10 @@ FILE *ftpd_popen(char *program, char *type, int closestderr)
/* begin CERT suggested fixes */
close(0);
i = geteuid();
- delay_signaling(); /* we can't allow any signals while euid==0: kinch */
- seteuid(0);
+ setid_priv_on(0);
setgid(getegid());
setuid(i);
- enable_signaling(); /* we can allow signals once again: kinch */
+ setid_priv_off(i);
/* end CERT suggested fixes */
execv(gargv[0], gargv);
perror(gargv[0]);
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c
index 400a9ffec0..912f27624f 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c
@@ -1,10 +1,8 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Least privilege support functions.
*/
@@ -24,17 +22,8 @@
#include "proto.h"
#ifdef SOLARIS_PRIVS
-/*
- * Before becoming privilege aware in init_privs(), no explicit privilege
- * manipulation using priv_on()/priv_off() is necessary as seteuid(0) sets
- * the effective privilege set to the limit set. Thus these are all
- * initialized to TRUE.
- */
-static boolean_t got_setid_priv = B_TRUE;
-static boolean_t got_privaddr_priv = B_TRUE;
-static boolean_t got_read_priv = B_TRUE;
-static boolean_t got_search_priv = B_TRUE;
-static boolean_t got_chown_priv = B_TRUE;
+/* When ununitialized, this indicates we still have all privs */
+static priv_set_t *uprivs;
#endif /* SOLARIS_PRIVS */
#ifdef SOLARIS_PRIVS
@@ -55,20 +44,20 @@ static void print_privs(priv_ptype_t which, const char *str)
}
#endif /* PRIVS_DEBUG */
-static void priv_on(const char *priv, boolean_t already_have)
+static void priv_on(const char *priv)
{
/* no need to add the privilege if already have it */
- if (already_have)
+ if (uprivs == NULL || priv_ismember(uprivs, priv))
return;
if (priv_set(PRIV_ON, PRIV_EFFECTIVE, priv, NULL) == -1)
syslog(LOG_ERR, "priv_set: error adding privilege %s: %m", priv);
}
-static void priv_off(const char *priv, boolean_t already_had)
+static void priv_off(const char *priv)
{
/* don't remove the privilege if already had it */
- if (already_had)
+ if (uprivs == NULL || priv_ismember(uprivs, priv))
return;
if (priv_set(PRIV_OFF, PRIV_EFFECTIVE, priv, NULL) == -1)
@@ -85,52 +74,64 @@ void init_privs(const char *username)
{
#ifdef SOLARIS_PRIVS
uid_t euid = geteuid();
- priv_set_t *privset;
+ priv_set_t *pset1, *pset2;
/*
- * The FTP server runs with "basic" inheritable privileges, which are
- * reset in pam_setcred() for non anonymous users. The seteuid() call in
- * pass() sets the effective privileges to the inheritable privileges.
+ * The FTP server runs with the inheritable set and the limit set
+ * filled in through user_attr (or with default values of basic and all).
+ * The privileges available to the user at login, is an intersection
+ * of both those sets. The only way to limit the root user is by
+ * changing the limit set, not by changing the I set.
*/
- if ((privset = priv_allocset()) == NULL) {
- syslog(LOG_ERR, "priv_allocset failed: %m");
+ if ((pset1 = priv_allocset()) == NULL ||
+ (uprivs = priv_allocset()) == NULL ||
+ (pset2 = priv_allocset()) == NULL) {
+ syslog(LOG_ERR, "priv_allocset failed: %m");
+ dologout(1);
+ }
+ if (getppriv(PRIV_LIMIT, pset1) == -1) {
+ syslog(LOG_ERR, "getppriv(limit) failed: %m");
dologout(1);
}
- if (getppriv(PRIV_EFFECTIVE, privset) == -1) {
- syslog(LOG_ERR, "getppriv(effective) failed: %m");
+ if (getppriv(euid == 0 ? PRIV_PERMITTED : PRIV_INHERITABLE, pset2) == -1) {
+ syslog(LOG_ERR, "getppriv() failed: %m");
dologout(1);
}
+ /* Compute the permitted set after login. */
+ priv_intersect(pset2, pset1);
+
/*
- * Set the permitted privilege set to the effective privileges plus
+ * Set the permitted privilege set to the allowable privileges plus
* those required after init_privs() is called. Keep note of which
- * effective privileges we already had so we don't turn them off.
+ * effective privileges we already had in uprivs so we don't turn
+ * them off.
*/
- if (!priv_ismember(privset, PRIV_PROC_SETID)) {
- got_setid_priv = B_FALSE;
- (void) priv_addset(privset, PRIV_PROC_SETID);
- }
- if (!priv_ismember(privset, PRIV_NET_PRIVADDR)) {
- got_privaddr_priv = B_FALSE;
- (void) priv_addset(privset, PRIV_NET_PRIVADDR);
- }
- if (!priv_ismember(privset, PRIV_FILE_DAC_READ)) {
- got_read_priv = B_FALSE;
- (void) priv_addset(privset, PRIV_FILE_DAC_READ);
- }
- if (!priv_ismember(privset, PRIV_FILE_DAC_SEARCH)) {
- got_search_priv = B_FALSE;
- (void) priv_addset(privset, PRIV_FILE_DAC_SEARCH);
- }
- if (!priv_ismember(privset, PRIV_FILE_CHOWN)) {
- got_chown_priv = B_FALSE;
- (void) priv_addset(privset, PRIV_FILE_CHOWN);
+ priv_emptyset(pset2);
+ (void) priv_addset(pset2, PRIV_PROC_SETID);
+ (void) priv_addset(pset2, PRIV_NET_PRIVADDR);
+ (void) priv_addset(pset2, PRIV_FILE_DAC_READ);
+ (void) priv_addset(pset2, PRIV_FILE_DAC_SEARCH);
+ (void) priv_addset(pset2, PRIV_FILE_CHOWN);
+
+ priv_copyset(pset2, uprivs);
+ priv_intersect(pset1, uprivs);
+
+ /* Now, set the effective privileges. */
+ if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pset1) == -1) {
+ syslog(LOG_ERR,
+ "unable to set privileges for %s: setppriv(effective): %m",
+ username);
+ dologout(1);
}
+
#if defined(SOLARIS_BSM_AUDIT) && !defined(SOLARIS_NO_AUDIT_FTPD_LOGOUT)
/* needed for audit_ftpd_logout() */
- (void) priv_addset(privset, PRIV_PROC_AUDIT);
+ (void) priv_addset(pset1, PRIV_PROC_AUDIT);
#endif
- if (setppriv(PRIV_SET, PRIV_PERMITTED, privset) == -1) {
+ /* And set the permitted, adding ftpd's required privileges in the mix. */
+ priv_union(pset2, pset1);
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, pset1) == -1) {
syslog(LOG_ERR,
"unable to set privileges for %s: setppriv(permitted): %m",
username);
@@ -140,8 +141,8 @@ void init_privs(const char *username)
* setppriv() has made us privilege aware, so the effective privileges
* are no longer modified by user ID changes.
*/
-
- priv_freeset(privset);
+ priv_freeset(pset1);
+ priv_freeset(pset2);
/* set the real, effective and saved group ID's */
setid_priv_on(0);
@@ -181,7 +182,7 @@ void port_priv_on(uid_t uid)
{
delay_signaling();
#ifdef SOLARIS_PRIVS
- priv_on(PRIV_NET_PRIVADDR, got_privaddr_priv);
+ priv_on(PRIV_NET_PRIVADDR);
#else
(void) seteuid(uid);
#endif
@@ -191,7 +192,7 @@ void port_priv_on(uid_t uid)
void port_priv_off(uid_t uid)
{
#ifdef SOLARIS_PRIVS
- priv_off(PRIV_NET_PRIVADDR, got_privaddr_priv);
+ priv_off(PRIV_NET_PRIVADDR);
#else
(void) seteuid(uid);
#endif
@@ -203,8 +204,8 @@ void access_priv_on(uid_t uid)
{
delay_signaling();
#ifdef SOLARIS_PRIVS
- priv_on(PRIV_FILE_DAC_READ, got_read_priv);
- priv_on(PRIV_FILE_DAC_SEARCH, got_search_priv);
+ priv_on(PRIV_FILE_DAC_READ);
+ priv_on(PRIV_FILE_DAC_SEARCH);
#endif
/* necessary on Solaris for access over NFS */
(void) seteuid(uid);
@@ -213,8 +214,8 @@ void access_priv_on(uid_t uid)
void access_priv_off(uid_t uid)
{
#ifdef SOLARIS_PRIVS
- priv_off(PRIV_FILE_DAC_READ, got_read_priv);
- priv_off(PRIV_FILE_DAC_SEARCH, got_search_priv);
+ priv_off(PRIV_FILE_DAC_READ);
+ priv_off(PRIV_FILE_DAC_SEARCH);
#endif
(void) seteuid(uid);
enable_signaling();
@@ -226,7 +227,7 @@ void setid_priv_on(uid_t uid)
{
delay_signaling();
#ifdef SOLARIS_PRIVS
- priv_on(PRIV_PROC_SETID, got_setid_priv);
+ priv_on(PRIV_PROC_SETID);
#else
(void) seteuid(uid);
#endif
@@ -236,7 +237,7 @@ void setid_priv_on(uid_t uid)
void setid_priv_off(uid_t uid)
{
#ifdef SOLARIS_PRIVS
- priv_off(PRIV_PROC_SETID, got_setid_priv);
+ priv_off(PRIV_PROC_SETID);
#else
(void) seteuid(uid);
#endif
@@ -248,7 +249,7 @@ void chown_priv_on(uid_t uid)
{
delay_signaling();
#ifdef SOLARIS_PRIVS
- priv_on(PRIV_FILE_CHOWN, got_chown_priv);
+ priv_on(PRIV_FILE_CHOWN);
#endif
/* necessary on Solaris for chown over NFS */
(void) seteuid(uid);
@@ -257,7 +258,7 @@ void chown_priv_on(uid_t uid)
void chown_priv_off(uid_t uid)
{
#ifdef SOLARIS_PRIVS
- priv_off(PRIV_FILE_CHOWN, got_chown_priv);
+ priv_off(PRIV_FILE_CHOWN);
#endif
(void) seteuid(uid);
enable_signaling();
diff --git a/usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm b/usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm
index 347cf12b16..10c6cd02b4 100644
--- a/usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm
+++ b/usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm
@@ -19,7 +19,7 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -40,7 +40,7 @@ XSLoader::load(__PACKAGE__, $VERSION);
our (@EXPORT_OK, %EXPORT_TAGS);
my @constants = qw(PRIV_STR_SHORT PRIV_STR_LIT PRIV_STR_PORT PRIV_ON PRIV_OFF
- PRIV_SET PRIV_AWARE PRIV_DEBUG);
+ PRIV_SET PRIV_AWARE PRIV_AWARE_RESET PRIV_DEBUG);
my @syscalls = qw(setppriv getppriv setpflags getpflags);
my @libcalls = qw(priv_addset priv_copyset priv_delset
priv_emptyset priv_fillset priv_intersect priv_inverse priv_ineffect
diff --git a/usr/src/cmd/ptools/ppriv/ppriv.c b/usr/src/cmd/ptools/ppriv/ppriv.c
index 9b88f01f30..d9a155a959 100644
--- a/usr/src/cmd/ptools/ppriv/ppriv.c
+++ b/usr/src/cmd/ptools/ppriv/ppriv.c
@@ -19,14 +19,12 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Program to examine or set process privileges.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
@@ -649,6 +647,7 @@ static struct {
{ PRIV_DEBUG, "PRIV_DEBUG" },
{ PRIV_AWARE, "PRIV_AWARE" },
{ PRIV_AWARE_INHERIT, "PRIV_AWARE_INHERIT" },
+ { PRIV_AWARE_RESET, "PRIV_AWARE_RESET" },
{ PRIV_XPOLICY, "PRIV_XPOLICY" },
{ NET_MAC_AWARE, "NET_MAC_AWARE" },
{ NET_MAC_AWARE_INHERIT, "NET_MAC_AWARE_INHERIT" },
diff --git a/usr/src/cmd/truss/print.c b/usr/src/cmd/truss/print.c
index 26a6daf30b..882497b4c6 100644
--- a/usr/src/cmd/truss/print.c
+++ b/usr/src/cmd/truss/print.c
@@ -2275,6 +2275,7 @@ prt_pfl(private_t *pri, int raw, long val)
case PRIV_DEBUG: s = "PRIV_DEBUG"; break;
case PRIV_AWARE: s = "PRIV_AWARE"; break;
case PRIV_XPOLICY: s = "PRIV_XPOLICY"; break;
+ case PRIV_AWARE_RESET: s = "PRIV_AWARE_RESET"; break;
case NET_MAC_AWARE: s = "NET_MAC_AWARE"; break;
case NET_MAC_AWARE_INHERIT:
s = "NET_MAC_AWARE_INHERIT";
diff --git a/usr/src/lib/pam_modules/unix_cred/unix_cred.c b/usr/src/lib/pam_modules/unix_cred/unix_cred.c
index 5230394f50..d862b2f652 100644
--- a/usr/src/lib/pam_modules/unix_cred/unix_cred.c
+++ b/usr/src/lib/pam_modules/unix_cred/unix_cred.c
@@ -596,18 +596,23 @@ adt_done:
}
if (!priv_issubset(lim, tset))
priv_intersect(tset, lim);
- /*
- * In order not to suprise certain applications, we
- * need to retain privilege awareness and thus we must
- * also set P and E.
- */
- if (setppriv(PRIV_SET, PRIV_LIMIT, lim) != 0 ||
- setppriv(PRIV_SET, PRIV_PERMITTED, lim) != 0) {
+ if (setppriv(PRIV_SET, PRIV_LIMIT, lim) != 0) {
syslog(LOG_AUTH | LOG_ERR,
"pam_setcred: setppriv(limitpriv) failed: %m");
ret = PAM_CRED_ERR;
+ goto out;
}
+ /*
+ * In order not to surprise certain applications, we
+ * need to get rid of privilege awareness and thus we must
+ * set this flag which will cause a reset on set*uid().
+ */
+ (void) setpflags(PRIV_AWARE_RESET, 1);
}
+ /*
+ * This may fail but we do not care as this will be reset later
+ * when the uids are set to their final values.
+ */
(void) setpflags(PRIV_AWARE, 0);
out:
diff --git a/usr/src/uts/common/os/priv.c b/usr/src/uts/common/os/priv.c
index d8ab0f2053..6af3caa036 100644
--- a/usr/src/uts/common/os/priv.c
+++ b/usr/src/uts/common/os/priv.c
@@ -614,18 +614,19 @@ out:
}
/*
- * Set the privilege aware bit, adding L to E/P if
- * necessasry.
+ * Set the privilege aware bit, adding L to E/P if necessary.
+ * Each time we set it, we also clear PRIV_AWARE_RESET.
*/
void
priv_set_PA(cred_t *cr)
{
ASSERT(cr->cr_ref <= 2);
- if (CR_FLAGS(cr) & PRIV_AWARE)
+ if ((CR_FLAGS(cr) & (PRIV_AWARE|PRIV_AWARE_RESET)) == PRIV_AWARE)
return;
CR_FLAGS(cr) |= PRIV_AWARE;
+ CR_FLAGS(cr) &= ~PRIV_AWARE_RESET;
if (cr->cr_uid == 0)
priv_union(&CR_LPRIV(cr), &CR_EPRIV(cr));
@@ -661,8 +662,10 @@ priv_adjust_PA(cred_t *cr)
ASSERT(cr->cr_ref <= 2);
if (!(CR_FLAGS(cr) & PRIV_AWARE) ||
- !priv_can_clear_PA(cr))
+ !priv_can_clear_PA(cr)) {
+ CR_FLAGS(cr) &= ~PRIV_AWARE_RESET;
return;
+ }
if (CR_FLAGS(cr) & PRIV_AWARE_INHERIT)
return;
@@ -679,5 +682,50 @@ priv_adjust_PA(cred_t *cr)
priv_intersect(&CR_IPRIV(cr), &CR_PPRIV(cr));
}
- CR_FLAGS(cr) &= ~PRIV_AWARE;
+ CR_FLAGS(cr) &= ~(PRIV_AWARE|PRIV_AWARE_RESET);
+}
+
+/*
+ * Reset privilege aware bit if so requested by setting the PRIV_AWARE_RESET
+ * flag.
+ */
+void
+priv_reset_PA(cred_t *cr, boolean_t finalize)
+{
+ ASSERT(cr->cr_ref <= 2);
+
+ if ((CR_FLAGS(cr) & (PRIV_AWARE|PRIV_AWARE_RESET)) !=
+ (PRIV_AWARE|PRIV_AWARE_RESET)) {
+ CR_FLAGS(cr) &= ~PRIV_AWARE_RESET;
+ return;
+ }
+
+ /*
+ * When PRIV_AWARE_RESET is enabled, any change of uids causes
+ * a change to the P and E sets. Bracketing with
+ * seteuid(0) ... seteuid(uid)/setreuid(-1, 0) .. setreuid(-1, uid)
+ * will cause the privilege sets "do the right thing.".
+ * When the change of the uid is "final", e.g., by using setuid(uid),
+ * or setreuid(uid, uid) or when the last set*uid() call causes all
+ * uids to be the same, we set P and E to I & L, like when you exec.
+ * We make an exception when all the uids are 0; this is required
+ * when we login as root as in that particular case we cannot
+ * make a distinction between seteuid(0) and seteuid(uid).
+ * We rely on seteuid/setreuid/setuid to tell us with the
+ * "finalize" argument that we no longer expect new uid changes,
+ * cf. setreuid(uid, uid) and setuid(uid).
+ */
+ if (cr->cr_suid == cr->cr_ruid && cr->cr_suid == cr->cr_uid) {
+ if (finalize || cr->cr_uid != 0) {
+ CR_EPRIV(cr) = CR_IPRIV(cr);
+ priv_intersect(&CR_LPRIV(cr), &CR_EPRIV(cr));
+ CR_PPRIV(cr) = CR_EPRIV(cr);
+ CR_FLAGS(cr) &= ~(PRIV_AWARE|PRIV_AWARE_RESET);
+ } else {
+ CR_EPRIV(cr) = CR_PPRIV(cr);
+ }
+ } else if (cr->cr_uid != 0 && (cr->cr_ruid == 0 || cr->cr_suid == 0)) {
+ CR_EPRIV(cr) = CR_IPRIV(cr);
+ priv_intersect(&CR_LPRIV(cr), &CR_EPRIV(cr));
+ }
}
diff --git a/usr/src/uts/common/sys/priv.h b/usr/src/uts/common/sys/priv.h
index d9be377cd9..e744e064c0 100644
--- a/usr/src/uts/common/sys/priv.h
+++ b/usr/src/uts/common/sys/priv.h
@@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_PRIV_H
#define _SYS_PRIV_H
-#pragma ident "%Z%%M% %I% %E% SMI" /* from TSOL 8 */
-
#include <sys/types.h>
#include <sys/cred.h>
#include <sys/priv_names.h>
@@ -137,11 +135,12 @@ typedef struct priv_impl_info {
#define __PROC_PROTECT 0x0008 /* Private */
#define NET_MAC_AWARE 0x0010 /* Is MAC aware */
#define NET_MAC_AWARE_INHERIT 0x0020 /* Inherit MAC aware */
+#define PRIV_AWARE_RESET 0x0040 /* Reset on setuid() */
#define PRIV_XPOLICY 0x0080 /* Extended policy */
/* user-settable flags: */
#define PRIV_USER (PRIV_DEBUG | NET_MAC_AWARE | NET_MAC_AWARE_INHERIT |\
- PRIV_XPOLICY)
+ PRIV_XPOLICY | PRIV_AWARE_RESET)
/*
* Header of the privilege info data structure; multiple structures can
@@ -234,6 +233,7 @@ extern void priv_inverse(priv_set_t *);
extern void priv_set_PA(cred_t *);
extern void priv_adjust_PA(cred_t *);
+extern void priv_reset_PA(cred_t *, boolean_t);
extern boolean_t priv_can_clear_PA(const cred_t *);
extern int setpflags(uint_t, uint_t, cred_t *);
diff --git a/usr/src/uts/common/syscall/ppriv.c b/usr/src/uts/common/syscall/ppriv.c
index 179f6e68fa..4c15504d74 100644
--- a/usr/src/uts/common/syscall/ppriv.c
+++ b/usr/src/uts/common/syscall/ppriv.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
@@ -238,7 +236,8 @@ setpflags(uint_t flag, uint_t val, cred_t *tcr)
if (val > 1 || (flag != PRIV_DEBUG && flag != PRIV_AWARE &&
flag != NET_MAC_AWARE && flag != NET_MAC_AWARE_INHERIT &&
- flag != __PROC_PROTECT && flag != PRIV_XPOLICY)) {
+ flag != __PROC_PROTECT && flag != PRIV_XPOLICY &&
+ flag != PRIV_AWARE_RESET)) {
return (EINVAL);
}
@@ -262,10 +261,13 @@ setpflags(uint_t flag, uint_t val, cred_t *tcr)
newflags = CR_FLAGS(pcr);
- if (val != 0)
+ if (val != 0) {
+ if (flag == PRIV_AWARE)
+ newflags &= ~PRIV_AWARE_RESET;
newflags |= flag;
- else
+ } else {
newflags &= ~flag;
+ }
/* No change */
if (CR_FLAGS(pcr) == newflags) {
@@ -342,7 +344,7 @@ getpflags(uint_t flag, const cred_t *cr)
{
if (flag != PRIV_DEBUG && flag != PRIV_AWARE &&
flag != NET_MAC_AWARE && flag != NET_MAC_AWARE_INHERIT &&
- flag != PRIV_XPOLICY)
+ flag != PRIV_XPOLICY && flag != PRIV_AWARE_RESET)
return ((uint_t)-1);
return ((CR_FLAGS(cr) & flag) != 0);
diff --git a/usr/src/uts/common/syscall/uid.c b/usr/src/uts/common/syscall/uid.c
index 967ebaf462..e3aa0a2dd2 100644
--- a/usr/src/uts/common/syscall/uid.c
+++ b/usr/src/uts/common/syscall/uid.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -27,8 +27,6 @@
* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
@@ -136,6 +134,9 @@ retry_locked:
newcr->cr_suid = uid;
newcr->cr_uid = uid;
crsetsid(newcr, ksp, KSID_USER);
+
+ priv_reset_PA(newcr, B_TRUE);
+
ASSERT(uid != oldruid ? uidchge : 1);
mutex_exit(&p->p_crlock);
} else {
@@ -230,6 +231,7 @@ retry:
p->p_cred = newcr;
newcr->cr_uid = uid;
crsetsid(newcr, ksp, KSID_USER);
+ priv_reset_PA(newcr, B_FALSE);
mutex_exit(&p->p_crlock);
if (do_nocd) {
mutex_enter(&p->p_lock);
@@ -364,6 +366,7 @@ retry_locked:
cr->cr_suid != newcr->cr_suid))
do_nocd = 1;
+ priv_reset_PA(newcr, ruid != -1 && euid != -1 && ruid == euid);
crfree(cr);
}
mutex_exit(&p->p_crlock);