From 6820e25447dc8d7f1f3992e915eade95768a4e56 Mon Sep 17 00:00:00 2001 From: David Bartley Date: Wed, 29 Apr 2009 03:52:26 -0400 Subject: [PATCH] New module 'sol10priv'. --- ChangeLog | 9 ++++ lib/sol10priv.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/sol10priv.h | 26 ++++++++++++ lib/unlinkdir.c | 27 +++--------- m4/sol10priv.m4 | 14 ++++++ modules/sol10priv | 25 +++++++++++ modules/unlinkdir | 3 +- 7 files changed, 200 insertions(+), 21 deletions(-) create mode 100644 lib/sol10priv.c create mode 100644 lib/sol10priv.h create mode 100644 m4/sol10priv.m4 create mode 100644 modules/sol10priv diff --git a/ChangeLog b/ChangeLog index 6389ebe..249f696 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-04-27 David Bartley + New module 'sol10priv'. + * lib/sol10priv.c: New file. + * lib/sol10priv.h: New file. + * m4/sol10priv.m4: New file. + * modules/sol10priv: New file. + * lib/unlinkdir.c: Make cannot_unlink_dir thread-safe. + * modules/unlinkdir: Add dependency on sol10priv module. + 2009-04-27 Bruno Haible New module 'libunistring'. diff --git a/lib/sol10priv.c b/lib/sol10priv.c new file mode 100644 index 0000000..e522ad2 --- /dev/null +++ b/lib/sol10priv.c @@ -0,0 +1,117 @@ +/* Query, remove, or restore a Solaris 10 privilege. + + Copyright (C) 2009 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Written by David Bartley. */ + +#include + +#if HAVE_GETPPRIV + +# include "sol10priv.h" +# include + +static priv_set_t *eff_set; +static priv_set_t *rem_set; +static bool initialized; + +static int +sol10priv_init (void) +{ + if (! initialized) + { + eff_pset = priv_allocset (); + if (!eff_pset) + { + return -1; + } + rem_pset = priv_allocset (); + if (!rem_pset) + { + priv_freeset (eff_pset); + return -1; + } + if (getppriv (PRIV_EFFECTIVE, eff_set) != 0) + { + priv_freeset (eff_pset); + priv_freeset (rem_pset); + return -1; + } + priv_emptyset (rem_set); + initialized = true; + } + + return 0; +} + + +/* Check if priv is in the effective set. */ +int +sol10priv_ismember (const char *priv) +{ + if (! initialized && ! sol10priv_initialize ()) + return -1; + + return priv_ismember (eff_set, priv); +} + + +/* Try to remove priv from the effective set. */ +int +sol10priv_remove (const char *priv) +{ + if (! initialized && ! sol10priv_initialize ()) + return -1; + + if (priv_ismember (eff_set, priv) && ! priv_ismember (rem_set, priv)) + { + if (priv_delset (eff_set, priv) != 0) + return -1; + if (setppriv (PRIV_EFFECTIVE, eff_set) != 0) + { + priv_addset (eff_set, priv); + return -1; + } + priv_addset (rem_set, priv); + } + + return 0; +} + + +/* Try to restore priv if it was previously removed from the effective set. */ +int +sol10priv_restore (const char *priv) +{ + if (! initialized && ! sol10priv_initialize ()) + return -1; + + if (priv_ismember (rem_set, priv) && ! priv_ismember (eff_set, priv)) + { + if (priv_addset (eff_set, priv) != 0) + return -1; + if (setppriv (PRIV_EFFECTIVE, eff_set) != 0) + { + priv_addset (eff_set, priv); + return -1; + } + priv_delset (rem_set, priv); + } + + return 0; +} + +#endif diff --git a/lib/sol10priv.h b/lib/sol10priv.h new file mode 100644 index 0000000..5e72fd6 --- /dev/null +++ b/lib/sol10priv.h @@ -0,0 +1,26 @@ +/* Query, remove, or restore a Solaris 10 privilege. + + Copyright (C) 2009 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Written by David Bartley. */ + +#if HAVE_GETPPRIV + +int sol10priv_ismember (const char *priv); +int sol10priv_remove (const char *priv); +int sol10priv_restore (const char *priv); + +#endif diff --git a/lib/unlinkdir.c b/lib/unlinkdir.c index 9c3ff00..e32986b 100644 --- a/lib/unlinkdir.c +++ b/lib/unlinkdir.c @@ -1,4 +1,4 @@ -/* unlinkdir.c - determine (and maybe change) whether we can unlink directories +/* unlinkdir.c - determine whether we can unlink directories Copyright (C) 2005-2006, 2009 Free Software Foundation, Inc. @@ -15,11 +15,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -/* Written by Paul Eggert and Jim Meyering. */ +/* Written by Paul Eggert, Jim Meyering, and David Bartley. */ #include #include "unlinkdir.h" +#include "sol10priv.h" #if HAVE_PRIV_H # include @@ -29,12 +30,7 @@ #if ! UNLINK_CANNOT_UNLINK_DIR /* Return true if we cannot unlink directories, false if we might be - able to unlink directories. If possible, tell the kernel we don't - want to be able to unlink directories, so that we can return true. - - Note: this function may modify the process privilege set, to remove - the PRIV_SYS_LINKDIR privilege, so is neither thread-safe, nor - appropriate for use in a library. */ + able to unlink directories. */ bool cannot_unlink_dir (void) @@ -44,20 +40,11 @@ cannot_unlink_dir (void) if (! initialized) { -# if defined PRIV_EFFECTIVE && defined PRIV_SYS_LINKDIR +# if HAVE_GETPPRIV && defined PRIV_SYS_LINKDIR /* We might be able to unlink directories if we cannot determine our privileges, or if we have the - PRIV_SYS_LINKDIR privilege and cannot delete it. */ - priv_set_t *pset = priv_allocset (); - if (pset) - { - cannot = - (getppriv (PRIV_EFFECTIVE, pset) == 0 - && (! priv_ismember (pset, PRIV_SYS_LINKDIR) - || (priv_delset (pset, PRIV_SYS_LINKDIR) == 0 - && setppriv (PRIV_SET, PRIV_EFFECTIVE, pset) == 0))); - priv_freeset (pset); - } + PRIV_SYS_LINKDIR privilege. */ + cannot = (sol10priv_ismember (PRIV_SYS_LINKDIR) == 0); # else /* In traditional Unix, only root can unlink directories. */ cannot = (geteuid () != 0); diff --git a/m4/sol10priv.m4 b/m4/sol10priv.m4 new file mode 100644 index 0000000..e58f402 --- /dev/null +++ b/m4/sol10priv.m4 @@ -0,0 +1,14 @@ +# serial 6 + +# Copyright (C) 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Written by David Bartley. + +AC_DEFUN([gl_SOL10PRIV], +[ + AC_CHECK_FUNCS([getppriv]) +]) diff --git a/modules/sol10priv b/modules/sol10priv new file mode 100644 index 0000000..5c35318 --- /dev/null +++ b/modules/sol10priv @@ -0,0 +1,25 @@ +Description: +Query, remove or, restore a Solaris 10 privilege + +Files: +lib/sol10priv.h +lib/sol10priv.c +m4/sol10priv.m4 + +Depends-on: +stdbool + +configure.ac: +gl_SOL10PRIV + +Makefile.am: +lib_SOURCES += sol10priv-remove.c sol10priv-restore.c + +Include: +"sol10priv.h" + +License: +GPL + +Maintainer: +David Bartley diff --git a/modules/unlinkdir b/modules/unlinkdir index e8c68a6..9a0a284 100644 --- a/modules/unlinkdir +++ b/modules/unlinkdir @@ -1,5 +1,5 @@ Description: -Determine (and maybe change) whether we can unlink directories. +Determine whether we can unlink directories. Files: lib/unlinkdir.h @@ -8,6 +8,7 @@ m4/unlinkdir.m4 Depends-on: stdbool +sol10priv configure.ac: gl_UNLINKDIR -- 1.5.6.5