[ETHTOOL]: let mortals use ethtool
authorStephen Hemminger <shemminger@osdl.org>
Thu, 28 Sep 2006 22:13:37 +0000 (15:13 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Fri, 29 Sep 2006 01:03:10 +0000 (18:03 -0700)
There is no reason to not allow non-admin users to query network
statistics and settings.

[ Removed PHYS_ID and GREGS based upon feedback from Auke Kok
  and Michael Chan -DaveM]

Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/ethtool.c

index e0ca04f..120786a 100644 (file)
@@ -806,13 +806,6 @@ int dev_ethtool(struct ifreq *ifr)
        int rc;
        unsigned long old_features;
 
        int rc;
        unsigned long old_features;
 
-       /*
-        * XXX: This can be pushed down into the ethtool_* handlers that
-        * need it.  Keep existing behaviour for the moment.
-        */
-       if (!capable(CAP_NET_ADMIN))
-               return -EPERM;
-
        if (!dev || !netif_device_present(dev))
                return -ENODEV;
 
        if (!dev || !netif_device_present(dev))
                return -ENODEV;
 
@@ -822,6 +815,31 @@ int dev_ethtool(struct ifreq *ifr)
        if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
                return -EFAULT;
 
        if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
                return -EFAULT;
 
+       /* Allow some commands to be done by anyone */
+       switch(ethcmd) {
+       case ETHTOOL_GSET:
+       case ETHTOOL_GDRVINFO:
+       case ETHTOOL_GWOL:
+       case ETHTOOL_GMSGLVL:
+       case ETHTOOL_GLINK:
+       case ETHTOOL_GCOALESCE:
+       case ETHTOOL_GRINGPARAM:
+       case ETHTOOL_GPAUSEPARAM:
+       case ETHTOOL_GRXCSUM:
+       case ETHTOOL_GTXCSUM:
+       case ETHTOOL_GSG:
+       case ETHTOOL_GSTRINGS:
+       case ETHTOOL_GSTATS:
+       case ETHTOOL_GTSO:
+       case ETHTOOL_GPERMADDR:
+       case ETHTOOL_GUFO:
+       case ETHTOOL_GGSO:
+               break;
+       default:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+       }
+
        if(dev->ethtool_ops->begin)
                if ((rc = dev->ethtool_ops->begin(dev)) < 0)
                        return rc;
        if(dev->ethtool_ops->begin)
                if ((rc = dev->ethtool_ops->begin(dev)) < 0)
                        return rc;
@@ -947,6 +965,10 @@ int dev_ethtool(struct ifreq *ifr)
        return rc;
 
  ioctl:
        return rc;
 
  ioctl:
+       /* Keep existing behaviour for the moment.       */
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
        if (dev->do_ioctl)
                return dev->do_ioctl(dev, ifr, SIOCETHTOOL);
        return -EOPNOTSUPP;
        if (dev->do_ioctl)
                return dev->do_ioctl(dev, ifr, SIOCETHTOOL);
        return -EOPNOTSUPP;