X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fchcontext.c;h=0e0ae484b119d2035efbb2e4292056376748b763;hb=3d3bef62d063caeb506a404e89fdac929b249591;hp=12e3d9869c6af91a5997b0bc9cb8cda2c7cfa865;hpb=3cdc468e49057bf44e7838e2e20ed97e229851a3;p=util-vserver.git diff --git a/util-vserver/src/chcontext.c b/util-vserver/src/chcontext.c index 12e3d98..0e0ae48 100644 --- a/util-vserver/src/chcontext.c +++ b/util-vserver/src/chcontext.c @@ -28,9 +28,8 @@ #include "util.h" #include "vserver.h" -#include "wrappers.h" -#include "wrappers-vserver.h" #include "internal.h" +#include "lib_internal/jail.h" #include #include @@ -39,6 +38,15 @@ #include #include #include +#include +#include +#include + +#define ENSC_WRAPPERS_PREFIX "chcontext: " +#define ENSC_WRAPPERS_VSERVER 1 +#define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_FCNTL 1 +#include #define CMD_HELP 0x1000 #define CMD_VERSION 0x1001 @@ -59,6 +67,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 }, @@ -85,10 +94,12 @@ static struct Arguments const * global_args = 0; static void showHelp(int fd, char const *cmd, int res) { + VSERVER_DECLARE_CMD(cmd); + 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" @@ -110,12 +121,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" @@ -160,7 +171,7 @@ static void showVersion() { WRITE_MSG(1, - "chcontext " VERSION " -- allocates/enters a security context\n" + "chcontext-compat " VERSION " -- allocates/enters a security context\n" "This program is part of " PACKAGE_STRING "\n\n" "Copyright (C) 2003,2004 Enrico Scholz\n" VERSION_COPYRIGHT_DISCLAIMER); @@ -187,34 +198,22 @@ setCap(char const *str, uint32_t *add_caps, uint32_t *remove_caps) WRITE_MSG(2, "Unknown capability '"); WRITE_STR(2, str); WRITE_MSG(2, "'\n"); - exit(255); + exit(wrapper_exit_code); } } static inline void setFlags(char const *str, uint32_t *flags) { - for (;;) { - char const *ptr = strchr(str, ','); - size_t cnt = ptr ? (size_t)(ptr-str) : strlen(str); - - if (strncmp(str, "lock", cnt)==0) *flags |= S_CTX_INFO_LOCK; - else if (strncmp(str, "sched", cnt)==0) *flags |= S_CTX_INFO_SCHED; - else if (strncmp(str, "nproc", cnt)==0) *flags |= S_CTX_INFO_NPROC; - else if (strncmp(str, "private", cnt)==0) *flags |= S_CTX_INFO_PRIVATE; - else if (strncmp(str, "fakeinit", cnt)==0) *flags |= S_CTX_INFO_INIT; - else if (strncmp(str, "hideinfo", cnt)==0) *flags |= S_CTX_INFO_HIDEINFO; - else if (strncmp(str, "ulimit", cnt)==0) *flags |= S_CTX_INFO_ULIMIT; - else { - WRITE_MSG(2, "Unknown flag '"); - write(2, str, cnt); - WRITE_MSG(2, "'\n"); - exit(255); - } + struct vc_err_listparser err; + + *flags = vc_list2cflag_compat(str, 0, &err); - - if (ptr==0) break; - str = ptr+1; + if (err.ptr!=0) { + WRITE_MSG(2, "Unknown flag '"); + Vwrite(2, err.ptr, err.len); + WRITE_MSG(2, "'\n"); + exit(wrapper_exit_code); } } @@ -223,8 +222,8 @@ setHostname(char const *name) { if (name == NULL) return; - if (vc_set_vhi_name(VC_SAMECTX, vcVHI_NODENAME, name, strlen(name))==-1) { - perror("setHostname()"); + if (sethostname(name, strlen(name))==-1) { + perror("chcontext: sethostname()"); exit(255); } if (!global_args->do_silent) { @@ -239,8 +238,8 @@ setDomainname(char const *name) { if (name == NULL) return; - if (vc_set_vhi_name(VC_SAMECTX, vcVHI_DOMAINNAME, name, strlen(name))==-1) { - perror("setDomainname()"); + if (setdomainname(name, strlen(name))==-1) { + perror("chcontext: setdomainname()"); exit(255); } if (!global_args->do_silent) { @@ -260,59 +259,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"); -} - -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(); + WRITE_MSG(1, "New security context is "); + Vwrite(1, buf, l); + WRITE_MSG(1, "\n"); } -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[]) { @@ -328,11 +280,12 @@ int main (int argc, char *argv[]) }; xid_t newctx; int xflags; - int p[2]; + int p[2][2]; pid_t pid; global_args = &args; - + signal(SIGCHLD, SIG_DFL); + while (1) { int c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0); if (c==-1) break; @@ -349,7 +302,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_insecurebcaps(); break; case CMD_FLAG : setFlags(optarg, &args.flags); @@ -361,7 +314,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; @@ -383,31 +336,33 @@ int main (int argc, char *argv[]) args.domainname = ""; if (args.nbctx == 0) - args.ctxs[args.nbctx++] = VC_RANDCTX; + args.ctxs[args.nbctx++] = VC_DYNAMIC_XID; - xflags = args.flags & 16; + xflags = args.flags & S_CTX_INFO_INIT; + args.flags &= ~S_CTX_INFO_INIT; - newctx = Evc_new_s_context(args.ctxs[0],0,args.flags&~16); - args.remove_caps &= (~args.add_caps); - setHostname(args.hostname); - setDomainname(args.domainname); - - 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); + setDomainname(args.domainname); + if (args.remove_caps!=0 || xflags!=0) Evc_new_s_context (VC_SAMECTX,args.remove_caps,xflags); - tellContext(args.ctxs[0]==VC_RANDCTX ? newctx : args.ctxs[0]); + 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("execvp()"); + PERROR_Q("chcontext: execvp", argv[optind]); exit(255); } - waitOnSync(pid, p); + waitOnSync(pid, p, args.ctxs[0]!=VC_DYNAMIC_XID); return EXIT_SUCCESS; }