2 # (C) 2008 Canonical Ltd.
3 # Author: Martin Pitt <martin.pitt@ubuntu.com>
4 # License: GPL v2 or later
5 # modified by David D Lowe and Thomas Detoux
7 # Setup user and temporary home directory for guest session.
8 # If this succeeds, this script needs to print the username as the last line to
11 export TEXTDOMAINDIR=/usr/share/locale-langpack
12 export TEXTDOMAIN=lightdm
14 # set the system wide locale for gettext calls
15 if [ -f /etc/default/locale ]; then
23 UID_MIN=$(cat /etc/login.defs | grep UID_MIN | awk '{print $2}')
24 SYS_UID_MIN=$(cat /etc/login.defs | grep SYS_UID_MIN | awk '{print $2}')
25 SYS_UID_MAX=$(cat /etc/login.defs | grep SYS_UID_MAX | awk '{print $2}')
27 SYS_UID_MIN=${SYS_UID_MIN:-101}
28 SYS_UID_MAX=${SYS_UID_MAX:-$(( UID_MIN - 1 ))}
30 [ ${1} -ge ${SYS_UID_MIN} ] && [ ${1} -le ${SYS_UID_MAX} ]
35 temp_home=$(mktemp -td guest-XXXXXX)
36 GUEST_HOME=$(echo ${temp_home} | tr '[:upper:]' '[:lower:]')
37 GUEST_USER=${GUEST_HOME#/tmp/}
38 [ ${GUEST_HOME} != ${temp_home} ] && mv ${temp_home} ${GUEST_HOME}
40 # if ${GUEST_USER} already exists, it must be a locked system account with no existing
42 if PWSTAT=$(passwd -S ${GUEST_USER}) 2>/dev/null; then
43 if [ $(echo ${PWSTAT} | cut -f2 -d' ') != L ]; then
44 echo "User account ${GUEST_USER} already exists and is not locked"
48 PWENT=$(getent passwd ${GUEST_USER}) || {
49 echo "getent passwd ${GUEST_USER} failed"
53 GUEST_UID=$(echo ${PWENT} | cut -f3 -d:)
55 if ! is_system_user ${GUEST_UID}; then
56 echo "Account ${GUEST_USER} is not a system user"
60 GUEST_HOME=$(echo ${PWENT} | cut -f6 -d:)
62 if [ ${GUEST_HOME} != / ] && [ ${GUEST_HOME#/tmp} = ${GUEST_HOME} ] && [ -d ${GUEST_HOME} ]; then
63 echo "Home directory of ${GUEST_USER} already exists"
67 # does not exist, so create it
68 useradd --system --home-dir ${GUEST_HOME} --comment $(gettext "Guest") --user-group --shell /bin/bash ${GUEST_USER} || {
74 dist_gs=/usr/share/lightdm/guest-session
75 site_gs=/etc/guest-session
77 # create temporary home directory
78 mount -t tmpfs -o mode=700,uid=${GUEST_USER} none ${GUEST_HOME} || {
83 if [ -d ${site_gs}/skel ] && [ "$(ls -A ${site_gs}/skel)" ]; then
84 # Only perform union-mounting if BindFS is available
85 if [ -x /usr/bin/bindfs ]; then
89 if modinfo -n overlay >/dev/null 2>&1; then
90 mkdir ${GUEST_HOME}/upper ${GUEST_HOME}/work
91 chown ${GUEST_USER}:${GUEST_USER} ${GUEST_HOME}/upper ${GUEST_HOME}/work
93 mount -t overlay -o lowerdir=${dist_gs}/skel:${site_gs}/skel,upperdir=${GUEST_HOME}/upper,workdir=${GUEST_HOME}/work overlay ${GUEST_HOME} || {
98 # If OverlayFS is not available, try AuFS
99 elif [ -x /sbin/mount.aufs ]; then
100 mount -t aufs -o br=${GUEST_HOME}:${dist_gs}/skel:${site_gs}/skel none ${GUEST_HOME} || {
105 # If none of them is available, fall back to copy over
107 cp -rT ${site_gs}/skel/ ${GUEST_HOME}
108 cp -rT ${dist_gs}/skel/ ${GUEST_HOME}
109 chown -R ${GUEST_USER}:${GUEST_USER} ${GUEST_HOME}
113 if ${bindfs_mount}; then
114 # Wrap ${GUEST_HOME} in a BindFS mount, so that
115 # ${GUEST_USER} will be seen as the owner of ${GUEST_HOME}'s contents.
116 bindfs -u ${GUEST_USER} -g ${GUEST_USER} ${GUEST_HOME} ${GUEST_HOME} || {
117 umount ${GUEST_HOME} # union mount
118 umount ${GUEST_HOME} # tmpfs mount
123 # If BindFS is not available, just fall back to copy over
125 cp -rT ${site_gs}/skel/ ${GUEST_HOME}
126 cp -rT ${dist_gs}/skel/ ${GUEST_HOME}
127 chown -R ${GUEST_USER}:${GUEST_USER} ${GUEST_HOME}
130 cp -rT /etc/skel/ ${GUEST_HOME}
131 cp -rT ${dist_gs}/skel/ ${GUEST_HOME}
132 chown -R ${GUEST_USER}:${GUEST_USER} ${GUEST_HOME}
136 su ${GUEST_USER} -c "env HOME=${GUEST_HOME} site_gs=${site_gs} ${dist_gs}/setup.sh"
138 # set possible local guest session preferences
139 source_local_prefs() {
140 local USER=${GUEST_USER}
141 local HOME=${GUEST_HOME}
142 . ${site_gs}/prefs.sh
143 chown -R ${USER}:${USER} ${HOME}
145 if [ -f ${site_gs}/prefs.sh ]; then
156 PWENT=$(getent passwd ${GUEST_USER}) || {
157 echo "Error: invalid user ${GUEST_USER}"
161 GUEST_UID=$(echo ${PWENT} | cut -f3 -d:)
163 if ! is_system_user ${GUEST_UID}; then
164 echo "Error: user ${GUEST_USER} is not a system user."
168 GUEST_HOME=$(echo ${PWENT} | cut -f6 -d:)
170 # kill all remaining processes
171 if [ -x /bin/loginctl ] || [ -x /usr/bin/loginctl ]; then
172 loginctl --signal=9 kill-user ${GUEST_USER} >/dev/null || true
174 while ps h -u ${GUEST_USER} >/dev/null
176 killall -9 -u ${GUEST_USER} || true
181 if [ ${GUEST_HOME} = ${GUEST_HOME#/tmp/} ]; then
182 echo "Warning: home directory ${GUEST_HOME} is not in /tmp/. It won't be removed."
184 umount ${GUEST_HOME} || umount -l ${GUEST_HOME} || true # BindFS mount
185 umount ${GUEST_HOME} || umount -l ${GUEST_HOME} || true # union mount
186 umount ${GUEST_HOME} || umount -l ${GUEST_HOME} || true # tmpfs mount
190 # remove leftovers in /tmp
191 find /tmp -mindepth 1 -maxdepth 1 -uid ${GUEST_UID} -print0 | xargs -0 rm -rf || true
193 # remove possible {/run,}/media/guest-XXXXXX folder
194 for media_dir in /run/media/${GUEST_USER} /media/${GUEST_USER}; do
195 if [ -d ${media_dir} ]; then
196 for dir in $(find ${media_dir} -mindepth 1 -maxdepth 1); do
197 umount ${dir} || true
200 rmdir ${media_dir} || true
204 userdel --force ${GUEST_USER}
212 if [ -z ${2} ] ; then
213 echo "Usage: ${0} remove [account]"
220 echo "Usage: ${0} add"
221 echo " ${0} remove [account]"