root/alternc/tags/0.9.7/src/functions.sh

Revision 1930, 9.2 kB (checked in by benjamin, 1 year ago)

Fixing dns/nodns issue (a bug in update_domains) Fixes #772

Line 
1 # some miscellaneous shell functions
2
3 print_domain_letter() {
4     local domain="$1"
5
6     local letter=`echo "$domain" | awk '{z=split($NF, a, ".") ; print substr(a[z-1], 1, 1)}'`
7     if [ -z "$letter" ]; then
8       letter="_"
9     fi
10     echo $letter
11 }
12
13 print_user_letter() {
14     local user="$1"
15
16     echo "$user" | awk '{print substr($1, 1, 1)}'
17 }
18
19 add_to_php_override() {
20     local fqdn="$1"
21
22     /usr/lib/alternc/basedir_prot.sh "$fqdn" >> "$DOMAIN_LOG_FILE"
23 }
24
25 remove_php_override() {
26     local fqdn="$1"
27     local letter=`print_domain_letter $fqdn`
28
29     sed -i "/$fqdn/d" $APACHECONF_DIR/override_php.conf
30     rm -f $APACHECONF_DIR/$letter/$fqdn
31 }
32
33 add_to_named_reload() {
34     local domain="$1"
35     local escaped_domain=`echo "$domain" | sed -e 's/\./\\\./g'`
36
37     if [ "domain" = "all" ] || grep -q "^all$" "$RELOAD_ZONES_TMP_FILE"; then
38         echo "all" > "$RELOAD_ZONES_TMP_FILE"
39     else
40         if ! grep -q "^${escaped_domain}$" "$RELOAD_ZONES_TMP_FILE"; then
41             echo "$domain" >> "$RELOAD_ZONES_TMP_FILE"
42         fi
43     fi
44 }
45
46 # we assume that the serial line contains the "serial string", eg.:
47 #                 2005012703      ; serial
48 #
49 # returns 1 if file isn't readable
50 # returns 2 if we can't find the serial number
51 # returns 3 if a tempfile can't be created
52 increment_serial() {
53     local domain="$1"
54     local zone_file="$ZONES_DIR/$domain"
55     local current_serial
56     local new_serial
57     local date
58     local revision
59     local today
60
61     if [ ! -f "$zone_file" ]; then
62         return 1
63     fi
64
65     # the assumption is here
66     current_serial=`awk '/^..*serial/ {print $1}' < "$zone_file"` || return 2
67     if [ -z "$current_serial" ]; then
68         return 2
69     fi
70
71     date=`echo $current_serial | cut -c1-8`
72     revision=`echo $current_serial | sed s/"${date}0\?"/""/g`
73     today=`date +%Y%m%d`
74     # increment the serial number only if the date hasn't changed
75     if [ "$date" = "$today" ] ; then
76         revision=$(($revision + 1))
77     else
78         revision=1
79         date=$today
80     fi
81     new_serial="$date`printf '%.2d' $revision`"
82
83     # replace serial number
84     cp -a -f "$zone_file" "$zone_file.$$"
85     awk -v "NEW_SERIAL=$new_serial" \
86         '{if ($3 == "serial")
87              print "            "NEW_SERIAL "   ; serial"
88           else
89              print $0}' < "$zone_file" > "$zone_file.$$"
90     mv -f "$zone_file.$$" "$zone_file"
91
92     add_to_named_reload "$domain"
93
94     return 0
95 }
96
97 change_host_ip() {
98     local domain="$1"
99     local zone_file="$ZONES_DIR/$domain"
100     local ip="$2"
101     local host="$3"
102     local pattern
103     local a_line
104
105     if [ -z "$host" ]; then
106         host="@"
107     fi
108     a_line="$host       IN      A       $ip"
109     pattern="^$host[[:space:]]*IN[[:space:]]*A[[:space:]]*.*\$"
110     if [ ! -f "$zone_file" ]; then
111         echo "Should change $host.$domain, but can't find $zone_file."
112         return 1
113     fi
114     if grep -q "$pattern" "$zone_file"; then
115         cp -a -f "$zone_file" "$zone_file.$$"
116         sed "s/$pattern/$a_line/" < "$zone_file" > "$zone_file.$$"
117         mv "$zone_file.$$" "$zone_file"
118     else
119         echo "$a_line" >> "$zone_file"
120     fi
121     add_to_named_reload "$domain"
122 }
123
124 add_host() {
125     local domain="$1"
126     local host_type="$2"
127     local host="$3"
128     local value="$4"
129     local user="$5"
130     local domain_letter=`print_domain_letter "$domain"`
131     local user_letter=`print_user_letter "$user"`
132     local ip
133     local fqdn
134     local vhost_directory
135        
136     delete_host "$domain" "$host"
137
138     if [ "$host" = "@" -o -z "$host" ]; then
139         FQDN="$domain"
140     else
141         FQDN="$host.$domain"
142     fi
143     if [ "$host_type" != "$TYPE_IP" ]; then
144         add_to_php_override "$FQDN"
145     fi
146
147     if [ "$host_type" = "$TYPE_IP" ]; then
148        ip="$value"
149     else
150        ip="$PUBLIC_IP"
151     fi
152     if [ "$host" = "@" -o -z "$host" ]; then
153         change_host_ip "$domain" "$ip" || true
154         fqdn="$domain"
155     else
156         change_host_ip "$domain" "$ip" "$host" || true
157         fqdn="${host}.${domain}"
158     fi
159
160     vhost_directory="${HTTP_DNS}/${domain_letter}/${fqdn}"
161     htaccess_directory="${HTTP_DNS}/redir/${domain_letter}/${fqdn}"
162
163     case "$host_type" in
164       $TYPE_LOCAL)
165         ln -snf "${HTML_HOME}/${user_letter}/${user}${value}" \
166                 "$vhost_directory"
167         ;;
168
169       $TYPE_WEBMAIL)
170         ln -snf "${WEBMAIL_DIR}" "$vhost_directory"
171         ;;
172
173       $TYPE_URL)
174         mkdir -p "$htaccess_directory"
175         (echo "RewriteEngine on"
176          echo "RewriteRule (.*) ${value}\$1 [R,L]"
177         ) > "$htaccess_directory/.htaccess"
178         ln -snf "$htaccess_directory" "$vhost_directory"
179         ;;
180        
181       $TYPE_IP)
182         rm -f "$vhost_directory"
183         rm -rf "$htaccess_directory/.htaccess"
184         ;;
185
186       *)
187         echo "Unknow type code: $type" >> "$DOMAIN_LOG_FILE"
188         ;;
189     esac
190 }
191
192 delete_host() {
193     local domain="$1"
194     local host="$2"
195     local domain_letter=`print_domain_letter "$domain"`
196     local fqdn
197     local escaped_host
198     local escaped_fqdn
199    
200     if [ "$host" = "@" -o -z "$host" ]; then
201         fqdn="$domain"
202         escaped_host=""
203     else
204         fqdn="$host.$domain"
205         escaped_host=`echo "$host" | sed 's/\([\*|\.]\)/\\\\\1/g'`
206     fi
207
208     if [ -f "$ZONES_DIR/$domain" ] ; then
209         cp -a -f "$ZONES_DIR/$domain" "$ZONES_DIR/$domain.$$"
210         sed -e "/^$escaped_host[[:space:]]*IN[[:space:]]*A[[:space:]]/d" \
211             < "$ZONES_DIR/$domain" > "$ZONES_DIR/$domain.$$"
212         mv "$ZONES_DIR/$domain.$$" "$ZONES_DIR/$domain"
213         increment_serial "$domain"
214         add_to_named_reload "$domain"
215     fi
216
217     rm -f "$APACHECONF_DIR/$domain_letter/$fqdn"
218
219     escaped_fqdn=`echo "$fqdn" | sed 's/\([\*|\.]\)/\\\\\1/g'`
220
221     cp -a -f "$OVERRIDE_PHP_FILE" "$OVERRIDE_PHP_FILE.$$"
222     sed -e "/\/${escaped_fqdn}\$/d" \
223         < "$OVERRIDE_PHP_FILE" > "$OVERRIDE_PHP_FILE.$$"
224     mv "$OVERRIDE_PHP_FILE.$$" "$OVERRIDE_PHP_FILE"
225
226     rm -f "$HTTP_DNS/$domain_letter/$fqdn"
227     rm -rf "$HTTP_DNS/redir/$domain_letter/$fqdn"
228 }
229
230
231 init_zone() {
232     local domain="$1"
233     local escaped_domain=`echo "$domain" | sed -e 's/\./\\\./g'`
234     local zone_file="$ZONES_DIR/$domain"
235     local serial
236
237     if [ ! -f "$zone_file" ]; then
238         serial=`date +%Y%m%d`00
239         sed -e "s/@@DOMAINE@@/$domain/g;s/@@SERIAL@@/$serial/g" \
240             < "$ZONE_TEMPLATE" > "$zone_file"
241         chgrp bind "$zone_file"
242         chmod 640  "$zone_file"
243     fi
244     if ! grep -q "\"$escaped_domain\"" "$NAMED_CONF_FILE"; then
245         cp -a -f "$NAMED_CONF_FILE" "$NAMED_CONF_FILE".prec
246         sed -e "s/@@DOMAINE@@/$domain/g" \
247                 < "$NAMED_TEMPLATE" >> "$NAMED_CONF_FILE"
248         add_to_named_reload "all"
249     fi
250 }
251
252 remove_zone() {
253     local domain="$1"
254     local escaped_domain=`echo "$domain" | sed -e 's/\./\\\./g'`
255     local zone_file="$ZONES_DIR/$domain"
256
257     if [ -f "$zone_file" ]; then
258         rm -f "$zone_file"
259     fi
260
261     if grep -q "\"$escaped_domain\"" "$NAMED_CONF_FILE"; then
262         cp -a -f "$NAMED_CONF_FILE" "$NAMED_CONF_FILE.prec"
263         cp -a -f "$NAMED_CONF_FILE" "$NAMED_CONF_FILE.$$"
264         # That's for multi-line template
265         #sed -e "/^zone \"$escaped_domain\"/,/^};/d" \
266         # That's for one-line template
267         grep -v "^zone \"$escaped_domain\"" \
268             < "$NAMED_CONF_FILE" > "$NAMED_CONF_FILE.$$" || true
269         mv -f "$NAMED_CONF_FILE.$$" "$NAMED_CONF_FILE"
270         add_to_named_reload "all"
271     fi
272 }
273
274 change_mx() {
275     local domain="$1"
276     local mx="$2"
277     local zone_file="$ZONES_DIR/$domain"
278     local pattern="^@*[[:space:]]*IN[[:space:]]*MX[[:space:]]*[[:digit:]]*[[:space:]].*\$"
279     local mx_line="@    IN      MX      5       $mx."
280
281     # aller chercher le numéro de la ligne MX
282     # XXX: comportement inconnu si plusieurs matchs ou MX commenté
283     if grep -q "$pattern" "$zone_file"; then
284         cp -a -f "$zone_file" "$zone_file.$$"
285         sed -e "s/$pattern/$mx_line/" < "$zone_file" > "$zone_file.$$"
286         mv "$zone_file.$$" "$zone_file"
287     else
288         echo "$mx_line" >> "$zone_file"
289     fi
290
291     increment_serial "$domain"
292     add_to_named_reload "$domain"
293 }
294
295
296
297 # imprime le nom d'usager associé au domaine
298 get_account_by_domain() {
299         # les admintools ne sont peut-être pas là
300         if [ -x "/usr/bin/get_account_by_domain" ]
301         then
302                 # only first field, only first line
303                 /usr/bin/get_account_by_domain "$1" | cut -d\  -f1 | cut -d'
304 ' -f 1
305         else
306                 # implantons localement ce que nous avons besoin, puisque admintools
307                 # n'est pas là
308                 mysql -h$MYSQL_HOST -u$MYSQL_USER -p$MYSQL_PASS -D$MYSQL_DATABASE -B -N -e \
309                 'SELECT a.login FROM membres a, sub_domaines b WHERE a.uid = b.compte AND \
310                 CONCAT(IF(sub="", "", CONCAT(sub, ".")), domaine) = "'"$1"'" LIMIT 1;'
311         fi
312 }
313
314 # add the standard input to a given file, only if not already present
315 append_no_dupe() {
316         realfile="$1"
317         tmpfile=`mktemp`
318         trap "rm -f $tmpfile; exit 1" 1 2 15
319         cat > $tmpfile
320         if [ -r "$realfile" ] &&
321                 (diff -q "$tmpfile" "$realfile" > /dev/null || \
322                         diff -u "$tmpfile" "$realfile"  | grep '^ ' | sed 's/^ //' | diff -q - "$tmpfile" > /dev/null)
323         then
324                 ret=0
325         else
326                 ret=1
327                 cat "$tmpfile" >> "$realfile"
328         fi
329         rm -f "$tmpfile"
330         return "$ret"
331 }
332
333 add_dom_entry() {
334         # protect ourselves from interrupts
335         trap "rm -f ${override_f}.new; exit 1" 1 2 15
336         # ajouter une entrée, seulement s'il n'y en pas déjà, pour ce domaine
337         (echo "$1"; [ -r $override_f ] && cat $override_f) | \
338         sort -u > ${override_f}.new && \
339         cp ${override_f}.new ${override_f} && \
340         rm ${override_f}.new
341 }
Note: See TracBrowser for help on using the browser.