File: transport.c

package info (click to toggle)
postfix 0.0.19991231pl11-2
  • links: PTS
  • area: main
  • in suites: potato
  • size: 5,044 kB
  • ctags: 4,401
  • sloc: ansic: 33,767; makefile: 5,099; sh: 1,790; awk: 19
file content (135 lines) | stat: -rw-r--r-- 3,425 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*++
/* NAME
/*	transport 3
/* SUMMARY
/*	transport mapping
/* SYNOPSIS
/*	#include "transport.h"
/*
/*	void	transport_init()
/*
/*	int	transport_lookup(domain, channel, nexthop)
/*	const char *domain;
/*	VSTRING *channel;
/*	VSTRING *nexthop;
/* DESCRIPTION
/*	This module implements access to the table that maps transport
/*	domains to (channel, nexthop) tuples.
/*
/*	transport_init() performs initializations that should be
/*	done before the process enters the chroot jail, and
/*	before calling transport_lookup().
/*
/*	transport_lookup() finds the channel and nexthop for the given
/*	domain, and returns 1 if something was found.	Otherwise, 0
/*	is returned.
/* DIAGNOSTICS
/*	The global \fIdict_errno\fR is non-zero when the lookup
/*	should be tried again.
/* SEE ALSO
/*	maps(3), multi-dictionary search
/*	transport(5), format of transport map
/* FILES
/*	/etc/postfix/transport*
/* CONFIGURATION PARAMETERS
/*	transport_maps, names of maps to be searched.
/* LICENSE
/* .ad
/* .fi
/*	The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/*	Wietse Venema
/*	IBM T.J. Watson Research
/*	P.O. Box 704
/*	Yorktown Heights, NY 10598, USA
/*--*/

/* System library. */

#include <sys_defs.h>
#include <string.h>

/* Utility library. */

#include <msg.h>
#include <stringops.h>
#include <mymalloc.h>
#include <vstring.h>
#include <split_at.h>
#include <dict.h>

/* Global library. */

#include <mail_params.h>
#include <maps.h>

/* Application-specific. */

#include "transport.h"

static MAPS *transport_path;

/* transport_init - pre-jail initialization */

void    transport_init(void)
{
    if (transport_path)
	msg_panic("transport_init: repeated call");
    transport_path = maps_create("transport", var_transport_maps,
				 DICT_FLAG_LOCK);
}

/* transport_lookup - map a transport domain */

int     transport_lookup(const char *domain, VSTRING *channel, VSTRING *nexthop)
{
    char   *low_domain = lowercase(mystrdup(domain));
    const char *name;
    const char *value;
    const char *host;
    char   *saved_value;
    char   *transport;
    int     found = 0;

#define FULL	0
#define PARTIAL		DICT_FLAG_FIXED

    int     maps_flag = FULL;

    if (transport_path == 0)
	msg_panic("transport_lookup: missing initialization");

    /*
     * Keep stripping domain components until nothing is left or until a
     * matching entry is found.
     * 
     * After checking the full name, check for .upper.domain, to distinguish
     * between the upper domain and it's decendants, ala sendmail and tcp
     * wrappers.
     * 
     * Before changing the DB lookup result, make a copy first, in order to
     * avoid DB cache corruption.
     * 
     * Specify if a key is partial or full, to avoid matching partial keys with
     * regular expressions.
     */
    for (name = low_domain; name != 0; name = strchr(name + 1, '.')) {
	if ((value = maps_find(transport_path, name, maps_flag)) != 0) {
	    saved_value = mystrdup(value);
	    if ((host = split_at(saved_value, ':')) == 0 || *host == 0)
		host = domain;
	    if (*(transport = saved_value) == 0)
		transport = var_def_transport;
	    vstring_strcpy(channel, transport);
	    vstring_strcpy(nexthop, host);
	    myfree(saved_value);
	    found = 1;
	    break;
	} else if (dict_errno != 0) {
	    msg_fatal("transport table lookup problem");
	}
	maps_flag = PARTIAL;
    }
    myfree(low_domain);
    return (found);
}