changeset 2715:9e9e203a43e5

6469795 ping no longer works in non-global zones for ordinary users
author pwernau
date Tue, 12 Sep 2006 12:02:08 -0700
parents f703af5e06a6
children bb7a9ab4a572
files usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c
diffstat 1 files changed, 19 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c	Tue Sep 12 11:24:26 2006 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c	Tue Sep 12 12:02:08 2006 -0700
@@ -246,16 +246,26 @@
 	char tmp_buf[INET6_ADDRSTRLEN];
 	int c;
 	int i;
+	boolean_t has_sys_net_config;
 
 	progname = argv[0];
 
 	/*
-	 * This program needs the net_icmpaccess privileges.  We'll fail
+	 * This program needs the net_icmpaccess privilege for creating
+	 * raw ICMP sockets.  It needs sys_net_config for using the
+	 * IP_NEXTHOP socket option (IPv4 only).  We'll fail
 	 * on the socket call and report the error there when we have
 	 * insufficient privileges.
+	 *
+	 * Non-global zones don't have the sys_net_config privilege, so
+	 * we need to check for it in our limit set before trying
+	 * to set it.
 	 */
+	has_sys_net_config = priv_ineffect(PRIV_SYS_NET_CONFIG);
+
 	(void) __init_suid_priv(PU_CLEARLIMITSET, PRIV_NET_ICMPACCESS,
-	    PRIV_SYS_NET_CONFIG, (char *)NULL);
+	    has_sys_net_config ? PRIV_SYS_NET_CONFIG : (char *)NULL,
+	    (char *)NULL);
 
 	setbuf(stdout, (char *)0);
 
@@ -1222,8 +1232,13 @@
 		(void) __priv_bracket(PRIV_ON);
 		if (setsockopt(sock, IPPROTO_IP, IP_NEXTHOP,
 		    &nh, sizeof (ipaddr_t)) < 0) {
-			Fprintf(stderr, "%s: setsockopt %s\n",
-			    progname, strerror(errno));
+			if (errno == EPERM)
+				Fprintf(stderr, "%s: Insufficient privilege "
+				    "to specify IPv4 nexthop router.\n",
+				    progname);
+			else
+				Fprintf(stderr, "%s: setsockopt %s\n",
+				    progname, strerror(errno));
 			exit(EXIT_FAILURE);
 		}
 		(void) __priv_bracket(PRIV_OFF);