Date: Thu, 3 Jan 2008 17:12:21 +0100 (CET) From: Frank Behrens <frank+pr20070103@harz.behrens.de> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/119305: [patch] jexec -n prisonname: selection by jail name Message-ID: <200801031612.m03GCLbd009269@moon.behrens> Resent-Message-ID: <200801031630.m03GU3EO052469@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 119305 >Category: bin >Synopsis: [patch] jexec -n prisonname: selection by jail name >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Thu Jan 03 16:30:02 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Frank Behrens >Release: FreeBSD 7.0-BETA4-200712071613 i386 >Organization: >Environment: >Description: jexec(8) needs the numeric id of jail. This id is not constant and changes on jail restarts. Therefore it is desirable to select a jail by it's name. The attached patch is a sample implementation. >How-To-Repeat: >Fix: --- jexec_prisonbyname.patch begins here --- --- jexec.8.orig 2007-03-16 12:09:03.000000000 +0100 +++ jexec.8 2008-01-03 16:56:53.000000000 +0100 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD: src/usr.sbin/jexec/jexec.8,v 1.4 2006/09/29 17:57:02 ru Exp $ .\" -.Dd April 19, 2006 +.Dd January 3, 2008 .Dt JEXEC 8 .Os .Sh NAME @@ -35,6 +35,10 @@ .Nm .Op Fl u Ar username | Fl U Ar username .Ar jid command ... +.Nm +.Op Fl u Ar username | Fl U Ar username +.Fl n Ar prisonname +.Ar command ... .Sh DESCRIPTION The .Nm @@ -45,6 +49,8 @@ .Pp The following options are available: .Bl -tag -width indent +.It Fl n Ar prisonname +Use jail identified by name. .It Fl u Ar username The user name from host environment as whom the .Ar command --- jexec.c.orig 2007-03-16 12:09:03.000000000 +0100 +++ jexec.c 2008-01-03 16:44:37.000000000 +0100 @@ -28,16 +28,19 @@ #include <sys/param.h> #include <sys/jail.h> +#include <sys/sysctl.h> #include <err.h> #include <errno.h> #include <login_cap.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <pwd.h> #include <unistd.h> static void usage(void); +static int prison_id_byname(const char* prisonname); #define GET_USER_INFO do { \ pwd = getpwnam(username); \ @@ -64,11 +67,15 @@ gid_t groups[NGROUPS]; int ch, ngroups, uflag, Uflag; char *username; + char *prisonname = NULL; ch = uflag = Uflag = 0; username = NULL; - while ((ch = getopt(argc, argv, "u:U:")) != -1) { + while ((ch = getopt(argc, argv, "n:u:U:")) != -1) { switch (ch) { + case 'n': + prisonname = optarg; + break; case 'u': username = optarg; uflag = 1; @@ -83,13 +90,21 @@ } argc -= optind; argv += optind; - if (argc < 2) + if (argc < 1 || (!prisonname && argc < 2)) usage(); if (uflag && Uflag) usage(); if (uflag) GET_USER_INFO; + if (prisonname) { + jid = prison_id_byname(prisonname); + if (jid == -1) + errx(1, "prison name not found: %s", prisonname); + } else { jid = (int)strtol(argv[0], NULL, 10); + argc--; + argv++; + } if (jail_attach(jid) == -1) err(1, "jail_attach(): %d", jid); if (chdir("/") == -1) @@ -106,8 +121,8 @@ err(1, "setusercontext"); login_close(lcap); } - if (execvp(argv[1], argv + 1) == -1) - err(1, "execvp(): %s", argv[1]); + if (execvp(argv[0], argv) == -1) + err(1, "execvp(): %s", argv[0]); exit(0); } @@ -117,6 +132,54 @@ fprintf(stderr, "%s%s\n", "usage: jexec [-u username | -U username]", - " jid command ..."); + " -n pname | jid command ..."); exit(1); } + +/* + * Returns prison id for prison name. + * return -1 if no prison with this name found. + */ +static int +prison_id_byname(const char* prisonname) +{ + struct xprison *sxp, *xp; + size_t i, len; + int id = -1; + + if (sysctlbyname("security.jail.list", NULL, &len, NULL, 0) == -1) + err(1, "sysctlbyname(): security.jail.list"); + + for (i = 0; i < 4; i++) { + if (len <= 0) + exit(0); + sxp = xp = malloc(len); + if (sxp == NULL) + err(1, "malloc()"); + + if (sysctlbyname("security.jail.list", xp, &len, NULL, 0) == -1) { + if (errno == ENOMEM) { + free(sxp); + sxp = NULL; + continue; + } + err(1, "sysctlbyname(): security.jail.list"); + } + break; + } + if (sxp == NULL) + err(1, "sysctlbyname(): security.jail.list"); + if (len < sizeof(*xp) || len % sizeof(*xp) || + xp->pr_version != XPRISON_VERSION) + errx(1, "Kernel and userland out of sync"); + + for (i = 0; i < len / sizeof(*xp); i++) { + if (strcmp(xp->pr_host, prisonname) == 0) { + id = xp->pr_id; + break; + } + xp++; + } + free(sxp); + return id; +} --- jexec_prisonbyname.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801031612.m03GCLbd009269>