Mercurial > pkg
view previous-work/more_control_helpers/sbin/add_package_user @ 1:d6bef198ae71
add work by Matthias S. Benkmann which is the inspiration for this project.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 08 Jan 2013 11:45:01 +0000 |
parents | |
children |
line wrap: on
line source
1 #!/bin/bash2 # Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>3 # You may do everything with this code except misrepresent its origin.4 # PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!6 #Package user home directories will be located under this directory7 homebase=/usr/src9 #Contents of following directory are copied into home directory when creating10 #a new package user (existing files will not be overwritten)11 skel=/etc/pkgusr/skel-package13 if [ $# -lt 7 ]; then14 echo 1>&2 'USAGE: '15 echo 1>&2 'add_package_user <description> <name> <minuid> <maxuid> \'16 echo 1>&2 ' <group> <mingid> <maxgid> [-d <home>]'17 echo 1>&218 echo 1>&2 'If a user account called <name> exists, a message will be printed and'19 echo 1>&2 'everything will be left as-is. If a user account called <name> does not'20 echo 1>&2 'exist, one will be created.'21 echo 1>&2 'The account'"'"'s primary group will be <group> and the /etc/passwd'22 echo 1>&2 'description field will be set to <description>. If a group called <group>'23 echo 1>&2 'does not already exist, one will be created.'24 echo 1>&2 'The new account will get the "install" group as a supplementary group. If'25 echo 1>&2 'a group named "install" does not exist, one will be created.'26 echo 1>&227 echo 1>&2 '<description> needs to be a valid string for the /etc/passwd description'28 echo 1>&2 ' field. This means, among other things, that it must not contain ":".'29 echo 1>&2 ' Don'"'"'t forget to properly quote <description> if it contains spaces or'30 echo 1>&2 ' other characters interpreted by the shell!'31 echo 1>&232 echo 1>&2 '<minuid>(incl.) and <maxuid>(excl.) determine the numeric range from which'33 echo 1>&2 ' the new account'"'"'s UID will be picked in the following way:'34 echo 1>&235 echo 1>&2 ' 1. If the range contains no unused UID => Exit with error.'36 echo 1>&2 ' 2. If <maxuid>-1 is still unused, find the greatest UID from the range'37 echo 1>&2 ' that is used and pick the number after that.'38 echo 1>&2 ' 3. If <maxuid>-1 is in use, pick the first unused number from the range.'39 echo 1>&240 echo 1>&2 '<mingid>(incl.) and <maxgid>(excl.) determine the numeric range from which'41 echo 1>&2 ' to pick the GID for group <group> and/or group "install", if it needs to be'42 echo 1>&2 ' created. The process for picking the GID is the same as that for the UID.'43 echo 1>&2 ''44 echo 1>&2 '<home> specifies the new user'"'"'s home directory. If it is not provided,'45 echo 1>&2 ' it will default to '"$homebase/<name> ."46 echo 1>&2 ' If the home directory does not exist yet it will be created, otherwise'47 echo 1>&2 ' the existing directory will be recursively chown'"'"'ed to the new user.'48 echo 1>&2 ' The home directory will be populated with a copy of the contents of'49 echo 1>&2 " $skel, but pre-existing files in the home directory"50 echo 1>&2 ' will not be overwritten. Note that symlinks will be copied as symlinks!'51 echo 1>&2 ''52 exit 153 fi55 grpfile=/etc/group56 passwd=/etc/passwd60 description=$161 name=$262 minuid=$363 maxuid=$464 gname=$565 mingid=$666 maxgid=$767 home=$homebase/$name69 set -- "$@" _eNd_OF_lisT_70 while [ "$1" != "_eNd_OF_lisT_" ]; do71 case "$1" in72 -d) shift 173 if [ "$1" = "_eNd_OF_lisT_" ]; then74 echo 1>&2 "-d directory name missing!"75 exit 176 fi77 home="$1"78 shift 179 ;;80 *) temp="$1"81 shift 182 set -- "$@" "$temp"83 ;;84 esac85 done86 shift 1 #throw away _eNd_OF_lisT_88 if [ $UID -ne 0 ]; then echo Please run this script as root. ; exit 1; fi90 #test if user already exists91 grep "^$name:.*" $passwd92 if [ $? -eq 0 ]; then93 echo 'Package user does already exist! Do su '$name' to do maintenance work.'94 exit 195 fi97 #test if minuid, maxuid, mingid and maxgid are integers, otherwise error98 error=099 expr ${minuid} + 1 2>/dev/null 1>&2 || error=1100 expr ${maxuid} + 1 2>/dev/null 1>&2 || error=1101 expr ${mingid} + 1 2>/dev/null 1>&2 || error=1102 expr ${maxgid} + 1 2>/dev/null 1>&2 || error=1104 if [ $error -eq 1 ]; then105 echo Error: Illegal numeric value!106 exit 1107 fi109 if [ $minuid -ge $maxuid ]; then110 echo 'Error: minuid must be less than maxuid !'111 exit 1112 fi114 if [ $mingid -ge $maxgid ]; then115 echo 'Error: mingid must be less than maxgid !'116 exit 1117 fi120 uidlist=`cut -d : -f 3 $passwd | sort -n`122 #find last used UID within range123 u=0124 for i in $uidlist125 do126 if [ $i -ge $maxuid ]; then break; fi127 if [ $i -ge $minuid ]; then u=$i; fi128 done130 #if no UID from the range is used, pick the first, otherwise pick the one131 #immediately following the last UID in use.132 if [ $u -eq 0 ]; then u=$minuid; else u=`expr $u + 1`; fi134 #if the UID determined above is >= maxuid (i.e. illegal)135 #then we look for the first unused uid in the range.136 if [ $u -ge $maxuid ]; then137 u=$minuid138 for i in $uidlist139 do140 if [ $u -eq $i ]; then u=`expr $u + 1` ; fi141 if [ $i -ge $maxuid ]; then break; fi142 done144 if [ $u -ge $maxuid ]; then145 echo Error: UID range is full!146 exit 1147 fi148 fi150 echo Will create user $name with uid: $u152 unset uidlist154 #############################################################################155 # group156 #############################################################################158 #execute the following for gname and "install" to get gids for those 2 groups160 g=0161 creategroup=0162 for group in install $gname163 do164 oldg=$g #save gid from previous run165 createinstall=$creategroup166 creategroup=0168 #test if group already exists and extract gid if so169 g=`grep ^${group}:.\* $grpfile | cut -d : -f 3 -`171 #if group does not exist, then check range for a free gid172 if [ z$g = z ]; then173 creategroup=1175 gidlist=`cut -d : -f 3 $grpfile | sort -n`177 #find last used GID within range178 g=0179 for i in $gidlist180 do181 if [ $i -ge $maxgid ]; then break; fi182 if [ $i -ge $mingid ]; then g=$i; fi183 done185 #if no GID from the range is used, pick the first, otherwise pick the one186 #immediately following the last GID in use.187 if [ $g -eq 0 ]; then g=$mingid; else g=`expr $g + 1`; fi189 #don't reuse gid from previous run190 if [ $g -eq $oldg ]; then g=`expr $g + 1`; fi192 #if the GID determined above is >= maxgid (i.e. illegal)193 #then we look for the first unused gid in the range.194 if [ $g -ge $maxgid ]; then195 g=$mingid196 for i in $gidlist197 do198 if [ $g -eq $i ]; then g=`expr $g + 1` ; fi199 if [ $g -eq $oldg ]; then g=`expr $g + 1` ; fi200 if [ $i -ge $maxgid ]; then break; fi201 done203 if [ $g -ge $maxgid ]; then204 echo Error: GID range is full!205 exit 1206 fi207 fi208 fi209 done211 unset gidlist213 if [ $createinstall -eq 1 ]; then214 echo Creating group install with gid $oldg215 groupadd -g $oldg install || exit 1216 else217 echo Group install has gid $oldg218 fi219 if [ $creategroup -eq 1 ]; then220 echo Creating group $gname with gid $g221 groupadd -g $g $gname || exit 1222 else223 echo Group $gname has gid $g224 fi228 useradd -c "${description}" -d ${home} -g ${gname} -G install \229 -s /bin/bash -u ${u} ${name} || exit 1231 mkdir -p $home || exit 1233 yes n|cp -ai -R ${skel}/{[^.],.[^.],..?}* ${home} 2>/dev/null >/dev/null235 cd ${home}236 chown --recursive ${u}:${g} .239 exit 0