(root)/
findutils-4.9.0/
gnulib-tests/
priv-set.c
       1  /* Query, remove, or restore a Solaris privilege.
       2  
       3     Copyright (C) 2009-2022 Free Software Foundation, Inc.
       4  
       5     This program is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU General Public License as published by
       7     the Free Software Foundation, either version 3 of the License, or
       8     (at your option) any later version.
       9  
      10     This program is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU General Public License for more details.
      14  
      15     You should have received a copy of the GNU General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.
      17  
      18     Written by David Bartley.  */
      19  
      20  #include <config.h>
      21  
      22  #define PRIV_SET_INLINE _GL_EXTERN_INLINE
      23  
      24  #include "priv-set.h"
      25  
      26  #if HAVE_GETPPRIV && HAVE_PRIV_H
      27  
      28  # include <errno.h>
      29  # include <stdbool.h>
      30  # include <priv.h>
      31  
      32  /* Holds a (cached) copy of the effective set.  */
      33  static priv_set_t *eff_set;
      34  
      35  /* Holds a set of privileges that we have removed.  */
      36  static priv_set_t *rem_set;
      37  
      38  static bool initialized;
      39  
      40  static int
      41  priv_set_initialize (void)
      42  {
      43    if (! initialized)
      44      {
      45        eff_set = priv_allocset ();
      46        if (!eff_set)
      47          {
      48            return -1;
      49          }
      50        rem_set = priv_allocset ();
      51        if (!rem_set)
      52          {
      53            priv_freeset (eff_set);
      54            return -1;
      55          }
      56        if (getppriv (PRIV_EFFECTIVE, eff_set) != 0)
      57          {
      58            priv_freeset (eff_set);
      59            priv_freeset (rem_set);
      60            return -1;
      61          }
      62        priv_emptyset (rem_set);
      63        initialized = true;
      64      }
      65  
      66    return 0;
      67  }
      68  
      69  
      70  /* Check if priv is in the effective set.
      71     Returns 1 if priv is a member and 0 if not.
      72     Returns -1 on error with errno set appropriately.  */
      73  int
      74  priv_set_ismember (const char *priv)
      75  {
      76    if (! initialized && priv_set_initialize () != 0)
      77      return -1;
      78  
      79    return priv_ismember (eff_set, priv);
      80  }
      81  
      82  
      83  /* Try to remove priv from the effective set.
      84     Returns 0 if priv was removed.
      85     Returns -1 on error with errno set appropriately.  */
      86  int
      87  priv_set_remove (const char *priv)
      88  {
      89    if (! initialized && priv_set_initialize () != 0)
      90      return -1;
      91  
      92    if (priv_ismember (eff_set, priv))
      93      {
      94        /* priv_addset/priv_delset can only fail if priv is invalid, which is
      95           checked above by the priv_ismember call.  */
      96        priv_delset (eff_set, priv);
      97        if (setppriv (PRIV_SET, PRIV_EFFECTIVE, eff_set) != 0)
      98          {
      99            priv_addset (eff_set, priv);
     100            return -1;
     101          }
     102        priv_addset (rem_set, priv);
     103      }
     104    else
     105      {
     106        errno = EINVAL;
     107        return -1;
     108      }
     109  
     110    return 0;
     111  }
     112  
     113  
     114  /* Try to restore priv to the effective set.
     115     Returns 0 if priv was re-added to the effective set (after being previously
     116     removed by a call to priv_set_remove).
     117     Returns -1 on error with errno set appropriately.  */
     118  int
     119  priv_set_restore (const char *priv)
     120  {
     121    if (! initialized && priv_set_initialize () != 0)
     122      return -1;
     123  
     124    if (priv_ismember (rem_set, priv))
     125      {
     126        /* priv_addset/priv_delset can only fail if priv is invalid, which is
     127           checked above by the priv_ismember call.  */
     128        priv_addset (eff_set, priv);
     129        if (setppriv (PRIV_SET, PRIV_EFFECTIVE, eff_set) != 0)
     130          {
     131            priv_delset (eff_set, priv);
     132            return -1;
     133          }
     134        priv_delset (rem_set, priv);
     135      }
     136    else
     137      {
     138        errno = EINVAL;
     139        return -1;
     140      }
     141  
     142    return 0;
     143  }
     144  
     145  #endif