sudo
has nothing to do with this little difference, the restriction is far closer to the kernel. You see, even though everyone has the right to execute the /sbin/ifconfig
program, it does not mean that this program will have sufficient permissions to do its job with normal user privileges.
Basically, with the UNIX permissions set, you have the right to create a process which executable code is /sbin/ifconfig
's. And actually, no matter how ls
and ifconfig
behave afterwards, their processes are indeed spawned. However, ifconfig
will exit prematurely because the privileges its given through the user executing it are not sufficient. Quoting Frank Thomas' comment:
[it cannot] grab the network card object
Note: it might actually be possible for you to run ifconfig --help
without privileges. Since this operation does not require using the network card, it won't fail nor require root privileges.
Now, if you want to know more specifically what operation has been denied to ifconfig
with low privileges, you might want to give strace
a try. Here's an example with ls
.
strace - trace system calls and signals
The error code for permission denied is 13 (EACCES
). By using strace
I can find out which system calls triggered EACCES
:
$ strace ls ~ 2>&1 | grep EACCES
# No output, I can read my home directory just fine.
$ strace ls /root 2>&1 | grep EACCES
openat(AT_FDCWD, "/root", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 EACCES (Permission denied)
There, you can see that the openat
system call failed. Indeed, as my current user, I have no right to read the /root
directory, therefore the kernel yells at ls
when it tries to get information about /root
. When ls
realises that openat
failed and returned EACCES
, it just tells me about it:
ls: cannot open directory /root: Permission denied
Now, it's up to the program to tell the user when a system call fails. For instance, in C:
if((rootdir = opendir("/root")) == NULL){
perror("myprogram");
exit(1);
}
With low privileges, this will result it:
$ ./myprogram
myprogram: Permission denied
Now, if you run strace /sbin/ifconfig
, you'll be able to find out which system call was denied to ifconfig
when run as your user. Here is an example of me trying to bring the wireless interface down:
$ strace ifconfig wlan0 down 2>&1 | grep EPERM
ioctl(4, SIOCSIFFLAGS, {ifr_name="wlan0", ???}) = -1 EPERM (Operation not permitted)
As you can see, the ioctl
system call failed. In this case, the error call is EPERM
(1: Operation not permitted). The ifconfig
programs warns you about it in its setifflags
function:
// ...
if (ioctl(s, SIOCSIFFLAGS, &ifreq) == -1)
err(EXIT_FAILURE, "SIOCSIFFLAGS");
// ...
/sbin/
is not in the normal user's$PATH
. At least on my Debian system, every user can call/sbin/ifconfig
if they want, just notifconfig
.