Some trivial utilities require special privileges to carry out their intended task. The inherent DAC problem was solved with some dirty tricks such as the special Unix access rights flags that allow users to run an executable with the permissions of the executable's owner or group.
The way it works is that when the program starts it is using the privileges of its owner id to run (such as root), executes the privileged task and then it will usually spawn children with lower privileges and the program continues or will drop the high privileges and continue execution.
One classic example is the ping command found in all operating systems and is available to all users by default. In UNIX/Linux you will notice that it is setuid "god" !!!!
Admins let them root alone
I will present how one can remove the "setuid" bit from ping and still allow an unprivileged mortal user to use this trivial but yet necessary application without disturbing the root object. The RBAC feature of the OpenSolaris/Solaris 10 OS resembles the "sudo" application found on most Unix/Linux like systems. Solaris RBAC provides more fine grained access control.
etz@opensolaris:~$ ls -la /usr/sbin/ping -r-sr-xr-x 1 root bin 55680 2009-05-14 18:52 /usr/sbin/ping etz@opensolaris:~$ /usr/sbin/ping 192.168.2.100 PING esx.etz (192.168.2.100): 56 data bytes 64 bytes from 192.168.2.100: icmp_seq=0 ttl=63 time=6.297 ms
As you can see I am not lying about ping being setuid! First I will remove the special bit from the ping utility.
root@opensolaris:/usr/sbin# chmod u-s /usr/bin/ping etz@opensolaris:~$ ls -la /usr/sbin/ping -r-xr-xr-x 1 root bin 55680 2009-05-14 18:52 /usr/sbin/ping etz@opensolaris:~$ ping 192.168.2.100 ping: socket Permission denied
This will indicate that ping is using some special socket option which requires high privileges. As it turns out ping must send and listen for control packets on a network interface.
In OpenSolaris ping is PA (privilege aware) executable which requires rewriting the application. With the OpenSolaris command "ppriv" we can inspect a running process privilege sets and attributes.
etz@opensolaris:~$ ppriv -v `pgrep ping` 6817: ping -n 192.168.1.100 flags = PRIV_AWARE E: file_link_any,proc_exec,proc_fork,proc_info,proc_session I: file_link_any,proc_exec,proc_fork,proc_info,proc_session P: file_link_any,proc_exec,proc_fork,proc_info,proc_session L: none
A few basic facts for OpenSolaris and RBAC
Privileges: Privileges are rights to do an operation in the kernel. OpenSolaris has defined 70 privileges. The names and their description can be found in "/etc/security/priv_names". Every process has four sets of privileges.
E: effective privileges set
I: inheritable privileges set
P: permitted privileges set
L: limit privileges set
Role: A named set of authorizations or Privileges that can be assumed
So the ping command is implementing a some high privileged operation in the kernel. In order to find out which specific set of rights we are missing we turn on privilege debugging and run the process again.
etz@opensolaris:~$ ppriv -e -D ping -s 192.168.0.1 ping[6873]: missing privilege "net_icmpaccess" (euid = 101, syscall = 230) needed at secpolicy_net_icmpaccess+0x24 ping: socket Permission denied
Ok, so we need the net_icmpaccess privilege to successfully run the ping command. There are several ways to assign a privilege to a user. One is to assign the privilege to the user' shell process.
etz@opensolaris:~$ ppriv -v $$ 6707: -bash flags =E: file_link_any,proc_exec,proc_fork,proc_info,proc_session I: file_link_any,proc_exec,proc_fork,proc_info,proc_session P: file_link_any,proc_exec,proc_fork,proc_info,proc_session
The bash process is missing the net_icmpaccess privilege from its E, I, and P privilege set. To modify the privileges for a running process we use the "ppriv -s" command.
root@opensolaris:~# ppriv -s PEI+net_icmpaccess 6707
This adds the net_icmpaccess privilege to the PEI privilege sets for the shell process of the user (id 6707)
etz@opensolaris:~$ ppriv -v $$ 6707: -bash flags =E: file_link_any,net_icmpaccess,proc_exec,proc_fork,proc_info,proc_session I: file_link_any,net_icmpaccess,proc_exec,proc_fork,proc_info,proc_session P: file_link_any,net_icmpaccess,proc_exec,proc_fork,proc_info,proc_session etz@opensolaris:~$ ping 192.168.2.100 192.168.2.100 is alive
Adding privileges with Roles to users
In order to permanently assign the privilege to the user for controlling ICMP packets we can create a new role. We will create a role named "Network diagnostics" and we will add the "net_icmpaccess" privilege.
root@opensolaris:~# roleadd -m -d /export/home/netdiag netdiag 80 blocks root@opensolaris:~# passwd netdiag New Password: Re-enter new Password: passwd: password successfully changed for netdiag root@opensolaris:~# root@opensolaris:~# grep netdiag /etc/passwd netdiag:x:102:1::/export/home/netdiag:/bin/pfsh
As you can see a new role is a normal UNIX system account with a special shell "/bin/pfsh". Now we need to create a profile which we will then use to assign the new privileges.
root@opensolaris:~# echo "Network Diag:::Profile for network Diagnostics:help=netdiag.htm" >> /etc/security/prof_attr
Add the new privileges to the bash shell and assign a profile name
root@opensolaris:~# echo "Network Diag:solaris:cmd:::/usr/bin/bash:privs=net_icmpaccess" >>/etc/security/exec_attr
Now we must assign the role profile "Network diag" to the role "netdiag" and finally assign the role "netdiag" to the user.
root@opensolaris:~# rolemod -P "Network Diag" netdiag root@opensolaris:~# usermod -R netdiag etz UX: usermod: etz is currently logged in, some changes may not take effect until next login.
Remove the privilege set before from the user and try his new roles.
root@opensolaris:~# ppriv -s PEI-net_icmpaccess 6707
Log in as the normal user etz and test ping functionality.
etz@opensolaris:~$ ping 192.168.2.100 ping: socket Permission denied etz@opensolaris:~$ ppriv -v $$ 6707: -bash flags =E: file_link_any,proc_exec,proc_fork,proc_info,proc_session I: file_link_any,proc_exec,proc_fork,proc_info,proc_session P: file_link_any,proc_exec,proc_fork,proc_info,proc_session etz@opensolaris:~$ roles netdiag etz@opensolaris:~$ su netdiag Password: $ bash etz@opensolaris:~$ ppriv -v $$ 7119: /usr/bin/bash flags = E: file_link_any,net_icmpaccess,proc_exec,proc_fork,proc_info,proc_session I: file_link_any,net_icmpaccess,proc_exec,proc_fork,proc_info,proc_session P: file_link_any,net_icmpaccess,proc_exec,proc_fork,proc_info,proc_session etz@opensolaris:~$ ping 192.168.2.100 192.168.2.100 is alive
Summary
Solaris RBAC is really a very powerful feature which can be used to implement fine grained access control permissions on the underlying system. Solaris comes with a large number of predefined profiles ready to use and a large number of applications are also rewritten to be PA.
