]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - debian/guest-account.sh
Releasing 1.17.0
[sojka/lightdm.git] / debian / guest-account.sh
1 #!/bin/sh -e
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
6 #
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
9 # stdout.
10
11 export TEXTDOMAINDIR=/usr/share/locale-langpack
12 export TEXTDOMAIN=lightdm
13
14 # set the system wide locale for gettext calls
15 if [ -f /etc/default/locale ]; then
16   . /etc/default/locale
17   LANGUAGE=
18   export LANG LANGUAGE
19 fi
20
21 add_account ()
22 {
23   HOME=$(mktemp -td guest-XXXXXX)
24   USER=$(echo ${HOME} | sed 's/\(.*\)guest/guest/')
25
26   # if ${USER} already exists, it must be a locked system account with no existing
27   # home directory
28   if PWSTAT=$(passwd -S ${USER}) 2>/dev/null; then
29     if [ $(echo ${PWSTAT} | cut -f2 -d' ') != L ]; then
30       echo "User account ${USER} already exists and is not locked"
31       exit 1
32     fi
33     PWENT=$(getent passwd ${USER}) || {
34       echo "getent passwd ${USER} failed"
35       exit 1
36     }
37     GUEST_UID=$(echo ${PWENT} | cut -f3 -d:)
38     if [ ${GUEST_UID} -ge 500 ]; then
39       echo "Account ${USER} is not a system user"
40       exit 1
41     fi
42     HOME=$(echo ${PWENT} | cut -f6 -d:)
43     if [ ${HOME} != / ] && [ ${HOME#/tmp} = ${HOME} ] && [ -d ${HOME} ]; then
44       echo "Home directory of ${USER} already exists"
45       exit 1
46     fi
47   else
48     # does not exist, so create it
49     adduser --system --no-create-home --home / --gecos $(gettext "Guest") --group --shell /bin/bash ${USER} || {
50       umount ${HOME}
51       rm -rf ${HOME}
52       exit 1
53     }
54   fi
55
56   dist_gs=/usr/share/lightdm/guest-session
57   site_gs=/etc/guest-session
58
59   # create temporary home directory
60   mount -t tmpfs -o mode=700,uid=${USER} none ${HOME} || {
61     rm -rf ${HOME}
62     exit 1
63   }
64
65   if [ -d ${site_gs}/skel ] && [ -n $(find ${site_gs}/skel -type f) ]; then
66     # Only perform union-mounting if BindFS is available
67     if [ -x /usr/bin/bindfs ]; then
68       bindfs_mount=true
69
70       # Try OverlayFS first
71       if modinfo -n overlay >/dev/null 2>&1; then
72         mkdir ${HOME}/upper ${HOME}/work
73         chown ${USER}:${USER} ${HOME}/upper ${HOME}/work
74         mount -t overlay -o lowerdir=${dist_gs}/skel:${site_gs}/skel,upperdir=${HOME}/upper,workdir=${HOME}/work overlay ${HOME} || {
75           umount ${HOME}
76           rm -rf ${HOME}
77           exit 1
78         }
79       # If OverlayFS is not available, try AuFS
80       elif [ -x /sbin/mount.aufs ]; then
81         mount -t aufs -o br=${HOME}:${dist_gs}/skel:${site_gs}/skel none ${HOME} || {
82           umount ${HOME}
83           rm -rf ${HOME}
84           exit 1
85         }
86       # If none of them is available, fall back to copy over
87       else
88         cp -rT ${site_gs}/skel/ ${HOME}
89         cp -rT ${dist_gs}/skel/ ${HOME}
90         chown -R ${USER}:${USER} ${HOME}
91         bindfs_mount=false
92       fi
93
94       if ${bindfs_mount}; then
95         # Wrap ${HOME} in a BindFS mount, so that
96         # ${USER} will be seen as the owner of ${HOME}'s contents.
97         bindfs -u ${USER} -g ${USER} ${HOME} ${HOME} || {
98           umount ${HOME} # union mount
99           umount ${HOME} # tmpfs mount
100           rm -rf ${HOME}
101           exit 1
102         }
103       fi
104     # If BindFS is not available, just fall back to copy over
105     else
106       cp -rT ${site_gs}/skel/ ${HOME}
107       cp -rT ${dist_gs}/skel/ ${HOME}
108       chown -R ${USER}:${USER} ${HOME}
109     fi
110   else
111     cp -rT /etc/skel/ ${HOME}
112     cp -rT ${dist_gs}/skel/ ${HOME}
113     chown -R ${USER}:${USER} ${HOME}
114   fi
115
116   usermod -d ${HOME} ${USER}
117
118   # setup session
119   su ${USER} -c "env HOME=${HOME} site_gs=${site_gs} ${dist_gs}/setup.sh"
120
121   echo ${USER}
122 }
123
124 remove_account ()
125 {
126   GUEST_USER=${1}
127   
128   PWENT=$(getent passwd ${GUEST_USER}) || {
129     echo "Error: invalid user ${GUEST_USER}"
130     exit 1
131   }
132   GUEST_UID=$(echo ${PWENT} | cut -f3 -d:)
133   GUEST_HOME=$(echo ${PWENT} | cut -f6 -d:)
134
135   if [ ${GUEST_UID} -ge 500 ]; then
136     echo "Error: user ${GUEST_USER} is not a system user."
137     exit 1
138   fi
139
140   if [ ${GUEST_HOME} = ${GUEST_HOME#/tmp/} ]; then
141     echo "Error: home directory ${GUEST_HOME} is not in /tmp/."
142     exit 1
143   fi
144
145   # kill all remaining processes
146   while ps h -u ${GUEST_USER} >/dev/null; do 
147     killall -9 -u ${GUEST_USER} || true
148     sleep 0.2; 
149   done
150
151   umount ${GUEST_HOME} || umount -l ${GUEST_HOME} || true # BindFS mount
152   umount ${GUEST_HOME} || umount -l ${GUEST_HOME} || true # union mount
153   umount ${GUEST_HOME} || umount -l ${GUEST_HOME} || true # tmpfs mount
154   rm -rf ${GUEST_HOME}
155
156   # remove leftovers in /tmp
157   find /tmp -mindepth 1 -maxdepth 1 -uid ${GUEST_UID} -print0 | xargs -0 rm -rf || true
158
159   # remove possible /media/guest-XXXXXX folder
160   if [ -d /media/${GUEST_USER} ]; then
161     for dir in $(find /media/${GUEST_USER} -mindepth 1 -maxdepth 1); do
162       umount ${dir} || true
163     done
164
165     rmdir /media/${GUEST_USER} || true
166   fi
167
168   deluser --system ${GUEST_USER}
169 }
170
171 case ${1} in
172   add)
173     add_account
174     ;;
175   remove)
176     if [ -z ${2} ] ; then
177       echo "Usage: ${0} remove [account]"
178       exit 1
179     fi
180     remove_account ${2}
181     ;;
182   *)
183     echo "Usage: ${0} add|remove"
184     exit 1
185 esac