summaryrefslogtreecommitdiffstats
path: root/src/postconf/postconf_service.c
blob: 38a4cce648240e4543741ffa5b7290ea633c0eb8 (plain)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*++
/* NAME
/*	postconf_service 3
/* SUMMARY
/*	service-defined main.cf parameter name support
/* SYNOPSIS
/*	#include <postconf.h>
/*
/*	void    pcf_register_service_parameters()
/* DESCRIPTION
/*	Service-defined parameter names are created by appending
/*	postfix-defined suffixes to master.cf service names. All
/*	service-defined parameters have default values that are
/*	defined by a built-in parameter.
/*
/*	pcf_register_service_parameters() adds the service-defined
/*	parameters to the global name space. This function must be
/*	called after the built-in parameters are added to the global
/*	name space, and after the master.cf file is read.
/* DIAGNOSTICS
/*	Problems are reported to the standard error stream.
/* 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
/*
/*	Wietse Venema
/*	Google, Inc.
/*	111 8th Avenue
/*	New York, NY 10011, USA
/*--*/

/* System library. */

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

/* Utility library. */

#include <msg.h>
#include <mymalloc.h>
#include <htable.h>
#include <vstring.h>
#include <stringops.h>
#include <argv.h>

/* Global library. */

#include <mail_params.h>

/* Application-specific. */

#include <postconf.h>

 /*
  * Basename of programs in $daemon_directory. XXX These belong in a header
  * file, or they should be made configurable.
  */
#ifndef MAIL_PROGRAM_LOCAL
#define MAIL_PROGRAM_LOCAL	"local"
#define MAIL_PROGRAM_ERROR	"error"
#define MAIL_PROGRAM_VIRTUAL	"virtual"
#define MAIL_PROGRAM_SMTP	"smtp"
#define MAIL_PROGRAM_LMTP	"lmtp"
#define MAIL_PROGRAM_PIPE	"pipe"
#define MAIL_PROGRAM_SPAWN	"spawn"
#endif

 /*
  * Ad-hoc name-value string pair.
  */
typedef struct {
    const char *name;
    const char *value;
} PCF_STRING_NV;

#define STR(x) vstring_str(x)

/* pcf_convert_service_parameter - get service parameter string value */

static const char *pcf_convert_service_parameter(void *ptr)
{
    return (STR(vstring_sprintf(pcf_param_string_buf, "$%s", (char *) ptr)));
}

/* pcf_register_service_parameter - add service parameter name and default */

static void pcf_register_service_parameter(const char *service,
					           const char *suffix,
					           const char *defparam)
{
    char   *name = concatenate(service, suffix, (char *) 0);
    PCF_PARAM_NODE *node;

    /*
     * Skip service parameter names that have built-in definitions. This
     * happens with message delivery transports that have a non-default
     * per-destination concurrency or recipient limit, such as local(8).
     * 
     * Some parameters were tentatively flagged as built-in, but they are
     * service parameters with their own default value. We don't change the
     * default but we correct the parameter class.
     */
    if ((node = PCF_PARAM_TABLE_FIND(pcf_param_table, name)) != 0) {
	PCF_PARAM_CLASS_OVERRIDE(node, PCF_PARAM_FLAG_SERVICE);
    } else {
	PCF_PARAM_TABLE_ENTER(pcf_param_table, name, PCF_PARAM_FLAG_SERVICE,
			  (void *) defparam, pcf_convert_service_parameter);
    }
    myfree(name);
}

/* pcf_register_service_parameters - add all service parameters with defaults */

void    pcf_register_service_parameters(void)
{
    const char *myname = "pcf_register_service_parameters";
    static const PCF_STRING_NV pipe_params[] = {
	/* suffix, default parameter name */
	_MAXTIME, VAR_COMMAND_MAXTIME,
#define service_params (pipe_params + 1)
	_XPORT_RCPT_LIMIT, VAR_XPORT_RCPT_LIMIT,
	_STACK_RCPT_LIMIT, VAR_STACK_RCPT_LIMIT,
	_XPORT_REFILL_LIMIT, VAR_XPORT_REFILL_LIMIT,
	_XPORT_REFILL_DELAY, VAR_XPORT_REFILL_DELAY,
	_DELIVERY_SLOT_COST, VAR_DELIVERY_SLOT_COST,
	_DELIVERY_SLOT_LOAN, VAR_DELIVERY_SLOT_LOAN,
	_DELIVERY_SLOT_DISCOUNT, VAR_DELIVERY_SLOT_DISCOUNT,
	_MIN_DELIVERY_SLOTS, VAR_MIN_DELIVERY_SLOTS,
	_INIT_DEST_CON, VAR_INIT_DEST_CON,
	_DEST_CON_LIMIT, VAR_DEST_CON_LIMIT,
	_DEST_RCPT_LIMIT, VAR_DEST_RCPT_LIMIT,
	_CONC_POS_FDBACK, VAR_CONC_POS_FDBACK,
	_CONC_NEG_FDBACK, VAR_CONC_NEG_FDBACK,
	_CONC_COHORT_LIM, VAR_CONC_COHORT_LIM,
	_DEST_RATE_DELAY, VAR_DEST_RATE_DELAY,
	_XPORT_RATE_DELAY, VAR_XPORT_RATE_DELAY,
	0,
    };
    static const PCF_STRING_NV spawn_params[] = {
	/* suffix, default parameter name */
	_MAXTIME, VAR_COMMAND_MAXTIME,
	0,
    };
    typedef struct {
	const char *progname;
	const PCF_STRING_NV *params;
    } PCF_SERVICE_DEF;
    static const PCF_SERVICE_DEF service_defs[] = {
	MAIL_PROGRAM_LOCAL, service_params,
	MAIL_PROGRAM_ERROR, service_params,
	MAIL_PROGRAM_VIRTUAL, service_params,
	MAIL_PROGRAM_SMTP, service_params,
	MAIL_PROGRAM_LMTP, service_params,
	MAIL_PROGRAM_PIPE, pipe_params,
	MAIL_PROGRAM_SPAWN, spawn_params,
	0,
    };
    const PCF_STRING_NV *sp;
    const char *progname;
    const char *service;
    PCF_MASTER_ENT *masterp;
    ARGV   *argv;
    const PCF_SERVICE_DEF *sd;

    /*
     * Sanity checks.
     */
    if (pcf_param_table == 0)
	msg_panic("%s: global parameter table is not initialized", myname);
    if (pcf_master_table == 0)
	msg_panic("%s: master table is not initialized", myname);

    /*
     * Extract service names from master.cf and generate service parameter
     * information.
     */
    for (masterp = pcf_master_table; (argv = masterp->argv) != 0; masterp++) {

	/*
	 * Add service parameters for message delivery transports or spawn
	 * programs.
	 */
	progname = argv->argv[7];
	for (sd = service_defs; sd->progname; sd++) {
	    if (strcmp(sd->progname, progname) == 0) {
		service = argv->argv[0];
		for (sp = sd->params; sp->name; sp++)
		    pcf_register_service_parameter(service, sp->name, sp->value);
		break;
	    }
	}
    }
}