Root, root, root, everybody always wants root. Developers, application administrators, users, they all seem to find a reason to "need" root access. Since normally these needs are for access to particular files or to perform very specific tasks, only a subset of root's access is actually needed. File access should be trivial enough, just configure the appropriate permissions or FACLs. For executable processes, traditionally 'sudo' or 'op' would come to mind. In Solaris, however, we could instead use RBAC and privileges, which are natively available.
Our host details for this are:
HOST: snorkle
PROMPT: user@snorkle [0]
OS: Solaris 10 10/09
USER: johnc
ROLE: netrole
For a sample setup, we have user 'johnc' from group 'neteng' who is tasked
with managing the network interfaces and routes on a system. He will need
access to 'ifconfig', 'route', 'dladm', 'snoop', and 'tcpdump'. Since we
won't give him root access, let's see how he fares with each command
and what we can do to help. Starting simple, 'johnc' uses 'ifconfig'
to check the available interfaces and attempt to bring "e1000g0" online:
johnc@snorkle [0] /usr/sbin/ifconfig -a
lo0: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
e1000g1: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
inet 192.168.56.15 netmask ffffff00 broadcast 192.168.56.255
johnc@snorkle [0] /usr/sbin/ifconfig e1000g0 plumb
ifconfig: cannot open link "e1000g0": Permission denied
johnc@snorkle [1]
As expected, he can review what's already configured but gets "Permission
denied" for trying to online "e1000g0". Being the diligent user he is,
'johnc' tries to online "e1000g0" again, but this time he uses 'ppriv'
(see note 1) to determine what's preventing him:
johnc@snorkle [1] /bin/ppriv -eD /usr/sbin/ifconfig e1000g0 plumb
ifconfig[514]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
ifconfig[514]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
ifconfig[514]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
ifconfig: cannot open link "e1000g0": Permission denied
Alright, 'johnc' needs the "net_rawaccess" privilege to actually manage
interfaces. So that he doesn't have to keep running back to us, 'johnc'
tries the rest of the commands:
johnc@snorkle [1] /bin/ppriv -eD /usr/sbin/snoop -d e1000g1
snoop[516]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
snoop[516]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
snoop[516]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
snoop: cannot open "e1000g1": Permission denied
johnc@snorkle [1] /bin/ppriv -eD /usr/local/sbin/tcpdump -i e1000g1
tcpdump[874]: missing privilege "net_rawaccess" (euid = 1002, syscall = 225) for \
"devpolicy" needed at spec_open+0xbf
tcpdump: e1000g1: You don't have permission to capture on that device
(/dev/e1000g: Permission denied)
johnc@snorkle [0] /usr/sbin/dladm show-dev -p
/usr/sbin/dladm: insufficient privileges
johnc@snorkle [1] /bin/ppriv -eDv /usr/sbin/dladm show-dev -p
/usr/sbin/dladm: insufficient privileges
johnc@snorkle [1] /usr/sbin/route add -net 192.168.75.0/24 192.168.56.2
add net 192.168.75.0/24: gateway 192.168.56.2: insufficient privileges
johnc@snorkle [1] /bin/ppriv -eDv /usr/sbin/route add -net 192.168.75.0/24 192.168.56.2
route[688]: missing privilege "sys_ip_config" (euid = 1002, syscall = 4) needed \
at ip_rts_request+0x164
add net 192.168.75.0/24: gateway 192.168.56.2: insufficient privileges
All of the above commands have failed due to missing privileges.
Aside from 'dladm', each command executed through 'ppriv' returned the
missing privileges. As a final check, 'johnc' runs 'ppriv' against
his current terminal process to see what privileges he currently has
(see note 2):
johnc@snorkle [0] /bin/ppriv $$
501: -ksh
flags = <none>
E: basic
I: basic
P: basic
L: all
johnc@snorkle [0]
Having returned to us with the above information, let's see what other
details we can dig up to help 'johnc'. Since RBAC and privileges
are closely related, we can check for the commands 'johnc' needs in
RBAC's execution database 'exec_attr':
root@snorkle [0] /bin/egrep 'ifconfig|snoop|tcpdump|dladm|route' /etc/security/exec_attr
Network Management:solaris:cmd:::/sbin/dladm:privs=sys_net_config
Network Management:solaris:cmd:::/sbin/ifconfig:uid=0
Network Management:solaris:cmd:::/sbin/route:privs=sys_ip_config
Network Management:solaris:cmd:::/sbin/routeadm:euid=0; privs=proc_chroot,\
proc_owner,sys_ip_config
Network Management:suser:cmd:::/usr/sbin/ifconfig:uid=0
Network Management:suser:cmd:::/usr/sbin/route:uid=0
Network Management:suser:cmd:::/usr/sbin/snoop:uid=0
Based on the format for 'exec_attr', all but 'tcpdump' are part of
the preconfigured "Network Management" RBAC profile. We also see the
"sys_net_config" privilege for 'dladm' which we didn't previously know.
Reviewing 'exec_attr' for the "Network Management" profile, we see it
has 18 commands associated with it:
root@snorkle [0] grep "Network Management:" /etc/security/exec_attr | grep ":cmd:"
Network Management:solaris:cmd:::/sbin/dladm:privs=sys_net_config
Network Management:solaris:cmd:::/sbin/ifconfig:uid=0
Network Management:solaris:cmd:::/sbin/route:privs=sys_ip_config
Network Management:solaris:cmd:::/sbin/routeadm:euid=0; privs=proc_chroot,proc_owner,\
sys_ip_config
Network Management:solaris:cmd:::/usr/sbin/quaggaadm:privs=basic
Network Management:solaris:cmd:::/usr/sbin/zebraadm:privs=basic
Network Management:suser:cmd:::/usr/bin/netstat:uid=0
Network Management:suser:cmd:::/usr/bin/rup:euid=0
Network Management:suser:cmd:::/usr/bin/ruptime:euid=0
Network Management:suser:cmd:::/usr/bin/setuname:euid=0
Network Management:suser:cmd:::/usr/sbin/asppp2pppd:euid=0
Network Management:suser:cmd:::/usr/sbin/ifconfig:uid=0
Network Management:suser:cmd:::/usr/sbin/ipaddrsel:euid=0
Network Management:suser:cmd:::/usr/sbin/ipqosconf:euid=0
Network Management:suser:cmd:::/usr/sbin/rndc:privs=file_dac_read
Network Management:suser:cmd:::/usr/sbin/route:uid=0
Network Management:suser:cmd:::/usr/sbin/snoop:uid=0
Network Management:suser:cmd:::/usr/sbin/spray:euid=0
Since 'johnc' currently only needs access to 5 commands, we can create
a role for him and group 'neteng' to use. The following creates a new
role, netrole, and sets a password to it (see note 3):
root@snorkle [0] /usr/sbin/groupadd -g 10300 netrole
root@snorkle [0] /usr/sbin/roleadd -u 10300 -g 10300 -c "Minimal Network Role" \
-d /export/roles/netrole -m -s /bin/pfksh netrole
64 blocks
root@snorkle [0] /bin/passwd netrole
New Password:
Re-enter new Password:
passwd: password successfully changed for netrole
root@snorkle [0]
Of note, in Solaris 11 (Express) a role can be configured to allow
a user to use their own login password to access the role:
root@snorkle [0] /usr/sbin/rolemod -K roleauth=user netrole
Since we don't want this role associated with the default profile
(ALL), we add profile "NetRole" to 'prof_attr' and set 'netrole' with
the profile. We also set the default privileges to be those identified
above (see note 4):
root@snorkle [0] echo "NetRole:::profile managing NICs and routes:">> /etc/security/prof_attr
root@snorkle [0] /usr/sbin/rolemod -P NetRole -K defaultpriv=basic,net_rawaccess,\
sys_ip_config,sys_net_config netrole
After associating 'johnc' with role 'netrole' below via 'usermod', we
can see that our user's account hasn't been modified with a check of
'id' and review of '/etc/passwd':
root@snorkle [0] /usr/sbin/usermod -R netrole johnc
root@snorkle [0] /bin/id -a johnc
uid=1002(johnc) gid=1002(neteng) groups=1002(neteng)
root@snorkle [0] /bin/id -a netrole
uid=10300(netrole) gid=10300(netrole) groups=10300(netrole)
root@snorkle [0] /bin/egrep 'johnc|netrole' /etc/passwd
johnc:x:1002:1002:John Chambers:/export/home/johnc:/bin/ksh
netrole:x:10300:10300:Minimal Network Role:/export/roles/netrole:/bin/pfksh
root@snorkle [0] /bin/egrep 'johnc|netrole' /etc/user_attr
netrole::::type=role;profiles=NetRole;defaultpriv=basic,net_rawaccess,sys_ip_config,\
sys_net_config
johnc::::type=normal;roles=netrole
root@snorkle [0] /bin/roles johnc
netrole
The association of 'johnc' to role 'netrole' is contained within
'/etc/user_attr' and verified with 'roles' above. At this point, we've
given 'johnc' a subset of root's privileges allowing him to accomplish
only what he needs:
johnc@snorkle [0] /usr/sbin/ifconfig e1000g0 plumb
ifconfig: cannot open link "e1000g0": Permission denied
johnc@snorkle [1] /sbin/su - netrole
Password:
netrole@snorkle [0] /bin/ppriv $$
945: -pfksh
flags = <none>
E: basic,net_rawaccess,sys_ip_config,sys_net_config
I: basic,net_rawaccess,sys_ip_config,sys_net_config
P: basic,net_rawaccess,sys_ip_config,sys_net_config
L: all
To illustrate how 'johnc' can use the new 'netrole', we have 'johnc'
try to online "e1000g0" again, only to fail. We didn't give any extra
privileges to 'johnc', we gave them to 'netrole' which we can see above
after the 'su'. In the following, we see that by using role 'netrole',
'johnc' now has the access and privileges he needs:
netrole@snorkle [0] /usr/sbin/ifconfig e1000g0 plumb
netrole@snorkle [0] /bin/grep snorkle /etc/hosts
192.168.56.15 snorkle loghost
10.0.23.191 snorkle-priv
netrole@snorkle [0] /usr/sbin/ifconfig e1000g0 10.0.23.191 netmask 255.255.254.0 \
broadcast + up
netrole@snorkle [0] /usr/sbin/ifconfig -a
lo0: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
e1000g0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 3
inet 10.0.23.191 netmask fffffe00 broadcast 10.0.23.255
ether 8:0:27:56:c2:d
e1000g1: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
inet 192.168.56.15 netmask ffffff00 broadcast 192.168.56.255
ether 8:0:27:cb:f8:20
netrole@snorkle [0] /usr/sbin/snoop -d e1000g0
Using device e1000g1 (promiscuous mode)
10.0.23.181 -> snorkle-priv ICMP Echo request (ID: 63848 Sequence number: 1)
snorkle-priv -> 10.0.23.181 ICMP Echo reply (ID: 63848 Sequence number: 1)
10.0.23.181 -> snorkle-priv ICMP Echo request (ID: 63848 Sequence number: 2)
snorkle-priv -> 10.0.23.181 ICMP Echo reply (ID: 63848 Sequence number: 2)
<snip...>
netrole@snorkle [0] /usr/local/sbin/tcpdump -i e1000g1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on e1000g1, link-type EN10MB (Ethernet), capture size 65535 bytes
18:37:10.382886 IP 10.0.23.181 > snorkle-priv: ICMP echo request, id 5993, seq 22, length 64
18:37:10.382920 IP snorkle-priv > 10.0.23.181: ICMP echo reply, id 5993, seq 22, length 64
18:37:11.383959 IP 10.0.23.181 > snorkle-priv: ICMP echo request, id 5993, seq 23, length 64
18:37:11.383999 IP snorkle-priv > 10.0.23.181: ICMP echo reply, id 5993, seq 23, length 64
<snip...>
netrole@snorkle [0] /usr/sbin/dladm show-dev -p
e1000g0 link=up speed=1000 duplex=full
e1000g1 link=up speed=1000 duplex=full
netrole@snorkle [0] /usr/sbin/route add -net 192.168.75.0/24 192.168.56.2
add net 192.168.75.0/24: gateway 192.168.56.2
netrole@snorkle [0] /bin/netstat -rn
Routing Table: IPv4
Destination Gateway Flags Ref Use Interface
-------------------- -------------------- ----- ----- ---------- ---------
default 127.0.0.1 U 1 0 lo0
10.0.22.0 10.0.23.191 U 1 0 e1000g0
192.168.56.0 192.168.56.15 U 1 5 e1000g1
192.168.75.0 192.168.56.2 UG 1 0
224.0.0.0 192.168.56.15 U 1 0 e1000g1
127.0.0.1 127.0.0.1 UH 1 0 lo0
Notes
Note 1: To see what privileges are available on the overall system,
execute 'ppriv -l'. To get further information, execute 'ppriv -lv'
or see the privileges(5) man page:
root@snorkle [0] /bin/ppriv -l
contract_event
contract_observer
cpc_cpu
dtrace_kernel
dtrace_proc
<snip...>
root@snorkle [0] /bin/ppriv -lv
contract_event
Allows a process to request critical events without limitation.
Allows a process to request reliable delivery of all events on
any event queue.
contract_observer
Allows a process to observe contract events generated by
contracts created and owned by users other than the process's
effective user ID.
Allows a process to open contract event endpoints belonging to
contracts created and owned by users other than the process's
effective user ID.
cpc_cpu
Allow a process to access per-CPU hardware performance counters.
dtrace_kernel
Allows DTrace kernel-level tracing.
dtrace_proc
Allows DTrace process-level tracing.
Allows process-level tracing probes to be placed and enabled in
processes to which the user has permissions.
dtrace_user
<snip...>
Note 2: Default privileges allowed to a user:
johnc@snorkle [0] /bin/ppriv -v $$
501: -ksh
flags = <none>
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: contract_event,contract_observer,cpc_cpu,dtrace_kernel,...
johnc@snorkle [0]
E => effective privileges currently in effect
I => privileges inherited on exec
P => the maximum set of privileges for the process
L => upper limit of privileges a process and its offspring can obtain
"basic" privileges:
file_link_any
Allows a process to create hardlinks to files owned by a uid
different from the process' effective uid.
proc_exec
Allows a process to call execve().
proc_fork
Allows a process to call fork1()/forkall()/vfork()
proc_info
Allows a process to examine the status of processes other
than those it can send signals to. Processes which cannot
be examined cannot be seen in /proc and appear not to exist.
proc_session
Allows a process to send signals or trace processes outside its
session.
Note 3: The parameters for 'roleadd' are very similar to 'useradd'.
If not specified, the default role values are::
root@snorkle [0] /usr/sbin/roleadd -D
group=other,1 project=default,3 basedir=/home
skel=/etc/skel shell=/bin/pfsh inactive=0
expire= auths= profiles=All limitpriv=
defaultpriv= lock_after_retries=
Note 4: Rather than assigning privileges, we could have updated
/etc/security/exec_attr, associating each command (and tcpdump)
to the new "NetRole" profile. We didn't since this was entirely an
exercise in using privileges.
Our host details for this are:
HOST: snorkle
PROMPT: user@snorkle [0]
OS: Solaris 10 10/09
USER: johnc
ROLE: netrole
For a sample setup, we have user 'johnc' from group 'neteng' who is tasked
with managing the network interfaces and routes on a system. He will need
access to 'ifconfig', 'route', 'dladm', 'snoop', and 'tcpdump'. Since we
won't give him root access, let's see how he fares with each command
and what we can do to help. Starting simple, 'johnc' uses 'ifconfig'
to check the available interfaces and attempt to bring "e1000g0" online:
johnc@snorkle [0] /usr/sbin/ifconfig -a
lo0: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
e1000g1: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
inet 192.168.56.15 netmask ffffff00 broadcast 192.168.56.255
johnc@snorkle [0] /usr/sbin/ifconfig e1000g0 plumb
ifconfig: cannot open link "e1000g0": Permission denied
johnc@snorkle [1]
As expected, he can review what's already configured but gets "Permission
denied" for trying to online "e1000g0". Being the diligent user he is,
'johnc' tries to online "e1000g0" again, but this time he uses 'ppriv'
(see note 1) to determine what's preventing him:
johnc@snorkle [1] /bin/ppriv -eD /usr/sbin/ifconfig e1000g0 plumb
ifconfig[514]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
ifconfig[514]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
ifconfig[514]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
ifconfig: cannot open link "e1000g0": Permission denied
Alright, 'johnc' needs the "net_rawaccess" privilege to actually manage
interfaces. So that he doesn't have to keep running back to us, 'johnc'
tries the rest of the commands:
johnc@snorkle [1] /bin/ppriv -eD /usr/sbin/snoop -d e1000g1
snoop[516]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
snoop[516]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
snoop[516]: missing privilege "net_rawaccess" (euid = 1002, syscall = 5) for \
"devpolicy" needed at spec_open+0xbf
snoop: cannot open "e1000g1": Permission denied
johnc@snorkle [1] /bin/ppriv -eD /usr/local/sbin/tcpdump -i e1000g1
tcpdump[874]: missing privilege "net_rawaccess" (euid = 1002, syscall = 225) for \
"devpolicy" needed at spec_open+0xbf
tcpdump: e1000g1: You don't have permission to capture on that device
(/dev/e1000g: Permission denied)
johnc@snorkle [0] /usr/sbin/dladm show-dev -p
/usr/sbin/dladm: insufficient privileges
johnc@snorkle [1] /bin/ppriv -eDv /usr/sbin/dladm show-dev -p
/usr/sbin/dladm: insufficient privileges
johnc@snorkle [1] /usr/sbin/route add -net 192.168.75.0/24 192.168.56.2
add net 192.168.75.0/24: gateway 192.168.56.2: insufficient privileges
johnc@snorkle [1] /bin/ppriv -eDv /usr/sbin/route add -net 192.168.75.0/24 192.168.56.2
route[688]: missing privilege "sys_ip_config" (euid = 1002, syscall = 4) needed \
at ip_rts_request+0x164
add net 192.168.75.0/24: gateway 192.168.56.2: insufficient privileges
All of the above commands have failed due to missing privileges.
Aside from 'dladm', each command executed through 'ppriv' returned the
missing privileges. As a final check, 'johnc' runs 'ppriv' against
his current terminal process to see what privileges he currently has
(see note 2):
johnc@snorkle [0] /bin/ppriv $$
501: -ksh
flags = <none>
E: basic
I: basic
P: basic
L: all
johnc@snorkle [0]
Having returned to us with the above information, let's see what other
details we can dig up to help 'johnc'. Since RBAC and privileges
are closely related, we can check for the commands 'johnc' needs in
RBAC's execution database 'exec_attr':
root@snorkle [0] /bin/egrep 'ifconfig|snoop|tcpdump|dladm|route' /etc/security/exec_attr
Network Management:solaris:cmd:::/sbin/dladm:privs=sys_net_config
Network Management:solaris:cmd:::/sbin/ifconfig:uid=0
Network Management:solaris:cmd:::/sbin/route:privs=sys_ip_config
Network Management:solaris:cmd:::/sbin/routeadm:euid=0; privs=proc_chroot,\
proc_owner,sys_ip_config
Network Management:suser:cmd:::/usr/sbin/ifconfig:uid=0
Network Management:suser:cmd:::/usr/sbin/route:uid=0
Network Management:suser:cmd:::/usr/sbin/snoop:uid=0
Based on the format for 'exec_attr', all but 'tcpdump' are part of
the preconfigured "Network Management" RBAC profile. We also see the
"sys_net_config" privilege for 'dladm' which we didn't previously know.
Reviewing 'exec_attr' for the "Network Management" profile, we see it
has 18 commands associated with it:
root@snorkle [0] grep "Network Management:" /etc/security/exec_attr | grep ":cmd:"
Network Management:solaris:cmd:::/sbin/dladm:privs=sys_net_config
Network Management:solaris:cmd:::/sbin/ifconfig:uid=0
Network Management:solaris:cmd:::/sbin/route:privs=sys_ip_config
Network Management:solaris:cmd:::/sbin/routeadm:euid=0; privs=proc_chroot,proc_owner,\
sys_ip_config
Network Management:solaris:cmd:::/usr/sbin/quaggaadm:privs=basic
Network Management:solaris:cmd:::/usr/sbin/zebraadm:privs=basic
Network Management:suser:cmd:::/usr/bin/netstat:uid=0
Network Management:suser:cmd:::/usr/bin/rup:euid=0
Network Management:suser:cmd:::/usr/bin/ruptime:euid=0
Network Management:suser:cmd:::/usr/bin/setuname:euid=0
Network Management:suser:cmd:::/usr/sbin/asppp2pppd:euid=0
Network Management:suser:cmd:::/usr/sbin/ifconfig:uid=0
Network Management:suser:cmd:::/usr/sbin/ipaddrsel:euid=0
Network Management:suser:cmd:::/usr/sbin/ipqosconf:euid=0
Network Management:suser:cmd:::/usr/sbin/rndc:privs=file_dac_read
Network Management:suser:cmd:::/usr/sbin/route:uid=0
Network Management:suser:cmd:::/usr/sbin/snoop:uid=0
Network Management:suser:cmd:::/usr/sbin/spray:euid=0
Since 'johnc' currently only needs access to 5 commands, we can create
a role for him and group 'neteng' to use. The following creates a new
role, netrole, and sets a password to it (see note 3):
root@snorkle [0] /usr/sbin/groupadd -g 10300 netrole
root@snorkle [0] /usr/sbin/roleadd -u 10300 -g 10300 -c "Minimal Network Role" \
-d /export/roles/netrole -m -s /bin/pfksh netrole
64 blocks
root@snorkle [0] /bin/passwd netrole
New Password:
Re-enter new Password:
passwd: password successfully changed for netrole
root@snorkle [0]
Of note, in Solaris 11 (Express) a role can be configured to allow
a user to use their own login password to access the role:
root@snorkle [0] /usr/sbin/rolemod -K roleauth=user netrole
Since we don't want this role associated with the default profile
(ALL), we add profile "NetRole" to 'prof_attr' and set 'netrole' with
the profile. We also set the default privileges to be those identified
above (see note 4):
root@snorkle [0] echo "NetRole:::profile managing NICs and routes:">> /etc/security/prof_attr
root@snorkle [0] /usr/sbin/rolemod -P NetRole -K defaultpriv=basic,net_rawaccess,\
sys_ip_config,sys_net_config netrole
After associating 'johnc' with role 'netrole' below via 'usermod', we
can see that our user's account hasn't been modified with a check of
'id' and review of '/etc/passwd':
root@snorkle [0] /usr/sbin/usermod -R netrole johnc
root@snorkle [0] /bin/id -a johnc
uid=1002(johnc) gid=1002(neteng) groups=1002(neteng)
root@snorkle [0] /bin/id -a netrole
uid=10300(netrole) gid=10300(netrole) groups=10300(netrole)
root@snorkle [0] /bin/egrep 'johnc|netrole' /etc/passwd
johnc:x:1002:1002:John Chambers:/export/home/johnc:/bin/ksh
netrole:x:10300:10300:Minimal Network Role:/export/roles/netrole:/bin/pfksh
root@snorkle [0] /bin/egrep 'johnc|netrole' /etc/user_attr
netrole::::type=role;profiles=NetRole;defaultpriv=basic,net_rawaccess,sys_ip_config,\
sys_net_config
johnc::::type=normal;roles=netrole
root@snorkle [0] /bin/roles johnc
netrole
The association of 'johnc' to role 'netrole' is contained within
'/etc/user_attr' and verified with 'roles' above. At this point, we've
given 'johnc' a subset of root's privileges allowing him to accomplish
only what he needs:
johnc@snorkle [0] /usr/sbin/ifconfig e1000g0 plumb
ifconfig: cannot open link "e1000g0": Permission denied
johnc@snorkle [1] /sbin/su - netrole
Password:
netrole@snorkle [0] /bin/ppriv $$
945: -pfksh
flags = <none>
E: basic,net_rawaccess,sys_ip_config,sys_net_config
I: basic,net_rawaccess,sys_ip_config,sys_net_config
P: basic,net_rawaccess,sys_ip_config,sys_net_config
L: all
To illustrate how 'johnc' can use the new 'netrole', we have 'johnc'
try to online "e1000g0" again, only to fail. We didn't give any extra
privileges to 'johnc', we gave them to 'netrole' which we can see above
after the 'su'. In the following, we see that by using role 'netrole',
'johnc' now has the access and privileges he needs:
netrole@snorkle [0] /usr/sbin/ifconfig e1000g0 plumb
netrole@snorkle [0] /bin/grep snorkle /etc/hosts
192.168.56.15 snorkle loghost
10.0.23.191 snorkle-priv
netrole@snorkle [0] /usr/sbin/ifconfig e1000g0 10.0.23.191 netmask 255.255.254.0 \
broadcast + up
netrole@snorkle [0] /usr/sbin/ifconfig -a
lo0: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
e1000g0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 3
inet 10.0.23.191 netmask fffffe00 broadcast 10.0.23.255
ether 8:0:27:56:c2:d
e1000g1: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
inet 192.168.56.15 netmask ffffff00 broadcast 192.168.56.255
ether 8:0:27:cb:f8:20
netrole@snorkle [0] /usr/sbin/snoop -d e1000g0
Using device e1000g1 (promiscuous mode)
10.0.23.181 -> snorkle-priv ICMP Echo request (ID: 63848 Sequence number: 1)
snorkle-priv -> 10.0.23.181 ICMP Echo reply (ID: 63848 Sequence number: 1)
10.0.23.181 -> snorkle-priv ICMP Echo request (ID: 63848 Sequence number: 2)
snorkle-priv -> 10.0.23.181 ICMP Echo reply (ID: 63848 Sequence number: 2)
<snip...>
netrole@snorkle [0] /usr/local/sbin/tcpdump -i e1000g1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on e1000g1, link-type EN10MB (Ethernet), capture size 65535 bytes
18:37:10.382886 IP 10.0.23.181 > snorkle-priv: ICMP echo request, id 5993, seq 22, length 64
18:37:10.382920 IP snorkle-priv > 10.0.23.181: ICMP echo reply, id 5993, seq 22, length 64
18:37:11.383959 IP 10.0.23.181 > snorkle-priv: ICMP echo request, id 5993, seq 23, length 64
18:37:11.383999 IP snorkle-priv > 10.0.23.181: ICMP echo reply, id 5993, seq 23, length 64
<snip...>
netrole@snorkle [0] /usr/sbin/dladm show-dev -p
e1000g0 link=up speed=1000 duplex=full
e1000g1 link=up speed=1000 duplex=full
netrole@snorkle [0] /usr/sbin/route add -net 192.168.75.0/24 192.168.56.2
add net 192.168.75.0/24: gateway 192.168.56.2
netrole@snorkle [0] /bin/netstat -rn
Routing Table: IPv4
Destination Gateway Flags Ref Use Interface
-------------------- -------------------- ----- ----- ---------- ---------
default 127.0.0.1 U 1 0 lo0
10.0.22.0 10.0.23.191 U 1 0 e1000g0
192.168.56.0 192.168.56.15 U 1 5 e1000g1
192.168.75.0 192.168.56.2 UG 1 0
224.0.0.0 192.168.56.15 U 1 0 e1000g1
127.0.0.1 127.0.0.1 UH 1 0 lo0
Notes
Note 1: To see what privileges are available on the overall system,
execute 'ppriv -l'. To get further information, execute 'ppriv -lv'
or see the privileges(5) man page:
root@snorkle [0] /bin/ppriv -l
contract_event
contract_observer
cpc_cpu
dtrace_kernel
dtrace_proc
<snip...>
root@snorkle [0] /bin/ppriv -lv
contract_event
Allows a process to request critical events without limitation.
Allows a process to request reliable delivery of all events on
any event queue.
contract_observer
Allows a process to observe contract events generated by
contracts created and owned by users other than the process's
effective user ID.
Allows a process to open contract event endpoints belonging to
contracts created and owned by users other than the process's
effective user ID.
cpc_cpu
Allow a process to access per-CPU hardware performance counters.
dtrace_kernel
Allows DTrace kernel-level tracing.
dtrace_proc
Allows DTrace process-level tracing.
Allows process-level tracing probes to be placed and enabled in
processes to which the user has permissions.
dtrace_user
<snip...>
Note 2: Default privileges allowed to a user:
johnc@snorkle [0] /bin/ppriv -v $$
501: -ksh
flags = <none>
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: contract_event,contract_observer,cpc_cpu,dtrace_kernel,...
johnc@snorkle [0]
E => effective privileges currently in effect
I => privileges inherited on exec
P => the maximum set of privileges for the process
L => upper limit of privileges a process and its offspring can obtain
"basic" privileges:
file_link_any
Allows a process to create hardlinks to files owned by a uid
different from the process' effective uid.
proc_exec
Allows a process to call execve().
proc_fork
Allows a process to call fork1()/forkall()/vfork()
proc_info
Allows a process to examine the status of processes other
than those it can send signals to. Processes which cannot
be examined cannot be seen in /proc and appear not to exist.
proc_session
Allows a process to send signals or trace processes outside its
session.
Note 3: The parameters for 'roleadd' are very similar to 'useradd'.
If not specified, the default role values are::
root@snorkle [0] /usr/sbin/roleadd -D
group=other,1 project=default,3 basedir=/home
skel=/etc/skel shell=/bin/pfsh inactive=0
expire= auths= profiles=All limitpriv=
defaultpriv= lock_after_retries=
Note 4: Rather than assigning privileges, we could have updated
/etc/security/exec_attr, associating each command (and tcpdump)
to the new "NetRole" profile. We didn't since this was entirely an
exercise in using privileges.
Comments
Post a Comment