xref: /netbsd-src/external/ibm-public/postfix/dist/src/postconf/postconf_service.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
1 /*	$NetBSD: postconf_service.c,v 1.2 2017/02/14 01:16:46 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	postconf_service 3
6 /* SUMMARY
7 /*	service-defined main.cf parameter name support
8 /* SYNOPSIS
9 /*	#include <postconf.h>
10 /*
11 /*	void    pcf_register_service_parameters()
12 /* DESCRIPTION
13 /*	Service-defined parameter names are created by appending
14 /*	postfix-defined suffixes to master.cf service names. All
15 /*	service-defined parameters have default values that are
16 /*	defined by a built-in parameter.
17 /*
18 /*	pcf_register_service_parameters() adds the service-defined
19 /*	parameters to the global name space. This function must be
20 /*	called after the built-in parameters are added to the global
21 /*	name space, and after the master.cf file is read.
22 /* DIAGNOSTICS
23 /*	Problems are reported to the standard error stream.
24 /* LICENSE
25 /* .ad
26 /* .fi
27 /*	The Secure Mailer license must be distributed with this software.
28 /* AUTHOR(S)
29 /*	Wietse Venema
30 /*	IBM T.J. Watson Research
31 /*	P.O. Box 704
32 /*	Yorktown Heights, NY 10598, USA
33 /*
34 /*	Wietse Venema
35 /*	Google, Inc.
36 /*	111 8th Avenue
37 /*	New York, NY 10011, USA
38 /*--*/
39 
40 /* System library. */
41 
42 #include <sys_defs.h>
43 #include <string.h>
44 
45 /* Utility library. */
46 
47 #include <msg.h>
48 #include <mymalloc.h>
49 #include <htable.h>
50 #include <vstring.h>
51 #include <stringops.h>
52 #include <argv.h>
53 
54 /* Global library. */
55 
56 #include <mail_params.h>
57 
58 /* Application-specific. */
59 
60 #include <postconf.h>
61 
62  /*
63   * Basename of programs in $daemon_directory. XXX These belong in a header
64   * file, or they should be made configurable.
65   */
66 #ifndef MAIL_PROGRAM_LOCAL
67 #define MAIL_PROGRAM_LOCAL	"local"
68 #define MAIL_PROGRAM_ERROR	"error"
69 #define MAIL_PROGRAM_VIRTUAL	"virtual"
70 #define MAIL_PROGRAM_SMTP	"smtp"
71 #define MAIL_PROGRAM_LMTP	"lmtp"
72 #define MAIL_PROGRAM_PIPE	"pipe"
73 #define MAIL_PROGRAM_SPAWN	"spawn"
74 #endif
75 
76  /*
77   * Ad-hoc name-value string pair.
78   */
79 typedef struct {
80     const char *name;
81     const char *value;
82 } PCF_STRING_NV;
83 
84 #define STR(x) vstring_str(x)
85 
86 /* pcf_convert_service_parameter - get service parameter string value */
87 
pcf_convert_service_parameter(void * ptr)88 static const char *pcf_convert_service_parameter(void *ptr)
89 {
90     return (STR(vstring_sprintf(pcf_param_string_buf, "$%s", (char *) ptr)));
91 }
92 
93 /* pcf_register_service_parameter - add service parameter name and default */
94 
pcf_register_service_parameter(const char * service,const char * suffix,const char * defparam)95 static void pcf_register_service_parameter(const char *service,
96 					           const char *suffix,
97 					           const char *defparam)
98 {
99     char   *name = concatenate(service, suffix, (char *) 0);
100     PCF_PARAM_NODE *node;
101 
102     /*
103      * Skip service parameter names that have built-in definitions. This
104      * happens with message delivery transports that have a non-default
105      * per-destination concurrency or recipient limit, such as local(8).
106      *
107      * Some parameters were tentatively flagged as built-in, but they are
108      * service parameters with their own default value. We don't change the
109      * default but we correct the parameter class.
110      */
111     if ((node = PCF_PARAM_TABLE_FIND(pcf_param_table, name)) != 0) {
112 	PCF_PARAM_CLASS_OVERRIDE(node, PCF_PARAM_FLAG_SERVICE);
113     } else {
114 	PCF_PARAM_TABLE_ENTER(pcf_param_table, name, PCF_PARAM_FLAG_SERVICE,
115 			  (void *) defparam, pcf_convert_service_parameter);
116     }
117     myfree(name);
118 }
119 
120 /* pcf_register_service_parameters - add all service parameters with defaults */
121 
pcf_register_service_parameters(void)122 void    pcf_register_service_parameters(void)
123 {
124     const char *myname = "pcf_register_service_parameters";
125     static const PCF_STRING_NV pipe_params[] = {
126 	/* suffix, default parameter name */
127 	_MAXTIME, VAR_COMMAND_MAXTIME,
128 #define service_params (pipe_params + 1)
129 	_XPORT_RCPT_LIMIT, VAR_XPORT_RCPT_LIMIT,
130 	_STACK_RCPT_LIMIT, VAR_STACK_RCPT_LIMIT,
131 	_XPORT_REFILL_LIMIT, VAR_XPORT_REFILL_LIMIT,
132 	_XPORT_REFILL_DELAY, VAR_XPORT_REFILL_DELAY,
133 	_DELIVERY_SLOT_COST, VAR_DELIVERY_SLOT_COST,
134 	_DELIVERY_SLOT_LOAN, VAR_DELIVERY_SLOT_LOAN,
135 	_DELIVERY_SLOT_DISCOUNT, VAR_DELIVERY_SLOT_DISCOUNT,
136 	_MIN_DELIVERY_SLOTS, VAR_MIN_DELIVERY_SLOTS,
137 	_INIT_DEST_CON, VAR_INIT_DEST_CON,
138 	_DEST_CON_LIMIT, VAR_DEST_CON_LIMIT,
139 	_DEST_RCPT_LIMIT, VAR_DEST_RCPT_LIMIT,
140 	_CONC_POS_FDBACK, VAR_CONC_POS_FDBACK,
141 	_CONC_NEG_FDBACK, VAR_CONC_NEG_FDBACK,
142 	_CONC_COHORT_LIM, VAR_CONC_COHORT_LIM,
143 	_DEST_RATE_DELAY, VAR_DEST_RATE_DELAY,
144 	_XPORT_RATE_DELAY, VAR_XPORT_RATE_DELAY,
145 	0,
146     };
147     static const PCF_STRING_NV spawn_params[] = {
148 	/* suffix, default parameter name */
149 	_MAXTIME, VAR_COMMAND_MAXTIME,
150 	0,
151     };
152     typedef struct {
153 	const char *progname;
154 	const PCF_STRING_NV *params;
155     } PCF_SERVICE_DEF;
156     static const PCF_SERVICE_DEF service_defs[] = {
157 	MAIL_PROGRAM_LOCAL, service_params,
158 	MAIL_PROGRAM_ERROR, service_params,
159 	MAIL_PROGRAM_VIRTUAL, service_params,
160 	MAIL_PROGRAM_SMTP, service_params,
161 	MAIL_PROGRAM_LMTP, service_params,
162 	MAIL_PROGRAM_PIPE, pipe_params,
163 	MAIL_PROGRAM_SPAWN, spawn_params,
164 	0,
165     };
166     const PCF_STRING_NV *sp;
167     const char *progname;
168     const char *service;
169     PCF_MASTER_ENT *masterp;
170     ARGV   *argv;
171     const PCF_SERVICE_DEF *sd;
172 
173     /*
174      * Sanity checks.
175      */
176     if (pcf_param_table == 0)
177 	msg_panic("%s: global parameter table is not initialized", myname);
178     if (pcf_master_table == 0)
179 	msg_panic("%s: master table is not initialized", myname);
180 
181     /*
182      * Extract service names from master.cf and generate service parameter
183      * information.
184      */
185     for (masterp = pcf_master_table; (argv = masterp->argv) != 0; masterp++) {
186 
187 	/*
188 	 * Add service parameters for message delivery transports or spawn
189 	 * programs.
190 	 */
191 	progname = argv->argv[7];
192 	for (sd = service_defs; sd->progname; sd++) {
193 	    if (strcmp(sd->progname, progname) == 0) {
194 		service = argv->argv[0];
195 		for (sp = sd->params; sp->name; sp++)
196 		    pcf_register_service_parameter(service, sp->name, sp->value);
197 		break;
198 	    }
199 	}
200     }
201 }
202