USERMOD command written in bash
#!/bin/bash
#Ver 1.3
#presmerovat chyb vystup dostderr
# -o
# -p -> prestehovat do shadow
#
function find_uid_in_passwd
{
grep -v "^#" $passwd_file |cut -d"#" -f1| while read line
do
CUR_UID=`echo $line |awk -F: '{print $3} '`
if [ $CUR_UID = $P_UID ]; then
echo $CUR_UID;
break;
fi
done
}
function group_to_number
{
if [ ! -z `echo $G_T_N |grep -E '^[0-9]+$'` ]
then
echo $G_T_N
else
which_file=$group_file
find_name=$G_T_N
group_line=`find_user_in_file`
group_result=`echo $group_line | awk -F: '{print $3}'`
echo $group_result
fi
}
function fill_entry_from_passwd
{
IFS_OLD=$IFS
export IFS=":"
set -- $line
name=$1
pass=$2
uid=$3
gid=$4
gecos=$5
home_dir=$6
shell=$7
#
#name=`echo $line |awk -F: '{print $1} '`
#pass=`echo $line |awk -F: '{print $2}'`
#uid=` echo $line |awk -F: '{print $3}'`
#gid=` echo $line |awk -F: '{print $4}'`
#gecos=`echo $line|awk -F: '{print $5}'`
#home_dir=`echo $line|awk -F: '{print $6}'`
#shell=`echo $line|awk -F: '{print $7}'`
IFS=$IFS_OLD
}
function fill_entry_from_shadow
{
IFS_OLD=$IFS
export IFS=":"
set -- $line
name=$1
pass=$2
d_last_p_change=$3
d_before_p_may_change=$4
d_after_p_must_change=$5
d_before_expire_warn=$6
d_after_expired_disabled=$7
d_disabled=$8
reserved=$9
#name=`echo $line |awk -F: '{print $1} '`
#pass=`echo $line |awk -F: '{print $2}'`
#d_last_p_change=` echo $line |awk -F: '{print $3}'`
#d_before_p_may_change=` echo $line |awk -F: '{print $4}'`
#d_after_p_must_change=`echo $line|awk -F: '{print $5}'`
#d_before_expire_warn=`echo $line|awk -F: '{print $6}'`
#d_after_expired_disabled=`echo $line|awk -F: '{print $7}'`
#d_disabled=`echo $line|awk -F: '{print $8}'`
#reserved=`echo $line|awk -F: '{print $9}'`
IFS=$IFS_OLD
}
function find_user_in_file
{
#cat $which_file |grep -v "^#"|cut -d"#" -f1| while read line
#do
#CUR_USER=`echo $line |awk -F: '{print $1} '`
#if [ $CUR_USER = $find_name ]; then
#echo $line;
#break;
#fi
#done
grep ^$find_name $which_file | cut -d"#" -f1
}
function find_user_in_passwd
{
which_file=$passwd_file
find_name=$P_LOGIN
find_user_in_file
}
function find_group_in_group
{
which_file=$group_file
find_name=$group_test
find_user_in_file
}
function find_user_in_shadow
{
which_file=$shadow_file
find_name=$P_LOGIN
find_user_in_file
}
function alter_line_passwd
{
line=$USER_LINE_PASSWD
fill_entry_from_passwd
if [ -n "$P_COMMENT" ]; then
gecos=$P_COMMENT
fi
if [ -n "$P_COMMENT_EMPTY" ]; then
gecos=
fi
if [ -n "$P_HOMEDIR" ]; then
home_dir=$P_HOMEDIR
fi
if [ -n "$P_LOGIN_NAME" ]; then
name=$P_LOGIN_NAME
fi
if [ -n "$P_PASSWD" ]; then
pass=$P_PASSWD
fi
if [ -n "$P_SHELL" ]; then
shell=$P_SHELL
fi
if [ -n "$P_UID" ]; then
uid_result=`find_uid_in_passwd`
if [ -n "$uid_result" ]; then
if [ -z "$P_OVERRIDE" ]; then
dummy="uid"
fi
fi
uid=$P_UID
#TODO set to rest of files
fi
if [ -n "$P_INITIAL_GROUP" ]; then
G_T_N=$P_INITIAL_GROUP
gid=`group_to_number`
if [ -z "gid" ]; then
dummy="gid"
fi
#TODO test na existenci skupiny
fi
if [ -z "$dummy" ]; then
echo $name:$pass:$uid:$gid:$gecos:$home_dir:$shell
fi
}
function alter_line_shadow
{
line=$USER_LINE_SHADOW
fill_entry_from_shadow
if [ -n "$P_LOGIN_NAME" ]; then
name=$P_LOGIN_NAME
fi
if [ -n "$P_INACTIVE_DAYS" ]; then
d_after_expired_disabled=$P_INACTIVE_DAYS
fi
if [ -n "$P_EXPIRE_DATE" ]; then
if [ $P_EXPIRE_DATE = "0" ]
then
d_disabled=
else
d_disabled=`date -d $P_EXPIRE_DATE +%s`
fi
fi
echo $name:$pass:$d_last_p_change:$d_before_p_may_change:$d_after_p_must_change:$d_before_expire_warn:$d_after_expired_disabled:$d_disabled:$reserved
}
function fill_entry_from_group
{
IFS_OLD=$IFS
export IFS=":"
set -- $line
group_name=$1
group_pass=$2
gid=$3
user_list=$4
#group_name=`echo $line |awk -F: '{print $1} '`
#group_pass=`echo $line |awk -F: '{print $2}'`
#gid=` echo $line |awk -F: '{print $3}'`
#user_list=` echo $line |awk -F: '{print $4}'`
IFS=$IFS_OLD
}
function alter_file_group
{
#echo T6
#line=$USER_LINE_GROUP
#fill_entry_from_group
if [ -n "$P_GROUP_SUPP" ]; then
for group_test in `echo $P_GROUP_SUPP | sed 's/,/ /g'`
do
find_result=`find_group_in_group`
if [ -z "$find_result" ]; then
echo "Warning non-exitent group:" $group_test
fi
done;
fi
if [ -n "$P_LOGIN_NAME" ]; then
sed 's/\(.*:.*:.*\)'$P_LOGIN'\(.*\)/\1'$P_LOGIN_NAME'\2/' $group_file > /tmp/g$$roup_tmp
mv /tmp/g$$roup_tmp $group_file
P_LOGIN=$P_LOGIN_NAME # MODIFIKACE globl USERA, posledni misto kde se to meni
fi
if [ -n "$P_GROUP_SUPP" ]; then
#echo T7
grep_param=^`echo $P_GROUP_SUPP | sed 's/,/|^/g'` #konstrukce regul vyrazu
egrep -v $grep_param $group_file > /tmp/g$$roup.new_p1 #skupiny co nechci modifikovat, ale chci zmenit if NOT user
#TODO:
# vyhazet s groups.new usera (nema se tam v zadnym pripade uz vyskytovat)
#
group_to_change=`egrep '.*:.*:.*:.*'$P_LOGIN'*' /tmp/g$$roup.new_p1` #radky z kterych musim vyhodit usera, neni nove clenem
egrep -v '.*:.*:.*:.*'$P_LOGIN'*' /tmp/g$$roup.new_p1 > /tmp/g$$roup.new #cisty
rm -f /tmp/g$$roup.new_p1
group_line_change=`egrep $grep_param $group_file|sort` #skupiny co chci zmenit (radky)
#group_list=`echo $P_GROUP_SUPP |tr , "\n" |sort` #seznam skupin
#echo T8
#echo $group_to_change
for line in $group_to_change
do
fill_entry_from_group #naplni z $line do promenych
new_user_list=
for users_to_change in `echo $user_list |tr , " " ` #skupina, kde odebereme
do
if [[ $P_LOGIN != $users_to_change ]]; then
new_user_list=$new_user_list,$users_to_change
fi
# echo $users_to_change
done;
echo $group_name:$group_pass:$gid:${new_user_list#,} >>/tmp/g$$roup.new
done;
# echo $group_list
# echo $group_line_change
# echo $group_list | while read line
# do
# TODO: test jestli skupina existuje
# + prejmenovani
#
# P_LOGIN
for line in $group_line_change
do
fill_entry_from_group
if [ -z `echo $user_list|grep $P_LOGIN` ] ; then
#Todo jestli je PRVNI
if [ -z "$user_list" ]; then
echo $group_name:$group_pass:$gid:$P_LOGIN >> /tmp/g$$roup.new #user je novy
else
echo $group_name:$group_pass:$gid:$user_list,$P_LOGIN >> /tmp/g$$roup.new #user je novy
fi
else
echo $group_name:$group_pass:$gid:$user_list >> /tmp/g$$roup.new #user uz tam je
fi
done;
#ODBLOKOVAT
mv /tmp/g$$roup.new $group_file
fi
}
function print_help
{
echo "usermod [-c comment] [-d home_dir [ -m]]"
echo " [-e expire_date] [-f inactive_time]"
echo " [-g initial_group] [-G group[,...]]"
echo " [-l login_name] [-p passwd]"
echo " [-s shell] [-u uid [ -o]] login"
}
# Program start:
passwd_file="passwd"
group_file="group"
shadow_file="shadow"
if [ $# = 1 ]; then
print_help
exit 255
fi
while [ $# != 1 ]
do
case "$1" in
'-c') #done
P_COMMENT=$2
if [ -n "$P_COMMENT" ] ;then P_COMMENT_EMPTY=TRUE
fi
shift 2
;;
'-d')
P_HOMEDIR=$2
shift 2
;;
'-e')
P_EXPIRE_DATE=$2
shift 2
;;
'-f')
P_INACTIVE_DAYS=$2
shift 2
;;
'-g')
P_INITIAL_GROUP=$2
shift 2
;;
'-G')
P_GROUP_SUPP=$2
shift 2
;;
'-l')
P_LOGIN_NAME=$2
TEST_NAME=`grep "^"$P_LOGIN_NAME $passwd_file`
# echo $passwd_file $P_LOGIN_NAME
if [ -n "$TEST_NAME" ]; then
echo Existing username !
exit 9
fi
shift 2
;;
'-p')
P_PASSWD=$2
shift 2
;;
'-s')
P_SHELL=$2
shift 2
;;
'-u')
P_UID=$2
shift 2
;;
'-m')
P_MOVE="YES"
shift 1
;;
'-o')
P_OVERRIDE="YES"
shift 1
;;
*)
print_help
exit 255
esac
done
if [ $# = 1 ]; then
P_LOGIN=$1
fi
USER_LINE_PASSWD=`find_user_in_passwd`
#echo T1
if [ -z "$USER_LINE_PASSWD" ]; then
echo No such user
exit 255;
fi
ALTERED_LINE_PASSWD=`alter_line_passwd`
#echo T2
if [ -z "$ALTERED_LINE_PASSWD" ]; then
echo Duplicit uid found, use -o to override, or non existing group
exit 255
fi
USER_LINE_SHADOW=`find_user_in_shadow`
#echo T3
if [ -z "$USER_LINE_SHADOW" ]; then
echo No such user in shadow file
exit 255;
fi
ALTERED_LINE_SHADOW=`alter_line_shadow`
#echo T4
alter_file_group
#echo ----------------------
#echo $USER_LINE_PASSWD
#echo $ALTERED_LINE_PASSWD
#echo ----------------------
#echo $USER_LINE_SHADOW
#echo $ALTERED_LINE_SHADOW
#echo ----------------------
#echo $USER_LINE_GROUP
#echo $ALTERED_LINE_GROUP
#echo ----------------------
cp $passwd_file $passwd_file""~
grep -v "$USER_LINE_PASSWD" $passwd_file""~ >$passwd_file ; echo $ALTERED_LINE_PASSWD >>$passwd_file
cp $shadow_file $shadow_file""~
grep -v "$USER_LINE_SHADOW" $shadow_file""~ >$shadow_file ; echo $ALTERED_LINE_SHADOW >>$shadow_file
cp $group_file $group_file""~
#mv group.new $group_file
if [ -n "$P_MOVE" ]; then
if [ -n "$P_HOMEDIR" ]; then
mv -R ~/$P_LOGIN/ $P_HOMEDIR
fi
fi