diff options
Diffstat (limited to 'usr/src/cmd')
-rw-r--r-- | usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c | 9 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c | 123 | ||||
-rw-r--r-- | usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.pm | 4 | ||||
-rw-r--r-- | usr/src/cmd/ptools/ppriv/ppriv.c | 5 | ||||
-rw-r--r-- | usr/src/cmd/truss/print.c | 1 |
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"; |