Bug 32680

Summary: [jail] [patch] Allows users to start jail(8) by hostname as well as IP address
Product: Base System Reporter: Evan Sarmiento <evms>
Component: binAssignee: Bjoern A. Zeeb <bz>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 5.0-CURRENT   
Hardware: Any   
OS: Any   

Description Evan Sarmiento 2001-12-10 19:30:01 UTC
When you need to start a jail, you have to specify the IP address
of the jail. This patch allows users to specify the name of the
jail instead of the Ip address if they choose to. For example..

host mrq's ip is 169.69.6.1.

jail /export/mrq mrq 169.69.6.1 /bin/sh /etc/rc
with patch:
jail /export/mrq mrq mrq /bin/sh /etc/rc

Just uses gethostbyname().

Fix: 

#include <err.h>
-#include <stdio.h>
+#include <netdb.h>
 #include <stdlib.h>
-#include <string.h>
 #include <unistd.h>

 int
 main(int argc, char **argv)
 {
+       struct hostent *hp;
        struct jail j;
        int i;
        struct in_addr in;

        if (argc < 5)
-               errx(1, "Usage: %s path hostname ip-number command ...\n",
+               errx(1, "Usage: %s path hostname address command ...\n",
                    argv[0]);
        i = chdir(argv[1]);
        if (i)
@@ -40,14 +40,26 @@
        j.path = argv[1];
        j.hostname = argv[2];
        i = inet_aton(argv[3], &in);
-       if (!i)
-               errx(1, "Couldn't make sense of ip-number\n");
+
+       if (!i) {
+         hp = gethostbyname(argv[3]);
+
+         if (hp == NULL)
+          errx(1, "gethostbyname(%s): %s (and) inet_aton(%s): Could not
+           make sense of ip-number", argv[3], hstrerror(h_errno), argv[3] );
+
+         else if (hp)
+          in = *(struct in_addr *)hp->h_addr;
+
+        }
+
        j.ip_number = ntohl(in.s_addr);
        i = jail(&j);
        if (i)
-               err(1, "Imprisonment failed");
+         err(1, "Imprisonment failed");
        i = execv(argv[4], argv + 4);
        if (i)
-               err(1, "execv(%s)", argv[4]);
+         err(1, "execv(%s)", argv[4]);
+
        exit (0);
 }--jUJNznyzcFzmXXgDGJYYqF1lgOczt7vakOlpAKzdoBI9CJLV
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

--- jail.c.orig Sun Jun 24 16:28:19 2001
+++ jail.c      Mon Dec 10 14:21:19 2001
@@ -17,20 +17,20 @@
 #include <arpa/inet.h>
Comment 1 Will Andrews 2001-12-12 22:27:42 UTC
On Mon, Dec 10, 2001 at 11:27:58AM -0800, Evan Sarmiento wrote:
> --- jail.c.orig Sun Jun 24 16:28:19 2001
> +++ jail.c      Mon Dec 10 14:21:19 2001
[...]
> @@ -40,14 +40,26 @@
[...]
> -       if (!i)
> -               errx(1, "Couldn't make sense of ip-number\n");
> +
> +       if (!i) {
> +         hp = gethostbyname(argv[3]);
> +
> +         if (hp == NULL)
> +          errx(1, "gethostbyname(%s): %s (and) inet_aton(%s): Could not
> +           make sense of ip-number", argv[3], hstrerror(h_errno), argv[3] );
> +
> +         else if (hp)
> +          in = *(struct in_addr *)hp->h_addr;
> +
> +        }
> +

style(9) says:

     Indentation is an 8 character tab.  Second level indents are four spaces.
     If you have to wrap a long statement, put the operator at the end of the
     line.

> -               err(1, "Imprisonment failed");
> +         err(1, "Imprisonment failed");
>         i = execv(argv[4], argv + 4);
>         if (i)
> -               err(1, "execv(%s)", argv[4]);
> +         err(1, "execv(%s)", argv[4]);
> +
>         exit (0);

Whitespace changes.

-- 
wca
Comment 2 Evan Sarmiento 2001-12-13 11:55:44 UTC
Hello,

Attached is the new, stylized (9) jail.c patch:

--- jail.c	Thu Dec 13 06:50:45 2001
+++ jail.new	Thu Dec 13 06:52:24 2001
@@ -17,20 +17,20 @@
 #include <arpa/inet.h>
 
 #include <err.h>
-#include <stdio.h>
+#include <netdb.h>
 #include <stdlib.h>
-#include <string.h>
 #include <unistd.h>
 
 int
 main(int argc, char **argv)
 {
+	struct hostent *hp;
 	struct jail j;
 	int i;
 	struct in_addr in;
 
 	if (argc < 5) 
-		errx(1, "Usage: %s path hostname ip-number command ...\n",
+		errx(1, "Usage: %s path hostname address command ...\n",
 		    argv[0]);
 	i = chdir(argv[1]);
 	if (i)
@@ -40,12 +40,22 @@
 	j.path = argv[1];
 	j.hostname = argv[2];
 	i = inet_aton(argv[3], &in);
-	if (!i)
-		errx(1, "Couldn't make sense of ip-number\n");
+
+	if (i == NULL) {
+	        hp = gethostbyname(argv[3]);
+
+	        if (hp == NULL)
+	            errx(1, "gethostbyname(%s): %s (and) inet_aton(%s): Could not make sense of either IP number or hostname.",
+                         argv[3], hstrerror(h_errno), argv[3] );
+
+	        else if (hp)
+	                in = *(struct in_addr *)hp->h_addr;
+        }
+	
 	j.ip_number = ntohl(in.s_addr);
 	i = jail(&j);
 	if (i)
-		err(1, "Imprisonment failed");
+	        err(1, "Imprisonment failed");
 	i = execv(argv[4], argv + 4);
 	if (i)
 	        err(1, "execv(%s)", argv[4]);
Comment 3 Will Andrews 2001-12-13 12:17:11 UTC
On Thu, Dec 13, 2001 at 06:55:44AM -0500, Evan Sarmiento wrote:
> -		err(1, "Imprisonment failed");
> +	        err(1, "Imprisonment failed");

Whitespace change (1 tab was converted -- leave them alone ;).

-- 
wca
Comment 4 Evan Sarmiento 2001-12-13 18:32:49 UTC
Finally, I fixed it, and it should all be fine now:

--- jail.c	Thu Dec 13 11:24:04 2001
+++ jail.new	Thu Dec 13 11:25:43 2001
@@ -17,20 +17,20 @@
 #include <arpa/inet.h>
 
 #include <err.h>
-#include <stdio.h>
+#include <netdb.h>
 #include <stdlib.h>
-#include <string.h>
 #include <unistd.h>
 
 int
 main(int argc, char **argv)
 {
+	struct hostent *hp;
 	struct jail j;
 	int i;
 	struct in_addr in;
 
 	if (argc < 5) 
-		errx(1, "Usage: %s path hostname ip-number command ...\n",
+		errx(1, "Usage: %s path hostname address command ...\n",
 		    argv[0]);
 	i = chdir(argv[1]);
 	if (i)
@@ -40,8 +40,18 @@
 	j.path = argv[1];
 	j.hostname = argv[2];
 	i = inet_aton(argv[3], &in);
-	if (!i)
-		errx(1, "Couldn't make sense of ip-number\n");
+
+	if (i == NULL) {
+	        hp = gethostbyname(argv[3]);
+
+	        if (hp == NULL)
+	            errx(1, "gethostbyname(%s): %s (and) inet_aton(%s): Could not make sense of either IP number or hostname.",
+                         argv[3], hstrerror(h_errno), argv[3] );
+
+	        else if (hp)
+	                in = *(struct in_addr *)hp->h_addr;
+        }
+	
 	j.ip_number = ntohl(in.s_addr);
 	i = jail(&j);
 	if (i)
Comment 5 Mark Linimon freebsd_committer freebsd_triage 2008-01-25 22:05:28 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-jail

Reassign to appropriate mailing list.
Comment 6 Bjoern A. Zeeb freebsd_committer freebsd_triage 2008-01-25 22:18:06 UTC
Responsible Changed
From-To: freebsd-jail->bz

Take. I have similar functionality for multi-IPv4/v6 jails already in my tree. 

For single-IP jails there is the problem with this patch, if the 
host resolves to multiple IP addresses as the jail might be started on 
a random one.
Comment 7 Bjoern A. Zeeb freebsd_committer freebsd_triage 2008-11-29 16:33:11 UTC
State Changed
From-To: open->patched

The jail update comitted today to HEAD added a -h option 
to the jail(8) command to resolve the given hostname to IPs 
and use those for jails.
Comment 8 Bjoern A. Zeeb freebsd_committer freebsd_triage 2008-11-29 16:41:10 UTC
State Changed
From-To: patched->closed

Submitters mail bounces "User unknown" and if anything 
will be done with this; it'll be MFCed with the entire jail 
work to 7-STABLE.