annotate 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
rev   line source
rlm@1 1 #!/bin/bash
rlm@1 2 # Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
rlm@1 3 # You may do everything with this code except misrepresent its origin.
rlm@1 4 # PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
rlm@1 5
rlm@1 6 #Package user home directories will be located under this directory
rlm@1 7 homebase=/usr/src
rlm@1 8
rlm@1 9 #Contents of following directory are copied into home directory when creating
rlm@1 10 #a new package user (existing files will not be overwritten)
rlm@1 11 skel=/etc/pkgusr/skel-package
rlm@1 12
rlm@1 13 if [ $# -lt 7 ]; then
rlm@1 14 echo 1>&2 'USAGE: '
rlm@1 15 echo 1>&2 'add_package_user <description> <name> <minuid> <maxuid> \'
rlm@1 16 echo 1>&2 ' <group> <mingid> <maxgid> [-d <home>]'
rlm@1 17 echo 1>&2
rlm@1 18 echo 1>&2 'If a user account called <name> exists, a message will be printed and'
rlm@1 19 echo 1>&2 'everything will be left as-is. If a user account called <name> does not'
rlm@1 20 echo 1>&2 'exist, one will be created.'
rlm@1 21 echo 1>&2 'The account'"'"'s primary group will be <group> and the /etc/passwd'
rlm@1 22 echo 1>&2 'description field will be set to <description>. If a group called <group>'
rlm@1 23 echo 1>&2 'does not already exist, one will be created.'
rlm@1 24 echo 1>&2 'The new account will get the "install" group as a supplementary group. If'
rlm@1 25 echo 1>&2 'a group named "install" does not exist, one will be created.'
rlm@1 26 echo 1>&2
rlm@1 27 echo 1>&2 '<description> needs to be a valid string for the /etc/passwd description'
rlm@1 28 echo 1>&2 ' field. This means, among other things, that it must not contain ":".'
rlm@1 29 echo 1>&2 ' Don'"'"'t forget to properly quote <description> if it contains spaces or'
rlm@1 30 echo 1>&2 ' other characters interpreted by the shell!'
rlm@1 31 echo 1>&2
rlm@1 32 echo 1>&2 '<minuid>(incl.) and <maxuid>(excl.) determine the numeric range from which'
rlm@1 33 echo 1>&2 ' the new account'"'"'s UID will be picked in the following way:'
rlm@1 34 echo 1>&2
rlm@1 35 echo 1>&2 ' 1. If the range contains no unused UID => Exit with error.'
rlm@1 36 echo 1>&2 ' 2. If <maxuid>-1 is still unused, find the greatest UID from the range'
rlm@1 37 echo 1>&2 ' that is used and pick the number after that.'
rlm@1 38 echo 1>&2 ' 3. If <maxuid>-1 is in use, pick the first unused number from the range.'
rlm@1 39 echo 1>&2
rlm@1 40 echo 1>&2 '<mingid>(incl.) and <maxgid>(excl.) determine the numeric range from which'
rlm@1 41 echo 1>&2 ' to pick the GID for group <group> and/or group "install", if it needs to be'
rlm@1 42 echo 1>&2 ' created. The process for picking the GID is the same as that for the UID.'
rlm@1 43 echo 1>&2 ''
rlm@1 44 echo 1>&2 '<home> specifies the new user'"'"'s home directory. If it is not provided,'
rlm@1 45 echo 1>&2 ' it will default to '"$homebase/<name> ."
rlm@1 46 echo 1>&2 ' If the home directory does not exist yet it will be created, otherwise'
rlm@1 47 echo 1>&2 ' the existing directory will be recursively chown'"'"'ed to the new user.'
rlm@1 48 echo 1>&2 ' The home directory will be populated with a copy of the contents of'
rlm@1 49 echo 1>&2 " $skel, but pre-existing files in the home directory"
rlm@1 50 echo 1>&2 ' will not be overwritten. Note that symlinks will be copied as symlinks!'
rlm@1 51 echo 1>&2 ''
rlm@1 52 exit 1
rlm@1 53 fi
rlm@1 54
rlm@1 55 grpfile=/etc/group
rlm@1 56 passwd=/etc/passwd
rlm@1 57
rlm@1 58
rlm@1 59
rlm@1 60 description=$1
rlm@1 61 name=$2
rlm@1 62 minuid=$3
rlm@1 63 maxuid=$4
rlm@1 64 gname=$5
rlm@1 65 mingid=$6
rlm@1 66 maxgid=$7
rlm@1 67 home=$homebase/$name
rlm@1 68
rlm@1 69 set -- "$@" _eNd_OF_lisT_
rlm@1 70 while [ "$1" != "_eNd_OF_lisT_" ]; do
rlm@1 71 case "$1" in
rlm@1 72 -d) shift 1
rlm@1 73 if [ "$1" = "_eNd_OF_lisT_" ]; then
rlm@1 74 echo 1>&2 "-d directory name missing!"
rlm@1 75 exit 1
rlm@1 76 fi
rlm@1 77 home="$1"
rlm@1 78 shift 1
rlm@1 79 ;;
rlm@1 80 *) temp="$1"
rlm@1 81 shift 1
rlm@1 82 set -- "$@" "$temp"
rlm@1 83 ;;
rlm@1 84 esac
rlm@1 85 done
rlm@1 86 shift 1 #throw away _eNd_OF_lisT_
rlm@1 87
rlm@1 88 if [ $UID -ne 0 ]; then echo Please run this script as root. ; exit 1; fi
rlm@1 89
rlm@1 90 #test if user already exists
rlm@1 91 grep "^$name:.*" $passwd
rlm@1 92 if [ $? -eq 0 ]; then
rlm@1 93 echo 'Package user does already exist! Do su '$name' to do maintenance work.'
rlm@1 94 exit 1
rlm@1 95 fi
rlm@1 96
rlm@1 97 #test if minuid, maxuid, mingid and maxgid are integers, otherwise error
rlm@1 98 error=0
rlm@1 99 expr ${minuid} + 1 2>/dev/null 1>&2 || error=1
rlm@1 100 expr ${maxuid} + 1 2>/dev/null 1>&2 || error=1
rlm@1 101 expr ${mingid} + 1 2>/dev/null 1>&2 || error=1
rlm@1 102 expr ${maxgid} + 1 2>/dev/null 1>&2 || error=1
rlm@1 103
rlm@1 104 if [ $error -eq 1 ]; then
rlm@1 105 echo Error: Illegal numeric value!
rlm@1 106 exit 1
rlm@1 107 fi
rlm@1 108
rlm@1 109 if [ $minuid -ge $maxuid ]; then
rlm@1 110 echo 'Error: minuid must be less than maxuid !'
rlm@1 111 exit 1
rlm@1 112 fi
rlm@1 113
rlm@1 114 if [ $mingid -ge $maxgid ]; then
rlm@1 115 echo 'Error: mingid must be less than maxgid !'
rlm@1 116 exit 1
rlm@1 117 fi
rlm@1 118
rlm@1 119
rlm@1 120 uidlist=`cut -d : -f 3 $passwd | sort -n`
rlm@1 121
rlm@1 122 #find last used UID within range
rlm@1 123 u=0
rlm@1 124 for i in $uidlist
rlm@1 125 do
rlm@1 126 if [ $i -ge $maxuid ]; then break; fi
rlm@1 127 if [ $i -ge $minuid ]; then u=$i; fi
rlm@1 128 done
rlm@1 129
rlm@1 130 #if no UID from the range is used, pick the first, otherwise pick the one
rlm@1 131 #immediately following the last UID in use.
rlm@1 132 if [ $u -eq 0 ]; then u=$minuid; else u=`expr $u + 1`; fi
rlm@1 133
rlm@1 134 #if the UID determined above is >= maxuid (i.e. illegal)
rlm@1 135 #then we look for the first unused uid in the range.
rlm@1 136 if [ $u -ge $maxuid ]; then
rlm@1 137 u=$minuid
rlm@1 138 for i in $uidlist
rlm@1 139 do
rlm@1 140 if [ $u -eq $i ]; then u=`expr $u + 1` ; fi
rlm@1 141 if [ $i -ge $maxuid ]; then break; fi
rlm@1 142 done
rlm@1 143
rlm@1 144 if [ $u -ge $maxuid ]; then
rlm@1 145 echo Error: UID range is full!
rlm@1 146 exit 1
rlm@1 147 fi
rlm@1 148 fi
rlm@1 149
rlm@1 150 echo Will create user $name with uid: $u
rlm@1 151
rlm@1 152 unset uidlist
rlm@1 153
rlm@1 154 #############################################################################
rlm@1 155 # group
rlm@1 156 #############################################################################
rlm@1 157
rlm@1 158 #execute the following for gname and "install" to get gids for those 2 groups
rlm@1 159
rlm@1 160 g=0
rlm@1 161 creategroup=0
rlm@1 162 for group in install $gname
rlm@1 163 do
rlm@1 164 oldg=$g #save gid from previous run
rlm@1 165 createinstall=$creategroup
rlm@1 166 creategroup=0
rlm@1 167
rlm@1 168 #test if group already exists and extract gid if so
rlm@1 169 g=`grep ^${group}:.\* $grpfile | cut -d : -f 3 -`
rlm@1 170
rlm@1 171 #if group does not exist, then check range for a free gid
rlm@1 172 if [ z$g = z ]; then
rlm@1 173 creategroup=1
rlm@1 174
rlm@1 175 gidlist=`cut -d : -f 3 $grpfile | sort -n`
rlm@1 176
rlm@1 177 #find last used GID within range
rlm@1 178 g=0
rlm@1 179 for i in $gidlist
rlm@1 180 do
rlm@1 181 if [ $i -ge $maxgid ]; then break; fi
rlm@1 182 if [ $i -ge $mingid ]; then g=$i; fi
rlm@1 183 done
rlm@1 184
rlm@1 185 #if no GID from the range is used, pick the first, otherwise pick the one
rlm@1 186 #immediately following the last GID in use.
rlm@1 187 if [ $g -eq 0 ]; then g=$mingid; else g=`expr $g + 1`; fi
rlm@1 188
rlm@1 189 #don't reuse gid from previous run
rlm@1 190 if [ $g -eq $oldg ]; then g=`expr $g + 1`; fi
rlm@1 191
rlm@1 192 #if the GID determined above is >= maxgid (i.e. illegal)
rlm@1 193 #then we look for the first unused gid in the range.
rlm@1 194 if [ $g -ge $maxgid ]; then
rlm@1 195 g=$mingid
rlm@1 196 for i in $gidlist
rlm@1 197 do
rlm@1 198 if [ $g -eq $i ]; then g=`expr $g + 1` ; fi
rlm@1 199 if [ $g -eq $oldg ]; then g=`expr $g + 1` ; fi
rlm@1 200 if [ $i -ge $maxgid ]; then break; fi
rlm@1 201 done
rlm@1 202
rlm@1 203 if [ $g -ge $maxgid ]; then
rlm@1 204 echo Error: GID range is full!
rlm@1 205 exit 1
rlm@1 206 fi
rlm@1 207 fi
rlm@1 208 fi
rlm@1 209 done
rlm@1 210
rlm@1 211 unset gidlist
rlm@1 212
rlm@1 213 if [ $createinstall -eq 1 ]; then
rlm@1 214 echo Creating group install with gid $oldg
rlm@1 215 groupadd -g $oldg install || exit 1
rlm@1 216 else
rlm@1 217 echo Group install has gid $oldg
rlm@1 218 fi
rlm@1 219 if [ $creategroup -eq 1 ]; then
rlm@1 220 echo Creating group $gname with gid $g
rlm@1 221 groupadd -g $g $gname || exit 1
rlm@1 222 else
rlm@1 223 echo Group $gname has gid $g
rlm@1 224 fi
rlm@1 225
rlm@1 226
rlm@1 227
rlm@1 228 useradd -c "${description}" -d ${home} -g ${gname} -G install \
rlm@1 229 -s /bin/bash -u ${u} ${name} || exit 1
rlm@1 230
rlm@1 231 mkdir -p $home || exit 1
rlm@1 232
rlm@1 233 yes n|cp -ai -R ${skel}/{[^.],.[^.],..?}* ${home} 2>/dev/null >/dev/null
rlm@1 234
rlm@1 235 cd ${home}
rlm@1 236 chown --recursive ${u}:${g} .
rlm@1 237
rlm@1 238
rlm@1 239 exit 0