/***************************************************************************
 *
 * Copyright (c) 2000, 2001 BalaBit IT Ltd, Budapest, Hungary
 *
 * 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 2 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, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: cap.c,v 1.2.2.1.2.2 2001/09/19 19:22:16 bazsi Exp $
 *
 ***************************************************************************/

#include <zorp/cap.h>
#include <zorp/log.h>


#if ENABLE_CAPS

#define CORE_ERROR "core.error"
#define CORE_CAPS "core.caps"

gchar *zorp_caps = "cap_net_admin,cap_net_bind_service=p";

gboolean 
cap_modify(int capability, int onoff)
{
  cap_t caps;
  gchar *cap_txt;

  z_enter();
  if (!zorp_caps)
    {
      z_leave();
      return TRUE;
    }
  
  caps = cap_get_proc();
  if (!caps)
    {
      z_leave();
      return FALSE;
    }


  if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &capability, onoff) == -1)
    {
      cap_free(caps);
      z_leave();
      return FALSE;
    }

  cap_txt = cap_to_text(caps, NULL);
  
  /*LOG
    This message is written when Zorp is about to change its effective
    capability set.
   */
  z_log(NULL, CORE_CAPS, 5, "Changing process capabilities; caps='%s'", cap_txt);
  if (cap_set_proc(caps) == -1)
    {
      /*LOG
        This message indicates that changing capability sets failed.
       */
      z_log(NULL, CORE_ERROR, 3, "Error changing process capabilities; caps='%s' error='%m'", cap_txt);
      cap_free(cap_txt);
      cap_free(caps);
      z_leave();
      return FALSE;
    }
  cap_free(cap_txt);
  cap_free(caps);
  z_leave();
  return TRUE;
}

cap_t 
cap_save(void)
{
  cap_t res;
  
  z_enter();
  if (!zorp_caps)
    {
      z_leave();
      return NULL;
    }
  res = cap_get_proc();
  z_leave();
  return res;
}

gboolean
cap_restore(cap_t r)
{
  gboolean rc;
  gchar *cap_txt;

  z_enter();
  if (!zorp_caps)
    {
      z_leave();
      return TRUE;
    }
  cap_txt = cap_to_text(r, NULL);
  
  /*LOG
    This message indicates that Zorp is giving up capabilities acquired earlier
    for some operation.
   */
  z_log(NULL, CORE_CAPS, 5, "Resetting process capabilities; caps='%s'", cap_txt);
  rc = cap_set_proc(r) != -1;
  if (!rc)
    {
      /*LOG
        This message indicates that changing capability sets failed.
       */
      z_log(NULL, CORE_CAPS, 5, "Error changing process capabilities; caps='%s' error='%m'", cap_txt);
    }
  cap_free(r);
  cap_free(cap_txt);
  z_leave();
  return rc;
}

#endif
