bt-audio: check for presence of snd-bt-sco
[grml-scripts.git] / usr_sbin / make_chroot_jail
1 #!/bin/sh
2 #
3 # (c) Copyright by Wolfgang Fuschlberger
4 #
5 #    This program is free software; you can redistribute it and/or modify
6 #    it under the terms of the GNU General Public License as published by
7 #    the Free Software Foundation; either version 2 of the License, or
8 #    (at your option) any later version.
9 #
10 #    This program is distributed in the hope that it will be useful,
11 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #    GNU General Public License for more details.
14 #    ( http://www.fsf.org/licenses/gpl.txt )
15
16 # first Release: 2004-07-30
17 # latest update: 2007-02-24
18 #
19 # The latest version of the script is available at
20 #   http://www.fuschlberger.net/programs/ssh-scp-chroot-jail/
21 #
22 # Feedback is welcome!
23 #
24 # Thanks for Bugfixes / Enhancements to 
25 # Michael Prokop <http://www.michael-prokop.at/chroot/>,
26 # Randy K., Randy D. and Jonathan Hunter.
27
28 #
29 # Features:
30 # - enable scp and sftp in the chroot-jail
31 # - use one directory (default /home/jail/) as chroot for all users
32 # - create new accounts
33 # - move existing accounts to chroot
34 ################################################################################
35
36 # Check if we are called with username or update
37 if [ -z "$1" ] ; then
38   echo
39   echo "Error: Parameter missing. Did you forget the username?"
40   echo "-------------------------------------------------------------"
41   echo "Creating new chrooted account:"
42   echo "Usage: $0 username"
43   echo
44   echo "or specify \$SHELL and path where the jail should be located:"
45   echo "Usage: $0 username [/path/to/chroot-shell [/path/to/jail]]"
46   echo "Default shell       = /bin/chroot-shell"
47   echo "Default chroot-path = /home/jail"
48   echo "-------------------------------------------------------------"
49   echo "Updating files in the chroot-jail:"
50   echo "Usage: $0 update [/path/to/chroot-shell [/path/to/jail]]"
51   echo "-------------------------------------------------------------"
52   echo "To uninstall: # userdel \$USER"
53   echo "              # rm -rf /home/jail"
54   echo "              # rm -f /bin/chroot-shell"
55   echo "              delete the User's line from /etc/sudoers"
56   exit
57 fi
58
59 echo "Am I root?  "
60 if [ "$(whoami &2>/dev/null)" != "root" ] && [ "$(id -un &2>/dev/null)" != "root" ] ; then
61   echo "  NO!
62
63 Error: You must be root to run this script."
64   exit 1
65 fi
66 echo "  OK";
67
68 # Check existence of necessary files
69 echo "Checking distribution... "
70 if [ -f /etc/debian_version ];
71   then echo "  Supported Distribution found"
72        echo "  System is running Debian Linux"
73        DISTRO=DEBIAN;
74 elif [ -f /etc/SuSE-release ];
75   then echo "  Supported Distribution found"
76        echo "  System is running SuSE Linux"
77        DISTRO=SUSE;
78 elif [ -f /etc/fedora-release ];
79   then echo "  Supported Distribution found"
80        echo "  System is running Fedora Linux"
81        DISTRO=FEDORA;
82 elif [ -f /etc/redhat-release ];
83   then echo "  Supported Distribution found"
84        echo "  System is running Red Hat Linux"
85        DISTRO=REDHAT;
86 else echo -e "  failed...........\nThis script works best on Debian, Red Hat, Fedora and SuSE Linux!\nLet's try it nevertheless....\nIf some program files cannot be found adjust the respective path in line 98\n"
87 #exit 1
88 fi
89
90 # Specify the apps you want to copy to the jail
91 if [ "$DISTRO" = SUSE ]; then
92   APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/netcat /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd"
93 elif [ "$DISTRO" = FEDORA ]; then
94   APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/nc /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd"
95 elif [ "$DISTRO" = REDHAT ]; then
96   APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/nc /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd"
97 elif [ "$DISTRO" = DEBIAN ]; then
98   APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd"
99 else
100   APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /usr/sbin/unix_chkpwd"
101 fi
102
103 # Check existence of necessary files
104 echo "Checking for which... " 
105 if ( test -f /usr/bin/which ) || ( test -f /bin/which ) || ( test -f /sbin/which ) || ( test -f /usr/sbin/which );
106   then echo "  OK";
107   else echo "  failed
108
109 Please install which-binary!
110 "
111 exit 1
112 fi
113
114 echo "Checking for chroot..." 
115 if [ `which chroot` ];
116   then echo "  OK";
117   else echo "  failed
118
119 chroot not found!
120 Please install chroot-package/binary!
121 "
122 exit 1
123 fi
124
125 echo "Checking for sudo..." 
126 if [ `which sudo` ]; then
127   echo "  OK";
128 else 
129   echo "  failed
130
131 sudo not found!
132 Please install sudo-package/binary!
133 "
134 exit 1
135 fi
136
137 echo "Checking for dirname..." 
138 if [ `which dirname` ]; then
139   echo "  OK";
140 else 
141   echo "  failed
142
143 dirname not found!
144 Please install dirname-binary (to be found eg in the package coreutils)!
145 "
146 exit 1
147 fi
148
149 echo "Checking for awk..." 
150 if [ `which awk` ]; then
151   echo "  OK
152 ";
153 else 
154   echo "  failed
155
156 awk not found!
157 Please install (g)awk-package/binary!
158 "
159 exit 1
160 fi
161
162 # get location of sftp-server binary from /etc/ssh/sshd_config
163 # check for existence of /etc/ssh/sshd_config and for
164 # (uncommented) line with sftp-server filename. If neither exists, just skip
165 # this step and continue without sftp-server
166 #
167 if  (test ! -f /etc/ssh/sshd_config &> /dev/null); then
168   echo "
169 File /etc/ssh/sshd_config not found.
170 Not checking for path to sftp-server.
171   ";
172 else
173   if !(grep -v "^#" /etc/ssh/sshd_config | grep -i sftp-server &> /dev/null); then
174     echo "Obviously no sftp-server is running on this system.
175 ";
176   else SFTP_SERVER=$(grep -v "^#" /etc/ssh/sshd_config | grep -i sftp-server | awk  '{ print $3}')
177   fi
178 fi
179
180 #if !(grep -v "^#" /etc/ssh/sshd_config | grep -i sftp-server /etc/ssh/sshd_config | awk  '{ print $3}' &> /dev/null); then
181 APPS="$APPS $SFTP_SERVER"
182
183 # Get accountname to create
184 CHROOT_USERNAME=$1
185
186 if ! [ -z "$2" ] ; then
187   SHELL=$2
188 else
189   SHELL=/bin/chroot-shell
190 fi
191
192 if ! [ -z "$3" ] ; then
193   JAILPATH=$3
194 else
195   JAILPATH=/home/jail
196 fi
197
198 # Exit if user already exists
199 #id $CHROOT_USERNAME > /dev/null 2>&1 && { echo "User exists."; echo "Exiting."; exit 1; }
200 if ( id $CHROOT_USERNAME > /dev/null 2>&1 ) ; then {
201 echo "
202 -----------------------------
203 User $CHROOT_USERNAME exists. 
204
205 Are you sure you want to modify the users home directory and lock him into the
206 chroot directory?
207 Are you REALLY sure?
208 Say only yes if you absolutely know what you are doing!"
209   read -p "(yes/no) -> " MODIFYUSER
210   if [ "$MODIFYUSER" != "yes" ]; then
211     echo "
212 Not entered yes. Exiting...."
213     exit 1
214   fi
215 }
216 else
217   CREATEUSER="yes"
218 fi
219
220 # Create $SHELL (shell for jailed accounts)
221 if [ -f ${SHELL} ] ; then
222   echo "
223 -----------------------------
224 The file $SHELL exists. 
225 Probably it was created by this script.
226
227 Are you sure you want to overwrite it?
228 (you want to say yes for example if you are running the script for the second
229 time when adding more than one account to the jail)"
230 read -p "(yes/no) -> " OVERWRITE
231 if [ "$OVERWRITE" != "yes" ]; then
232   echo "
233 Not entered yes. Exiting...."
234   exit 1
235 fi
236 else
237   echo "Creating $SHELL"
238   echo '#!/bin/sh' > $SHELL
239   echo "`which sudo` `which chroot` $JAILPATH /bin/su - \$USER" \"\$@\" >> $SHELL
240   chmod 755 $SHELL
241 fi
242
243 # make common jail for everybody if inexistent
244 if [ ! -d ${JAILPATH} ] ; then
245   mkdir -p ${JAILPATH}
246   echo "Creating ${JAILPATH}"
247 fi
248 cd ${JAILPATH}
249
250 # Create directories in jail that do not exist yet
251 JAILDIRS="dev etc etc/pam.d bin home sbin usr usr/bin usr/lib"
252 for directory in $JAILDIRS ; do
253   if [ ! -d "$JAILPATH/$directory" ] ; then
254     mkdir $JAILPATH/"$directory"
255     echo "Creating $JAILPATH/$directory"
256   fi
257 done
258 echo
259
260 # Comment in the following lines if your apache can't read the directories and
261 # uses the security contexts
262 # Fix security contexts so Apache can read files
263 #CHCON=$(`which chcon`)
264 #if [ -n "$CHCON" ] && [ -x $CHCON ]; then
265 #    $CHCON -t home_root_t $JAILPATH/home
266 #    $CHCON -t user_home_dir_t $JAILPATH/home/$CHROOT_USERNAME
267 #fi
268
269 # Creating necessary devices
270 [ -r $JAILPATH/dev/urandom ] || mknod $JAILPATH/dev/urandom c 1 9
271 [ -r $JAILPATH/dev/null ]    || mknod -m 666 $JAILPATH/dev/null    c 1 3
272 [ -r $JAILPATH/dev/zero ]    || mknod -m 666 $JAILPATH/dev/zero    c 1 5
273 [ -r $JAILPATH/dev/tty ]     || mknod -m 666 $JAILPATH/dev/tty     c 5 0 
274
275 # if we only want to update the files in the jail
276 # skip the creation of the new account
277 if [ "$1" != "update" ]; then
278
279 # Modifiy /etc/sudoers to enable chroot-ing for users
280 # must be removed by hand if account is deleted
281 echo "Modifying /etc/sudoers"
282 echo "$CHROOT_USERNAME       ALL=NOPASSWD: `which chroot`, /bin/su - $CHROOT_USERNAME" >> /etc/sudoers
283
284 # Define HomeDir for simple referencing
285 HOMEDIR="$JAILPATH/home/$CHROOT_USERNAME"
286
287 # Create new account, setting $SHELL to the above created script and
288 # $HOME to $JAILPATH/home/*
289 if [ "$CREATEUSER" != "yes" ] ; then echo "
290 Not creating new User account
291 Modifying User \"$CHROOT_USERNAME\" 
292 Copying files in $CHROOT_USERNAME's \$HOME to \"$HOMEDIR\"
293 "
294 usermod -d "$HOMEDIR" -m -s "$SHELL" $CHROOT_USERNAME && chmod 700 "$HOMEDIR"
295 fi
296
297 if [ "$CREATEUSER" = "yes" ] ; then {
298 echo "Adding User \"$CHROOT_USERNAME\" to system"
299 useradd -m -d "$HOMEDIR" -s "$SHELL" $CHROOT_USERNAME && chmod 700 "$HOMEDIR"
300
301 # Enter password for new account
302 if !(passwd $CHROOT_USERNAME);
303   then echo "Passwords are probably not the same, try again."
304   exit 1;
305 fi
306 echo
307 }
308 fi
309
310 # Create /usr/bin/groups in the jail
311 echo "#!/bin/bash" > usr/bin/groups
312 echo "id -Gn" >> usr/bin/groups
313 chmod 755 usr/bin/groups
314
315 # Add users to etc/passwd
316 #
317 # check if file exists (ie we are not called for the first time)
318 # if yes skip root's entry and do not overwrite the file
319 if [ ! -f etc/passwd ] ; then
320  grep /etc/passwd -e "^root" > ${JAILPATH}/etc/passwd
321 fi
322 if [ ! -f etc/group ] ; then
323  grep /etc/group -e "^root" > ${JAILPATH}/etc/group
324 # add the group for all users to etc/group (otherwise there is a nasty error
325 # message and probably because of that changing directories doesn't work with
326 # winSCP)
327  grep /etc/group -e "^users" >> ${JAILPATH}/etc/group
328 fi
329
330 # grep the username which was given to us from /etc/passwd and add it
331 # to ./etc/passwd replacing the $HOME with the directory as it will then 
332 # appear in the jail
333 echo "Adding User $CHROOT_USERNAME to jail"
334 grep -e "^$CHROOT_USERNAME:" /etc/passwd | \
335  sed -e "s#$JAILPATH##"      \
336      -e "s#$SHELL#/bin/bash#"  >> ${JAILPATH}/etc/passwd
337
338 # if the system uses one account/one group we write the
339 # account's group to etc/group
340 grep -e "^$CHROOT_USERNAME:" /etc/group >> ${JAILPATH}/etc/group
341
342 # write the user's line from /etc/shadow to /home/jail/etc/shadow
343 grep -e "^$CHROOT_USERNAME:" /etc/shadow >> ${JAILPATH}/etc/shadow
344 chmod 600 ${JAILPATH}/etc/shadow
345
346 # endif for =! update
347 fi
348
349 # Copy the apps and the related libs
350 echo "Copying necessary library-files to jail (may take some time)"
351
352 # The original code worked fine on RedHat 7.3, but did not on FC3.
353 # On FC3, when the 'ldd' is done, there is a 'linux-gate.so.1' that 
354 # points to nothing (or a 90xb.....), and it also does not pick up
355 # some files that start with a '/'. To fix this, I am doing the ldd
356 # to a file called ldlist, then going back into the file and pulling
357 # out the libs that start with '/'
358
359 # Randy K.
360 #
361 # The original code worked fine on 2.4 kernel systems. Kernel 2.6
362 # introduced an internal library called 'linux-gate.so.1'. This 
363 # 'phantom' library caused non-critical errors to display during the 
364 # copy since the file does not actually exist on the file system. 
365 # To fix re-direct output of ldd to a file, parse the file and get 
366 # library files that start with /
367 #
368 if [ -x ${HOME}/ldlist ]; then 
369    mv ${HOME}/ldlist ${HOME}/ldlist.bak
370 fi
371 if [ -x ${HOME}/lddlist2 ]; then 
372    mv ${HOME}/lddlist2 ${HOME}/lddlist2.bak
373 fi
374
375 for app in $APPS;  do
376
377     # First of all, check that this application exists
378     if [ -x $app ]; then
379         # Check that the directory exists; create it if not.
380         app_path=`echo $app | sed -e 's#\(.\+\)/[^/]\+#\1#'`
381         if ! [ -d .$app_path ]; then
382             mkdir -p .$app_path
383         fi
384
385                 # If the files in the chroot are on the same file system as the
386                 # original files you should be able to use hard links instead of
387                 # copying the files, too. Symbolic links cannot be used, because the
388                 # original files are outside the chroot.
389                 cp -p $app .$app
390
391         # get list of necessary libraries
392         ldd $app >> ${HOME}/ldlist
393     fi
394 done
395
396 # Clear out any old temporary file before we start
397 if [ -e ${HOME}/ldlist2 ]; then
398     rm ${HOME}/ldlist2
399 fi
400 for libs in `cat ${HOME}/ldlist`; do
401    frst_char="`echo $libs | cut -c1`"
402    if [ "$frst_char" = "/" ]; then
403      echo "$libs" >> ${HOME}/ldlist2
404    fi
405 done
406 for lib in `cat ${HOME}/ldlist2`; do
407     mkdir -p .`dirname $lib` > /dev/null 2>&1
408
409         # If the files in the chroot are on the same file system as the original
410         # files you should be able to use hard links instead of copying the files,
411         # too. Symbolic links cannot be used, because the original files are
412         # outside the chroot.
413     cp $lib .$lib
414 done
415
416 #
417 # Now, cleanup the 2 files we created for the library list
418 #
419 /bin/rm -f ${HOME}/ldlist
420 /bin/rm -f ${HOME}/ldlist2
421
422 # Necessary files that are not listed by ldd.
423 #
424 # There might be errors because of files that do not exist but in the end it
425 # may work nevertheless (I added new file names at the end without deleting old
426 # ones for reasons of backward compatibility).
427 # So please test ssh/scp before reporting a bug.
428 if [ "$DISTRO" = SUSE ]; then
429   cp /lib/libnss_compat.so.2 /lib/libnss_files.so.2 /lib/libnss_dns.so.2 /lib/libxcrypt.so.1 ${JAILPATH}/lib/
430 elif [ "$DISTRO" = FEDORA ]; then
431   cp /lib/libnss_compat.so.2 /lib/libnsl.so.1 /lib/libnss_files.so.2 /lib/ld-linux.so.2 /lib/ld-ldb.so.3 /lib/ld-lsb.so.3 /lib/libnss_dns.so.2 /lib/libxcrypt.so.1 ${JAILPATH}/lib/
432   cp /lib/*.* ${JAILPATH}/lib/
433   cp /usr/lib/libcrack.so.2 ${JAILPATH}/usr/lib/
434 elif [ "$DISTRO" = REDHAT ]; then
435   cp /lib/libnss_compat.so.2 /lib/libnsl.so.1 /lib/libnss_files.so.2 /lib/ld-linux.so.2 /lib/ld-lsb.so.1 /lib/libnss_dns.so.2 /lib/libxcrypt.so.1 ${JAILPATH}/lib/
436   # needed for scp on RHEL
437   echo "export LD_LIBRARY_PATH=/usr/kerberos/lib" >> ${JAILPATH}/etc/profile
438 elif [ "$DISTRO" = DEBIAN ]; then
439   cp /lib/libnss_compat.so.2 /lib/libnsl.so.1 /lib/libnss_files.so.2 /lib/libcap.so.1 /lib/libnss_dns.so.2 ${JAILPATH}/lib/
440 else
441   cp /lib/libnss_compat.so.2 /lib/libnsl.so.1 /lib/libnss_files.so.2 /lib/libcap.so.1 /lib/libnss_dns.so.2 ${JAILPATH}/lib/
442 fi
443
444 # if you are using a 64 bit system and have strange problems with login comment
445 # the following lines in, perhaps it works then (motto: if you can't find the
446 # needed library just copy all of them)
447 #
448 #cp /lib/*.* ${JAILPATH}/lib/
449 #cp /lib/lib64/*.* ${JAILPATH}/lib/lib64/ 
450
451 # if you are using PAM you need stuff from /etc/pam.d/ in the jail,
452 echo "Copying files from /etc/pam.d/ to jail"
453 cp /etc/pam.d/* ${JAILPATH}/etc/pam.d/
454
455 # ...and of course the PAM-modules...
456 echo "Copying PAM-Modules to jail"
457 cp -r /lib/security ${JAILPATH}/lib/
458
459 # ...and something else useful for PAM
460 cp -r /etc/security ${JAILPATH}/etc/
461 cp /etc/login.defs ${JAILPATH}/etc/
462
463 if [ -f /etc/DIR_COLORS ] ; then
464   cp /etc/DIR_COLORS ${JAILPATH}/etc/
465 fi 
466
467 # Don't give more permissions than necessary
468 chown root.root ${JAILPATH}/bin/su
469 chmod 700 ${JAILPATH}/bin/su
470
471 exit
472