I just wondered why on a Debian system with sudo installed a default user can execute ls but not ifconfig since the binaries do have the same rights:-rwxr-xr-x 1 root root 114032 Jan 26  2013 /bin/ls-rwxr-xr-x 1 root root 72296 Sep  7  2012 /sbin/ifconfigSo I suppose there must be some kind of database or policy that tells the system who's allowed to execute a command and who is not, but where do I find it? It can't be /etc/sudoers since in that file one only defines who is a root sudoer and who is not just like that:%admin  ALL=(ALL)   ALLjohn ALL=/usr/sbin/useradd, /usr/sbin/userdel, /usr/bin/passwdSo john wouldn't be able to execute /sbin/ifconfig, but how does the system know he's not allowed?
How does sudo decide whether a command is only executable by sudoers with ALL rights?
linux;bash;debian;sudo
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 objectNote: 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 signalsThe 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 EACCESopenat(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 deniedNow, 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:$ ./myprogrammyprogram: Permission deniedNow, 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 EPERMioctl(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);// ...