root/alternc/tags/0.9.6.3/src/basedir_prot.sh

Revision 1772, 3.8 kB (checked in by anarcat, 2 years ago)

Fix a race condition in update_domaines.sh that could allow users to
bypass open_basedir protections when creating domains. Reported by
jerome.

This required changing basedir_prot's behavior so that it creates the
protection even if the symlink doesn't exist, which might create extra
files that are not necessary, but "better be safe than sorry". We
could also fix this in a subsequent release.

  • Property svn:executable set to *
Line 
1 #!/bin/sh
2
3 set -e
4
5 # Ceci créé un hack php pour chacun des domaines hébergés par alternc
6 # ce hack consiste à restreindre chaque usager à son propre répertoire
7 # dans alternc/html/u/user avec open_base_dir
8
9 # ce script a les dépendances suivantes:
10 # (mysql, /etc/alternc/local.sh) OR /usr/bin/get_account_by_domain dans
11 # l'ancien package alternc-admintools désormais dans alternc natif.
12 # cut, awk, sort
13
14 override_d=/var/alternc/apacheconf
15 override_f=${override_d}/override_php.conf
16 extra_paths="/var/alternc/dns/redir:/usr/share/php/:/var/alternc/tmp/:/tmp/"
17
18 . /etc/alternc/local.sh
19 if [ -z "$MYSQL_HOST" ]
20 then
21     MYSQL_HOST="localhost"
22 fi
23
24 # imprime le nom d'usager associé au domaine
25 get_account_by_domain() {
26         # les admintools ne sont peut-être pas là
27         if [ -x "/usr/bin/get_account_by_domain" ]
28         then
29                 # only first field, only first line
30                 /usr/bin/get_account_by_domain "$1" | cut -d\  -f1 | cut -d'
31 ' -f 1
32         else
33                 # implantons localement ce que nous avons besoin, puisque admintools
34                 # n'est pas là
35                 mysql -h$MYSQL_HOST -u$MYSQL_USER -p$MYSQL_PASS -D$MYSQL_DATABASE -B -N -e \
36                 'SELECT a.login FROM membres a, sub_domaines b WHERE a.uid = b.compte AND \
37                 CONCAT(IF(sub="", "", CONCAT(sub, ".")), domaine) = "'"$1"'" LIMIT 1;'
38         fi
39 }
40
41 # add the standard input to a given file, only if not already present
42 append_no_dupe() {
43         realfile="$1"
44         tmpfile=`mktemp`
45         trap "rm -f $tmpfile; exit 1" 1 2 15
46         cat > $tmpfile
47         if [ -r "$realfile" ] &&
48                 (diff -q "$tmpfile" "$realfile" > /dev/null || \
49                         diff -u "$tmpfile" "$realfile"  | grep '^ ' | sed 's/^ //' | diff -q - "$tmpfile" > /dev/null)
50         then
51                 ret=0
52         else
53                 ret=1
54                 cat "$tmpfile" >> "$realfile"
55         fi
56         rm -f "$tmpfile"
57         return "$ret"
58 }
59
60 add_dom_entry() {
61         # protect ourselves from interrupts
62         trap "rm -f ${override_f}.new; exit 1" 1 2 15
63         # ajouter une entrée, seulement s'il n'y en pas déjà, pour ce domaine
64         (echo "$1"; [ -r $override_f ] && cat $override_f) | \
65         sort -u > ${override_f}.new && \
66         cp ${override_f}.new ${override_f} && \
67         rm ${override_f}.new
68 }
69
70 # la première lettre de l'avant-dernière partie du domaine (e.g.
71 # www.alternc.org -> a)
72 #
73 # argument: le domaine
74 # imprime: la lettre
75 init_dom_letter() {
76     echo "$1" | awk '{z=split($NF, a, ".") ; print substr(a[z-1], 1, 1)}'
77 }
78
79 echo -n "adding open_base_dir protection for:"
80 # boucle sur tous les domaines hébergés, ou sur les arguments de la
81 # ligne de commande
82 if [ $# -gt 0 ]; then
83         for i in "$*"
84         do
85                 if echo "$i" | grep -q '^\*\.'
86                 then
87                     echo skipping wildcard "$i" >&2
88                     continue
89                 fi
90                 if echo "$i" | grep -q /var/alternc/dns > /dev/null; then
91                         dom="$i"
92                 else
93                     initial_domain=`init_dom_letter "$i"`
94                     dom="/var/alternc/dns/$initial_domain/$i"
95                 fi
96                 doms="$doms $dom"
97         done
98 else
99         doms=`find /var/alternc/dns -type l`
100 fi
101
102 for i in $doms
103 do
104         # don't "protect" squirrelmail, it legitimatly needs to consult
105         # files out of its own directory
106         if readlink "$i" | grep -q '^/var/alternc/bureau/admin/webmail/*$' || \
107            readlink "$i" | grep -q '^/var/alternc/bureau/*$'
108         then
109                 continue
110         fi
111         domain=`basename "$i"`
112         account=`get_account_by_domain $domain`
113         if [ -z "$account" ]; then
114                 continue
115         fi
116         # la première lettre de l'avant-dernière partie du domaine (e.g.
117         # www.alternc.org -> a)
118         initial_domain=`init_dom_letter "$domain"`
119         # la première lettre du username
120         initial_account=`echo "$account" | cut -c1`
121         path1="/var/alternc/dns/$initial_domain/$domain"
122         path2="/var/alternc/html/$initial_account/$account"
123
124         mkdir -p "$override_d/$initial_domain"
125         if append_no_dupe "$override_d/$initial_domain/$domain" <<EOF
126 <Directory ${path1}>
127   php_admin_value open_basedir ${path2}/:${extra_paths}
128 </Directory>
129 EOF
130         then
131                 true
132         else
133                 echo -n " $domain"
134                 add_dom_entry "Include $override_d/$initial_domain/$domain"
135         fi
136 done
137
138 echo .
Note: See TracBrowser for help on using the browser.