~ubuntu-branches/ubuntu/trusty/sendmail/trusty

« back to all changes in this revision

Viewing changes to debian/local/update_conf

  • Committer: Bazaar Package Importer
  • Author(s): Richard A Nelson (Rick)
  • Date: 2009-03-01 18:45:00 UTC
  • mfrom: (8.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20090301184500-z6683zxyomgmop6c
Tags: 8.14.3-9
Batting 1000, build-depend on quilt      Closes: #517676

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl -w
 
2
#------------------------------------------------------------------------
 
3
#
 
4
# $Sendmail: update_conf,v 8.14.3 2009-03-01 10:48:34 cowboy Exp $
 
5
#
 
6
# Parse and update /etc/mail/sendmail.conf and reflect its values in
 
7
# /etc/cron.d/sendmail and /etc/inetd.conf.
 
8
#
 
9
# Copyright (c) 2001-2009 Richard Nelson.  All Rights Reserved.
 
10
#
 
11
#------------------------------------------------------------------------
 
12
#
 
13
use strict;                     # be kosher
 
14
use Cwd;                        # provide cwd()
 
15
use Env;                        # A few environmental references
 
16
use integer;            # Peformance
 
17
use Sys::Hostname;      # make sure we have a valid hostname
 
18
use Getopt::Long;       # parameter handling
 
19
use FileHandle;         # I/O
 
20
 
 
21
# Local libraries - for Debian Sendmail Perl helper functions
 
22
# BEGIN { $main::my_path = substr($0,$[,rindex($0,'/')) };
 
23
use lib ('.', substr($0,$[,rindex($0,'/')), "/usr/share/sendmail");
 
24
require Parse_conf;
 
25
require Parse_mc;
 
26
 
 
27
$main::program_name = $0; #'update_conf';
 
28
$main::program_version = '8.14.3';
 
29
$main::program_date = '2009-03-01 10:48:34 cowboy';
 
30
$main::debug = 0;
 
31
 
 
32
my $interp_pgm = "$^X";
 
33
my $interp_vrm = $];
 
34
$interp_vrm = ("$^V" | '000') if (defined $^V);
 
35
my $current_time = scalar localtime;
 
36
my $user = getlogin || (getpwuid($<))[0] || "Unknown!!";
 
37
my $hostname = hostname();
 
38
my $directory = getcwd();
 
39
 
 
40
my $Conffile = "/etc/mail/sendmail.conf";
 
41
my $output_file = '';
 
42
my $ofh = new FileHandle;
 
43
my $debug = 0;
 
44
 
 
45
#
 
46
#------------------------------------------------------------------------------
 
47
# Global variables
 
48
#------------------------------------------------------------------------------
 
49
 
 
50
#
 
51
#------------------------------------------------------------------------------
 
52
# Finally, some code (almost)
 
53
#------------------------------------------------------------------------------
 
54
 
 
55
#
 
56
# Argument handling...
 
57
$main::opt_help='';
 
58
$main::opt_output_file='';
 
59
$main::opt_input_file='';
 
60
$main::opt_debug='';
 
61
$main::opt_test='';
 
62
$main::opt_static='';
 
63
my @options = qw(
 
64
        help|h
 
65
        output-file|output_file|o:s
 
66
        input-file|input_file|i:s
 
67
        debug!
 
68
        test!
 
69
        static!
 
70
        );
 
71
my $result = GetOptions(@options);
 
72
if ( ! $result ) {
 
73
        die "Terminating due to parameter error";
 
74
        };
 
75
if ( $main::opt_help ) {
 
76
        warn "$main::program_name $main::program_version $main::program_date\n";
 
77
        warn "$0 \n";
 
78
        warn "   -help\n" if $main::opt_help;
 
79
        warn "   -debug\n" if $main::opt_debug;
 
80
        warn "   -test\n" if $main::opt_debug;
 
81
        warn "   -static\n" if $main::opt_static;
 
82
        warn "   -o $main::opt_output_file\n" if $main::opt_output_file;
 
83
        warn "   -i $main::opt_input_file\n"  if $main::opt_input_file;
 
84
        exit 0;
 
85
        };
 
86
 
 
87
if ( $main::opt_test ) {
 
88
        &sm2cron_time("");
 
89
        &sm2cron_time("6s");
 
90
        &sm2cron_time("5m");
 
91
        &sm2cron_time("4h");
 
92
        &sm2cron_time("3d");
 
93
        &sm2cron_time("2w");
 
94
        &sm2cron_time("2w3d4h5m6s");
 
95
        &sm2cron_time("89s");
 
96
        &sm2cron_time("90m");
 
97
        &sm2cron_time("150m");
 
98
        &sm2cron_time("125");
 
99
        &sm2cron_time("31d");
 
100
        &sm2cron_time("35d");
 
101
        &sm2cron_time("5w");
 
102
        &sm2cron_time("9w");
 
103
        exit 0;
 
104
        };
 
105
 
 
106
$output_file = $main::opt_output_file if ($main::opt_output_file);
 
107
my $input_file = $main::opt_input_file || $Conffile;
 
108
# $main::debug is used in Parse_mc !
 
109
$main::debug = $main::opt_debug || $main::debug;
 
110
 
 
111
# Read /etc/mail/sendmail.conf (if extant)
 
112
&Parse_conf::read_config($Conffile);
 
113
 
 
114
# [Re]write /etc/mail/sendmail.config
 
115
&Parse_conf::write_config($Conffile);
 
116
 
 
117
my ($ok, $value) = &Parse_conf::get_value('HANDS_OFF');
 
118
if ($value ne '0') {
 
119
        unlink "/etc/cron.d/sendmail";
 
120
        exit;
 
121
        };
 
122
 
 
123
# Reflect settings in /etc/cron.d/sendmail
 
124
&write_crontab;
 
125
if ( $output_file eq '' ) {
 
126
        chown '0', '0', "/etc/cron.d/sendmail";
 
127
        chmod 0644, "/etc/cron.d/sendmail";
 
128
        };
 
129
 
 
130
# Reflect settings in /etc/inetd.conf
 
131
&update_inetd;
 
132
 
 
133
# Create/Delete files
 
134
&update_files;
 
135
 
 
136
exit (0);
 
137
 
 
138
#
 
139
#------------------------------------------------------------------------
 
140
# Check for nullclient mode in /etc/mail/sendmail.mc
 
141
#------------------------------------------------------------------------
 
142
sub check_nullclient {
 
143
        my $nullclient = 0;
 
144
        my $in_file = "/etc/mail/sendmail.mc";
 
145
        if ( -r $in_file ) {
 
146
                my $ifh;
 
147
                unless ( open($ifh, "<$in_file") ) {
 
148
                        warn("Could not open $in_file($!), ignoring it.\n");
 
149
                        };
 
150
 
 
151
                line: while (<$ifh>) {
 
152
                        next line if /^$/;         # skip empty lines
 
153
                        next line if /^#/;         # skip comments
 
154
                        next line if /^dnl /;  # skip comments
 
155
                        chomp;                             # drop tailing \n
 
156
 
 
157
                        if (/^\s*FEATURE\(\s*`?nullclient/) {
 
158
                                $nullclient = 1;
 
159
                                last line;
 
160
                                };
 
161
                        };
 
162
                };
 
163
        return $nullclient;
 
164
        };
 
165
 
 
166
#
 
167
#------------------------------------------------------------------------
 
168
# Compute time setting for Crontab entry (simplistic)
 
169
# NOTE:  It does the basics pretty darned well...  *BUT*
 
170
#        It fails, miserably, on things that would multiple lines:
 
171
#            90 minutes:  does it at 30 minutes (90-60)
 
172
#        Or are just edge conditions:
 
173
#            25 hours: treated as 24 hours
 
174
#            35 days:  does it the 7rd of every month (35-28)
 
175
#------------------------------------------------------------------------
 
176
sub sm2cron_time {
 
177
        my $month  = 0;
 
178
        my $week   = 0;
 
179
        my $day    = 0;
 
180
        my $hour   = 0;
 
181
        my $minute = 0;
 
182
        my $second = 0;
 
183
        my $tmp    = 0;
 
184
        my $t      = '';
 
185
        my $cron   = '';
 
186
 
 
187
        my ($sm)        = @_;
 
188
        my $seconds = 0;
 
189
        my $elapsed = 0;
 
190
        my $randstart = '00';
 
191
        if ($sm eq '') {
 
192
                if ( $main::opt_test ) {
 
193
                        print "mm   hh  dom  mon dow = sm2cron_time($sm);\n";
 
194
                        };
 
195
                return ($cron, $seconds);
 
196
                };
 
197
 
 
198
        # Convert sendmail time
 
199
        #       1w2d3h4m5s
 
200
        # to cron time
 
201
        #       m h dom mon dow
 
202
        $t = $sm;
 
203
        if ( $t =~ /^\d+$/ ) {
 
204
                $minute  = $sm; }
 
205
        else {
 
206
                ($week   = $sm) =~ s/.*?(\d+)w.*/$1/ if ( $t =~ /w/ );
 
207
                ($day    = $sm) =~ s/.*?(\d+)d.*/$1/ if ( $t =~ /d/ );
 
208
                ($hour   = $sm) =~ s/.*?(\d+)h.*/$1/ if ( $t =~ /h/ );
 
209
                ($minute = $sm) =~ s/.*?(\d+)m.*/$1/ if ( $t =~ /m/ );
 
210
                ($second = $sm) =~ s/.*?(\d+)s.*/$1/ if ( $t =~ /s/ );
 
211
                }
 
212
        # Rationalize the time
 
213
        $seconds = ($week   * 7 * 24 * 60 * 60)
 
214
                 + ($day    * 24 * 60 * 60)
 
215
                 + ($hour   * 60 * 60)
 
216
                 + ($minute * 60)
 
217
                 + $second;
 
218
        $elapsed = $seconds;
 
219
        $month   = $seconds / (4 * 7 * 24 * 60 * 60);
 
220
        $seconds = $seconds % (4 * 7 * 24 * 60 * 60);
 
221
        $week    = $seconds / (7 * 24 * 60 * 60);
 
222
        $seconds = $seconds % (7 * 24 * 60 * 60);
 
223
        $day     = $seconds / (24 * 60 * 60);
 
224
        $seconds = $seconds % (24 * 60 * 60);
 
225
        $hour    = $seconds / (60 * 60);
 
226
        $seconds = $seconds % (60 * 60);
 
227
        $minute  = $seconds / (60);
 
228
        $seconds = $seconds % (60);
 
229
        $second  = $seconds;
 
230
 
 
231
        # Cron doesn't do seconds, round to minutes or ignore
 
232
        $minute = $minute + 1 if ($second > 30);
 
233
 
 
234
        # Minute of hour (0-59)
 
235
        $minute = sprintf("%02d", $minute);
 
236
        $randstart = sprintf("%02d", int(rand(60))) if (!$main::opt_static);
 
237
        if (0 < $hour + $day + $week + $month) {
 
238
                if (1 >= $minute) {
 
239
                        $cron = "$randstart  "; }
 
240
                else {
 
241
                        $cron = "$minute  "; }
 
242
                }
 
243
        elsif (1 >= $minute) {
 
244
                $cron = "*   ";
 
245
                }
 
246
        else {
 
247
                $cron = "*/$minute";
 
248
                };
 
249
 
 
250
        # Hour of day (0-23)
 
251
        $hour = sprintf("%02d", $hour);
 
252
        $randstart = sprintf("%02d", int(rand(24))) if (!$main::opt_static);
 
253
        if (0 < $day + $week + $month) {
 
254
                if (1 >= $hour) {
 
255
                        $cron = "$cron $randstart  "; }
 
256
                else {
 
257
                        $cron = "$cron $hour  "; }
 
258
                }
 
259
        elsif (1 >= $hour) {
 
260
                $cron = "$cron *   ";
 
261
                }
 
262
        else {
 
263
                $cron = "$cron */$hour";
 
264
                };
 
265
 
 
266
        # Day of month (1-31)
 
267
        $day = $day + (7 * $week);
 
268
        $day   = sprintf("%02d", $day);
 
269
        $randstart = 1 + sprintf("%02d", int(rand(31))) if (!$main::opt_static);
 
270
        if (0 < $month) {
 
271
                if (1 >= $day) {
 
272
                        $cron = "$cron $randstart  "; }
 
273
                else {
 
274
                        $cron = "$cron $day  "; }
 
275
                }
 
276
        elsif (1 >= $day) {
 
277
                $cron = "$cron *   ";
 
278
                }
 
279
        else {
 
280
                $cron = "$cron */$day";
 
281
                };
 
282
 
 
283
        # Month in year (1-12)
 
284
        $month = sprintf("%02d", $month);
 
285
        $randstart = 1 + sprintf("%02d", int(rand(12))) if (!$main::opt_static);
 
286
        if (1 >= $month) {
 
287
                $cron = "$cron *   ";
 
288
                }
 
289
        else {
 
290
                $cron = "$cron */$month";
 
291
                };
 
292
 
 
293
        $cron = "$cron *";                              # Day of week (0-7)
 
294
 
 
295
        if ( $main::opt_test ) {
 
296
                print "$cron = sm2cron_time($sm);\n";
 
297
                };
 
298
        return ($cron, $elapsed);       
 
299
        };
 
300
 
 
301
#
 
302
#------------------------------------------------------------------------
 
303
# Write updated cron file
 
304
#------------------------------------------------------------------------
 
305
sub write_crontab {
 
306
        my $var;
 
307
        my $interval = '';
 
308
        my $cronint  = '';
 
309
        my $test         = "test -x /etc/init.d/sendmail";
 
310
        my $command  = '';
 
311
        my $ok           = '';
 
312
        my $mailto       = '';
 
313
        my $mmode        = '';
 
314
        my $qmode        = '';
 
315
        my $msp_line = '';
 
316
        my $mta_line = '';
 
317
        my $age_line = '';
 
318
 
 
319
        ($ok, $mailto) = &Parse_conf::get_value('CRON_MAILTO');
 
320
        if ( ! $ok ) {
 
321
                return;
 
322
                };
 
323
 
 
324
        my $out_file = $output_file || "/etc/cron.d/sendmail";
 
325
        print STDOUT "Writing $out_file.\n";
 
326
        $out_file = '&STDOUT' if ($out_file eq '-');
 
327
        unless ( open($ofh, ">$out_file") ) {
 
328
                warn("Could not open $out_file($!), using STDOUT\n");
 
329
                open($ofh, ">&STDOUT");
 
330
                };
 
331
        $out_file = '-' if ($out_file eq '&STDOUT');
 
332
 
 
333
        print $ofh <<"EOT";
 
334
####################################################################
 
335
##### This file is automagically generated -- edit at your own risk
 
336
#####
 
337
##### file: ${out_file}
 
338
##### generated via: (${interp_pgm} ${interp_vrm})
 
339
#####           ${main::program_name}
 
340
#####           version: ${main::program_version} ${main::program_date}
 
341
##### by: ${user}\@${hostname}
 
342
##### on: ${current_time}
 
343
##### in: ${directory}
 
344
##### input files:
 
345
EOT
 
346
        foreach my $file ( split(' ', $input_file) ) {
 
347
                print $ofh <<"EOT";
 
348
#####   ${file}
 
349
EOT
 
350
                };
 
351
        print $ofh <<"EOT";
 
352
#####
 
353
####################################################################
 
354
#------------------------------------------------------------------------------
 
355
#
 
356
# $out_file
 
357
#
 
358
# Copyright (c) 2001-2009 Richard Nelson.  All Rights Reserved.
 
359
# Version:        ${main::program_version}
 
360
# Time-stamp: <${main::program_date}>
 
361
#
 
362
# Sendmail crontab - Call sendmail at various times to do the following:
 
363
#       1) Age queues - move undelivered mail to a slower queue
 
364
#       2) Retry any mail queued by the message submission process
 
365
#       3) run the queues (deliver mail) if a standalone daemon is not desired
 
366
#
 
367
# Each processes is independant and guided by /etc/mail/sendmail.conf and
 
368
# {sendmail,submit}.mc files.
 
369
#
 
370
# There isn't anything here that should need touching.
 
371
#
 
372
# Any requisite queue/misc parameters must be set in /etc/mail/sendmail.conf
 
373
# and reflected herein via /usr/sbin/sendmailconfig (or more directly via
 
374
# ${main::program_name}).
 
375
#
 
376
#------------------------------------------------------------------------------
 
377
#
 
378
# use default path, shell, home
 
379
#SHELL=/bin/sh
 
380
#PATH=
 
381
#HOME=
 
382
# send mail to this user, as `mail/smmsp` isn't real.
 
383
MAILTO=$mailto
 
384
#
 
385
# format of entries:
 
386
# m h dom mon dow       user    command
 
387
#
 
388
#------------------------------------------------------------------------------
 
389
# Every so often, give sendmail a chance to run the MSP queues.
 
390
#
 
391
EOT
 
392
        ($ok, $interval) = &Parse_conf::get_value('MSP_INTERVAL');
 
393
        ($cronint, $ok) = &sm2cron_time($interval);
 
394
        $command  = "$test && /usr/share/sendmail/sendmail cron-msp";
 
395
        ($ok, $mmode) = &Parse_conf::get_value('MSP_MODE');
 
396
        ($ok, $qmode) = &Parse_conf::get_value('QUEUE_MODE');
 
397
        if ($mmode eq 'Cron'
 
398
                and ($interval ne '')
 
399
                #or ($mmode eq 'None' and $qmode eq 'Cron')
 
400
                ) {
 
401
                $msp_line =
 
402
                        "$cronint\t\tsmmsp\t$command";
 
403
                }
 
404
        else {
 
405
                $msp_line =
 
406
                        "#$cronint\t\tsmmsp\t$command";
 
407
                };
 
408
        print $ofh "$msp_line\n";
 
409
 
 
410
        print $ofh <<"EOT";
 
411
#
 
412
#------------------------------------------------------------------------------
 
413
# Every so often, give sendmail a chance to run the MTA queues.
 
414
# Will also run MSP queues if enabled
 
415
#
 
416
EOT
 
417
        ($ok, $interval) = &Parse_conf::get_value('QUEUE_INTERVAL');
 
418
        ($cronint, $ok) = &sm2cron_time($interval);
 
419
        $command  = "$test && /usr/share/sendmail/sendmail cron-mta";
 
420
        if ($qmode eq 'Cron'
 
421
                and ($interval ne '')
 
422
                ) {
 
423
                $mta_line =
 
424
                        "$cronint\t\troot\t$command";
 
425
                }
 
426
        else {
 
427
                $mta_line =
 
428
                        "#$cronint\t\troot\t$command";
 
429
                };
 
430
        print $ofh "$mta_line\n";
 
431
 
 
432
        print $ofh <<"EOT";
 
433
#
 
434
#------------------------------------------------------------------------------
 
435
# Every so often, give sendmail a chance to age the queues.
 
436
#
 
437
EOT
 
438
        ($ok, $var) = &Parse_conf::get_value('AGE_DATA');
 
439
        my $tmpval = eval $var;
 
440
        if ($@) {
 
441
                warn $@;
 
442
                }
 
443
        else {
 
444
                $var = $tmpval;
 
445
                };
 
446
        if (not ref $var) {
 
447
                print $ofh "# No queue aging\n";
 
448
                }
 
449
        elsif (@{$var} == 0) {
 
450
                print $ofh "# No queue aging\n";
 
451
                }
 
452
        else {
 
453
                foreach my $entry (@{$var}) {
 
454
                        ($interval, $ok) = &sm2cron_time(@$entry[0]);
 
455
                        my $criteria = @$entry[1] || join('','-s ',$ok);
 
456
                        my $to           = @$entry[2];
 
457
                        my $from         = @$entry[3];
 
458
                        $command         = "$test && /usr/share/sendmail/qtool.pl";
 
459
                        $from            = "/var/spool/mqueue/$from"
 
460
                                if ($from !~ /^\//);
 
461
                        $to                      = "/var/spool/mqueue/$to"
 
462
                                if ($to !~ /^\//);
 
463
                        $age_line        =
 
464
                                "$interval\t\troot\t$command $criteria $to $from";
 
465
                        print $ofh "$age_line >/dev/null\n";
 
466
                        };
 
467
                };
 
468
        print $ofh <<"EOT";
 
469
#
 
470
EOT
 
471
 
 
472
        close($ofh);
 
473
        };
 
474
 
 
475
#
 
476
#------------------------------------------------------------------------
 
477
# Update /etc/inetd.conf file
 
478
#------------------------------------------------------------------------
 
479
sub update_inetd {
 
480
 
 
481
        # Don't try to write if we're debugging
 
482
        if ($output_file ne '') {
 
483
                return;
 
484
                };
 
485
 
 
486
        my ($ok, $mode) = &Parse_conf::get_value('DAEMON_MODE');
 
487
        if ( $ok and -x '/usr/sbin/update-inetd' ) {
 
488
                if ( $mode eq 'Inetd' ) {
 
489
                        system 'update-inetd --group MAIL --enable smtp,smtps,submission'
 
490
                        }
 
491
                else {
 
492
                        system 'update-inetd --group MAIL --disable smtp,smtps,submission'
 
493
                        };
 
494
                };
 
495
 
 
496
        };
 
497
 
 
498
#
 
499
#------------------------------------------------------------------------
 
500
# Update mail statistics information (create/delete files)
 
501
#------------------------------------------------------------------------
 
502
sub update_files {
 
503
 
 
504
        # Don't try to write if we're debugging
 
505
        if ($output_file ne '') {
 
506
                return;
 
507
                };
 
508
 
 
509
        my ($class, $flags, $files, $options);
 
510
        my ($ok, $stats);
 
511
        my $file;
 
512
 
 
513
        #
 
514
        # Read the mc/m4 files
 
515
        &Parse_mc::read_dbs('', '');
 
516
 
 
517
        # Obtain entry for HOST_STATUS_DIRECTORY
 
518
        ($class, $flags, $files, $options) =
 
519
                &Parse_mc::entry_dbs('confHOST_STATUS_DIRECTORY');
 
520
        $file = @{$files}[0];
 
521
        ($ok, $stats) = &Parse_conf::get_value('DAEMON_HOSTSTATS');
 
522
        if ( $ok and $file ne '-' ) {
 
523
                if ( $stats and ! -d $file) {
 
524
                        print STDOUT "Enabling HOST statistics file($file).\n";
 
525
                        system "mkdir ${file}";
 
526
                        my $gid = getgrnam('smmsp');
 
527
                        chown '0', $gid, $file;
 
528
                        chmod 02755, $file;
 
529
                        }
 
530
                elsif ( ! $stats and -d $file ) {
 
531
                        print STDOUT "Disabling HOST statistics file($file).\n";
 
532
                        system "rm -rf ${file}";
 
533
                        };
 
534
                };
 
535
 
 
536
        # Obtain entry for STATUS_FILE
 
537
        ($class, $flags, $files, $options) =
 
538
                &Parse_mc::entry_dbs('STATUS_FILE');
 
539
        $file = @{$files}[0];
 
540
        ($ok, $stats) = &Parse_conf::get_value('DAEMON_MAILSTATS');
 
541
        if ( $ok and $file ne '-' ) {
 
542
                if ( $stats and ! -e $file) {
 
543
                        print STDOUT "Enabling MTA statistics file($file).\n";
 
544
                        open  'STATS', ">$file";
 
545
                        close 'STATS';
 
546
                        my $gid = getgrnam('smmsp');
 
547
                        chown '0', $gid, $file;
 
548
                        chmod 0640, $file;
 
549
                        }
 
550
                elsif ( ! $stats and -e $file ) {
 
551
                        print STDOUT "Disabling MTA statistics file($file).\n";
 
552
                        unlink $file;
 
553
                        };
 
554
                };
 
555
 
 
556
        # Obtain entry for MSP_STATUS_FILE
 
557
        ($class, $flags, $files, $options) =
 
558
                &Parse_mc::entry_dbs('MSP_STATUS_FILE');
 
559
        $file = @{$files}[0];
 
560
        ($ok, $stats) = &Parse_conf::get_value('MSP_MAILSTATS');
 
561
        if ( $ok and $file ne '-') {
 
562
                if ( $stats and ! -e $file ) {
 
563
                        print STDOUT "Enabling MSP statistics file($file).\n";
 
564
                        open  'STATS', ">$file";
 
565
                        close 'STATS';
 
566
                        my $gid = getgrnam('smmsp');
 
567
                        chown '0', $gid, $file;
 
568
                        chmod 0660, $file;
 
569
                        }
 
570
                elsif ( ! $stats and -e $file ) {
 
571
                        print STDOUT "Disabling MSP statistics file($file).\n";
 
572
                        unlink $file;
 
573
                        };
 
574
                };
 
575
 
 
576
        };
 
577