Controlling su access with sugroups

Using sugroups allows system administrators to restrict access by group members on who can su to what account. Using the NOT operator, further restriction can be placed on access control. Reporting on who is a member of what sugroup, and what accounts they can su to, needs to be identified for auditing purposes. This involves generating a report on sugroup member access and is generally considered a compliance task.

Sugroup overview

System administrators who provide su access to a user gives the ability for a user to switch or substitute to another user without logging out from their current account. Typically, su accounts are setup so that a user can temporarily switch to another account, for example the root user or an application owner. However, as application support grows so does the maintenance overhead on administrating the system. Using sugroups makes the management of su permissions more manageable, as you are dealing with groups instead of lots of individual users.

Using sugroups allows system administrators to group certain users and give them the ability to su to different accounts. The actual su access is controlled by being a member of a certain AIX® group. When a user is created, you can specify a sugroup as part of the users attributes; only members of this group are allowed to su to that user. Of course the user su-ing needs to know the password to su successfully. Other users who know the password of the user, but do not belong to the sugroup specified, will not be able to su to the said user, since they do not belong to the correct sugroup.

Having stated the previous, it may not be the security policy of some systems to divulge passwords to other users. In that case, one can use sudo. This is discussed later.

Commands to know

To determine what sugroups are in place, there are a couple of commands that will be useful. They are:

  • lsuser
  • lsgroup

In the following example, the lsuser command is used to output all sugroups of all users. This list could be quite long depending on the amount of users configured on the system:

#lsuser ‑a sugroups ALL

When a user is created and no sugroup is specified, AIX defaults to ALL. This means any group can su to that user. To filter out the default ALL, use ‘grep -v‘ to list all users with sugroups that do not have the default ALL attribute set. Replace ALL with your default sugroup on your system, located in:


#lsuser ‑a sugroups ALL|grep ‑v ALL

To list a single user with its sugroups attributes, in this case user pinky, use the following code:

#lsuser ‑a sugroups pinky
pinky sugroups=wasgrp,websp

In the above output, we can see that user pinky has sugroups of wasgrp and websp.

To then list the members of the sugroups wasgrp and websp, use the following code:

#lsgroup ‑a users wasgrp
admin users=dxtans,pxcon,jgena
#lsgroup ‑a users websp
admin users=dcand,

So we now know that user pinky has sugroups of wasgrp and websp, and the members of those groups who are allowed to su to user pinky are:


You can use the grep utility to search the system user attribute defaults in the file. Depending on the placement of comments in the file, one of the following will extract just the default stanza :

grep ‑p "default:" /etc/security/user
grep ‑v ^"∗" /etc/security/user| grep ‑p "default:"

Or better still just grep for the sugroups in the defaults stanza:

#grep ‑p "default:" /etc/security/user| grep sugroups
        sugroups = ALL

Using sugroups

Let’s look at an example of how a sugroup is implemented.

#lsuser ‑a sugroups dxtans
dxtans sugroups=ALL

We can see from the previous output that the sugroup attributes is set to ALL. That means any user, or any group member, has the ability to su to the account of dxtans provided they know user dxtans password. Now let’s change the sugroups attribute to only include the group smoke:

#chuser sugroups=smoke dxtans
#lsuser ‑a sugroups dxtans
dxtans sugroups=smoke

Looking at the members of group smoke, we only have one member: papa

#lsgroup ‑a users smoke
smoke users=papa

If another user who is not a member of group smoke tries to su, this is what happens:

$ whoami
$ su – dxtans
dxtans's Password:
3004‑307 You are not allowed to su to this account.
3004‑501 Cannot su to "dxtans" : Account is not accessible.

Now if user papa tries to su to dxtans account and the password is known, access is granted:

$ whoami
$ su ‑ dxtans
dxtans's Password:
$ id 
uid=203(dxtans) gid=1(staff)

Attempts of su access are logged to /var/adm/sulog.

Using the previous demonstration of the su attempts, we have two entries. A plus sign indicates a successful su attempt occurred from user papa to user dxtans. A minus sign indicates a failed su attempt occurred from user bravo to user dxtans:

$ tail /var/adm/sulog
SU 04/17 19:51 + pts/1 papa‑dxtans
SU 04/17 19:52 ‑ pts/1 bravo‑dxtans

If a user is trying to su to another user and is getting an ‘Account is not accessible’ message, and you are sure that the authentication via sugroups or su is correct, then check that the destination user does not have unsuccessful login attempts breeched. Perhaps the password has expired, or an initial password has not been set.

A must have sugroup on any system

Hopefully thus far I have convinced you why creating sugroups is more attractive than creating lots of individual su permissions. Even if you do not buy into the use of sugroups, at least create one sugroup to manage the su to the root account. Typically, system administrators login in as themselves then su to root. I will now demonstrate how the following users (who are system administrators) will only be allowed to su to root. The users are:


The first task is to create a group, we’ll call it sysadmin, whose members are listed above. Only members of this group are allowed to su to root.

Create the group with members john,peter,jane:

#mkgroup ‑A users="john,peter,jane" sysadmin

Confirm group members:

#lsgroup ‑a users sysadmin
sysadmin users=john,peter,jane

Give user root sugroup of sysadmin:

#chuser sugroups=sysadmin root
#lsuser ‑a sugroups root
root sugroups=sysadmin

Only members of sysadmin can now su to root.

The root user should not be allowed to login directly via telnet. The user root should only be allowed to login via direct console. Having stated this, when using ssh, using root to ssh across systems can be desirable when dealing with updates and file/script roll-out. It is good practice for root to only be allowed to ssh out from deployment servers.

Initial denial

There may be occasions when you create a new user on a system that you want to forbid access from anyone being able to su to this user. One way to do this is to create a group that has no members. Then you can use that group (name) as a sugroup attribute to that user. For example, suppose we had a user called brown. Due to the sensitive nature of the users environment, no one should be able to su to that account (except root). We could create a group called none with no members:

#mkgroup ‑A none
#lsgroup ‑a users none
none users=

Then change the users account sugroups attribute to include that group:

#chuser sugroups=none brown
#lsuser ‑a sugroups brown
brown sugroups=none

As no one belongs to the group none, and it is to be used as a sugroup, no normal user can su to the account of user brown.

If you want to make it a more permanent feature, you could edit the /etc/security/user file. Within the default stanza in the sugroups entry, put in that group just created:

sugroups  =  none

Now when all new users are created, by default they will have that sugroup set (no one can su to that user). Please note, all users that already have their sugroups set to ALL (the default) will now have ‘none’ as their sugroups attribute. Then one can gradually lift the security of that user as your security policy demands.

Sugroup restriction

As previously stated, unless you change the default sugroups value, all users will use that default (which is ALL). To further restrict sugroups access AIX provides the NOT operator ‘!’. The format for the rule is:

!<group_name >

By enforcing this rule in the sugroups attribute, the group names that have the NOT operator before the group name will be denied access to su to that account. That may beg the question, “Why?” For ordinary users, you can specify by groups who are denied the ability to su to certain users. You can also use this method by temporary restricting certain groups. This provides greater flexibility in su management by not creating many groups to control or satisfy access to different accounts.

Let’s look at an example at how sugroups using the NOT operator might be effective. Suppose we had a group called sun. From the output of the following lsgroup, we can determine the users of the group:

#lsgroup ‑a users sun
sun users=alpha,bravo

So, the members are:


To allow all users the ability to su to user charlie, but deny access to the members of the group sun, we would use the following command:

#chuser sugroups="!sun,ALL" charlie

Note in the above command the order of the NOT operator, we first deny then allow.

The following commands list the sugroups and group attributes of the users discussed:

alpha, bravo, charlie

#lsuser ‑a sugroups groups alpha
alpha sugroups=ALL groups=staff,sun

#lsuser ‑a sugroups groups bravo
bravo sugroups=ALL groups=staff,sun

#lsuser ‑a sugroups groups charlie
charlie sugroups=!sun,ALL groups=staff

Now if user delta, who is not a member of the restricted group sun, attempts to su to user charlie and knows the password, the authentication will succeed:

#lsuser ‑a sugroups groups delta

delta sugroups=ALL groups=staff,water,fire,mobgrp

As user delta:

$ id
uid=220(delta) gid=1(staff) groups=206(water),207(fire),215(mobgrp)
$ su ‑ charlie
charlie's Password:
$ id
uid=211(charlie) gid=1(staff)

If user alpha, who is a member of the restricted group sun, tries to su to the user charlie, he will be denied access.

As user alpha:

$ id
uid=209(alpha) gid=1(staff) groups=214(sun)
$ su ‑ charlie
charlie's Password:
3004‑307 You are not allowed to su to this account.
3004‑501 Cannot su to "charlie" : Account is not accessible.

Let’s look at another example of why we might use the NOT operator. Suppose we had an account called ukflag. We do not want users whom belong to the groups fire and cloud being able to su to user ukflag, only members of earth should be allowed. First change the user ukflag sugroups attributes, and then confirm the change:

#chuser sugroups="!fire,!cloud,earth" ukflag

#lsuser ‑a sugroups ukflag
ukflag sugroups=!fire,!cloud,earth

Members of group earthare going to be allowed su access to user: ukflag

#lsgroup ‑a users earth
earth users=zulu

Let’s now see who belongs to the groups cloud and fire, whom we are going to restrict su access to user ukflag.

#lsgroup ‑a users fire
fire users=plutt,echoa,golf,hotel,india,juliet,kilo

#lsgroup ‑a users cloud
cloud users=hotel,india

From the lsgroup output we now know that the following user will only be allowed to su to the ukflag account: zulu. Also from the lsgroup output, we know the following users will be denied access to su to the ukflag account: plutt,echoa,golf,hotel,india,juliet,kilo.

This can now be demonstrated, from the account of user plutt, a member of the fire group:

$ id
uid=230(plutt) gid=1(staff) groups=206(water),207(fire)
$ su ‑ ukflag
ukflag's Password:
3004‑307 You are not allowed to su to this account.

3004‑501 Cannot su to "ukflag" : Account is not accessible.

And from user zulu, a member of the earth group:

$ id
uid=228(zulu) gid=1(staff) groups=209(earth)
$ su ‑ ukflag
ukflag's Password:

As demonstrated, using the NOT operator allows fine tuning of access to user accounts via sugroups the ability to su.

Password not required

When providing su access, it may not be appropriate to allow other users to know the password of an account that they are allowed to su to. This could particularly be the case for application accounts, when support users need to gain access to resolve an issue. Using sudo, one can let these users gain authorized access without knowing the password that are allowed to su to.

Imagine we have support users alpha, bravo,charlie, whom all belong to the group app_supp. As part of their responsibility, they need to gain access to the production environment account: ukflag. Simply edit the /etc/sudoers file and put in the following entry, replacing rs6000 with your hostname:

%app_supp rs6000 = NOPASSWD:/usr/bin/su – ukflag

Check group members:

#lsgroup ‑a users app_supp
app_supp users=alpha,bravo,charlie

Check the user can su via sudo to the account ukflag:

$ whoami
$ sudo ‑l
User alpha may run the following commands on this host:
    (root) NOPASSWD: /usr/bin/su ‑ ukflag
$ sudo ‑u root su ‑ ukflag
$ whoami

You can have many su entries in sudo, just be sure to separate each su entry with comma, like so:

%app_supp rs6000 = NOPASSWD:/usr/bin/su – ukflag, /usr/bin/su – ieflag, 
/usr/bin/su ‑ plflag

Reporting on sugroups

When using sugroups, it can sometimes become time consuming to review all your sugroups access you have in place, especially when dealing with many systems. It could be advantageous to create a script that generates a snapshot of the sugroups and members. In Listing 1, I present a script that will give an overview of the sugroups in place. It was originally two scripts, but I have merged them for this demonstration into one script. The script builds on the commands used in the section “Commands to know.”

When the script is executed, it displays all users who do not have ALL as part of their sugroup attribute. Then, it list the user and the sugroups of that user. The second part of the script will display each sugroup and its respective members.

Listing 1. su_rep1
list=$(cat /etc/passwd| awk ‑F: '{print $1}' | sort)
echo "user      su groups  ∗(Denied su access)
#display user and sugroups
for loop in $list
sugrp=$(lsuser ‑a sugroups $loop | sed s/ALL//g | awk ‑F= '{print $2}'|sed 's/,/ /g')
 if  "$sugrp" != ""   then
sugrp=$(echo $sugrp|sed 's/!/∗/g')    
printf "%‑10s %‑40s\n" "$loop" "$sugrp"
#list sugroups and members
echo "\nsugroup    sugroup members
sugrp_list=$(lsuser ‑a sugroups ALL| sed s/ALL//g | awk ‑F= '{print $2}'| tr " " "\n" \
|sed 's/,/ /g' | sed 's/!//g'|tr " " "\n" |awk '!array [$0]++')
for loop in $sugrp_list
sugrp_list=$(lsgroup ‑a users $loop | awk ‑F= '{print $2}')
 if  "$sugrp_list" = ""     then
     sugrp_list=" ‑‑ No Members ‑‑"
printf "%‑10s %‑40s\n" "$loop" "$sugrp_list"

When su_rep1 contained in Listing 1 is executed, on my system similar output to the following is produced:

user       su groups  ∗(Denied su access)
charlie    ∗sun
dxtans     smoke
papa       syb
root       admin sysadmin
ukflag     ∗fire ∗cloud earth
xray       water earth ∗smoke
zulu       fire

sugroup    sugroup members
admin      dxtans
sysadmin   john,peter,jane
smoke      papa
sun        alpha,bravo
water      delta,echoa,golf,plutt
earth      zulu
fire       delta,echoa,golf,hotel,india,juliet,kilo,plutt
syb        wwpdpga1,wwpdclt2,ukflag
cloud      hotel,india,spoll


Using sugroups enables system administrators to control access to individual user accounts by group membership. Sugroups provides one method of implementing and managing the security policy on your systems. When being audited, you will have to prove to the auditor access control between normal and application, system accounts, and how the sugroup policy is being monitored. This article has demonstrated how sugroups can be implemented. A script has also been provided to display sugroup access.