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