#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/fsuid.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

#include <sys/capability.h>
#include <sys/types.h>


#define SIZE 10240 
#define MOI 3051
#define GRP 5973

int main( int argc, char * argv[] )
{
  int fd =0 ;
  struct __user_cap_data_struct capdata ;
  struct __user_cap_header_struct caphdr ;
  char * buff = NULL ;

  buff = malloc( SIZE ) ;

  printf( "setfsuid=%u\n", setfsuid( MOI ) ) ;
  printf( "setfsgid=%u\n", setfsgid( GRP ) ) ;

  caphdr.version = _LINUX_CAPABILITY_VERSION_2 ; // kernel is newer than 2.6.25
  caphdr.pid = getpid() ;

  printf( "capget=%d errno=%d\n", capget( &caphdr, &capdata ), errno ) ;
  printf( "effective=%x|%x permitted=%x|%x inheritable=%x|%x\n", 
          capdata.effective, capdata.effective & CAP_SYS_RESOURCE,
          capdata.permitted, capdata.permitted & CAP_SYS_RESOURCE,
          capdata.inheritable, capdata.inheritable & CAP_SYS_RESOURCE ) ;

  capdata.effective &= ~CAP_SYS_RESOURCE ;
  capdata.permitted &= ~CAP_SYS_RESOURCE ;

  printf( "effective=%x|%x permitted=%x|%x inheritable=%x|%x\n", 
          capdata.effective, capdata.effective & CAP_SYS_RESOURCE,
          capdata.permitted, capdata.permitted & CAP_SYS_RESOURCE,
          capdata.inheritable, capdata.inheritable & CAP_SYS_RESOURCE ) ;
  printf( "capset=%d errno=%d\n", capset( &caphdr, &capdata ), errno ) ;

  printf( "capget=%d errno=%d\n", capget( &caphdr, &capdata ), errno ) ;
  printf( "effective=%x|%x permitted=%x|%x inheritable=%x|%x\n", 
          capdata.effective, capdata.effective & CAP_SYS_RESOURCE,
          capdata.permitted, capdata.permitted & CAP_SYS_RESOURCE,
          capdata.inheritable, capdata.inheritable & CAP_SYS_RESOURCE ) ;

  fd = open( argv[1], O_CREAT|O_RDWR, 0644 ) ;
  printf( "buff=%p, errno=%u\n", buff, errno ) ;

  printf( "fd = %d\n", fd ) ;

  printf( "bytes written = %d, errno=%u\n", write( fd, buff, SIZE  ), errno ) ; 

  printf( "fsync:%d errno=%u\n", fsync( fd ), errno ) ;
  printf( "close:%d errno=%u\n", close( fd ), errno )  ;
}
