Hello,

Here is a patch which gives to jail(8) an ability to specify a user
context before execv(3).  Comments/suggestions?

P.S. I am aware of bin/44320.

Index: Makefile
===================================================================
RCS file: /home/ncvs/src/usr.sbin/jail/Makefile,v
retrieving revision 1.8
diff -u -r1.8 Makefile
--- Makefile    20 Jul 2001 06:19:52 -0000      1.8
+++ Makefile    21 Mar 2003 14:16:25 -0000
@@ -2,6 +2,7 @@

 PROG=  jail
 MAN=   jail.8
+LDADD= -lutil

 WARNS?=        2

Index: jail.8
===================================================================
RCS file: /home/ncvs/src/usr.sbin/jail/jail.8,v
retrieving revision 1.41
diff -u -r1.41 jail.8
--- jail.8      18 Mar 2003 14:01:02 -0000      1.41
+++ jail.8      24 Mar 2003 15:06:08 -0000
@@ -41,11 +41,28 @@
 .Nd "imprison process and its descendants"
 .Sh SYNOPSIS
 .Nm
+.Op Fl u Ar username
 .Ar path hostname ip-number command ...
 .Sh DESCRIPTION
 The
 .Nm
 utility imprisons a process and all future descendants.
+.Pp
+The options are as follows:
+.Bl -tag -width ".Fl u Ar username"
+.It Fl u Ar username
+The user name as whom the
+.Ar command
+should run.
+.It Ar path
+Directory which is to be the root of the prison.
+.It Ar hostname
+Hostname of the prison.
+.It Ar ip-number
+IP number assigned to the prison.
+.It Ar command
+Pathname of the program which is to be executed.
+.El
 .Pp
 Please see the
 .Xr jail 2
Index: jail.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/jail/jail.c,v
retrieving revision 1.8
diff -u -r1.8 jail.c
--- jail.c      22 Apr 2002 13:44:43 -0000      1.8
+++ jail.c      21 Mar 2003 16:15:15 -0000
@@ -10,44 +10,97 @@
  *
  */

-#include <sys/types.h>
+#include <sys/param.h>
 #include <sys/jail.h>

 #include <netinet/in.h>
 #include <arpa/inet.h>

 #include <err.h>
+#include <grp.h>
+#include <login_cap.h>
+#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>

+static void    usage(void);
+
 int
 main(int argc, char **argv)
 {
+       login_cap_t *lcap;
        struct jail j;
-       int i;
+       struct passwd *pwd;
        struct in_addr in;
+       int ch, groups[NGROUPS], i, ngroups;
+       char *username;
+
+       username = NULL;
+
+       while ((ch = getopt(argc, argv, "u:")) != -1)
+               switch (ch) {
+               case 'u':
+                       username = optarg;
+                       break;
+               default:
+                       usage();
+                       break;
+               }
+       argc -= optind;
+       argv += optind;
+       if (argc < 4)
+               usage();

-       if (argc < 5)
-               errx(1, "usage: %s path hostname ip-number command ...\n",
-                   argv[0]);
-       i = chdir(argv[1]);
+       if (username != NULL) {
+               pwd = getpwnam(username);
+               if (pwd == NULL)
+                       err(1, "getpwnam %s", username);
+               lcap = login_getpwclass(pwd);
+               if (lcap == NULL)
+                       err(1, "getpwclass failed", username);
+               ngroups = NGROUPS;
+               i = getgrouplist(username, pwd->pw_gid, groups, &ngroups);
+               if (i)
+                       err(1, "getgrouplist %s", username);
+       }
+       i = chdir(argv[0]);
        if (i)
-               err(1, "chdir %s", argv[1]);
+               err(1, "chdir %s", argv[0]);
        memset(&j, 0, sizeof(j));
        j.version = 0;
-       j.path = argv[1];
-       j.hostname = argv[2];
-       i = inet_aton(argv[3], &in);
+       j.path = argv[0];
+       j.hostname = argv[1];
+       i = inet_aton(argv[2], &in);
        if (!i)
                errx(1, "Couldn't make sense of ip-number\n");
        j.ip_number = ntohl(in.s_addr);
        i = jail(&j);
        if (i)
                err(1, "Imprisonment failed");
-       i = execv(argv[4], argv + 4);
+       if (username != NULL) {
+               i = setgroups(ngroups, groups);
+               if (i)
+                       err(1, "setgroups failed");
+               i = setgid(pwd->pw_gid);
+               if (i)
+                       err(1, "setgid failed");
+               i = setusercontext(lcap, pwd, pwd->pw_uid,
+                   LOGIN_SETALL & ~LOGIN_SETGROUP);
+               if (i)
+                       err(1, "setusercontext failed");
+       }
+       i = execv(argv[3], argv + 3);
        if (i)
-               err(1, "execv(%s)", argv[4]);
+               err(1, "execv(%s)", argv[3]);
        exit (0);
+}
+
+static void
+usage(void)
+{
+
+       errx(1,
+           "Usage: jail [-u username] path hostname ip-number command ...");
 }

%%%

-- 
Maxim Konovalov, [EMAIL PROTECTED], [EMAIL PROTECTED]

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to