/*
 * michael gebetsroither <michael.geb@gmx.at>
 * GPL
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
 
#undef _POSIX_SOURCE
#include <sys/capability.h>
 
extern int errno;
 
#define checkResults(string, val) { \
 if (val) { \
   printf("Failed with %d at %s:%i - %s\n", val, string, __LINE__, strerror(errno)); \
 } \
}
 
void whoami(void)
{
  printf("uid=%i  euid=%i  gid=%i\n", getuid(), geteuid(), getgid());
}
 
void listCaps()
{
  cap_t caps = cap_get_proc();
  ssize_t y = 0;
  printf("The process %d was give capabilities %s\n",
         (int) getpid(), cap_to_text(caps, &y));
  fflush(0);
  cap_free(caps);
}
 
int setCaps(cap_t caps, cap_value_t cap_list[], unsigned num_caps)
{
  cap_set_flag(caps, CAP_EFFECTIVE, num_caps, cap_list, CAP_SET);
  cap_set_flag(caps, CAP_INHERITABLE, num_caps, cap_list, CAP_SET);
  cap_set_flag(caps, CAP_PERMITTED, num_caps, cap_list, CAP_SET);
 
  if (cap_set_proc(caps)) {
    perror("capset()");
    return 0;
  }
  return 1;
}
 
int main(int argc, char **argv)
{
  int stat;
  whoami();
  stat = setuid(geteuid());
  checkResults("setuid", stat)
  stat = setgid(1008);
  checkResults("setgid", stat);
  whoami();
  pid_t parentPid = getpid();
 
  if(!parentPid)
    return 1;
 
  cap_t caps = cap_init();
 
  /*
     CAP_NET_RAW       -  raw sockets
     CAP_NET_BIND_SERVICE -> ports <1024
     CAP_SETUID        -> setuid
     CAP_SETGID        -> setgid
  */
 
  cap_value_t capList[4] =
  { CAP_NET_RAW, CAP_NET_BIND_SERVICE , CAP_SETUID, CAP_SETGID } ;
  unsigned num_caps = 4;
  cap_set_flag(caps, CAP_EFFECTIVE, num_caps, capList, CAP_SET);
  cap_set_flag(caps, CAP_INHERITABLE, num_caps, capList, CAP_SET);
  cap_set_flag(caps, CAP_PERMITTED, num_caps, capList, CAP_SET);
 
  if (cap_set_proc(caps)) {
    perror("capset()");
 
    return EXIT_FAILURE;
  }
  listCaps();
 
  printf("dropping root privs\n");
  stat = setuid(1008);
  checkResults("setuid", stat);
  whoami();
 
  printf("\ntry to change back to uid=0\n");
  checkResults("setuid", seteuid(0));
  checkResults("setuid", setuid(0));
  checkResults("setuid", setuid(1000));
 
  printf("\nend of permission flicking\n");
  whoami();
  listCaps();
 
  // could not drop capas CAP_SET_UID/CAP_SET_GID because operation net permittet
  //    error in manpage, CAP_SETPCAP sould not be required to remove capas.
  //
  // but CAP_SET_UID/CAP_SET_GID are imho nonworking because we are not root anymore (wtf)?
/*
  printf("dropping caps\n");
  cap_clear(caps);  // resetting caps storage
  cap_value_t newCapList[3] = { CAP_SYS_NICE, CAP_NET_RAW, CAP_NET_BIND_SERVICE };
  num_caps = 3;
  //cap_set_flag(caps, CAP_EFFECTIVE, num_caps, newCapList, CAP_SET);
  //cap_set_flag(caps, CAP_INHERITABLE, num_caps, newCapList, CAP_SET);
  cap_set_flag(caps, CAP_PERMITTED, num_caps, newCapList, CAP_SET);
 
  if (cap_set_proc(caps)) {
    perror("capset()");
    return EXIT_FAILURE;
  }
  listCaps();
*/
  cap_free(caps);
  return 0;
}
 
 
snippets/linux_kernel_capabilites_example.txt · Last modified: 2006/02/17 14:01
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki