3

Is there a way to ensure that when a user is added to a permissions group on a system, that user is automatically added to one or more other defined groups?

For example adding a user to a group created as netadmin would add the user to the groups www-data, tomcat, sambashare and ftp. (This is only a hypothetical situation)

Another example group of vmadmin could add a user to the groups, kvm, libvirt and vboxusers.

I know that a group cannot be added to a group, but would like to avoid having to set up and maintain ACLs for different directories and files.

3

I don't think there's a built-in way to do that.

However there's a pretty easy solution: you could add a function to ~/.bashrc to wrap the whole task into a single command.

Listing the sets of groups in a case statement (ok for a few sets of groups)

function add_user {
    [ ! -z "$1" -a ! -z "$2" ] || return
    case "$1" in
    netadmin)
        groups=(netadmin www-data tomcat sambashare ftp)
        ;;
    vmadmin)
        groups=(kvm libvirt vboxusers)
        ;;
    *)
        printf "Group '%s' is not listed.\n" "$1"
        return
    esac
    printf "Adding '%s' to group '%s'...\n" "$2" "$1"
    usermod -aG ${groups[@]} "$1"
}

After that running e.g. add_user netadmin user will add user to netadmin, www-data, tomcat, sambashare and ftp, and running e.g. add_user vmadmin user will add user to kvm, libvirt and vboxusers.

Adding other sets of groups would be as easy as adding other entries to the case statement after the vmadmin entry and before the * entry:

foo)
    groups=(bar foobar raboof)
    ;;

Listing the sets of groups in an external configuration file

Create a file named config in ~/ whith the following content:

netadmin,netadmin,www-data,tomcat,sambashare,ftp
vmadmin,kvm,libvirt,vboxusers
  • The first field identifies the name of the set of groups
  • The fields after the first identify the groups to which the user is to add
function add_user {
    [ ! -z "$1" -a ! -z "$2" ] || exit
    groups=( $(awk -F , -v group="$1" '$1==group {$1=""; print; exit}' config) )
    if [ ${#groups} -eq 0 ]; then
        printf "Group '%s' is not listed.\n" "$1"
        return
    fi
    printf "Adding '%s' to group '%s'...\n" "$2" "$1"
    usermod -aG ${groups[@]} "$1"
}

After that running e.g. add_user netadmin user will add user to netadmin, www-data, tomcat, sambashare and ftp, and running e.g. add_user vmadmin user will add user to kvm, libvirt and vboxusers.

Adding other sets of groups would be as easy as adding another entry to ~/config:

foo,bar,foobar,raboof
  • That looks marvellous. I could create a separate function for each group that links to other groups. Would it be difficult to have the function read a config file, so that I wouldn't need a separate function for each? – Arronical Jan 14 '16 at 16:09
  • @Arronical I don't think so, but you'll need to do some parsing. Do you have so many to add? If not it would probably be faster / cleaner to expand the function to use a case statement to determine what to do based on the arguments (e.g. add_user netadmin user would add user to the groups listed above, add_user foo user would add user to another custom defined group of groups etc.). If you add another example I can modify the function so that it can work for multiple groups of groups. – kos Jan 14 '16 at 16:16
  • @Arronical I edited the function so that it handles both groups of groups and explained briefly how to add other groups. Anyway I think it would be interesting to make it work with a configuration file like you suggested, so I'm currently looking into that as well, I'll ping you when I have something. – kos Jan 14 '16 at 16:59
  • @Arronical Done, it was easier than it looked :) See how it fits. – kos Jan 14 '16 at 17:46
  • This is utterly marvellous, thanks for the extra effort :) – Arronical Jan 15 '16 at 8:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.