X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fvserver-info.c;h=d695fee402b477593e10b8a2d0319984fe8f6640;hb=faa778968d1a7dfeaebc9fe4b847e691dc62fd15;hp=b64212d0ee97b563c3fd20abc43526891fde7ccb;hpb=cba7be6122383e419da755909d3f6a612fd41918;p=util-vserver.git diff --git a/util-vserver/src/vserver-info.c b/util-vserver/src/vserver-info.c index b64212d..d695fee 100644 --- a/util-vserver/src/vserver-info.c +++ b/util-vserver/src/vserver-info.c @@ -43,12 +43,16 @@ #define ENSC_WRAPPERS_VSERVER 1 #include +#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, + tgFEATURE, tgCANONIFY, + tgVERIFYCAP, tgXIDTYPE, tgVERIFYPROC, } VserverTag; static struct { @@ -74,6 +78,10 @@ static struct { { "SYSINFO", tgSYSINFO, "gives out information about the systen" }, { "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" }, + { "VERIFYPROC", tgVERIFYPROC, "test if /proc can be read by contexts!=0" }, + { "XIDTYPE", tgXIDTYPE, "returns the type of the given XID" }, }; int wrapper_exit_code = 1; @@ -151,6 +159,61 @@ utsText2Tag(char const *str) } } +static bool +verifyProc() +{ + char const *errptr; + + if (!switchToWatchXid(&errptr)) { + perror(errptr); + return false; + } + + if (access("/proc/uptime", R_OK)==-1) { + if (errno!=ENOENT) + perror("access(\"/proc/uptime\")"); + + return false; + } + + return true; +} + +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) { @@ -168,9 +231,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()"); @@ -257,6 +320,13 @@ getInitPid_emulated(char *buf, xid_t xid) return 0; } +#else // VC_ENABLE_API_COMPAT +static char * +getInitPid_emulated(char UNUSED *buf, xid_t UNUSED xid) +{ + WRITE_MSG(2, "tools were built without compat API, getInitPid() not available\n"); + return 0; +} #endif // VC_ENABLE_API_COMPAT static char * @@ -371,6 +441,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[]) { @@ -380,14 +475,14 @@ testFeature(int argc, char *argv[]) static bool str2bool(char const *str) { - return atoi(str)!=0 || strchr("yYtY", str[0])!=0 || strcasecmp("true", str)==0; + return atoi(str)!=0 || strchr("yYtT", str[0])!=0 || strcasecmp("true", str)==0; } static int execQuery(char const *vserver, VserverTag tag, int argc, char *argv[]) { char const * res = 0; - char buf[sizeof(xid_t)*4 + 1024]; + char buf[sizeof(xid_t)*4 + 1024 + strlen(vserver)]; memset(buf, 0, sizeof buf); switch (tag) { @@ -400,10 +495,23 @@ execQuery(char const *vserver, VserverTag tag, int argc, char *argv[]) res = vc_getVserverAppDir(vserver, vcCFG_AUTO, argc==0 ? "" : argv[0]); break; - case tgRUNNING : - res = (vc_getVserverCtx(vserver, vcCFG_AUTO, false, 0)==VC_NOCTX) ? 0 : "1"; + case tgRUNNING : { + signed long xid; // type is a small hack, but should be ok... + struct vc_vx_info info; + + if (isNumber(vserver, &xid, true) && xid>=0) + res = (vc_get_vx_info(xid, &info)==-1) ? 0 : "1"; + else + res = (vc_getVserverCtx(vserver, vcCFG_AUTO, false, 0)==VC_NOCTX) ? 0 : "1"; + break; + } + case tgCANONIFY : + strcpy(buf, vserver); + if (canonifyVserverName(buf)>0) res = buf; + break; + case tgCONTEXT : res = getContext(buf, vserver, argc==0 || str2bool(argv[0])); break; case tgINITPID_PID : res = getInitPidPid(buf, vserver); break; @@ -412,6 +520,9 @@ 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; + case tgVERIFYPROC : return verifyProc() ? 0 : 1; break; + default : { xid_t xid = *vserver!='\0' ? vc_xidopt2xid(vserver,true,0) : VC_SAMECTX; @@ -420,6 +531,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 }