X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fchcontext.c;h=6102aa64cc07168f2c54d99293294452ff80a275;hb=a917f24ef7b003dcef54a3db2644cf9cb4bc2db2;hp=c4a36e9434bac789c320f1c1496321152c4e9e62;hpb=60b79214fde270652df01511999580f1d14688cd;p=util-vserver.git diff --git a/util-vserver/src/chcontext.c b/util-vserver/src/chcontext.c index c4a36e9..6102aa6 100644 --- a/util-vserver/src/chcontext.c +++ b/util-vserver/src/chcontext.c @@ -29,6 +29,7 @@ #include "util.h" #include "vserver.h" #include "internal.h" +#include "lib_internal/jail.h" #include #include @@ -65,6 +66,7 @@ CMDLINE_OPTIONS[] = { { "version", no_argument, 0, CMD_VERSION }, { "cap", required_argument, 0, CMD_CAP }, { "ctx", required_argument, 0, CMD_CTX }, + { "xid", required_argument, 0, CMD_CTX }, { "disconnect", no_argument, 0, CMD_DISCONNECT }, { "domainname", required_argument, 0, CMD_DOMAINNAME }, { "flag", required_argument, 0, CMD_FLAG }, @@ -96,7 +98,7 @@ showHelp(int fd, char const *cmd, int res) WRITE_MSG(fd, "Usage: "); WRITE_STR(fd, cmd); WRITE_MSG(fd, - " [--cap [!]] [--secure] [--ctx ] [--disconnect]\n" + " [--cap [!]] [--secure] [--xid ] [--disconnect]\n" " [--domainname ] [--hostname ] [--flag +]\n" " [--silent] [--] command arguments ...\n" "\n" @@ -118,12 +120,12 @@ showHelp(int fd, char const *cmd, int res) " repeated several time.\n" " See /usr/include/linux/capability.h\n" "\n" - "--ctx num\n" + "--xid num\n" " Select the context. On root in context 0 is allowed to\n" " select a specific context.\n" " Context number 1 is special. It can see all processes\n" " in any contexts, but can't kill them though.\n" - " Option --ctx may be repeated several times to specify up to 16 contexts.\n" + " Option --xid may be repeated several times to specify up to 16 contexts.\n" "--disconnect\n" " Start the command in background and make the process\n" @@ -202,14 +204,13 @@ setCap(char const *str, uint32_t *add_caps, uint32_t *remove_caps) static inline void setFlags(char const *str, uint32_t *flags) { - char const *err_ptr; - size_t err_len; + struct vc_err_listparser err; - *flags = vc_list2flag_compat(str, 0, &err_ptr, &err_len); + *flags = vc_list2flag_compat(str, 0, &err); - if (err_ptr!=0) { + if (err.ptr!=0) { WRITE_MSG(2, "Unknown flag '"); - write(2, err_ptr, err_len); + write(2, err.ptr, err.len); WRITE_MSG(2, "'\n"); exit(wrapper_exit_code); } @@ -257,59 +258,12 @@ tellContext(xid_t ctx) l = utilvserver_fmt_long(buf,ctx); - WRITE_MSG(2, "New security context is "); - write(2, buf, l); - WRITE_MSG(2, "\n"); + WRITE_MSG(1, "New security context is "); + write(1, buf, l); + WRITE_MSG(1, "\n"); } -static inline ALWAYSINLINE int -initSync(int p[2]) -{ - if (!global_args->do_disconnect) return 0; - - Epipe(p); - fcntl(p[1], F_SETFD, FD_CLOEXEC); - return Efork(); -} - -static inline ALWAYSINLINE void -doSyncStage1(int p[2]) -{ - int fd; - - if (!global_args->do_disconnect) return; - - fd = Eopen("/dev/null", O_RDONLY, 0); - Esetsid(); - Edup2(fd, 0); - Eclose(p[0]); - if (fd!=0) Eclose(fd); - Ewrite(p[1], ".", 1); -} - -static inline ALWAYSINLINE void -doSyncStage2(int p[2]) -{ - if (!global_args->do_disconnect) return; - - Ewrite(p[1], "X", 1); -} - -static void -waitOnSync(pid_t pid, int p[2]) -{ - int c; - size_t l; - - assert(global_args->do_disconnect); - assert(pid!=0); - - Eclose(p[1]); - l = Eread(p[0], &c, 1); - if (l!=1) exitLikeProcess(pid); - l = Eread(p[0], &c, 1); - if (l!=0) exitLikeProcess(pid); -} +#include "context-sync.hc" int main (int argc, char *argv[]) { @@ -325,7 +279,7 @@ int main (int argc, char *argv[]) }; xid_t newctx; int xflags; - int p[2]; + int p[2][2]; pid_t pid; global_args = &args; @@ -346,7 +300,7 @@ int main (int argc, char *argv[]) setCap(optarg, &args.add_caps, &args.remove_caps); break; case CMD_SECURE : - args.remove_caps |= vc_get_securecaps(); + args.remove_caps |= vc_get_insecurecaps(); break; case CMD_FLAG : setFlags(optarg, &args.flags); @@ -358,7 +312,7 @@ int main (int argc, char *argv[]) WRITE_MSG(2, "Too many contexts given\n"); exit(255); } - args.ctxs[args.nbctx++] = atoi(optarg); + args.ctxs[args.nbctx++] = Evc_xidopt2xid(optarg, true); break; @@ -385,8 +339,10 @@ int main (int argc, char *argv[]) xflags = args.flags & S_CTX_INFO_INIT; args.flags &= ~S_CTX_INFO_INIT; - pid = initSync(p); + pid = initSync(p, args.do_disconnect); if (pid==0) { + doSyncStage0(p, args.do_disconnect); + newctx = Evc_new_s_context(args.ctxs[0],0,args.flags); args.remove_caps &= (~args.add_caps); setHostname(args.hostname); @@ -396,15 +352,15 @@ int main (int argc, char *argv[]) Evc_new_s_context (VC_SAMECTX,args.remove_caps,xflags); tellContext(args.ctxs[0]==VC_DYNAMIC_XID ? newctx : args.ctxs[0]); - doSyncStage1(p); + doSyncStage1(p, args.do_disconnect); execvp (argv[optind],argv+optind); - doSyncStage2(p); + doSyncStage2(p, args.do_disconnect); PERROR_Q("chcontext: execvp", argv[optind]); exit(255); } - waitOnSync(pid, p); + waitOnSync(pid, p, args.ctxs[0]!=VC_DYNAMIC_XID); return EXIT_SUCCESS; }