| 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; |