chiark / gitweb /
92b0d7194e9e3354fcf82096862a4e3a00130d10
[qmail] / debian / preinst
1 #!/usr/bin/perl
2
3 require 5.002;
4 use strict 'subs';
5 use strict 'barewords';
6 use English;
7
8 sub check_uid($$$$$$) {
9     my ($name, $uid, $gid, $gecos, $home, $shell) = @_;
10     my $ok = 1;
11
12     print "Checking user $name (uid $uid, gid $gid, homedir $home)... ";
13     @name_entry = getpwnam("$name");
14     if ( @name_entry == () ) {
15         my @uid_entry = getpwuid($uid);
16         if ( @uid_entry == () ) {
17             system("adduser --system --quiet --home $home --gid $gid --uid $uid --gecos \'$gecos\' $name >/dev/null 2>&1");
18             if ( $? != 0 ) {
19                 print "\n Error while adding user $name!\n";
20                 $ok = 0;
21             }
22             else {
23                 print "added.\n";
24             }
25             system("chsh -s $shell $name");
26         }
27         else {
28             print "error!\n Uid $uid is being used by user $uid_entry[0]\n";
29             $ok = 0;
30         }
31     }
32     else {
33         if ( $name_entry[3] != $gid ) {
34             print "error!\n" if $ok;
35             print " User $name has primary group $name_entry[3] instead of $gid\n";
36             $ok = 0;
37         }
38         if ( $name_entry[2] != $uid ) {
39             print "error!\n" if $ok;
40             print " User $name has uid $name_entry[2] instead of $uid\n";
41             $ok = 0;
42         }
43         if ( $name_entry[7] ne $home ) {
44             print "error!\n" if $ok;
45             print " User $name has home directory $name_entry[7] instead of $home\n";
46             $ok = 0;
47         }
48         if ( $ok ) {
49             print "ok.\n";
50         }
51     }
52     return $ok;
53 }
54
55 sub check_gid($$@) {
56     my ($name, $gid, @members) = @_;
57     my $ok = 1;
58
59     print "Checking group $name (gid $gid)... ";
60     @name_entry = getgrnam($name);
61     if ( @name_entry == () ) {
62         my @gid_entry = getgrgid($gid);
63         if ( @gid_entry == () ) {
64             system("addgroup --quiet --gid $gid $name");
65             if ( $? != 0 ) {
66                 print "\n Error while adding group $name\n";
67                 $ok = 0;
68             }
69             else {
70                 print "added.\n";
71             }
72         }
73         else {
74             print "error!\n Gid $gid is being used by group $gid_entry[0]\n";
75             $ok = 0;
76         }
77     }
78     else {
79         if ( $name_entry[2] != $gid ) {
80             print "error!\n Group $name has gid $name_entry[2] instead of $gid\n";
81             $ok = 0;
82         }
83         if ( $ok ) {
84             print "ok.\n";
85         }
86     }
87     return $ok;
88 }
89
90 sub is_qmail_installed {
91     my $qmail_installed = 0;
92
93     print "Checking if qmail is already installed on this computer... ";
94
95     $qmail_home = '';
96     if ( -d '/var/qmail' ) {
97         print "\n Found /var/qmail directory";
98         $qmail_home = '/var/qmail';
99         $qmail_installed = 1;
100     }
101     else {
102         $qmail_home = `qmail-home`;
103         if ( $qmail_home ne '') {
104             print "\n Found qmail home directory at $qmail_home (using qmail-home program)";
105             $qmail_installed = 1;
106         }
107     }
108
109     if ( -d '/var/spool/qmail' ) {
110         print "\n Found qmail spool directory at /var/spool/qmail";
111         $qmail_installed = 1;
112     }
113     if ( -d '/etc/qmail' ) {
114         print "\n Found qmail control directory at /etc/qmail";
115         $qmail_installed = 1;
116     }
117     
118     if ( (-r '/etc/inetd.conf') and `fgrep -q qmail-smtpd /etc/inetd.conf` ) {
119         print "\n Found reference to qmail-smtpd in /etc/inetd.conf";
120         $qmail_installed = 1;
121     }
122     if ( (-r '/etc/xinetd.conf') and `fgrep -q qmail-smtpd /etc/xinetd.conf` ) {
123         print "\n Found reference to qmail-smtpd in /etc/xinetd.conf";
124         $qmail_installed = 1;
125     }
126
127     if ( -x '/etc/init.d/qmail' ) {
128         print "\n Found /etc/init.d/qmail script";
129         $qmail_installed = 1;
130     }
131     elsif ( `fgrep -q qmail-start /etc/init.d/*` ) {
132         print "\n Found reference to qmail-start in /etc/init.d directory";
133         $qmail_installed = 1;
134     }
135     if ( -x '/etc/rc.local' and `fgrep -q qmail-start /etc/rc.local` ) {
136         print "\n Found reference to qmail-start in /etc/rc.local";
137         $qmail_installed = 1;
138     }
139
140     if ( `killall -0 qmail-send >/dev/null 2>&1` ) {
141         print "\n Found qmail-send process running";
142         $qmail_installed = 1;
143     }
144
145     print 'no.' unless $qmail_installed;
146     print "\n";
147     return $qmail_installed;
148 }
149         
150
151 $| = 1;
152
153 $action = shift;
154
155 if ( $action eq 'install' ) {
156     $old_version = shift;
157     if ( ! defined $old_version || $old_version eq '' ) {
158         print "First installation of the Debian qmail package...\n";
159         # Check if a non-Debian qmail is installed...
160         if ( is_qmail_installed() ) {
161             print "Please remove your copy of qmail before installing the qmail Debian package.\n\n";
162             exit 1;
163         }
164         # Check for qmail uids and gids
165         my $errors;
166         $errors++ unless check_gid('qmail', 64010, ());
167         #$errors++ unless check_gid('nogroup', 65534, ());
168
169         $errors++ unless check_uid('alias', 64010, 65534, 'qmail alias', '/var/qmail/alias', '/bin/sh');
170         $errors++ unless check_uid('qmaild', 64011, 65534, 'qmail daemon', '/var/qmail', '/bin/sh');
171         $errors++ unless check_uid('qmails', 64012, 64010, 'qmail send', '/var/qmail', '/bin/sh');
172         $errors++ unless check_uid('qmailr', 64013, 64010, 'qmail remote', '/var/qmail', '/bin/sh');
173         $errors++ unless check_uid('qmailq', 64015, 64010, 'qmail queue', '/var/qmail', '/bin/sh');
174         $errors++ unless check_uid('qmaill', 64016, 65534, 'qmail log', '/var/qmail', '/bin/sh');
175         $errors++ unless check_uid('qmailp', 64017, 65534, 'qmail pw', '/var/qmail', '/bin/sh');
176         #$errors++ unless check_uid('nobody', 65534, 65534, 'nobody', '/tmp', '/bin/sh');
177
178         if ( $errors ) {
179             print "\n$errors entries have errors. Please correct these errors and reinstall qmail.\n";
180             exit 2;
181         }
182     }
183
184     # Make sure there are no smtp entries in /etc/inetd.conf
185     # Kludge around smail buggy /etc/inetd.conf handling. (Grr.)
186     my $fixed_smail = 0;
187     my $found_commented = 0;
188     my $found_uncommented = 0;
189     my $new_inetd = "/etc/inetd.conf.qmail-preinst.$$";
190     open I, '</etc/inetd.conf' or die "Could not open /etc/inetd.conf\n";
191     open N, ">$new_inetd" or die "Could not create $new_inetd\n";
192     while (<I>) {
193         if ( m|^\# *smtp\s+.*/usr/sbin/in.smtpd.*\(will be restored by smail postinst\)\s*$| ) {
194                 $fixed_smail = 1;
195                 next;
196             } elsif ( m/^\# *smtp\s+/ ) {
197                 $found_commented= 1;
198             } elsif ( m/^smtp\s+/ ) {
199                 $found_uncommented= 1;
200             }
201         print N or die "Cannot write to $new_inetd\n";
202         }
203     close N or die "Could not close $new_inetd\n";
204     close I or die "Could not close /etc/inetd.conf\n";
205     if ( $found_commented or $found_uncommented ) {
206         print "Your /etc/inetd.conf already containts entries for the SMTP service.\n";
207         print "Please remove all SMTP entries from /etc/inetd.conf (even those commented out)\n";
208         print "and reinstall the qmail package.\n\n";
209         exit 1; 
210     }
211     if ( $fixed_smail ) {
212         print "Removing commented smtp entry left by buggy version of smail postinst... ";
213         rename "$new_inetd", '/etc/inetd.conf' or die "failed!\n";
214         print "done.\n";
215     }
216 }
217
218 exit 0;