Index: configure.ac
===================================================================
RCS file: /arthur/cvsd/configure.ac,v
retrieving revision 1.69
diff -u -r1.69 configure.ac
--- configure.ac	17 Apr 2004 10:10:25 -0000	1.69
+++ configure.ac	17 Jun 2004 17:56:57 -0000
@@ -101,6 +101,7 @@
 AC_CHECK_HEADERS(fcntl.h)
 AC_CHECK_HEADERS(stdarg.h)
 AC_CHECK_HEADERS(stdio.h)
+AC_CHECK_HEADERS(sys/capability.h)
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -162,6 +163,9 @@
   AC_LIBOBJ(getinfos)
   AC_CHECK_FUNCS(getservbyname getservbyport gethostbyaddr htons hstrerror)
 fi
+
+# check for libcap
+AC_SEARCH_LIBS(cap_init,cap)
 
 # Check for debugging options
 AC_ARG_ENABLE(debug,
Index: cfg.c
===================================================================
RCS file: /arthur/cvsd/cfg.c,v
retrieving revision 1.2
diff -u -r1.2 cfg.c
--- cfg.c	10 Aug 2003 20:40:30 -0000	1.2
+++ cfg.c	17 Jun 2004 17:56:57 -0000
@@ -60,6 +60,9 @@
   cfg->gid        = NOGID;
   cfg->nice       = 0;
   cfg->umask      = 0027;
+#ifdef HAVE_SYS_CAPABILITY_H
+  cfg->capabilities = NULL;
+#endif
   cfg->addresses  = NULL;
   cfg->maxconnections = 0;
   cfg->cvscmd     = NULL; /* default is set according to configured rootjail */
Index: cfg.h
===================================================================
RCS file: /arthur/cvsd/cfg.h,v
retrieving revision 1.1
diff -u -r1.1 cfg.h
--- cfg.h	3 Aug 2003 15:33:16 -0000	1.1
+++ cfg.h	17 Jun 2004 17:56:57 -0000
@@ -88,6 +88,11 @@
   
   /* TODO: limits (are currently stored in structures in reslimit.c)*/
 
+#ifdef HAVE_SYS_CAPABILITY_H
+  /* the capabilities for cvs */
+  char *capabilities;
+#endif
+
   /* the addresses/ports that should be listened on */
   struct cvsd_addrs *addresses;
  
Index: cfgfile.c
===================================================================
RCS file: /arthur/cvsd/cfgfile.c,v
retrieving revision 1.16
diff -u -r1.16 cfgfile.c
--- cfgfile.c	10 Aug 2003 20:40:30 -0000	1.16
+++ cfgfile.c	17 Jun 2004 17:56:58 -0000
@@ -437,6 +437,25 @@
       exit(1);
 #endif /* not HAVE_SETRLIMIT */
     }
+    else if (strcmp(opts[0],"Capabilities")==0)
+    {
+#ifdef HAVE_SYS_CAPABILITY_H
+      if (nopts!=2)
+      {
+        log_log(LOG_ERR,"%s:%d: Capabilities: wrong number of arguments",filename,lnr);
+        exit(1);
+      }
+      /* save value */
+      if (cfg->capabilities!=NULL)
+      {
+        log_log(LOG_ERR,"%s:%d: Capabilities: can only be specified once",filename,lnr);
+      }
+      else
+      {
+        cfg->capabilities=xstrdup(opts[1]);
+      }
+#endif /* not HAVE_SYS_CAPABILITY_H */
+    }
     else if (strcmp(opts[0],"Umask")==0)
     {
       if (nopts!=2)
Index: cvsd.c
===================================================================
RCS file: /arthur/cvsd/cvsd.c,v
retrieving revision 1.101
diff -u -r1.101 cvsd.c
--- cvsd.c	14 Feb 2004 12:49:42 -0000	1.101
+++ cvsd.c	17 Jun 2004 17:56:58 -0000
@@ -75,6 +75,10 @@
 #ifdef HAVE_GRP_H
 #include <grp.h>
 #endif /* HAVE_GRP_H */
+#ifdef HAVE_SYS_CAPABILITY_H
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#endif /* HAVE_SYS_CAPABILITY_H */
 
 #include "xmalloc.h"
 #ifdef HAVE_SETRLIMIT
@@ -663,6 +667,9 @@
   char *cvs_cmdline=NULL;
   struct cvsd_addrs *tmp,*nxt;
   struct cvsd_cfg *cfg;
+#ifdef HAVE_SYS_CAPABILITY_H
+  cap_t capabilities;
+#endif
 
   /* save program name */
   program_name=argv[0];
@@ -816,6 +823,26 @@
     }
     log_log(LOG_DEBUG,"debug: setuid(%d) done",cfg->uid);
   }
+
+#ifdef HAVE_SYS_CAPABILITY_H
+  /* do the capability stuff */
+  if (cfg->capabilities!=NULL)
+  {
+    capabilities = cap_from_text(cfg->capabilities);
+    if (capabilities==NULL)
+    {
+      log_log(LOG_ERR,"cannot cap_from_text(%s): %s",cfg->capabilities,strerror(errno));
+      exit(1);
+    }
+    prctl(PR_SET_KEEPCAPS,1);
+    if (cap_set_proc(capabilities)!=0)
+    {
+      log_log(LOG_ERR,"cannot cap_set_proc(%s): %s",cfg->capabilities,strerror(errno));
+      exit(1);
+    }
+    cap_free(capabilities);
+  }
+#endif
 
   /* build cvs command line */
   j=strlen(cfg->cvscmd)+1;
