/* 
 * Zebra privileges.
 *
 * Copyright (C) 2003 Paul Jakma.
 * Copyright (C) 2005 Sun Microsystems, Inc.
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra 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 2, or (at your option) any
 * later version.
 *
 * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.  
 */
#include <zebra.h>
#include "log.h"
#include "privs.h"
#include "memory.h"

#ifdef HAVE_CAPABILITIES
/* sort out some generic internal types for:
 *
 * privilege values (cap_value_t, priv_t) 	-> pvalue_t
 * privilege set (..., priv_set_t) 		-> pset_t
 * privilege working storage (cap_t, ...) 	-> pstorage_t
 *
 * values we think of as numeric (they're ints really, but we dont know)
 * sets are mostly opaque, to hold a set of privileges, related in some way.
 * storage binds together a set of sets we're interested in.
 * (in reality: cap_value_t and priv_t are ints)
 */ 
#ifdef HAVE_LCAPS
/* Linux doesn't have a 'set' type: a set of related privileges */
struct _pset {
  int num;
  cap_value_t *caps;
};
typedef cap_value_t pvalue_t;
typedef struct _pset pset_t;
typedef cap_t pstorage_t;

#elif defined (HAVE_SOLARIS_CAPABILITIES)
typedef priv_t pvalue_t;
typedef priv_set_t pset_t;
typedef priv_set_t *pstorage_t;
#else /* neither LCAPS nor SOLARIS_CAPABILITIES */
#error "HAVE_CAPABILITIES defined, but neither LCAPS nor Solaris Capabilties!"
#endif /* HAVE_LCAPS */
#endif /* HAVE_CAPABILITIES */

/* the default NULL state we report is RAISED, but could be LOWERED if
 * zprivs_terminate is called and the NULL handler is installed.
 */
static zebra_privs_current_t zprivs_null_state = ZPRIVS_RAISED;

/* internal privileges state */
static struct _zprivs_t
{
#ifdef HAVE_CAPABILITIES
  pstorage_t caps;		/* working storage        */
  pset_t *syscaps_p;		/* system-type requested permitted caps    */
  pset_t *syscaps_i;     	/* system-type requested inheritable caps  */
#endif /* HAVE_CAPABILITIES */
  uid_t zuid,                 /* uid to run as            */
        zsuid;                /* saved uid                */
  gid_t zgid;                 /* gid to run as            */
  gid_t vtygrp;               /* gid for vty sockets      */
} zprivs_state;

/* externally exported but not directly accessed functions */
#ifdef HAVE_CAPABILITIES
int zprivs_change_caps (zebra_privs_ops_t);
zebra_privs_current_t zprivs_state_caps (void);
#endif /* HAVE_CAPABILITIES */
int zprivs_change_uid (zebra_privs_ops_t);
zebra_privs_current_t zprivs_state_uid (void);
int zprivs_change_null (zebra_privs_ops_t);
zebra_privs_current_t zprivs_state_null (void);

#ifdef HAVE_CAPABILITIES
/* internal capability API */
static pset_t *zcaps2sys (zebra_capabilities_t *, int);
static void zprivs_caps_init (struct zebra_privs_t *);
static void zprivs_caps_terminate (void);

/* Map of Quagga abstract capabilities to system capabilities */
static struct
{
  int num;
  pvalue_t *system_caps;
} cap_map [ZCAP_MAX] =
{
#ifdef HAVE_LCAPS /* Quagga -> Linux capabilities mappings */
  [ZCAP_SETID] = 	{ 2, (pvalue_t []) { CAP_SETGID,
                                             CAP_SETUID 		}, },
  [ZCAP_BIND] =		{ 2, (pvalue_t []) { CAP_NET_BIND_SERVICE,
                                             CAP_NET_BROADCAST 		}, },
  [ZCAP_NET_ADMIN] =	{ 1, (pvalue_t []) { CAP_NET_ADMIN		}, },
  [ZCAP_NET_RAW] = 	{ 1, (pvalue_t []) { CAP_NET_RAW		}, },
  [ZCAP_CHROOT] = 	{ 1, (pvalue_t []) { CAP_SYS_CHROOT,		}, },
  [ZCAP_NICE] = 	{ 1, (pvalue_t []) { CAP_SYS_NICE 		}, },
  [ZCAP_PTRACE] =  	{ 1, (pvalue_t []) { CAP_SYS_PTRACE 		}, },
  [ZCAP_DAC_OVERRIDE] = { 1, (pvalue_t []) { CAP_DAC_OVERRIDE 		}, },
  [ZCAP_READ_SEARCH] =  { 1, (pvalue_t []) { CAP_DAC_READ_SEARCH 	}, },
  [ZCAP_SYS_ADMIN] =	{ 1, (pvalue_t []) { CAP_SYS_ADMIN 		}, },
  [ZCAP_FOWNER] = 	{ 1, (pvalue_t []) { CAP_FOWNER			}, },
#elif defined(HAVE_SOLARIS_CAPABILITIES) /* HAVE_LCAPS */
  /* Quagga -> Solaris privilege mappings */
  [ZCAP_SETID] =	{ 1, (pvalue_t []) { PRIV_PROC_SETID		}, },
  [ZCAP_BIND] = 	{ 1, (pvalue_t []) { PRIV_NET_PRIVADDR		}, },
  [ZCAP_NET_ADMIN] =	{ 1, (pvalue_t []) { PRIV_SYS_NET_CONFIG	}, },
  [ZCAP_NET_RAW] = 	{ 2, (pvalue_t []) { PRIV_NET_RAWACCESS,
                                             PRIV_NET_ICMPACCESS 	}, },
  [ZCAP_CHROOT] = 	{ 1, (pvalue_t []) { PRIV_PROC_CHROOT		}, },
  [ZCAP_NICE] = 	{ 1, (pvalue_t []) { PRIV_PROC_PRIOCNTL		}, },
  [ZCAP_PTRACE] =	{ 1, (pvalue_t []) { PRIV_PROC_SESSION		}, },
  [ZCAP_DAC_OVERRIDE] = { 2, (pvalue_t []) { PRIV_FILE_DAC_EXECUTE, 
                                             PRIV_FILE_DAC_READ,
                                             PRIV_FILE_DAC_SEARCH,
                                             PRIV_FILE_DAC_WRITE,
                                             PRIV_FILE_DAC_SEARCH	}, },
  [ZCAP_READ_SEARCH] =	{ 2, (pvalue_t []) { PRIV_FILE_DAC_SEARCH,
                                             PRIV_FILE_DAC_READ		}, },
  [ZCAP_SYS_ADMIN] =	{ 1, (pvalue_t []) { PRIV_SYS_ADMIN		}, },
  [ZCAP_FOWNER] =	{ 1, (pvalue_t []) { PRIV_FILE_OWNER		}, },
#endif /* HAVE_SOLARIS_CAPABILITIES */
};

#ifdef HAVE_LCAPS
/* Linux forms of capabilities methods */
/* convert zebras privileges to system capabilities */
static pset_t *
zcaps2sys (zebra_capabilities_t *zcaps, int num)
{
  pset_t *syscaps;
  int i, j = 0, count = 0;
  
  if (!num)
    return NULL;
  
  /* first count up how many system caps we have */
  for (i= 0; i < num; i++)
    count += cap_map[zcaps[i]].num;
  
  if ( (syscaps = XCALLOC (MTYPE_PRIVS, (sizeof(pset_t) * num))) == NULL)
    {
      fprintf (stderr, "%s: could not allocate syscaps!", __func__);
      return NULL;
    }
  
  syscaps->caps = XCALLOC (MTYPE_PRIVS, (sizeof (pvalue_t) * count));
  
  if (!syscaps->caps)
    {
      fprintf (stderr, "%s: could not XCALLOC caps!", __func__);
      return NULL;
    }
  
  /* copy the capabilities over */
  count = 0;
  for (i=0; i < num; i++)
    for (j = 0; j < cap_map[zcaps[i]].num; j++)
      syscaps->caps[count++] = cap_map[zcaps[i]].system_caps[j];
  
  /* iterations above should be exact same as previous count, obviously.. */
  syscaps->num = count;
  
  return syscaps;
}

/* set or clear the effective capabilities to/from permitted */
int 
zprivs_change_caps (zebra_privs_ops_t op)
{
  cap_flag_value_t cflag;
  
  /* should be no possibility of being called without valid caps */
  assert (zprivs_state.syscaps_p && zprivs_state.caps);
  if (! (zprivs_state.syscaps_p && zprivs_state.caps))
    exit (1);
    
  if (op == ZPRIVS_RAISE)
    cflag = CAP_SET;
  else if (op == ZPRIVS_LOWER)
    cflag = CAP_CLEAR;
  else
    return -1;

  if ( !cap_set_flag (zprivs_state.caps, CAP_EFFECTIVE,
                       zprivs_state.syscaps_p->num, 
                       zprivs_state.syscaps_p->caps, 
                       cflag))
    return cap_set_proc (zprivs_state.caps);
  return -1;
}

zebra_privs_current_t
zprivs_state_caps (void)
{
  int i;
  cap_flag_value_t val;

  /* should be no possibility of being called without valid caps */
  assert (zprivs_state.syscaps_p && zprivs_state.caps);
  if (! (zprivs_state.syscaps_p && zprivs_state.caps))
    exit (1);
  
  for (i=0; i < zprivs_state.syscaps_p->num; i++)
    {
      if ( cap_get_flag (zprivs_state.caps, zprivs_state.syscaps_p->caps[i], 
                         CAP_EFFECTIVE, &val) )
        {
          zlog_warn ("zprivs_state_caps: could not cap_get_flag, %s",
                     safe_strerror (errno) );
          return ZPRIVS_UNKNOWN;
        }
      if (val == CAP_SET)
        return ZPRIVS_RAISED;
    }
  return ZPRIVS_LOWERED;
}

static void
zprivs_caps_init (struct zebra_privs_t *zprivs)
{
  zprivs_state.syscaps_p = zcaps2sys (zprivs->caps_p, zprivs->cap_num_p);
  zprivs_state.syscaps_i = zcaps2sys (zprivs->caps_i, zprivs->cap_num_i);

  /* Tell kernel we want caps maintained across uid changes */
  if ( prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1 )
    {
      fprintf (stderr, "privs_init: could not set PR_SET_KEEPCAPS, %s\n",
                safe_strerror (errno) );
      exit(1);
    }

  if ( !zprivs_state.syscaps_p )
    {
      fprintf (stderr, "privs_init: capabilities enabled, "
                       "but no capabilities supplied\n");
    }

  if ( !(zprivs_state.caps = cap_init()) )
    {
      fprintf (stderr, "privs_init: failed to cap_init, %s\n", 
               safe_strerror (errno));
      exit (1);
    }

  /* we have caps, we have no need to ever change back the original user */
  if (zprivs_state.zuid)
    {
      if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) )
        {
          fprintf (stderr, "zprivs_init (cap): could not setreuid, %s\n", 
                     safe_strerror (errno));
          exit (1);
        }
    }
  
  if ( cap_clear (zprivs_state.caps) )
    {
      fprintf (stderr, "privs_init: failed to cap_clear, %s\n", 
               safe_strerror (errno));
      exit (1);
    }
  
  /* set permitted caps */
  cap_set_flag(zprivs_state.caps, CAP_PERMITTED, 
               zprivs_state.syscaps_p->num,
               zprivs_state.syscaps_p->caps,
               CAP_SET);
    
  /* set inheritable caps, if any */
  if (zprivs_state.syscaps_i && zprivs_state.syscaps_i->num)
    {
      cap_set_flag(zprivs_state.caps, CAP_INHERITABLE, 
                   zprivs_state.syscaps_i->num, 
                   zprivs_state.syscaps_i->caps, 
                   CAP_SET);
    }
  
  /* apply caps. CAP_EFFECTIVE is cleared. we'll raise the caps as 
   * and when, and only when, they are needed.
   */
  if ( cap_set_proc (zprivs_state.caps) ) 
    {
      fprintf (stderr, "privs_init: initial cap_set_proc failed\n");
      exit (1);
    }
  
  /* set methods for the caller to use */
  zprivs->change = zprivs_change_caps;
  zprivs->current_state = zprivs_state_caps;
}

static void
zprivs_caps_terminate (void)
{
  /* clear all capabilities */
  if (zprivs_state.caps)
      cap_clear (zprivs_state.caps);

  /* and boom, capabilities are gone forever */
  if ( cap_set_proc (zprivs_state.caps) ) 
    {
      fprintf (stderr, "privs_terminate: cap_set_proc failed, %s",
                safe_strerror (errno) );
      exit (1);
    }  

  /* free up private state */
  if (zprivs_state.syscaps_p->num)
    {
      XFREE (MTYPE_PRIVS, zprivs_state.syscaps_p->caps);
      XFREE (MTYPE_PRIVS, zprivs_state.syscaps_p);
    }
  
  if (zprivs_state.syscaps_i && zprivs_state.syscaps_i->num)
    {
      XFREE (MTYPE_PRIVS, zprivs_state.syscaps_i->caps);
      XFREE (MTYPE_PRIVS, zprivs_state.syscaps_i);
    }
  
  cap_free (zprivs_state.caps);
}
#elif defined (HAVE_SOLARIS_CAPABILITIES) /* !HAVE_LCAPS */

/* Solaris specific capability/privilege methods 
 *
 * Resources:
 * - the 'privileges' man page
 * - http://cvs.opensolaris.org
 * - http://blogs.sun.com/roller/page/gbrunett?entry=privilege_enabling_set_id_programs1
 */

/* convert zebras privileges to system capabilities */
static pset_t *
zcaps2sys (zebra_capabilities_t *zcaps, int num)
{
  pset_t *syscaps;
  int i, j = 0, count = 0;
  
  if ((syscaps = priv_allocset()) == NULL)
    {
      fprintf (stderr, "%s: could not allocate syscaps!\n", __func__);
      exit (1);
    }
    
  priv_emptyset (syscaps);
  
  for (i=0; i < num; i++)
    for (j = 0; j < cap_map[zcaps[i]].num; j++)
      priv_addset (syscaps, cap_map[zcaps[i]].system_caps[j]);
  
  return syscaps;
}

/* callback exported to users to RAISE and LOWER effective privileges
 * from nothing to the given permitted set and back down
 */
int 
zprivs_change_caps (zebra_privs_ops_t op)
{
  
  /* 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 caps!", __func__);
      exit (1);
    }
  
  /* to raise: copy original permitted into our working effective set
   * to lower: just clear the working effective set
   */
  if (op == ZPRIVS_RAISE)
    priv_copyset (zprivs_state.syscaps_p, zprivs_state.caps);
  else if (op == ZPRIVS_LOWER)
    priv_emptyset (zprivs_state.caps);
  else
    return -1;
  
  if (setppriv (PRIV_SET, PRIV_EFFECTIVE, zprivs_state.caps) != 0)
    return -1;
  
  return 0;
}

/* Retrieve current privilege state, is it RAISED or LOWERED? */
zebra_privs_current_t 
zprivs_state_caps (void)
{
  zebra_privs_current_t result;
  pset_t *effective;
  
  if ( (effective = priv_allocset()) == NULL)
    {
      fprintf (stderr, "%s: failed to get priv_allocset!\n", __func__,
               safe_strerror (errno));
      return ZPRIVS_UNKNOWN;
    }
  
  if (getppriv (PRIV_EFFECTIVE, effective))
    {
      fprintf (stderr, "%s: failed to get state!%s\n", __func__,
               safe_strerror (errno));
      result = ZPRIVS_UNKNOWN;
    }
  else
    {
      if (priv_isemptyset (effective) == B_TRUE)
        result = ZPRIVS_LOWERED;
      else
        result = ZPRIVS_RAISED;
    }
  
  if (effective)
    priv_freeset (effective);
  
  return result;
}

static void
zprivs_caps_init (struct zebra_privs_t *zprivs)
{
  pset_t *basic;
  pset_t *empty;
  
  /* the specified sets */
  zprivs_state.syscaps_p = zcaps2sys (zprivs->caps_p, zprivs->cap_num_p);
  zprivs_state.syscaps_i = zcaps2sys (zprivs->caps_i, zprivs->cap_num_i);
  
  /* nonsensical to have gotten here but not have capabilities */
  if (!zprivs_state.syscaps_p)
    {
      fprintf (stderr, "%s: capabilities enabled, "
                       "but no valid capabilities supplied\n",
                       __func__);
    }
  
  /* We retain the basic set in our permitted set, as Linux has no
   * equivalent. The basic set on Linux hence is implicit, always
   * there.
   */
  if ((basic = priv_str_to_set("basic", ",", NULL)) == NULL)
    {
      fprintf (stderr, "%s: couldn't get basic set!\n", __func__);
      exit (1);
    }
 
  /* Add the basic set to the permitted set */
  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
   */
  if (setpflags (PRIV_AWARE, 1))
    {
      fprintf (stderr, "%s: error setting PRIV_AWARE!, %s\n", __func__,
               safe_strerror (errno) );
      exit (1);
    }
  
  /* need either valid or empty sets for both p and i.. */
  assert (zprivs_state.syscaps_i && zprivs_state.syscaps_p);
  
  /* set the permitted set */
  if (setppriv (PRIV_SET, PRIV_PERMITTED, zprivs_state.syscaps_p))
    {
      fprintf (stderr, "%s: error setting permitted set!, %s\n", __func__,
               safe_strerror (errno) );
      exit (1);
    }
  
  /* set the inheritable set */
  if (setppriv (PRIV_SET, PRIV_INHERITABLE, zprivs_state.syscaps_i))
    {
      fprintf (stderr, "%s: error setting inheritable set!, %s\n", __func__,
               safe_strerror (errno) );
      exit (1);
    }

  /* we have caps, we have no need to ever change back the original user */
  if (zprivs_state.zuid)
    {
      if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) )
        {
          fprintf (stderr, "%s: could not setreuid, %s\n", 
                   __func__, safe_strerror (errno));
          exit (1);
        }
    }
  
  /* now clear the effective set and we're ready to go */
  if (setppriv (PRIV_SET, PRIV_EFFECTIVE, empty))
    {
      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;
  
  /* set methods for the caller to use */
  zprivs->change = zprivs_change_caps;
  zprivs->current_state = zprivs_state_caps;
}

static void
zprivs_caps_terminate (void)
{
  assert (zprivs_state.caps);
  
  /* clear all capabilities */
  priv_emptyset (zprivs_state.caps);
  setppriv (PRIV_SET, PRIV_EFFECTIVE, zprivs_state.caps);
  setppriv (PRIV_SET, PRIV_PERMITTED, zprivs_state.caps);
  setppriv (PRIV_SET, PRIV_INHERITABLE, zprivs_state.caps);
  
  /* free up private state */
  if (zprivs_state.syscaps_p)
    priv_freeset (zprivs_state.syscaps_p);
  if (zprivs_state.syscaps_i)
    priv_freeset (zprivs_state.syscaps_i);
  
  priv_freeset (zprivs_state.caps);
}
#else /* !HAVE_LCAPS && ! HAVE_SOLARIS_CAPABILITIES */
#error "Neither Solaris nor Linux capabilities, dazed and confused..."
#endif /* HAVE_LCAPS */
#endif /* HAVE_CAPABILITIES */

int
zprivs_change_uid (zebra_privs_ops_t op)
{

  if (op == ZPRIVS_RAISE)
    return seteuid (zprivs_state.zsuid);
  else if (op == ZPRIVS_LOWER)
    return seteuid (zprivs_state.zuid);
  else
    return -1;
}

zebra_privs_current_t
zprivs_state_uid (void)
{
  return ( (zprivs_state.zuid == geteuid()) ? ZPRIVS_LOWERED : ZPRIVS_RAISED);
}

int
zprivs_change_null (zebra_privs_ops_t op)
{
  return 0;
}

zebra_privs_current_t
zprivs_state_null (void)
{
  return zprivs_null_state;
}

void
zprivs_init(struct zebra_privs_t *zprivs)
{
  struct passwd *pwentry = NULL;
  struct group *grentry = NULL;

  if (!zprivs)
    {
      fprintf (stderr, "zprivs_init: called with NULL arg!\n");
      exit (1);
    }

  /* NULL privs */
  if (! (zprivs->user || zprivs->group 
         || zprivs->cap_num_p || zprivs->cap_num_i) )
    {
      zprivs->change = zprivs_change_null;
      zprivs->current_state = zprivs_state_null;
      return;
    }

  if (zprivs->user)
    {
      if ( (pwentry = getpwnam (zprivs->user)) )
        {
          zprivs_state.zuid = pwentry->pw_uid;
        }
      else
        {
          /* cant use log.h here as it depends on vty */
          fprintf (stderr, "privs_init: could not lookup user %s\n",
                   zprivs->user);
          exit (1);
        }
    }

  grentry = NULL;

  if (zprivs->vty_group)
    /* Add the vty_group to the supplementary groups so it can be chowned to */
    {
      if ( (grentry = getgrnam (zprivs->vty_group)) )
        {
          zprivs_state.vtygrp = grentry->gr_gid;
          if ( setgroups (1, &zprivs_state.vtygrp) )
            {
              fprintf (stderr, "privs_init: could not setgroups, %s\n",
                         safe_strerror (errno) );
              exit (1);
            }       
        }
      else
        {
          fprintf (stderr, "privs_init: could not lookup vty group %s\n",
                   zprivs->vty_group);
          exit (1);
        }
    }
  
  if (zprivs->group)
    {
      if ( (grentry = getgrnam (zprivs->group)) )
        {
          zprivs_state.zgid = grentry->gr_gid;
        }
      else
        {
          fprintf (stderr, "privs_init: could not lookup group %s\n",
                   zprivs->group);
          exit (1);
        }
      /* change group now, forever. uid we do later */
      if ( setregid (zprivs_state.zgid, zprivs_state.zgid) )
        {
          fprintf (stderr, "zprivs_init: could not setregid, %s\n",
                    safe_strerror (errno) );
          exit (1);
        }
    }
  
#ifdef HAVE_CAPABILITIES
  zprivs_caps_init (zprivs);
#else /* !HAVE_CAPABILITIES */
  /* we dont have caps. we'll need to maintain rid and saved uid
   * and change euid back to saved uid (who we presume has all neccessary
   * privileges) whenever we are asked to raise our privileges.
   *
   * This is not worth that much security wise, but all we can do.
   */
  zprivs_state.zsuid = geteuid();  
  if ( zprivs_state.zuid )
    {
      if ( setreuid (-1, zprivs_state.zuid) )
        {
          fprintf (stderr, "privs_init (uid): could not setreuid, %s\n", 
                   safe_strerror (errno));
          exit (1);
        }
    }
  
  zprivs->change = zprivs_change_uid;
  zprivs->current_state = zprivs_state_uid;
#endif /* HAVE_CAPABILITIES */
}

void 
zprivs_terminate (struct zebra_privs_t *zprivs)
{
  if (!zprivs)
    {
      fprintf (stderr, "%s: no privs struct given, terminating", __func__);
      exit (0);
    }
  
#ifdef HAVE_CAPABILITIES
  zprivs_caps_terminate();
#else /* !HAVE_CAPABILITIES */
  if (zprivs_state.zuid)
    {
      if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) )
        {
          fprintf (stderr, "privs_terminate: could not setreuid, %s", 
                     safe_strerror (errno) );
          exit (1);
        }
     }
#endif /* HAVE_LCAPS */

  zprivs->change = zprivs_change_null;
  zprivs->current_state = zprivs_state_null;
  zprivs_null_state = ZPRIVS_LOWERED;
  return;
}

void
zprivs_get_ids(struct zprivs_ids_t *ids)
{

   ids->uid_priv = getuid();
   (zprivs_state.zuid) ? (ids->uid_normal = zprivs_state.zuid)
                     : (ids->uid_normal = -1);
   (zprivs_state.zgid) ? (ids->gid_normal = zprivs_state.zgid)
                     : (ids->gid_normal = -1);
   (zprivs_state.vtygrp) ? (ids->gid_vty = zprivs_state.vtygrp)
                       : (ids->gid_vty = -1);
   
   return;
}
