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

« back to all changes in this revision

Viewing changes to src/postmap/postmap.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:
5
5
/*      Postfix lookup table management
6
6
/* SYNOPSIS
7
7
/* .fi
8
 
/*      \fBpostmap\fR [\fB-Nfinoprsuvw\fR] [\fB-c \fIconfig_dir\fR]
 
8
/*      \fBpostmap\fR [\fB-Nbfhimnoprsuvw\fR] [\fB-c \fIconfig_dir\fR]
9
9
/*      [\fB-d \fIkey\fR] [\fB-q \fIkey\fR]
10
10
/*              [\fIfile_type\fR:]\fIfile_name\fR ...
11
11
/* DESCRIPTION
57
57
/* COMMAND-LINE ARGUMENTS
58
58
/* .ad
59
59
/* .fi
 
60
/* .IP \fB-b\fR
 
61
/*      Enable message body query mode. When reading lookup keys
 
62
/*      from standard input with "\fB-q -\fR", process the input
 
63
/*      as if it is an email message in RFC 2822 format.  Each line
 
64
/*      of body content becomes one lookup key.
 
65
/* .sp
 
66
/*      By default, the \fB-b\fR option starts generating lookup
 
67
/*      keys at the first non-header line, and stops when the end
 
68
/*      of the message is reached.
 
69
/*      To simulate \fBbody_checks\fR(5) processing, enable MIME
 
70
/*      parsing with \fB-m\fR. With this, the \fB-b\fR option
 
71
/*      generates no body-style lookup keys for attachment MIME
 
72
/*      headers and for attached message/* headers.
 
73
/* .sp
 
74
/*      This feature is available in Postfix version 2.6 and later.
60
75
/* .IP "\fB-c \fIconfig_dir\fR"
61
76
/*      Read the \fBmain.cf\fR configuration file in the named directory
62
77
/*      instead of the default configuration directory.
74
89
/*      With Postfix version 2.3 and later, this option has no
75
90
/*      effect for regular expression tables. There, case folding
76
91
/*      is controlled by appending a flag to a pattern.
 
92
/* .IP \fB-h\fR
 
93
/*      Enable message header query mode. When reading lookup keys
 
94
/*      from standard input with "\fB-q -\fR", process the input
 
95
/*      as if it is an email message in RFC 2822 format.  Each
 
96
/*      logical header line becomes one lookup key. A multi-line
 
97
/*      header becomes one lookup key with one or more embedded
 
98
/*      newline characters.
 
99
/* .sp
 
100
/*      By default, the \fB-h\fR option generates lookup keys until
 
101
/*      the first non-header line is reached.
 
102
/*      To simulate \fBheader_checks\fR(5) processing, enable MIME
 
103
/*      parsing with \fB-m\fR. With this, the \fB-h\fR option also
 
104
/*      generates header-style lookup keys for attachment MIME
 
105
/*      headers and for attached message/* headers.
 
106
/* .sp
 
107
/*      This feature is available in Postfix version 2.6 and later.
77
108
/* .IP \fB-i\fR
78
109
/*      Incremental mode. Read entries from standard input and do not
79
110
/*      truncate an existing database. By default, \fBpostmap\fR(1) creates
80
111
/*      a new database from the entries in \fBfile_name\fR.
 
112
/* .IP \fB-m\fR
 
113
/*      Enable MIME parsing with "\fB-b\fR" and "\fB-h\fR".
 
114
/* .sp
 
115
/*      This feature is available in Postfix version 2.6 and later.
81
116
/* .IP \fB-N\fR
82
117
/*      Include the terminating null character that terminates lookup keys
83
118
/*      and values. By default, \fBpostmap\fR(1) does whatever is
113
148
/*      \fIkey value\fR output for each element. The elements are
114
149
/*      printed in database order, which is not necessarily the same
115
150
/*      as the original input order.
 
151
/* .sp
116
152
/*      This feature is available in Postfix version 2.2 and later,
117
153
/*      and is not available for all database types.
118
154
/* .IP \fB-u\fR
193
229
/*      and \fBpostmap\fR(1) commands.
194
230
/* .IP "\fBsyslog_facility (mail)\fR"
195
231
/*      The syslog facility of Postfix logging.
196
 
/* .IP "\fBsyslog_name (postfix)\fR"
 
232
/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
197
233
/*      The mail system name that is prepended to the process name in syslog
198
234
/*      records, so that "smtpd" becomes, for example, "postfix/smtpd".
199
235
/* SEE ALSO
253
289
#include <mkmap.h>
254
290
#include <mail_task.h>
255
291
#include <dict_proxy.h>
 
292
#include <mime_state.h>
 
293
#include <rec_type.h>
256
294
 
257
295
/* Application-specific. */
258
296
 
259
297
#define STR     vstring_str
 
298
#define LEN     VSTRING_LEN
260
299
 
261
300
#define POSTMAP_FLAG_AS_OWNER   (1<<0)  /* open dest as owner of source */
262
301
#define POSTMAP_FLAG_SAVE_PERM  (1<<1)  /* copy access permission from source */
 
302
#define POSTMAP_FLAG_HEADER_KEY (1<<2)  /* apply to header text */
 
303
#define POSTMAP_FLAG_BODY_KEY   (1<<3)  /* apply to body text */
 
304
#define POSTMAP_FLAG_MIME_KEY   (1<<4)  /* enable MIME parsing */
 
305
 
 
306
#define POSTMAP_FLAG_HB_KEY (POSTMAP_FLAG_HEADER_KEY | POSTMAP_FLAG_BODY_KEY)
 
307
#define POSTMAP_FLAG_FULL_KEY (POSTMAP_FLAG_BODY_KEY | POSTMAP_FLAG_MIME_KEY)
 
308
#define POSTMAP_FLAG_ANY_KEY (POSTMAP_FLAG_HB_KEY | POSTMAP_FLAG_MIME_KEY)
 
309
 
 
310
 /*
 
311
  * MIME Engine call-back state for generating lookup keys from an email
 
312
  * message read from standard input.
 
313
  */
 
314
typedef struct {
 
315
    DICT  **dicts;                      /* map handles */
 
316
    char  **maps;                       /* map names */
 
317
    int     map_count;                  /* yes, indeed */
 
318
    int     dict_flags;                 /* query flags */
 
319
    int     header_done;                /* past primary header */
 
320
    int     found;                      /* result */
 
321
} POSTMAP_KEY_STATE;
263
322
 
264
323
/* postmap - create or update mapping database */
265
324
 
369
428
        vstream_fclose(source_fp);
370
429
}
371
430
 
 
431
/* postmap_body - MIME engine body call-back routine */
 
432
 
 
433
static void postmap_body(void *ptr, int unused_rec_type,
 
434
                                 const char *keybuf,
 
435
                                 ssize_t unused_len,
 
436
                                 off_t unused_offset)
 
437
{
 
438
    POSTMAP_KEY_STATE *state = (POSTMAP_KEY_STATE *) ptr;
 
439
    DICT  **dicts = state->dicts;
 
440
    char  **maps = state->maps;
 
441
    int     map_count = state->map_count;
 
442
    int     dict_flags = state->dict_flags;
 
443
    const char *map_name;
 
444
    const char *value;
 
445
    int     n;
 
446
 
 
447
    for (n = 0; n < map_count; n++) {
 
448
        if (dicts[n] == 0)
 
449
            dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
 
450
                        dict_open3(maps[n], map_name, O_RDONLY, dict_flags) :
 
451
                    dict_open3(var_db_type, maps[n], O_RDONLY, dict_flags));
 
452
        if ((value = dict_get(dicts[n], keybuf)) != 0) {
 
453
            if (*value == 0) {
 
454
                msg_warn("table %s:%s: key %s: empty string result is not allowed",
 
455
                         dicts[n]->type, dicts[n]->name, keybuf);
 
456
                msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
 
457
                         dicts[n]->type, dicts[n]->name);
 
458
            }
 
459
            vstream_printf("%s  %s\n", keybuf, value);
 
460
            state->found = 1;
 
461
            break;
 
462
        }
 
463
    }
 
464
}
 
465
 
 
466
/* postmap_header - MIME engine header call-back routine */
 
467
 
 
468
static void postmap_header(void *ptr, int unused_header_class,
 
469
                                   const HEADER_OPTS *unused_header_info,
 
470
                                   VSTRING *header_buf,
 
471
                                   off_t offset)
 
472
{
 
473
 
 
474
    /*
 
475
     * Don't re-invent an already working wheel.
 
476
     */
 
477
    postmap_body(ptr, 0, STR(header_buf), LEN(header_buf), offset);
 
478
}
 
479
 
 
480
/* postmap_head_end - MIME engine end-of-header call-back routine */
 
481
 
 
482
static void postmap_head_end(void *ptr)
 
483
{
 
484
    POSTMAP_KEY_STATE *state = (POSTMAP_KEY_STATE *) ptr;
 
485
 
 
486
    /*
 
487
     * Don't process the message body when we only examine primary headers.
 
488
     */
 
489
    state->header_done = 1;
 
490
}
 
491
 
372
492
/* postmap_queries - apply multiple requests from stdin */
373
493
 
374
494
static int postmap_queries(VSTREAM *in, char **maps, const int map_count,
 
495
                                   const int postmap_flags,
375
496
                                   const int dict_flags)
376
497
{
377
498
    int     found = 0;
398
519
     * Perform all queries. Open maps on the fly, to avoid opening unecessary
399
520
     * maps.
400
521
     */
401
 
    while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) {
402
 
        for (n = 0; n < map_count; n++) {
403
 
            if (dicts[n] == 0)
404
 
                dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
 
522
    if ((postmap_flags & POSTMAP_FLAG_HB_KEY) == 0) {
 
523
        while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) {
 
524
            for (n = 0; n < map_count; n++) {
 
525
                if (dicts[n] == 0)
 
526
                    dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
405
527
                       dict_open3(maps[n], map_name, O_RDONLY, dict_flags) :
406
528
                    dict_open3(var_db_type, maps[n], O_RDONLY, dict_flags));
407
 
            if ((value = dict_get(dicts[n], STR(keybuf))) != 0) {
408
 
                if (*value == 0) {
409
 
                    msg_warn("table %s:%s: key %s: empty string result is not allowed",
410
 
                             dicts[n]->type, dicts[n]->name, STR(keybuf));
411
 
                    msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
412
 
                             dicts[n]->type, dicts[n]->name);
 
529
                if ((value = dict_get(dicts[n], STR(keybuf))) != 0) {
 
530
                    if (*value == 0) {
 
531
                        msg_warn("table %s:%s: key %s: empty string result is not allowed",
 
532
                               dicts[n]->type, dicts[n]->name, STR(keybuf));
 
533
                        msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
 
534
                                 dicts[n]->type, dicts[n]->name);
 
535
                    }
 
536
                    vstream_printf("%s  %s\n", STR(keybuf), value);
 
537
                    found = 1;
 
538
                    break;
413
539
                }
414
 
                vstream_printf("%s      %s\n", STR(keybuf), value);
415
 
                found = 1;
416
 
                break;
417
540
            }
418
541
        }
 
542
    } else {
 
543
        POSTMAP_KEY_STATE key_state;
 
544
        MIME_STATE *mime_state;
 
545
        int     mime_errs = 0;
 
546
 
 
547
        /*
 
548
         * Bundle up the request and instantiate a MIME parsing engine.
 
549
         */
 
550
        key_state.dicts = dicts;
 
551
        key_state.maps = maps;
 
552
        key_state.map_count = map_count;
 
553
        key_state.dict_flags = dict_flags;
 
554
        key_state.header_done = 0;
 
555
        key_state.found = 0;
 
556
        mime_state =
 
557
            mime_state_alloc((postmap_flags & POSTMAP_FLAG_MIME_KEY) ?
 
558
                             0 : MIME_OPT_DISABLE_MIME,
 
559
                             (postmap_flags & POSTMAP_FLAG_HEADER_KEY) ?
 
560
                             postmap_header : (MIME_STATE_HEAD_OUT) 0,
 
561
                             (postmap_flags & POSTMAP_FLAG_FULL_KEY) ?
 
562
                             (MIME_STATE_ANY_END) 0 : postmap_head_end,
 
563
                             (postmap_flags & POSTMAP_FLAG_BODY_KEY) ?
 
564
                             postmap_body : (MIME_STATE_BODY_OUT) 0,
 
565
                             (MIME_STATE_ANY_END) 0,
 
566
                             (MIME_STATE_ERR_PRINT) 0,
 
567
                             (void *) &key_state);
 
568
 
 
569
        /*
 
570
         * Process the input message.
 
571
         */
 
572
        while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF
 
573
               && key_state.header_done == 0 && mime_errs == 0)
 
574
            mime_errs = mime_state_update(mime_state, REC_TYPE_NORM,
 
575
                                          STR(keybuf), LEN(keybuf));
 
576
 
 
577
        /*
 
578
         * Flush the MIME engine output buffer and tidy up loose ends.
 
579
         */
 
580
        if (mime_errs == 0)
 
581
            mime_errs = mime_state_update(mime_state, REC_TYPE_END, "", 0);
 
582
        if (mime_errs)
 
583
            msg_fatal("message format error: %s",
 
584
                      mime_state_detail(mime_errs)->text);
 
585
        mime_state_free(mime_state);
 
586
        found = key_state.found;
419
587
    }
420
588
    if (found)
421
589
        vstream_fflush(VSTREAM_OUT);
634
802
    /*
635
803
     * Parse JCL.
636
804
     */
637
 
    while ((ch = GETOPT(argc, argv, "Nc:d:finopq:rsuvw")) > 0) {
 
805
    while ((ch = GETOPT(argc, argv, "Nbc:d:fhimnopq:rsuvw")) > 0) {
638
806
        switch (ch) {
639
807
        default:
640
808
            usage(argv[0]);
643
811
            dict_flags |= DICT_FLAG_TRY1NULL;
644
812
            dict_flags &= ~DICT_FLAG_TRY0NULL;
645
813
            break;
 
814
        case 'b':
 
815
            postmap_flags |= POSTMAP_FLAG_BODY_KEY;
 
816
            break;
646
817
        case 'c':
647
818
            if (setenv(CONF_ENV_PATH, optarg, 1) < 0)
648
819
                msg_fatal("out of memory");
655
826
        case 'f':
656
827
            dict_flags &= ~DICT_FLAG_FOLD_FIX;
657
828
            break;
 
829
        case 'h':
 
830
            postmap_flags |= POSTMAP_FLAG_HEADER_KEY;
 
831
            break;
658
832
        case 'i':
659
833
            open_flags &= ~O_TRUNC;
660
834
            break;
 
835
        case 'm':
 
836
            postmap_flags |= POSTMAP_FLAG_MIME_KEY;
 
837
            break;
661
838
        case 'n':
662
839
            dict_flags |= DICT_FLAG_TRY0NULL;
663
840
            dict_flags &= ~DICT_FLAG_TRY1NULL;
700
877
    if (strcmp(var_syslog_name, DEF_SYSLOG_NAME) != 0)
701
878
        msg_syslog_init(mail_task(argv[0]), LOG_PID, LOG_FACILITY);
702
879
    mail_dict_init();
 
880
    if ((query == 0 || strcmp(query, "-") != 0) 
 
881
        && (postmap_flags & POSTMAP_FLAG_ANY_KEY))
 
882
        msg_fatal("specify -b -h or -m only with \"-q -\"");
703
883
 
704
884
    /*
705
885
     * Use the map type specified by the user, or fall back to a default
728
908
            usage(argv[0]);
729
909
        if (strcmp(query, "-") == 0)
730
910
            exit(postmap_queries(VSTREAM_IN, argv + optind, argc - optind,
731
 
                                 dict_flags | DICT_FLAG_LOCK) == 0);
 
911
                          postmap_flags, dict_flags | DICT_FLAG_LOCK) == 0);
732
912
        while (optind < argc) {
733
913
            if ((path_name = split_at(argv[optind], ':')) != 0) {
734
914
                found = postmap_query(argv[optind], path_name, query,