summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd')
-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
5 files changed, 70 insertions, 72 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";