diff --git lib/privs.c lib/privs.c
index d290a59..d4dcdf2 100644
--- lib/privs.c
+++ lib/privs.c
@@ -2,7 +2,7 @@
* Zebra privileges.
*
* Copyright (C) 2003 Paul Jakma.
- * Copyright (C) 2005 Sun Microsystems, Inc.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
*
* This file is part of GNU Zebra.
*
@@ -351,6 +351,26 @@ zprivs_caps_terminate (void)
*/
+static pset_t *
+zprivs_caps_minimal ()
+{
+ pset_t *minimal;
+
+ if ((minimal = priv_str_to_set("basic", ",", NULL)) == NULL)
+ {
+ fprintf (stderr, "%s: couldn't get basic set!\n", __func__);
+ exit (1);
+ }
+
+ /* create a minimal privilege set from the basic set */
+ (void) priv_delset(minimal, PRIV_PROC_EXEC);
+ (void) priv_delset(minimal, PRIV_PROC_INFO);
+ (void) priv_delset(minimal, PRIV_PROC_SESSION);
+ (void) priv_delset(minimal, PRIV_FILE_LINK_ANY);
+
+ return minimal;
+}
+
/* convert zebras privileges to system capabilities */
static pset_t *
zcaps2sys (zebra_capabilities_t *zcaps, int num)
@@ -379,26 +399,34 @@ zcaps2sys (zebra_capabilities_t *zcaps, int num)
int
zprivs_change_caps (zebra_privs_ops_t op)
{
+ pset_t *privset;
/* should be no possibility of being called without valid caps */
assert (zprivs_state.syscaps_p);
if (!zprivs_state.syscaps_p)
{
+ fprintf (stderr, "%s: Eek, missing privileged caps!", __func__);
+ exit (1);
+ }
+
+ assert (zprivs_state.caps);
+ if (!zprivs_state.caps)
+ {
fprintf (stderr, "%s: Eek, missing caps!", __func__);
exit (1);
}
-
- /* to raise: copy original permitted into our working effective set
- * to lower: just clear the working effective set
+
+ /* to raise: copy original permitted as our working effective set
+ * to lower: copy regular effective set stored in zprivs_state.caps
*/
if (op == ZPRIVS_RAISE)
- priv_copyset (zprivs_state.syscaps_p, zprivs_state.caps);
+ privset = zprivs_state.syscaps_p;
else if (op == ZPRIVS_LOWER)
- priv_emptyset (zprivs_state.caps);
+ privset = zprivs_state.caps;
else
return -1;
- if (setppriv (PRIV_SET, PRIV_EFFECTIVE, zprivs_state.caps) != 0)
+ if (setppriv (PRIV_SET, PRIV_EFFECTIVE, privset) != 0)
return -1;
return 0;
@@ -426,15 +454,15 @@ zprivs_state_caps (void)
}
else
{
- if (priv_isemptyset (effective) == B_TRUE)
+ if (priv_isequalset (effective, zprivs_state.syscaps_p))
+ result = ZPRIVS_RAISED;
+ else if (priv_isequalset (effective, zprivs_state.caps))
result = ZPRIVS_LOWERED;
else
- result = ZPRIVS_RAISED;
+ result = ZPRIVS_UNKNOWN;
}
- if (effective)
- priv_freeset (effective);
-
+ priv_freeset (effective);
return result;
}
@@ -442,7 +470,7 @@ static void
zprivs_caps_init (struct zebra_privs_t *zprivs)
{
pset_t *basic;
- pset_t *empty;
+ pset_t *minimal;
/* the specified sets */
zprivs_state.syscaps_p = zcaps2sys (zprivs->caps_p, zprivs->cap_num_p);
@@ -470,14 +498,6 @@ zprivs_caps_init (struct zebra_privs_t *zprivs)
priv_union (basic, zprivs_state.syscaps_p);
priv_freeset (basic);
- /* we need an empty set for 'effective', potentially for inheritable too */
- if ( (empty = priv_allocset()) == NULL)
- {
- fprintf (stderr, "%s: couldn't get empty set!\n", __func__);
- exit (1);
- }
- priv_emptyset (empty);
-
/* Hey kernel, we know about privileges!
* this isn't strictly required, use of setppriv should have same effect
*/
@@ -520,16 +540,19 @@ zprivs_caps_init (struct zebra_privs_t *zprivs)
exit (1);
}
- /* now clear the effective set and we're ready to go */
- if (setppriv (PRIV_SET, PRIV_EFFECTIVE, empty))
+ /* we need a minimal basic set for 'effective', potentially for inheritable too */
+ minimal = zprivs_caps_minimal();
+
+ /* now set the effective set with a subset of basic privileges */
+ if (setppriv (PRIV_SET, PRIV_EFFECTIVE, minimal))
{
fprintf (stderr, "%s: error setting effective set!, %s\n", __func__,
safe_strerror (errno) );
exit (1);
}
- /* we'll use this as our working-storage privset */
- zprivs_state.caps = empty;
+ /* we'll use the minimal set as our working-storage privset */
+ zprivs_state.caps = minimal;
/* set methods for the caller to use */
zprivs->change = zprivs_change_caps;
@@ -541,8 +564,7 @@ zprivs_caps_terminate (void)
{
assert (zprivs_state.caps);
- /* clear all capabilities */
- priv_emptyset (zprivs_state.caps);
+ /* clear all capabilities by using working-storage privset */
setppriv (PRIV_SET, PRIV_EFFECTIVE, zprivs_state.caps);
setppriv (PRIV_SET, PRIV_PERMITTED, zprivs_state.caps);
setppriv (PRIV_SET, PRIV_INHERITABLE, zprivs_state.caps);