programmatically clone /etc/skel for new users
/etc/skel
is a folder that will be cloned for new users. Is there a possible way that we can define rules what to copy from /etc/skel
folder?
For example, I'm looking for a way that if a user is created and belongs to group named A
, clone /etc/skel
folder except /etc/skel/not_for_a.txt
. Possible?
Note that useradd
command allows you to specify a custom SKEL directory using the -k
option. You may create a /etc/skel-for-group-A directory without the not-for-a.txt
, and then add new users with their default group as A, and specify their SKEL directory using the command:
useradd username -g groupA -k /etc/skel-for-group-A -m
Refer: http://manpages.ubuntu.com/manpages/trusty/man8/useradd.8.html
-
Create additional
skel
directories.sudo mkdir /etc/skel{A,B}
-
Copy the contents of
/etc/skel
to/etc/skelA
.sudo cp /etc/skel/* /etc/skelA/
Customize the alternative skel directory contents.
-
adduser
without a homedir, but with otherwise normal settings. Replace the ellipsis with the appropriate settings.sudo adduser --no-create-home ... bob
-
mkhomedir_helper
to create users homedir based on alternative skel dir.sudo mkhomedir_helper bob /etc/skelA
#!/bin/bash
### a bare bones dumb script to create a user with a homedir based on an alternitive skeldir
adduseropt="--no-create-home --ingroup"
# assumes $1 will be user TODO add sanity check
# Assumes $2 will be alternitive skeldir TODO add sanity check
# assumes $3 will be a group TODO add sanity check
sudo adduser --no-create-home $adduseropt $3 $1
sudo mkhomedir_helper $1 $2
adduser
does support a limited way to exclude files from the skeleton directory. From man adduser.conf
:
SKEL_IGNORE_REGEX
Files in /etc/skel/ are checked against this regex, and not
copied to the newly created home directory if they match. This
is by default set to the regular expression matching files left
over from unmerged config files (dpkg-(old|new|dist)).
While you can't set this regex from the command line, you can set the config file used using the --conf
option. So you can create additional copies of /etc/adduser.conf
that only differ on the SKEL_IGNORE_REGEX
, and use those:
(grep -v '^SKEL_IGNORE_REGEX' /etc/adduser.conf; printf "%s\n" 'SKEL_IGNORE_REGEX="not_for_a.txt"') > /etc/adduser_A.txt
sudo adduser --conf /etc/adduser_A.txt ...
The adduser
command can run a site-specific script to do any setup like removing files. As long as it is acceptable to start with a full copy and then delete some files afterwards, then this approach could work for you.
From the adduser(8) man page:
If the file
/usr/local/sbin/adduser.local
exists, it will be executed after the user account has been set up in order to do any local setup. The arguments passed toadduser.local
are:username uid gid home-directory
So all you need to do is write a script that takes four parameters and use it remove any files you need. Save it as /usr/local/sbin/adduser.local
and make sure it's marked executable (chmod a+x
).
Here's something to get you started:
#!/bin/bash
## Site-specific setup for newly-created users.
## adduser(8) will call this script after setting up a new user.
set -euo pipefail
if [[ "$#" != 4 ]]; then
echo "usage: $0 username uid gid home" > /dev/stderr
fi
NEW_USERNAME="${1:?}"
NEW_UID="${2:?}"
NEW_GID="${3:?}"
NEW_HOME="${4:?}"
# The groups command outputs a space-separated list of group names
IFS=' '
for group in $(groups "${NEW_USERNAME}"); do
case "${group}" in
a)
[[ "${VERBOSE}" > 0 ]] && echo Removing file for a
rm "${NEW_HOME}/not_for_a.txt"
;;
b)
[[ "${VERBOSE}" > 0 ]] && echo Removing dir for b
rm -r "${NEW_HOME}/not_for_b/"
;;
*)
[[ "${VERBOSE}" > 1 ]] && echo No special setup required for $group
;;
esac
done
The interesting part, which you'll want to edit, are the lines that look like this one:
a)
[[ "${VERBOSE}" > 0 ]] && echo Removing file for a
rm "${NEW_HOME}/not_for_a.txt"
;;
You can fill in the actual group name and behaviour you'd like to see instead of a)
and rm not_for_a.txt
.