Wednesday, 4 February 2009

A script to add user in Linux

# Path to files
pfile=/etc/passwd
gfile=/etc/group
sfile=/etc/shells

# Paths to binaries
useradd=/usr/sbin/useradd
chfn=/usr/bin/chfn
passwd=/usr/bin/passwd
chmod=/bin/chmod

# Defaults
defhome=/home
defshell=/bin/bash
defchmod=711 # home dir permissions - may be preferable to use 701, however.
defgroup=users
AGID="audio cdrom floppy plugdev video" # additional groups for desktop users

# Determine what the minimum UID is (for UID recycling)
# (we ignore it if it's not at the beginning of the line (i.e. commented out with #))
export recycleUIDMIN="$(grep ^UID_MIN /etc/login.defs | awk '{print $2}' 2>/dev/null)"
# If we couldn't find it, set it to the default of 1000
if [ -z "$recycleUIDMIN" ]; then
export recycleUIDMIN=1000
fi


# This setting enables the 'recycling' of older unused UIDs.
# When you userdel a user, it removes it from passwd and shadow but it will
# never get used again unless you specify it expliticly -- useradd (appears to) just
# look at the last line in passwd and increment the uid. I like the idea of
# recycling uids but you may have very good reasons not to (old forgotten
# confidential files still on the system could then be owned by this new user).
# We'll set this to no because this is what the original adduser shell script
# did and it's what users expect.
recycleuids=no

# Function to read keyboard input.
# bash1 is broken (even ash will take read -ep!), so we work around
# it (even though bash1 is no longer supported on Slackware).
function get_input() {
local output
if [ "`echo $BASH_VERSION | cut -b1`" = "1" ]; then
echo -n "${1} " >&2 # fudge for use with bash v1
read output
else # this should work with any other /bin/sh
read -ep "${1} " output
fi
echo $output
}

# Function to display the account info
function display () {
local goose
goose="$(echo $2 | cut -d ' ' -f 2-)" # lop off the prefixed argument useradd needs
echo -n "$1 "
# If it's null then display the 'other' information
if [ -z "$goose" -a ! -z "$3" ]; then
echo "$3"
else
echo "$goose"
fi
}

# Function to check whether groups exist in the /etc/group file
function check_group () {
local got_error group
if [ ! -z "$@" ]; then
for group in $@ ; do
local uid_not_named="" uid_not_num=""
grep -v "$^" $gfile | awk -F: '{print $1}' | grep "^${group}$" >/dev/null 2>&1 || uid_not_named=yes
grep -v "$^" $gfile | awk -F: '{print $3}' | grep "^${group}$" >/dev/null 2>&1 || uid_not_num=yes
if [ ! -z "$uid_not_named" -a ! -z "$uid_not_num" ]; then
echo "- Group '$group' does not exist"
got_error=yes
fi
done
fi
# Return exit code of 1 if at least one of the groups didn't exist
if [ ! -z "$got_error" ]; then
return 1
fi
}

#: Read the login name for the new user :#
#
# Remember that most Mail Transfer Agents are case independant, so having
# 'uSer' and 'user' may cause confusion/things to break. Because of this,
# useradd from shadow-4.0.3 no longer accepts usernames containing uppercase,
# and we must reject them, too.

# Set the login variable to the command line param
echo
LOGIN="$1"
needinput=yes
while [ ! -z $needinput ]; do
if [ -z "$LOGIN" ]; then
while [ -z "$LOGIN" ]; do LOGIN="$(get_input "Login name for new user []:")" ; done
fi
grep "^${LOGIN}:" $pfile >/dev/null 2>&1 # ensure it's not already used
if [ $? -eq 0 ]; then
echo "- User '$LOGIN' already exists; please choose another"
unset LOGIN
elif [ ! -z "$( echo $LOGIN | grep "^[0-9]" )" ]; then
echo "- User names cannot begin with a number; please choose another"
unset LOGIN
elif [ ! "$LOGIN" = "`echo $LOGIN | tr A-Z a-z`" ]; then # useradd does not allow uppercase
echo "- User '$LOGIN' contains illegal characters (uppercase); please choose another"
unset LOGIN
elif [ ! -z "$( echo $LOGIN | grep '\.' )" ]; then
echo "- User '$LOGIN' contains illegal characters (period/dot); please choose another"
unset LOGIN
else
unset needinput
fi
done

# Display the user name passed from the shell if it hasn't changed
if [ "$1" = "$LOGIN" ]; then
echo "Login name for new user: $LOGIN"
fi

#: Get the UID for the user & ensure it's not already in use :#
#
# Whilst we _can_ allow users with identical UIDs, it's not a 'good thing' because
# when you change password for the uid, it finds the first match in /etc/passwd
# which isn't necessarily the correct user
#
echo
needinput=yes
while [ ! -z "$needinput" ]; do
_UID="$(get_input "User ID ('UID') [ defaults to next available ]:")"
grep -v "^$" $pfile | awk -F: '{print $3}' | grep "^${_UID}$" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "- That UID is already in use; please choose another"
elif [ ! -z "$(echo $_UID | egrep '[A-Za-z]')" ]; then
echo "- UIDs are numerics only"
else
unset needinput
fi
done
# If we were given a UID, then syntax up the variable to pass to useradd
if [ ! -z "$_UID" ]; then
U_ID="-u ${_UID}"
else
# Will we be recycling UIDs?
if [ "$recycleuids" = "yes" ]; then
U_ID="-u $(awk -F: '{uid[$3]=1} END { for (i=ENVIRON["recycleUIDMIN"];i in uid;i++);print i}' $pfile)"
fi
fi

#: Get the initial group for the user & ensure it exists :#
#
# We check /etc/group for both the text version and the group ID number
echo
needinput=yes
while [ ! -z "$needinput" ]; do
GID="$(get_input "Initial group [ ${defgroup} ]:")"
check_group "$GID"
if [ $? -gt 0 ]; then
echo "- Please choose another"
else
unset needinput
fi
done
# Syntax the variable ready for useradd
if [ -z "$GID" ]; then
GID="-g ${defgroup}"
else
GID="-g ${GID}"
fi

#: Get additional groups for the user :#
#
echo "Additional UNIX groups:"
echo
echo "Users can belong to additional UNIX groups on the system."
echo "For local users using graphical desktop login managers such"
echo "as XDM/KDM, users may need to be members of additional groups"
echo "to access the full functionality of removable media devices."
echo
echo "* Security implications *"
echo "Please be aware that by adding users to additional groups may"
echo "potentially give access to the removable media of other users."
echo
echo "If you are creating a new user for remote shell access only,"
echo "users do not need to belong to any additional groups as standard,"
echo "so you may press ENTER at the next prompt."
echo
needinput=yes
while [ ! -z "$needinput" ]; do
history -c
history -s "$AGID"
echo "Press ENTER to continue without adding any additional groups"
echo "Or press the UP arrow to add/select/edit additional groups"
AGID="$(get_input ": " | tr -d '[:punct:]' | tr -s ' ' | sed 's?^ $??g' )"
if [ ! -z "$AGID" ]; then
check_group "$AGID" # check all groups at once (treated as N # of params)
if [ $? -gt 0 ]; then
echo "- Please re-enter the group(s)"
echo
else
unset needinput # we found all groups specified
AGID="-G $(echo $AGID | tr ' ' ,)" # useradd takes comma delimited groups
fi
else
unset needinput # we don't *have* to have additional groups
fi
done

#: Get the new user's home dir :#
#
echo
needinput=yes
while [ ! -z "$needinput" ]; do
HME="$(get_input "Home directory [ ${defhome}/${LOGIN} ]")"
if [ -z "$HME" ]; then
HME="${defhome}/${LOGIN}"
fi
# Warn the user if the home dir already exists
if [ -d "$HME" ]; then
echo "- Warning: '$HME' already exists !"
getyn="$(get_input " Do you wish to change the home directory path ? (Y/n) ")"
if [ "$(echo $getyn | grep -i "n")" ]; then
unset needinput
# You're most likely going to only do this if you have the dir *mounted* for this user's $HOME
getyn="$(get_input " Do you want to chown $LOGIN.$( echo $GID | awk '{print $2}') $HME ? (y/N) ")"
if [ "$(echo $getyn | grep -i "y")" ]; then
CHOWNHOMEDIR=$HME # set this to the home directory
fi
fi
else
unset needinput
fi
done
HME="-d ${HME}"

#: Get the new user's shell :#
echo
needinput=yes
while [ ! -z "$needinput" ]; do
unset got_error
SHL="$(get_input "Shell [ ${defshell} ]")"
if [ -z "$SHL" ]; then
SHL="${defshell}"
fi
# Warn the user if the shell doesn't exist in /etc/shells or as a file
if [ -z "$(grep "^${SHL}$" $sfile)" ]; then
echo "- Warning: ${SHL} is not in ${sfile} (potential problem using FTP)"
got_error=yes
fi
if [ ! -f "$SHL" ]; then
echo "- Warning: ${SHL} does not exist as a file"
got_error=yes
fi
if [ ! -z "$got_error" ]; then
getyn="$(get_input " Do you wish to change the shell ? (Y/n) ")"
if [ "$(echo $getyn | grep -i "n")" ]; then
unset needinput
fi
else
unset needinput
fi
done
SHL="-s ${SHL}"

#: Get the expiry date :#
echo
needinput=yes
while [ ! -z "$needinput" ]; do
EXP="$(get_input "Expiry date (YYYY-MM-DD) []:")"
if [ ! -z "$EXP" ]; then
# Check to see whether the expiry date is in the valid format
if [ -z "$(echo "$EXP" | grep "^[[:digit:]]\{4\}[-]\?[[:digit:]]\{2\}[-]\?[[:digit:]]\{2\}$")" ]; then
echo "- That is not a valid expiration date"
else
unset needinput
EXP="-e ${EXP}"
fi
else
unset needinput
fi
done

# Display the info about the new impending account
echo
echo "New account will be created as follows:"
echo
echo "---------------------------------------"
display "Login name.......: " "$LOGIN"
display "UID..............: " "$_UID" "[ Next available ]"
display "Initial group....: " "$GID"
display "Additional groups: " "$AGID" "[ None ]"
display "Home directory...: " "$HME"
display "Shell............: " "$SHL"
display "Expiry date......: " "$EXP" "[ Never ]"
echo

echo "This is it... if you want to bail out, hit Control-C. Otherwise, press"
echo "ENTER to go ahead and make the account."
read junk

echo
echo "Creating new account..."
echo
echo

# Add the account to the system
CMD="$useradd "$HME" -m "$EXP" "$U_ID" "$GID" "$AGID" "$SHL" "$LOGIN""
$CMD

if [ $? -gt 0 ]; then
echo "- Error running useradd command -- account not created!"
echo "(cmd: $CMD)"
exit 1
fi

# chown the home dir ? We can only do this once the useradd has
# completed otherwise the user name doesn't exist.
if [ ! -z "${CHOWNHOMEDIR}" ]; then
chown "$LOGIN"."$( echo $GID | awk '{print $2}')" "${CHOWNHOMEDIR}"
fi

# Set the finger information
$chfn "$LOGIN"
if [ $? -gt 0 ]; then
echo "- Warning: an error occurred while setting finger information"
fi

# Set a password
$passwd "$LOGIN"
if [ $? -gt 0 ]; then
echo "* WARNING: An error occured while setting the password for"
echo " this account. Please manually investigate this *"
exit 1
fi

# If it was created (it should have been!), set the permissions for that user's dir
HME="$(echo "$HME" | awk '{print $2}')" # We have to remove the -g prefix
if [ -d "$HME" ]; then
$chmod $defchmod "$HME"
fi

echo
echo
echo "Account setup complete."
exit 0

26 comments:

Anonymous said...

This is (most of) the slackware useradd script by Stuart Winter, version 1.10 if I'm not mistaken

Anonymous said...

Or rather I should say, it's based on the original Slackware adduser script by Hrvoje Dogan, with modifications by Patrick Volkerding and Stuart Winter :)

Anonymous said...

http://markonzo.edu magic story very thanks actual ashley furniture [url=http://jguru.com/guru/viewbio.jsp?EID=1536072]actual ashley furniture[/url], cwlokkx, watch allegiant air [url=http://jguru.com/guru/viewbio.jsp?EID=1536075]watch allegiant air[/url], oisvm, best pressure washers [url=http://jguru.com/guru/viewbio.jsp?EID=1536078]best pressure washers[/url], 5674, follow dishnetwork [url=http://jguru.com/guru/viewbio.jsp?EID=1536080]follow dishnetwork[/url], :-0, fresh adt security [url=http://jguru.com/guru/viewbio.jsp?EID=1536076]fresh adt security[/url], eyaswnk,

Anonymous said...

Lovingly done is better than spectacularly said.

Anonymous said...

Well done is sick than spectacularly said.

Anonymous said...

Splendidly done is well-advised b wealthier than spectacularly said.

Anonymous said...

Artistically done is richer reconsider than spectacularly said.

Anonymous said...

Lovingly done is well-advised b wealthier than spectacularly said.

Anonymous said...

A man who dares to atrophy bromide hour of every now has not discovered the value of life.

[url=http://forum.hostican.com/member.php?u=3556&vmid=70#vmessage70]Jake[/url]


Linda

Anonymous said...

A human beings begins scathing his discernment teeth the first often he bites on holiday more than he can chew.

Anonymous said...

To be a noble human being is to procure a philanthropic of openness to the world, an gift to group uncertain things beyond your own pilot, that can lead you to be shattered in very exceptional circumstances as which you were not to blame. That says something very outstanding relating to the get of the righteous autobiography: that it is based on a corporation in the up in the air and on a willingness to be exposed; it's based on being more like a shop than like a sparkler, something somewhat fragile, but whose very item beauty is inseparable from that fragility.

Anonymous said...

Work out ferments the humors, casts them into their right channels, throws off redundancies, and helps cosmos in those secretive distributions, without which the fuselage cannot subsist in its vigor, nor the man role of with cheerfulness.

Anonymous said...

To be a adroit human being is to from a kind of openness to the world, an skill to guardianship aleatory things beyond your own restrain, that can lead you to be shattered in very exceptional circumstances pro which you were not to blame. That says something remarkably impressive about the fettle of the honest autobiography: that it is based on a conviction in the up in the air and on a willingness to be exposed; it's based on being more like a shop than like a jewel, something rather feeble, but whose mere precise attractiveness is inseparable from that fragility.

Anonymous said...

In everyone's time, at some dated, our inner fire goes out. It is then bust into flame at hand an encounter with another hominoid being. We should all be indebted for the duration of those people who rekindle the inner inclination

Anonymous said...

I don't like the earshot of all those lists he's making - it's like taking too many notes at philosophy; you sensible of you've achieved something when you haven't.

Anonymous said...

In every tom's life, at some occasion, our inner foment goes out. It is then break asunder into flame beside an contend with with another human being. We should all be thankful for those people who rekindle the inner spirit

Anonymous said...

In harry's time, at some time, our inner throw goes out. It is then bust into passion beside an encounter with another hominoid being. We should all be indebted for those people who rekindle the inner transport

Anonymous said...

In every tom's time, at some pass‚, our inner throw goes out. It is then bust into passion by an contend with with another magnanimous being. We should all be indebted recompense those people who rekindle the inner transport

Anonymous said...

In harry's life, at some dated, our inner fire goes out. It is then break asunder into flame at hand an face with another hominoid being. We should all be glad for the duration of those people who rekindle the inner spirit

Anonymous said...

In harry's existence, at some occasion, our inner pep goes out. It is then break asunder into flame beside an contend with with another magnanimous being. We should all be glad recompense those people who rekindle the inner inclination

Anonymous said...

In every tom's time, at some time, our inner throw goes out. It is then bust into enthusiasm by an contend with with another hominoid being. We should all be thankful for the duration of those people who rekindle the inner spirit

Anonymous said...

In the whole world's life, at some pass‚, our inner foment goes out. It is then break asunder into flame by an contend with with another hominoid being. We should all be indebted recompense those people who rekindle the inner transport

Anonymous said...

In harry's sustenance, at some dated, our inner foment goes out. It is then blow up into zeal at hand an contend with with another hominoid being. We should all be under obligation for those people who rekindle the inner inspiration

Anonymous said...

In every tom's time, at some dated, our inner fire goes out. It is then bust into enthusiasm at near an face with another hominoid being. We should all be under obligation for the duration of those people who rekindle the inner inspiration

Anonymous said...

In everyone's existence, at some dated, our inner throw goes out. It is then blow up into zeal by an face with another benign being. We should all be indebted for those people who rekindle the inner spirit

Anonymous said...

In every tom's sustenance, at some occasion, our inner pep goes out. It is then burst into flame at near an contend with with another hominoid being. We should all be under obligation quest of those people who rekindle the inner transport