~ubuntu-branches/ubuntu/maverick/postfix/maverick-security

« back to all changes in this revision

Viewing changes to src/postconf/postconf.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones, Wietse Venema, LaMont Jones
  • Date: 2009-06-03 14:17:08 UTC
  • mfrom: (1.1.22 upstream)
  • Revision ID: james.westby@ubuntu.com-20090603141708-o9u59xlor7nmd2x1
[Wietse Venema]

* New upstream release: 2.6.2~rc1

[LaMont Jones]

* move postfix-add-{filter,policy} manpages to section 8, and deliver
* provide: default-mta on ubuntu

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
/*      \fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
14
14
/*      [\fIparameter=value ...\fR]
15
15
/*
 
16
/*      \fBpostconf\fR [\fB-#v\fR] [\fB-c \fIconfig_dir\fR]
 
17
/*      [\fIparameter ...\fR]
 
18
/*
16
19
/*      \fBpostconf\fR [\fB-btv\fR] [\fB-c \fIconfig_dir\fR] [\fItemplate_file\fR]
17
20
/* DESCRIPTION
18
21
/*      The \fBpostconf\fR(1) command displays the actual values
31
34
/*      This server plug-in is available when Postfix is built with
32
35
/*      Cyrus SASL support.
33
36
/* .IP \fBdovecot\fR
34
 
/*      This server plug-in requires the Dovecot authentication
35
 
/*      server.
 
37
/*      This server plug-in uses the Dovecot authentication server,
 
38
/*      and is available when Postfix is built with any form of SASL
 
39
/*      support.
36
40
/* .RE
37
41
/* .IP
38
42
/*      This feature is available with Postfix 2.3 and later.
177
181
/* .IP \fB-v\fR
178
182
/*      Enable verbose logging for debugging purposes. Multiple \fB-v\fR
179
183
/*      options make the software increasingly verbose.
 
184
/* .IP \fB-#\fR
 
185
/*      Edit the \fBmain.cf\fR configuration file. The file is copied
 
186
/*      to a temporary file then renamed into place. The parameters
 
187
/*      specified on the command line are commented-out, so that they
 
188
/*      revert to their default values. Specify a list of parameter
 
189
/*      names, not name=value pairs.  There is no \fBpostconf\fR command
 
190
/*      to perform the reverse operation.
 
191
/*
 
192
/*      This feature is available with Postfix 2.6 and later.
180
193
/* DIAGNOSTICS
181
194
/*      Problems are reported to the standard error stream.
182
195
/* ENVIRONMENT
253
266
#include <myflock.h>
254
267
#include <inet_proto.h>
255
268
#include <argv.h>
 
269
#include <edit_file.h>
256
270
 
257
271
/* Global library. */
258
272
 
282
296
#define SHOW_EVAL       (1<<6)          /* expand right-hand sides */
283
297
#define SHOW_SASL_SERV  (1<<7)          /* show server auth plugin types */
284
298
#define SHOW_SASL_CLNT  (1<<8)          /* show client auth plugin types */
 
299
#define COMMENT_OUT     (1<<9)          /* #-out selected main.cf entries */
285
300
 
286
301
 /*
287
302
  * Lookup table for in-core parameter info.
301
316
#include "int_vars.h"
302
317
#include "str_vars.h"
303
318
#include "raw_vars.h"
 
319
#include "nint_vars.h"
304
320
 
305
321
 /*
306
322
  * Manually extracted.
338
354
    0,
339
355
};
340
356
 
 
357
static const CONFIG_NINT_TABLE nint_table[] = {
 
358
#include "nint_table.h"
 
359
    0,
 
360
};
 
361
 
341
362
 /*
342
363
  * Parameters with default values obtained via function calls.
343
364
  */
450
471
 
451
472
/* edit_parameters - edit parameter file */
452
473
 
453
 
static void edit_parameters(int argc, char **argv)
 
474
static void edit_parameters(int cmd_mode, int argc, char **argv)
454
475
{
455
476
    char   *config_dir;
456
477
    char   *path;
457
 
    char   *temp;
 
478
    EDIT_FILE *ep;
458
479
    VSTREAM *src;
459
480
    VSTREAM *dst;
460
481
    VSTRING *buf = vstring_alloc(100);
479
500
    table = htable_create(argc);
480
501
    while ((cp = *argv++) != 0) {
481
502
        if (strchr(cp, '\n') != 0)
482
 
            msg_fatal("edit accepts no multi-line input");
 
503
            msg_fatal("-e or -# accepts no multi-line input");
483
504
        while (ISSPACE(*cp))
484
505
            cp++;
485
506
        if (*cp == '#')
486
 
            msg_fatal("edit accepts no comment input");
487
 
        if ((err = split_nameval(cp, &edit_key, &edit_val)) != 0)
488
 
            msg_fatal("%s: \"%s\"", err, cp);
 
507
            msg_fatal("-e or -# accepts no comment input");
 
508
        if (cmd_mode & EDIT_MAIN) {
 
509
            if ((err = split_nameval(cp, &edit_key, &edit_val)) != 0)
 
510
                msg_fatal("%s: \"%s\"", err, cp);
 
511
        } else if (cmd_mode & COMMENT_OUT) {
 
512
            if (*cp == 0)
 
513
                msg_fatal("-# requires non-blank parameter names");
 
514
            if (strchr(cp, '=') != 0)
 
515
                msg_fatal("-# requires parameter names only");
 
516
            edit_key = mystrdup(cp);
 
517
            trimblanks(edit_key, 0);
 
518
            edit_val = 0;
 
519
        } else {
 
520
            msg_panic("edit_parameters: unknown mode %d", cmd_mode);
 
521
        }
489
522
        cvalue = (struct cvalue *) mymalloc(sizeof(*cvalue));
490
523
        cvalue->value = edit_val;
491
524
        cvalue->found = 0;
502
535
    set_mail_conf_str(VAR_CONFIG_DIR, var_config_dir);
503
536
 
504
537
    /*
 
538
     * Open a temp file for the result. This uses a deterministic name so we
 
539
     * don't leave behind thrash with random names.
 
540
     */
 
541
    path = concatenate(var_config_dir, "/", "main.cf", (char *) 0);
 
542
    if ((ep = edit_file_open(path, O_CREAT | O_WRONLY, 0644)) == 0)
 
543
        msg_fatal("open %s%s: %m", path, EDIT_FILE_SUFFIX);
 
544
    dst = ep->tmp_fp;
 
545
 
 
546
    /*
505
547
     * Open the original file for input.
506
548
     */
507
 
    path = concatenate(var_config_dir, "/", "main.cf", (char *) 0);
508
 
    if ((src = vstream_fopen(path, O_RDONLY, 0)) == 0)
 
549
    if ((src = vstream_fopen(path, O_RDONLY, 0)) == 0) {
 
550
        /* OK to delete, since we control the temp file name exclusively. */
 
551
        (void) unlink(ep->tmp_path);
509
552
        msg_fatal("open %s for reading: %m", path);
510
 
 
511
 
    /*
512
 
     * Open a temp file for the result. We use a fixed name so we don't leave
513
 
     * behind thrash with random names. Lock the temp file to avoid
514
 
     * accidents. Truncate the file only after we have an exclusive lock.
515
 
     */
516
 
    temp = concatenate(path, ".tmp", (char *) 0);
517
 
    if ((dst = vstream_fopen(temp, O_CREAT | O_WRONLY, 0644)) == 0)
518
 
        msg_fatal("open %s: %m", temp);
519
 
    if (myflock(vstream_fileno(dst), INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
520
 
        msg_fatal("lock %s: %m", temp);
521
 
    if (ftruncate(vstream_fileno(dst), 0) < 0)
522
 
        msg_fatal("truncate %s: %m", temp);
 
553
    }
523
554
 
524
555
    /*
525
556
     * Copy original file to temp file, while replacing parameters on the
535
566
        if (*cp == '#' || *cp == 0) {
536
567
            vstream_fputs(STR(buf), dst);
537
568
        }
538
 
        /* Copy or skip continued text. */
 
569
        /* Copy, skip or replace continued text. */
539
570
        else if (cp > STR(buf)) {
540
571
            if (interesting == 0)
541
572
                vstream_fputs(STR(buf), dst);
 
573
            else if (cmd_mode & COMMENT_OUT)
 
574
                vstream_fprintf(dst, "#%s", STR(buf));
542
575
        }
543
576
        /* Copy or replace start of logical line. */
544
577
        else {
547
580
            if ((interesting = !!cvalue) != 0) {
548
581
                if (cvalue->found++ == 1)
549
582
                    msg_warn("%s: multiple entries for \"%s\"", path, STR(key));
550
 
                vstream_fprintf(dst, "%s = %s\n", STR(key), cvalue->value);
 
583
                if (cmd_mode & EDIT_MAIN)
 
584
                    vstream_fprintf(dst, "%s = %s\n", STR(key), cvalue->value);
 
585
                else if (cmd_mode & COMMENT_OUT)
 
586
                    vstream_fprintf(dst, "#%s", cp);
 
587
                else
 
588
                    msg_panic("edit_parameters: unknown mode %d", cmd_mode);
551
589
            } else {
552
590
                vstream_fputs(STR(buf), dst);
553
591
            }
557
595
    /*
558
596
     * Generate new entries for parameters that were not found.
559
597
     */
560
 
    for (ht_info = ht = htable_list(table); *ht; ht++) {
561
 
        cvalue = (struct cvalue *) ht[0]->value;
562
 
        if (cvalue->found == 0)
563
 
            vstream_fprintf(dst, "%s = %s\n", ht[0]->key, cvalue->value);
 
598
    if (cmd_mode & EDIT_MAIN) {
 
599
        for (ht_info = ht = htable_list(table); *ht; ht++) {
 
600
            cvalue = (struct cvalue *) ht[0]->value;
 
601
            if (cvalue->found == 0)
 
602
                vstream_fprintf(dst, "%s = %s\n", ht[0]->key, cvalue->value);
 
603
        }
 
604
        myfree((char *) ht_info);
564
605
    }
565
 
    myfree((char *) ht_info);
566
606
 
567
607
    /*
568
608
     * When all is well, rename the temp file to the original one.
569
609
     */
570
610
    if (vstream_fclose(src))
571
611
        msg_fatal("read %s: %m", path);
572
 
    if (vstream_fclose(dst))
573
 
        msg_fatal("write %s: %m", temp);
574
 
    if (rename(temp, path) < 0)
575
 
        msg_fatal("rename %s to %s: %m", temp, path);
 
612
    if (edit_file_close(ep) != 0)
 
613
        msg_fatal("close %s%s: %m", path, EDIT_FILE_SUFFIX);
576
614
 
577
615
    /*
578
616
     * Cleanup.
579
617
     */
580
618
    myfree(path);
581
 
    myfree(temp);
582
619
    vstring_free(buf);
583
620
    vstring_free(key);
584
621
    htable_free(table, myfree);
640
677
    const CONFIG_STR_TABLE *cst;
641
678
    const CONFIG_STR_FN_TABLE *csft;
642
679
    const CONFIG_RAW_TABLE *rst;
 
680
    const CONFIG_NINT_TABLE *nst;
643
681
 
644
682
    param_table = htable_create(100);
645
683
 
657
695
        htable_enter(param_table, csft->name, (char *) csft);
658
696
    for (rst = raw_table; rst->name; rst++)
659
697
        htable_enter(param_table, rst->name, (char *) rst);
 
698
    for (nst = nint_table; nst->name; nst++)
 
699
        htable_enter(param_table, nst->name, (char *) nst);
660
700
}
661
701
 
662
702
/* show_strval - show string-valued parameter */
849
889
    }
850
890
}
851
891
 
 
892
/* print_nint - print new integer parameter */
 
893
 
 
894
static void print_nint(int mode, CONFIG_NINT_TABLE * rst)
 
895
{
 
896
    const char *value;
 
897
 
 
898
    if (mode & SHOW_EVAL)
 
899
        msg_warn("parameter %s expands at run-time", rst->name);
 
900
    mode &= ~SHOW_EVAL;
 
901
 
 
902
    if (mode & SHOW_DEFS) {
 
903
        show_strval(mode, rst->name, rst->defval);
 
904
    } else {
 
905
        value = dict_lookup(CONFIG_DICT, rst->name);
 
906
        if ((mode & SHOW_NONDEF) == 0) {
 
907
            if (value == 0) {
 
908
                show_strval(mode, rst->name, rst->defval);
 
909
            } else {
 
910
                show_strval(mode, rst->name, value);
 
911
            }
 
912
        } else {
 
913
            if (value != 0)
 
914
                show_strval(mode, rst->name, value);
 
915
        }
 
916
    }
 
917
}
 
918
 
852
919
/* print_parameter - show specific parameter */
853
920
 
854
921
static void print_parameter(int mode, char *ptr)
873
940
        print_str_fn_2(mode, (CONFIG_STR_FN_TABLE *) ptr);
874
941
    if (INSIDE(ptr, raw_table))
875
942
        print_raw(mode, (CONFIG_RAW_TABLE *) ptr);
 
943
    if (INSIDE(ptr, nint_table))
 
944
        print_nint(mode, (CONFIG_NINT_TABLE *) ptr);
876
945
    if (msg_verbose)
877
946
        vstream_fflush(VSTREAM_OUT);
878
947
}
1010
1079
    /*
1011
1080
     * Parse JCL.
1012
1081
     */
1013
 
    while ((ch = GETOPT(argc, argv, "aAbc:deEhmlntv")) > 0) {
 
1082
    while ((ch = GETOPT(argc, argv, "aAbc:deE#hmlntv")) > 0) {
1014
1083
        switch (ch) {
1015
1084
        case 'a':
1016
1085
            cmd_mode |= SHOW_SASL_SERV;
1046
1115
            cmd_mode |= SHOW_EVAL;
1047
1116
            break;
1048
1117
#endif
 
1118
        case '#':
 
1119
            cmd_mode = COMMENT_OUT;
 
1120
            break;
 
1121
 
1049
1122
        case 'h':
1050
1123
            cmd_mode &= ~SHOW_NAME;
1051
1124
            break;
1068
1141
            msg_verbose++;
1069
1142
            break;
1070
1143
        default:
1071
 
            msg_fatal("usage: %s [-a (server SASL types)] [-A (client SASL types)] [-b (bounce templates)] [-c config_dir] [-d (defaults)] [-e (edit)] [-h (no names)] [-l (lock types)] [-m (map types)] [-n (non-defaults)] [-v] [name...]", argv[0]);
 
1144
            msg_fatal("usage: %s [-a (server SASL types)] [-A (client SASL types)] [-b (bounce templates)] [-c config_dir] [-d (defaults)] [-e (edit)] [-# (comment-out)] [-h (no names)] [-l (lock types)] [-m (map types)] [-n (non-defaults)] [-v] [name...]", argv[0]);
1072
1145
        }
1073
1146
    }
1074
1147
 
1075
1148
    /*
1076
1149
     * Sanity check.
1077
1150
     */
1078
 
    junk = (cmd_mode & (SHOW_DEFS | SHOW_NONDEF | SHOW_MAPS | SHOW_LOCKS | EDIT_MAIN | SHOW_SASL_SERV | SHOW_SASL_CLNT));
 
1151
    junk = (cmd_mode & (SHOW_DEFS | SHOW_NONDEF | SHOW_MAPS | SHOW_LOCKS | EDIT_MAIN | SHOW_SASL_SERV | SHOW_SASL_CLNT | COMMENT_OUT));
1079
1152
    if (junk != 0 && ((junk != SHOW_DEFS && junk != SHOW_NONDEF
1080
1153
             && junk != SHOW_MAPS && junk != SHOW_LOCKS && junk != EDIT_MAIN
1081
 
                       && junk != SHOW_SASL_SERV && junk != SHOW_SASL_CLNT)
 
1154
                       && junk != SHOW_SASL_SERV && junk != SHOW_SASL_CLNT
 
1155
                       && junk != COMMENT_OUT)
1082
1156
                      || ext_argv != 0))
1083
 
        msg_fatal("specify one of -a, -A, -b, -d, -e, -m, -l and -n");
 
1157
        msg_fatal("specify one of -a, -A, -b, -d, -e, -#, -m, -l and -n");
1084
1158
 
1085
1159
    /*
1086
1160
     * Display bounce template information and exit.
1130
1204
    /*
1131
1205
     * Edit main.cf.
1132
1206
     */
1133
 
    else if (cmd_mode & EDIT_MAIN) {
1134
 
        edit_parameters(argc - optind, argv + optind);
 
1207
    else if (cmd_mode & (EDIT_MAIN | COMMENT_OUT)) {
 
1208
        edit_parameters(cmd_mode, argc - optind, argv + optind);
1135
1209
    }
1136
1210
 
1137
1211
    /*