summaryrefslogtreecommitdiff
path: root/user-init
blob: 076b2f95cbf2a0f7d951a3955d0e0fc068e055b2 (plain)
  1. #!/bin/sh
  2. set -e
  3. # reset flags
  4. apache_reload_needed=""
  5. runmode="normal"
  6. mac="mac"
  7. pc="pc"
  8. xchange="xchange"
  9. if [ -e /etc/adduser.conf ]; then
  10. . /etc/adduser.conf
  11. else
  12. echo "/etc/adduser.conf missing. Exiting..."
  13. exit 1
  14. fi
  15. [ -f /etc/local/users.conf ] && . /etc/local/users.conf
  16. if [ -e /etc/local/volumes ]; then
  17. . /etc/local/volumes
  18. else
  19. # exit silently if this system lacks required hints
  20. exit 0
  21. fi
  22. XDIRREAL="$XDIR/users/root"
  23. if [ $XCHANGE ]; then
  24. if [ ! -d "$XDIR" ]; then
  25. echo "XDIR doesn't exist. Ignoring XCHANGE!"
  26. XCHANGE=""
  27. fi
  28. fi
  29. if [ $# -gt 0 ]; then
  30. USERS=$*
  31. else
  32. # USERS=`getent passwd | awk -F: '{print $1}'`
  33. echo "uid required!"
  34. exit 1
  35. fi
  36. [ $NETATALK_HOME ] && mac=$NETATALK_HOME
  37. [ $SAMBA_HOME ] && pc=$SAMBA_HOME
  38. [ $XCHANGE_HOME ] && xchange=$XCHANGE_HOME
  39. echo "Setting up additional folders and permissions..."
  40. for user in $USERS; do
  41. uid="`getent passwd \"$user\" | awk -F: '{print $3}' | head -1`"
  42. HOME="`getent passwd \"$user\" | awk -F: '{print $6}' | head -1`"
  43. if [ -z "$HOME" ]; then
  44. echo "User $user doesn't exist. Ignoring..."
  45. continue
  46. fi
  47. # Ignore non-human accounts silently
  48. [ "$uid" -ge "$FIRST_UID" -a "$uid" -le "$LAST_UID" ] || continue
  49. [ -d $HOME ] || continue
  50. # [ -L $HOME ] && continue
  51. echo -n $user
  52. # if [ -x /etc/local/quota.sh ]; then
  53. # /etc/local/quota.sh $user
  54. # fi
  55. [ $QUOTASOFT ] || QUOTASOFT="0"
  56. [ $QUOTAHARD ] || QUOTAHARD="0"
  57. for QUOTAHOME in $QUOTAHOMES; do
  58. if [ $NEW_QUOTA ]; then
  59. setquota $user $QUOTASOFT $QUOTAHARD 0 0 $QUOTAHOME
  60. else
  61. setquota $user $QUOTAHOME $QUOTASOFT $QUOTAHARD 0 0
  62. fi
  63. done
  64. mkdir -p $HOME/mail
  65. if [ "$USE_MBOX" ]; then
  66. touch $HOME/mail/mbox
  67. elif [ -f $HOME/mail/mbox -a ! -s $HOME/mail/mbox ]; then
  68. rm -f $HOME/mail/mbox
  69. fi
  70. if [ $NETATALK ]; then
  71. mkdir -p $HOME/$mac
  72. fi
  73. if [ $SAMBA ]; then
  74. mkdir -p $HOME/$pc
  75. fi
  76. if [ $XCHANGE ]; then
  77. mkdir -p $XDIRREAL/$user
  78. fi
  79. if [ $PUBLIC ]; then
  80. mkdir -p $HOME/public_html
  81. fi
  82. chown $user: $HOME
  83. chmod u=rwX,go=rX $HOME
  84. # Mail handling
  85. chown -R $user: $HOME/mail
  86. chmod -R u=rw,go=,u+X $HOME/mail
  87. if [ -f $HOME/.mailboxlist ]; then
  88. chown $user: $HOME/.mailboxlist
  89. chmod 0640 $HOME/.mailboxlist
  90. fi
  91. if [ -f $HOME/.forward ]; then
  92. chown $user: $HOME/.forward
  93. chmod 0640 $HOME/.forward
  94. fi
  95. if [ -f /var/mail/$user ]; then
  96. chown $user:mail /var/mail/$user
  97. chmod ug=rw,o= /var/mail/$user
  98. elif [ -f /var/spool/mail/$user ]; then
  99. chown $user:mail /var/spool/mail/$user
  100. chmod ug=rw,o= /var/spool/mail/$user
  101. fi
  102. # MySQL handling
  103. if [ -f $HOME/.my.cnf ]; then
  104. chown $user: $HOME/.my.cnf
  105. chmod 0600 $HOME/.my.cnf
  106. fi
  107. # Mac dir permissions
  108. if [ -d $HOME/$mac ]; then
  109. chown -R $user: $HOME/$mac
  110. chmod -R u=rw,g=r,o=,ug+X $HOME/$mac
  111. rm -rf $HOME/$mac/Network\ Trash\ Folder
  112. mkdir $HOME/$mac/Network\ Trash\ Folder
  113. chown nobody: $HOME/$mac/Network\ Trash\ Folder
  114. chmod a= $HOME/$mac/Network\ Trash\ Folder
  115. fi
  116. # PC dir permissions
  117. if [ -d $HOME/$pc ]; then
  118. chown -R $user: $HOME/$pc
  119. chmod -R u=rw,g=r,o=,ug+X $HOME/$pc
  120. fi
  121. # Exchange dir permissions
  122. if [ -d $XDIRREAL/$user ]; then
  123. chown -R $user:users $XDIRREAL/$user
  124. chmod -R g=r,g+X $XDIRREAL/$user
  125. if [ -e "x$HOME/$xchange" ]; then
  126. if [ -L "x$HOME/$xchange" ]; then
  127. ln -sf $XDIRREAL/$user $HOME/$xchange
  128. else
  129. echo "ERROR: $HOME/$xchange exists already. Leaving it as is..."
  130. fi
  131. else
  132. ln -s $XDIRREAL/$user $HOME/$xchange
  133. fi
  134. fi
  135. # Public dir permissions
  136. if [ -d $HOME/public_html ]; then
  137. chown -R $user: $HOME/public_html
  138. chmod -R u+rX,go=r,go+X $HOME/public_html
  139. if [ $NETATALK ]; then
  140. rm -rf $HOME/public_html/Network\ Trash\ Folder
  141. mkdir $HOME/public_html/Network\ Trash\ Folder
  142. chown nobody: $HOME/public_html/Network\ Trash\ Folder
  143. chmod a= $HOME/public_html/Network\ Trash\ Folder
  144. fi
  145. fi
  146. # Fileshares: <home>/shares.<sharetype>/<rogroup>/<rwgroup>/<sharename>
  147. # <sharetype>: Either mac or win depending on which of netatalk and samba provides r/w access to the shares
  148. # <rwgroup>: Group with write access to the share (usually the default group of the owner)
  149. # <rogroup>: Either rwgroup or secondary group with read-only access to the share
  150. # owner and rwgroup members must be member of both groups
  151. find "$HOME" -mindepth 1 -maxdepth 1 -type d -print | egrep "^$HOME/shares\." | (while read thisdir; do
  152. sharetype="`basename \"$thisdir\" | awk -F. '{print $2}'`"
  153. # Define dir and file exceptions
  154. case "$sharetype" in
  155. mac)
  156. dirs_world_rw_create='.AppleDB'
  157. dirs_group_rw_create='.AppleDesktop/Temporary Items/TheFindByContentFolder'
  158. dirs_group_ro_create='TheVolumeSettingsFolder'
  159. dirs_group_ro_update='.AppleDouble'
  160. files_group_ro_update=':2eDS_Store'
  161. dirs_no_access_purge='Network Trash Folder'
  162. ;;
  163. win)
  164. ;;
  165. *)
  166. continue
  167. ;;
  168. esac
  169. exceptions="$dirs_world_rw_create/$dirs_group_rw_create/$dirs_group_ro_create/$dirs_group_ro_update/$files_group_ro_update/$dirs_no_access_purge"
  170. exception_dirs_create="$dirs_world_rw_create/$dirs_group_rw_create/$dirs_group_ro_create"
  171. chown "$user": "$thisdir"
  172. chmod a=rX "$thisdir"
  173. find "$thisdir" -mindepth 1 -maxdepth 1 -type d -print | (while read thisdir; do
  174. rogroup="`basename \"$thisdir\"`"
  175. chown "$user":"$rogroup" "$thisdir"
  176. chmod ug=rX,o= "$thisdir"
  177. find "$thisdir" -mindepth 1 -maxdepth 1 -type d -print | (while read thisdir; do
  178. rwgroup="`basename \"$thisdir\"`"
  179. chown "$user":"$rwgroup" "$thisdir"
  180. chmod a=rX,g+s "$thisdir"
  181. find "$thisdir" -mindepth 1 -maxdepth 1 -type d -print | (while read thisdir; do
  182. sharename="`basename \"$thisdir\"`"
  183. chown "$user":"$rwgroup" "$thisdir"
  184. chmod u=rw,go=r,a+X,g+s "$thisdir"
  185. ifs="$IFS"
  186. # Set default permissions
  187. find "$thisdir" -mindepth 1 -maxdepth 1 -print | (while read thisdir; do
  188. item="`basename \"$thisdir\"`"
  189. IFS="/"; for exception in $exceptions; do IFS="$ifs";
  190. if [ "$item" = "$exception" ]; then
  191. continue 2
  192. fi
  193. done
  194. chgrp -R "$rwgroup" "$thisdir"
  195. chmod -R ug=rw,o=r,a+X,g+s "$thisdir"
  196. done)
  197. # Handle exception dirs to be created if not existing
  198. IFS="/"; for dir in $exception_dirs_create; do IFS="$ifs";
  199. if [ ! -d "$thisdir/$dir" ]; then
  200. rm -f "$thisdir/$dir"
  201. fi
  202. if [ ! -e "$thisdir/$dir" ]; then
  203. mkdir "$thisdir/$dir"
  204. fi
  205. chown "$user":"$rwgroup" "$thisdir/$dir"
  206. done
  207. IFS="/"; for dir in $dirs_world_rw_create; do IFS="$ifs";
  208. if [ "$rogroup" = "$rwgroup" ]; then
  209. chmod -R ug=rw,o=r,a+X,g+s "$thisdir/$dir"
  210. else
  211. chmod -R a=rw,a+X,g+s "$thisdir/$dir"
  212. fi
  213. done
  214. IFS="/"; for dir in $dirs_group_rw_create; do IFS="$ifs";
  215. chmod -R ug=rw,o=r,a+X,g+s "$thisdir/$dir"
  216. done
  217. IFS="/"; for dir in $dirs_group_ro_create; do IFS="$ifs";
  218. chmod -R u=rw,go=r,a+X,g+s "$thisdir/$dir"
  219. done
  220. # Handle exception dirs to be updated if already there
  221. IFS="/"; for dir in $dirs_group_ro_update; do IFS="$ifs";
  222. if [ -e "$thisdir/$dir" ]; then
  223. chmod u=rw,go=r,a+X,g+s "$thisdir/$dir"
  224. fi
  225. done
  226. # Handle exception files to be updated if already there
  227. IFS="/"; for file in $files_group_ro_update; do IFS="$ifs";
  228. if [ -e "$thisdir/$file" ]; then
  229. chmod u=rw,go=r,g+s "$thisdir/$file"
  230. fi
  231. done
  232. # Handle exception dirs to be purged and recreated
  233. IFS="/"; for dir in $dirs_no_access_purge; do IFS="$ifs";
  234. rm -rf "$thisdir/$dir"
  235. mkdir -m a= "$thisdir/$dir"
  236. chown nobody: "$thisdir/$dir"
  237. done
  238. IFS="$ifs"
  239. done)
  240. done)
  241. done)
  242. done)
  243. # Deprecated share permissions
  244. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/shares_win"`; do
  245. chgrp -R $user $dir
  246. chmod -R u=rw,g=rw,o=,ug+X,g+s $dir
  247. done
  248. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/shares_mac"`; do
  249. chgrp -R $user $dir
  250. chmod -R u=rw,g=rw,o=,ug+X,g+s $dir
  251. rm -rf $dir/Network\ Trash\ Folder
  252. mkdir $dir/Network\ Trash\ Folder
  253. chown nobody: $dir/Network\ Trash\ Folder
  254. chmod a= $dir/Network\ Trash\ Folder
  255. done
  256. # Ftp shares permissions
  257. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/ftp_$USER$"`; do
  258. chgrp -R $user $dir
  259. chmod -R ug=rw,o=r,a+X,g+s $dir
  260. rm -rf $dir/Network\ Trash\ Folder
  261. mkdir $dir/Network\ Trash\ Folder
  262. chown nobody: $dir/Network\ Trash\ Folder
  263. chmod a= $dir/Network\ Trash\ Folder
  264. done
  265. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/ftp_${USER}_ro$"`; do
  266. chown -R $user: $dir
  267. chmod -R u=rw,go=r,a+X $dir
  268. rm -rf $dir/Network\ Trash\ Folder
  269. mkdir $dir/Network\ Trash\ Folder
  270. chown nobody: $dir/Network\ Trash\ Folder
  271. chmod a= $dir/Network\ Trash\ Folder
  272. done
  273. # Web shares permissions
  274. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/web_"`; do
  275. chown -R $user: $dir
  276. # chmod -R u=rw,go=r,a+X $webdir
  277. #TODO: Only cgi scripts (.cgi and .pl) should be executable
  278. chmod -R u+rw,go+r,a+X $dir
  279. # leftover from ancient times with another policy
  280. if [ $NETATALK ]; then
  281. rm -rf $dir/Network\ Trash\ Folder
  282. fi
  283. done
  284. # Web shares permissions
  285. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/websites"`; do
  286. chown root: $dir
  287. chmod a=r,u+w,a+X $dir
  288. done
  289. for dir in `find $HOME -mindepth 2 -maxdepth 2 -type d | egrep "^$HOME/websites/"`; do
  290. chown -R $user: $dir
  291. # chmod -R u=rw,go=r,a+X $webdir
  292. #TODO: Only cgi scripts (.cgi and .pl) should be executable
  293. chmod -R u+rw,go+r,a+X $dir
  294. # leftover from ancient times with another policy
  295. if [ $NETATALK ]; then
  296. rm -rf $dir/Network\ Trash\ Folder
  297. fi
  298. done
  299. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/webscripts"`; do
  300. chown root: $dir
  301. chmod a=r,u+w,a+X $dir
  302. done
  303. for dir in `find $HOME -mindepth 2 -maxdepth 2 -type d | egrep "^$HOME/webscripts/"`; do
  304. chown -R $user: $dir
  305. # chmod -R u=rw,go=r,a+X $webdir
  306. #TODO: Only cgi scripts (.cgi and .pl) should be executable
  307. chmod -R u+rw,go+r,a+X $dir
  308. done
  309. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/webdata"`; do
  310. chown $user: $dir
  311. chmod a=r,u+w,a+X $dir
  312. done
  313. for dir in `find $HOME -mindepth 2 -maxdepth 2 -type d | egrep "^$HOME/webdata/"`; do
  314. chown -R $user: $dir
  315. chmod -R u=rw,go=,u+X $dir
  316. done
  317. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/webshareddata"`; do
  318. chown $user: $dir
  319. chmod a=r,u+w,a+X $dir
  320. done
  321. for dir in `find $HOME -mindepth 2 -maxdepth 2 -type d | egrep "^$HOME/webshareddata/"`; do
  322. chown -R $user: $dir
  323. chmod -R u=rw,go=r,a+X $dir
  324. done
  325. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/webphpsites"`; do
  326. chown root: $dir
  327. chmod u=rw,go=r,a+X $dir
  328. done
  329. for dir in `find $HOME -mindepth 2 -maxdepth 2 -type d | egrep "^$HOME/webphpsites/"`; do
  330. chown -R $user:www-data $dir
  331. # chmod -R ug=rw,o=r,a+X $dir
  332. chmod -R ug=rw,o=,ug+X $dir
  333. done
  334. for dir in `find $HOME -mindepth 1 -maxdepth 1 -type d | egrep "^$HOME/webphpdata"`; do
  335. chown root: $dir
  336. chmod a=r,u+w,a+X $dir
  337. done
  338. for dir in `find $HOME -mindepth 2 -maxdepth 2 -type d | egrep "^$HOME/webphpdata/"`; do
  339. chown -R $user:www-data $dir
  340. chmod -R ug=rw,o=,ug+X $dir
  341. done
  342. # Dummy user restrictions
  343. if [ -n "$REALUSERS_GROUPNAME" -a -n "$DUMMYSHAREDIR" -a -n "$DUMMYSHAREOWNER" -a -n "$DUMMYSHARENAME" ]; then
  344. [ -e $DUMMYSHAREDIR/$user ] \
  345. || mkdir $DUMMYSHAREDIR/$user
  346. chown $DUMMYSHAREOWNER: $DUMMYSHAREDIR/$user
  347. chmod u=rw,go=r,a+X $DUMMYSHAREDIR/$user
  348. if [ -e $HOME/$DUMMYSHARENAME ]; then
  349. if [ -L $HOME/$DUMMYSHARENAME ]; then
  350. ln -sf $DUMMYSHAREDIR/$user $HOME/$DUMMYSHARENAME
  351. chown $user: $HOME/$DUMMYSHARENAME
  352. else
  353. echo "WARNING: $HOME/$DUMMYSHAREDIR exists already. Leaving it as is..."
  354. fi
  355. else
  356. ln -s $DUMMYSHAREDIR/$user $HOME/$DUMMYSHARENAME
  357. chown $user: $HOME/$DUMMYSHARENAME
  358. fi
  359. if [ -n "$DUMMYAPACHECFG" -a -n "$DUMMYAPACHESHAREDIR" ]; then
  360. if [ -f /etc/apache/include.d/$DUMMYAPACHECFG -a -x /etc/init.d/apache ]; then
  361. if [ -e /etc/apache/include.d/$DUMMYAPACHECFG-$user ]; then
  362. echo "/etc/apache/include.d/$DUMMYAPACHECFG-$user exists already. Ignoring..."
  363. else
  364. echo "# Created automatically by adduser.local
  365. <Location /$DUMMYAPACHESHAREDIR/$user>
  366. <Limit GET POST>
  367. require user $user
  368. </Limit>
  369. </Location>" \
  370. > /etc/apache/include.d/$DUMMYAPACHECFG-$user
  371. apache_reload_needed="1"
  372. fi
  373. fi
  374. fi
  375. fi
  376. echo "."
  377. done
  378. if [ $XCHANGE ]; then
  379. for USER in $(ls $XDIRREAL); do
  380. id $user >/dev/null 2>&1 || rm -rf $XDIRREAL/$user
  381. done
  382. fi
  383. if [ "$apache_reload_needed" ]; then
  384. apache_do_reload=""
  385. case runmode in
  386. interactive)
  387. echo -n "Apache config changed. Reload Apache now (Y/n)? "
  388. read apache_reload
  389. case $apache_reload in
  390. y|Y|"")
  391. apache_do_reload="1"
  392. ;;
  393. esac
  394. ;;
  395. force)
  396. apache_do_reload="1"
  397. ;;
  398. *)
  399. echo "Apache config has changed. Remember to reload Apache...!"
  400. ;;
  401. esac
  402. if "$apache_do_reload" ]; then
  403. /etc/init.d/apache force-reload
  404. fi
  405. fi