X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fchcontext.c;h=4da51d99837f893a9f981525c7fcd40d97171f9a;hb=0e981c77a8a6215525e86fbe432cda11ee3ede40;hp=e6e742516ca7944f9bc9b0fcedcc0e5a6f638adc;hpb=3cf26507111b7886b74cee48c27c15b758e8cfb0;p=util-vserver.git diff --git a/util-vserver/src/chcontext.c b/util-vserver/src/chcontext.c index e6e7425..4da51d9 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 @@ -38,7 +39,10 @@ #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 @@ -63,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 }, @@ -89,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" @@ -114,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" @@ -164,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); @@ -198,14 +205,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_textlist2flag(str, 0, &err_ptr, &err_len); + *flags = vc_list2cflag_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); } @@ -217,7 +223,7 @@ setHostname(char const *name) if (name == NULL) return; if (sethostname(name, strlen(name))==-1) { - perror("sethostname()"); + perror("chcontext: sethostname()"); exit(255); } if (!global_args->do_silent) { @@ -233,7 +239,7 @@ setDomainname(char const *name) if (name == NULL) return; if (setdomainname(name, strlen(name))==-1) { - perror("setdomainname()"); + perror("chcontext: setdomainname()"); exit(255); } if (!global_args->do_silent) { @@ -253,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"); + 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[]) { @@ -321,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; @@ -342,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); @@ -354,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; @@ -376,13 +336,15 @@ 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 & 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); @@ -390,17 +352,17 @@ int main (int argc, char *argv[]) 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; }