Date: Mon, 21 Oct 2002 03:27:53 +0400 (MSD)
From: "Aleksandr A. Babaylov" <babolo@aaz.links.ru>
To: FreeBSD-gnats-submit@FreeBSD.org
Subject: bin/44320: jail(1) change for set{uid|gid}
Message-ID: <200210202327.g9KNRr2G088968@aaz.links.ru>
next in thread | raw e-mail | index | archive | help
>Number: 44320
>Category: bin
>Synopsis: jail(1) change for set{uid|gid}
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Sun Oct 20 16:30:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Aleksandr A. Babaylov
>Release: FreeBSD 4.7-PRERELEASE i386
>Organization:
home
>Environment:
System: FreeBSD 4.7-PRERELEASE i386
>Description:
It is impossible to start jailed daemon with
lowered privileges in jail without some tools
in that jail, when daemon has no option to do it itself.
>How-To-Repeat:
try start ports/www/junkbuster in jail without
su(1) or somethig similar in jail with uid www
>Fix:
I know English bad, so my patch to man may need correction
--- usr.sbin/jail/jail.8 21 May 2002 04:42:25 -0000 1.13.2.14
+++ usr.sbin/jail/jail.8 20 Oct 2002 15:44:38 -0000
@@ -41,11 +41,14 @@
.Nd "imprison process and its descendants"
.Sh SYNOPSIS
.Nm
+.Op Fl u Ar user
+.Oo Fl g Ar group Oc ...
.Ar path hostname ip-number command ...
.Sh DESCRIPTION
The
.Nm
command imprisons a process and all future descendants.
+Command executes with user, group and group access list privilegies.
.Pp
Please see the
.Xr jail 2
--- usr.sbin/jail/jail.c 30 Jul 2001 10:19:54 -0000 1.5.2.1
+++ usr.sbin/jail/jail.c 20 Oct 2002 15:50:09 -0000
@@ -5,6 +5,7 @@
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
+ * -g -u by babolo. No beer!!
*
* $FreeBSD: src/usr.sbin/jail/jail.c,v 1.5.2.1 2001/07/30 10:19:54 dd Exp $
*
@@ -12,11 +13,22 @@
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
#include <string.h>
+#include <sys/param.h>
+#include <unistd.h>
#include <err.h>
#include <sys/types.h>
#include <sys/jail.h>
#include <netinet/in.h>
+#include <pwd.h>
+#include <grp.h>
+
+#define J_PATH argv[0]
+#define J_HOSTNAME argv[1]
+#define J_HOSTADDR argv[2]
+#define J_EXEC_N 3
+#define J_EXEC argv[J_EXEC_N]
int
main(int argc, char **argv)
@@ -24,26 +36,72 @@
struct jail j;
int i;
struct in_addr in;
+ uid_t chuser;
+ gid_t gidset[NGROUPS], chgrp, tgrp;
+ int uset = 0, gset = 0, gnumset = 0;
+ char *end;
+ struct passwd *chuserp = NULL;
+ struct group *chgrpp = NULL;
- if (argc < 5)
- errx(1, "Usage: %s path hostname ip-number command ...\n",
+ while ((i = getopt(argc, argv, "g:u:")) != -1) {
+ switch (i) {
+ case 'g':
+ if ((chgrpp = getgrnam(optarg)) == NULL) {
+ /* Try if group is by number, not by name */
+ tgrp = (gid_t)strtol(optarg, &end, 10);
+ if (*end)
+ errx(1, "%s: no such group", optarg);
+ } else {
+ tgrp = chgrpp->gr_gid;
+ }
+ if (gset) {
+ if (gnumset >= NGROUPS)
+ errx(1, "group number > %d", NGROUPS + 1);
+ gidset[gnumset++] = tgrp;
+ } else {
+ chgrp = tgrp;
+ gset = 1;
+ }
+ break;
+ case 'u':
+ if ((chuserp = getpwnam(optarg)) == NULL) {
+ /* Try if user is by number, not by name */
+ chuser = (uid_t)strtol(optarg, &end, 10);
+ if (*end)
+ errx(1, "%s: no such user", optarg);
+ } else {
+ chuser = chuserp->pw_uid;
+ }
+ uset = 1;
+ break;
+ default:
+ errx(1, "unknown option -%c", i);
+ }
+ }
+ argc -= optind;
+ if (argc < 4)
+ errx(1, "Usage: %s [-u user ][-g group ]... path hostname ip-number command ...\n",
argv[0]);
- i = chdir(argv[1]);
- if (i)
- err(1, "chdir %s", argv[1]);
+ argv += optind;
+ if (chdir(J_PATH))
+ err(1, "chdir %s", J_PATH);
memset(&j, 0, sizeof(j));
j.version = 0;
- j.path = argv[1];
- j.hostname = argv[2];
- i = inet_aton(argv[3], &in);
- if (!i)
+ j.path = J_PATH;
+ j.hostname = J_HOSTNAME;
+ if (!inet_aton(J_HOSTADDR, &in))
errx(1, "Couldn't make sense of ip-number\n");
j.ip_number = ntohl(in.s_addr);
- i = jail(&j);
- if (i)
+ if (jail(&j))
err(1, "Imprisonment failed");
- i = execv(argv[4], argv + 4);
- if (i)
- err(1, "execv(%s)", argv[4]);
+ if (gset) {
+ setgid(chgrp);
+ if (setgroups(gnumset, gidset) == -1)
+ err(1, "group access list failed");
+ }
+ if (uset)
+ setuid(chuser);
+ if (execv(J_EXEC, argv + J_EXEC_N))
+ err(1, "execv(%s)", J_EXEC);
exit (0);
}
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200210202327.g9KNRr2G088968>
