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 */ 79typedef 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 88static 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 95static 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 122void 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