use $(LIBENSCVECTOR) instead of libensc_vector.a
[util-vserver.git] / util-vserver / src / vserver-info.c
index 0e7f321..3c73d93 100644 (file)
 #define ENSC_WRAPPERS_VSERVER  1
 #include <wrappers.h>
 
+#undef _POSIX_SOURCE
+#include "capability-compat.h"
+
 typedef enum { tgNONE,tgCONTEXT, tgID, tgRUNNING,
               tgVDIR, tgNAME, tgCFGDIR, tgAPPDIR,
               tgAPIVER, tgPXID,
               tgINITPID, tgINITPID_PID,
               tgXID, tgUTS, tgSYSINFO,
               tgFEATURE, tgCANONIFY,
+              tgVERIFYCAP, tgXIDTYPE,
 }      VserverTag;
 
 static struct {
@@ -75,6 +79,8 @@ static struct {
   { "FEATURE",     tgFEATURE,     "returns 0 iff the queried feature is supported" },
   { "PXID",        tgPXID,        "returns the xid of the parent context" },
   { "CANONIFY",    tgCANONIFY,    "canonifies the vserver-name and removes dangerous characters" },
+  { "VERIFYCAP",   tgVERIFYCAP,   "test if the kernel supports linux capabilities" },
+  { "XIDTYPE",     tgXIDTYPE,     "returns the type of the given XID" },
 };
 
 int wrapper_exit_code = 1;
@@ -152,6 +158,41 @@ utsText2Tag(char const *str)
   }
 }
 
+static bool
+verifyCap()
+{
+  struct __user_cap_header_struct header;
+  struct __user_cap_data_struct user;
+  header.version = _LINUX_CAPABILITY_VERSION;
+  header.pid     = 0;
+
+  if (getuid()!=0) {
+    WRITE_MSG(2, "'VERIFYCAP' can be executed as root only\n");
+    return false;
+  }
+
+//  if( prctl( PR_SET_KEEPCAPS, 1,0,0,0 ) < 0 ) {
+//    perror( "prctl:" );
+//    return false;
+//  }
+  
+  if (capget(&header, &user)==-1) {
+    perror("capget()");
+    return false;
+  }
+
+  user.effective   = 0;
+  user.permitted   = 0;
+  user.inheritable = 0;
+
+  if (capset(&header, &user)==-1) {
+    perror("capset()");
+    return false;
+  }
+
+  return chroot("/")==-1;
+}
+
 static char *
 getAPIVer(char *buf)
 {
@@ -169,9 +210,9 @@ getAPIVer(char *buf)
 }
 
 static char *
-getXid(char *buf, char const *vserver)
+getXid(char *buf, char const *pid_str)
 {
-  pid_t                pid = atoi(vserver);
+  pid_t                pid = atoi(pid_str);
   xid_t                xid = vc_get_task_xid(pid);
 
   if (xid==VC_NOCTX) perror("vc_get_task_xid()");
@@ -372,6 +413,31 @@ getContext(char *buf, char const *vserver, bool allow_only_static)
   return buf;
 }
 
+static char const *
+getXIDType(xid_t xid, int argc, char *argv[])
+{
+  char const *         tp;
+  
+  switch (vc_getXIDType(xid)) {
+    case vcTYPE_INVALID                :  tp = "invalid"; break;
+    case vcTYPE_MAIN           :  tp = "main";    break;
+    case vcTYPE_WATCH          :  tp = "watch";   break;
+    case vcTYPE_STATIC         :  tp = "static";  break;
+    case vcTYPE_DYNAMIC                :  tp = "dynamic"; break;
+    default                    :  tp = 0;         break;
+  }
+
+  if (argc==0 || tp==0)
+    return tp;
+
+  while (argc>0) {
+    --argc;
+    if (strcasecmp(argv[argc], tp)==0) return tp;
+  }
+
+  return 0;
+}
+
 static int
 testFeature(int argc, char *argv[])
 {
@@ -418,6 +484,7 @@ execQuery(char const *vserver, VserverTag tag, int argc, char *argv[])
     case tgPXID                :  res = getPXid(buf, vserver);        break;
     case tgSYSINFO     :  return printSysInfo(buf);           break;
     case tgFEATURE     :  return testFeature(argc,argv);      break;
+    case tgVERIFYCAP   :  return verifyCap() ? 0 : 1;         break;
 
 
     default            : {
@@ -427,6 +494,7 @@ execQuery(char const *vserver, VserverTag tag, int argc, char *argv[])
        case tgID       :  res = vc_getVserverByCtx(xid,0,0);  break;
        case tgINITPID  :  res = getInitPid(buf, xid);         break;
        case tgUTS      :  res = getUTS(buf, xid, argc, argv); break;
+       case tgXIDTYPE  :  res = getXIDType(xid, argc, argv);  break;
     
        default         :  assert(false); abort();  // TODO
       }