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