X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Frpm-fake-resolver.c;h=39438b46cd5e2fabbf1c89ece912fb47913e5615;hb=5b39edfee423f5f3cbe8fa223dcfdc9e8d66e286;hp=7fb15f7c534df11798115ecfbe102c2fb0e28247;hpb=acaa462b7db1ab82b9caff7033f329b68a1dcef9;p=util-vserver.git diff --git a/util-vserver/src/rpm-fake-resolver.c b/util-vserver/src/rpm-fake-resolver.c index 7fb15f7..39438b4 100644 --- a/util-vserver/src/rpm-fake-resolver.c +++ b/util-vserver/src/rpm-fake-resolver.c @@ -16,6 +16,15 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// Protocol: +// 1. startup +// 2. initialize (setuid, ctx-migrate, chroot, ...) +// 3. send "." token to fd 3 +// 4. wait one character on fd 1 +// 5. process this character and consume further characters from fd 1 as far +// as needed +// 6. go to 3) (or exit) + #ifdef HAVE_CONFIG_H # include #endif @@ -23,14 +32,21 @@ #include "internal.h" #include "vserver.h" #include "util.h" -#include "wrappers.h" -#include "wrappers-vserver.h" #include #include #include #include #include +#include +#include + +#define ENSC_WRAPPERS_PREFIX "rpm-fake-resolver: " +#define ENSC_WRAPPERS_VSERVER 1 +#define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_IO 1 +#define ENSC_WRAPPERS_FCNTL 1 +#include #define MAX_RQSIZE 0x1000 @@ -41,8 +57,11 @@ struct ArgInfo { uid_t uid; gid_t gid; bool do_fork; + bool in_ctx; char const * pid_file; char const * chroot; + uint32_t caps; + int flags; }; static struct option const @@ -58,7 +77,7 @@ showHelp(int fd, char const *cmd, int res) WRITE_MSG(fd, "Usage: "); WRITE_STR(fd, cmd); WRITE_MSG(fd, - " [-c ] [-u ] [-g ] [-r ] [-n]\n" + " [-c ] [-u ] [-g ] [-r ] [-s] [-n]\n" "Please report bugs to " PACKAGE_BUGREPORT "\n"); exit(res); } @@ -79,18 +98,21 @@ inline static void parseArgs(struct ArgInfo *args, int argc, char *argv[]) { while (1) { - int c = getopt_long(argc, argv, "c:u:g:r:n", CMDLINE_OPTIONS, 0); + int c = getopt_long(argc, argv, "F:C:c:u:g:r:ns", CMDLINE_OPTIONS, 0); if (c==-1) break; switch (c) { case 'h' : showHelp(1, argv[0], 0); case 'v' : showVersion(); - case 'c' : args->ctx = atoi(optarg); break; - case 'u' : args->uid = atoi(optarg); break; - case 'g' : args->gid = atoi(optarg); break; + case 'c' : args->ctx = atoi(optarg); break; + case 'u' : args->uid = atoi(optarg); break; + case 'g' : args->gid = atoi(optarg); break; + case 'F' : args->flags = atoi(optarg); break; + case 'C' : args->caps = atoi(optarg); break; case 'r' : args->chroot = optarg; break; case 'n' : args->do_fork = false; break; + case 's' : args->in_ctx = true; break; default : WRITE_MSG(2, "Try '"); WRITE_STR(2, argv[0]); @@ -130,15 +152,17 @@ static void do_getpwnam() { uint32_t len; - Eread(0, &len, sizeof len); - if (lenpw_uid); else sendResult(false, -1); } @@ -149,15 +173,17 @@ static void do_getgrnam() { uint32_t len; - Eread(0, &len, sizeof len); - if (lengr_gid); else sendResult(false, -1); } @@ -168,11 +194,13 @@ static void do_closenss() { uint8_t what; - Eread(0, &what, sizeof what); - switch (what) { - case 'p' : endpwent(); break; - case 'g' : endgrent(); break; - default : break; + + if (EreadAll(0, &what, sizeof what)) { + switch (what) { + case 'p' : endpwent(); break; + case 'g' : endgrent(); break; + default : break; + } } } @@ -181,9 +209,8 @@ run() { uint8_t c; - while (true) { - Ewrite(3, ".", 1); - Eread (0, &c, sizeof c); + while (EwriteAll(3, ".", 1), + EreadAll (0, &c, sizeof c)) { switch (c) { case 'P' : do_getpwnam(); break; case 'G' : do_getgrnam(); break; @@ -217,31 +244,63 @@ daemonize(struct ArgInfo const UNUSED * args, int pid_fd) _exit(0); } Eclose(p[1]); - read(p[0], &c, 1); + TEMP_FAILURE_RETRY(read(p[0], &c, 1)); Eclose(p[0]); } +static void +activateContext(xid_t xid, bool in_ctx, + uint32_t xid_caps, int xid_flags) +{ + if (in_ctx) { + struct vc_ctx_flags flags = { + .flagword = 0, + .mask = VC_VXF_STATE_SETUP, + }; + + Evc_set_cflags(xid, &flags); + } + else if (vc_isSupported(vcFEATURE_MIGRATE)) + Evc_ctx_migrate(xid); + else { +#ifdef VC_ENABLE_API_COMPAT + Evc_new_s_context(xid, xid_caps, xid_flags); +#else + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "can not change context: migrate kernel feature missing and 'compat' API disabled\n"); + exit(wrapper_exit_code); +#endif + } +} + int main(int argc, char * argv[]) { struct ArgInfo args = { - .ctx = VC_RANDCTX, + .ctx = VC_DYNAMIC_XID, .uid = 99, .gid = 99, .do_fork = true, .pid_file = 0, - .chroot = 0 + .chroot = 0, + .in_ctx = false, + .flags = S_CTX_INFO_LOCK, }; int pid_fd = -1; +#ifndef __dietlibc__ +# warning *** rpm-fake-resolver is built against glibc; please do not report errors before trying a dietlibc version *** + WRITE_MSG(2, + "*** rpm-fake-resolver was built with glibc; please do ***\n" + "*** not report errors before trying a dietlibc version. ***\n"); +#endif + parseArgs(&args, argc, argv); if (args.pid_file && args.do_fork) - pid_fd = Eopen(args.pid_file, O_CREAT|O_WRONLY, 0644); + pid_fd = EopenD(args.pid_file, O_CREAT|O_WRONLY, 0644); if (args.chroot) Echroot(args.chroot); Echdir("/"); - //Evc_new_s_context(args.ctx, ~(VC_CAP_SETGID|VC_CAP_SETUID), S_CTX_INFO_LOCK); - Evc_new_s_context(args.ctx, 0, S_CTX_INFO_LOCK); + activateContext(args.ctx, args.in_ctx, args.caps, args.flags); Esetgroups(0, &args.gid); Esetgid(args.gid); Esetuid(args.uid);