1c2aa98e2SPeter Wemm /* 25dd76dd0SGregory Neil Shapiro * Copyright (c) 1998-2006, 2008-2010, 2013 Proofpoint, Inc. and its suppliers. 306f25ae9SGregory Neil Shapiro * All rights reserved. 4c2aa98e2SPeter Wemm * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5c2aa98e2SPeter Wemm * Copyright (c) 1988, 1993 6c2aa98e2SPeter Wemm * The Regents of the University of California. All rights reserved. 7c2aa98e2SPeter Wemm * 8c2aa98e2SPeter Wemm * By using this file, you agree to the terms and conditions set 9c2aa98e2SPeter Wemm * forth in the LICENSE file which can be found at the top level of 10c2aa98e2SPeter Wemm * the sendmail distribution. 11c2aa98e2SPeter Wemm * 12c2aa98e2SPeter Wemm */ 13c2aa98e2SPeter Wemm 1406f25ae9SGregory Neil Shapiro #include <sendmail.h> 15d0cef73dSGregory Neil Shapiro #include <sm/sendmail.h> 16*5b0945b5SGregory Neil Shapiro #if STARTTLS 17*5b0945b5SGregory Neil Shapiro # include <tls.h> 18*5b0945b5SGregory Neil Shapiro #endif 19*5b0945b5SGregory Neil Shapiro #if DNSSEC_TEST 20*5b0945b5SGregory Neil Shapiro # include <sm_resolve.h> 21*5b0945b5SGregory Neil Shapiro #endif 2206f25ae9SGregory Neil Shapiro 234313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: readcf.c,v 8.692 2013-11-22 20:51:56 ca Exp $") 2406f25ae9SGregory Neil Shapiro 2506f25ae9SGregory Neil Shapiro #if NETINET || NETINET6 2606f25ae9SGregory Neil Shapiro # include <arpa/inet.h> 27*5b0945b5SGregory Neil Shapiro #endif 2806f25ae9SGregory Neil Shapiro 296f9c8e5bSGregory Neil Shapiro 3006f25ae9SGregory Neil Shapiro #define SECONDS 3106f25ae9SGregory Neil Shapiro #define MINUTES * 60 3206f25ae9SGregory Neil Shapiro #define HOUR * 3600 3306f25ae9SGregory Neil Shapiro #define HOURS HOUR 3406f25ae9SGregory Neil Shapiro 35605302a5SGregory Neil Shapiro static void fileclass __P((int, char *, char *, bool, bool, bool)); 3606f25ae9SGregory Neil Shapiro static char **makeargv __P((char *)); 3706f25ae9SGregory Neil Shapiro static void settimeout __P((char *, char *, bool)); 3806f25ae9SGregory Neil Shapiro static void toomany __P((int, int)); 3940266059SGregory Neil Shapiro static char *extrquotstr __P((char *, char **, char *, bool *)); 40b6bacd31SGregory Neil Shapiro static void parse_class_words __P((int, char *)); 41c2aa98e2SPeter Wemm 42da7d7b9cSGregory Neil Shapiro 43da7d7b9cSGregory Neil Shapiro #if _FFR_BOUNCE_QUEUE 44da7d7b9cSGregory Neil Shapiro static char *bouncequeue = NULL; 45da7d7b9cSGregory Neil Shapiro static void initbouncequeue __P((void)); 46da7d7b9cSGregory Neil Shapiro 47da7d7b9cSGregory Neil Shapiro /* 48da7d7b9cSGregory Neil Shapiro ** INITBOUNCEQUEUE -- determine BounceQueue if option is set. 49da7d7b9cSGregory Neil Shapiro ** 50da7d7b9cSGregory Neil Shapiro ** Parameters: 51da7d7b9cSGregory Neil Shapiro ** none. 52da7d7b9cSGregory Neil Shapiro ** 53da7d7b9cSGregory Neil Shapiro ** Returns: 54da7d7b9cSGregory Neil Shapiro ** none. 55da7d7b9cSGregory Neil Shapiro ** 56da7d7b9cSGregory Neil Shapiro ** Side Effects: 57da7d7b9cSGregory Neil Shapiro ** sets BounceQueue 58da7d7b9cSGregory Neil Shapiro */ 59da7d7b9cSGregory Neil Shapiro 60da7d7b9cSGregory Neil Shapiro static void 61da7d7b9cSGregory Neil Shapiro initbouncequeue() 62da7d7b9cSGregory Neil Shapiro { 63da7d7b9cSGregory Neil Shapiro STAB *s; 64da7d7b9cSGregory Neil Shapiro 65da7d7b9cSGregory Neil Shapiro BounceQueue = NOQGRP; 66da7d7b9cSGregory Neil Shapiro if (bouncequeue == NULL || bouncequeue[0] == '\0') 67da7d7b9cSGregory Neil Shapiro return; 68da7d7b9cSGregory Neil Shapiro 69da7d7b9cSGregory Neil Shapiro s = stab(bouncequeue, ST_QUEUE, ST_FIND); 70da7d7b9cSGregory Neil Shapiro if (s == NULL) 71da7d7b9cSGregory Neil Shapiro { 72da7d7b9cSGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 73da7d7b9cSGregory Neil Shapiro "Warning: option BounceQueue: unknown queue group %s\n", 74da7d7b9cSGregory Neil Shapiro bouncequeue); 75da7d7b9cSGregory Neil Shapiro } 76da7d7b9cSGregory Neil Shapiro else 77da7d7b9cSGregory Neil Shapiro BounceQueue = s->s_quegrp->qg_index; 78da7d7b9cSGregory Neil Shapiro } 79da7d7b9cSGregory Neil Shapiro #endif /* _FFR_BOUNCE_QUEUE */ 80da7d7b9cSGregory Neil Shapiro 81da7d7b9cSGregory Neil Shapiro #if _FFR_RCPTFLAGS 82da7d7b9cSGregory Neil Shapiro void setupdynmailers __P((void)); 83da7d7b9cSGregory Neil Shapiro #else 84da7d7b9cSGregory Neil Shapiro #define setupdynmailers() 85da7d7b9cSGregory Neil Shapiro #endif 86da7d7b9cSGregory Neil Shapiro 87c2aa98e2SPeter Wemm /* 88c2aa98e2SPeter Wemm ** READCF -- read configuration file. 89c2aa98e2SPeter Wemm ** 90c2aa98e2SPeter Wemm ** This routine reads the configuration file and builds the internal 91c2aa98e2SPeter Wemm ** form. 92c2aa98e2SPeter Wemm ** 93c2aa98e2SPeter Wemm ** The file is formatted as a sequence of lines, each taken 94c2aa98e2SPeter Wemm ** atomically. The first character of each line describes how 95c2aa98e2SPeter Wemm ** the line is to be interpreted. The lines are: 96c2aa98e2SPeter Wemm ** Dxval Define macro x to have value val. 97c2aa98e2SPeter Wemm ** Cxword Put word into class x. 98c2aa98e2SPeter Wemm ** Fxfile [fmt] Read file for lines to put into 99c2aa98e2SPeter Wemm ** class x. Use scanf string 'fmt' 100c2aa98e2SPeter Wemm ** or "%s" if not present. Fmt should 101c2aa98e2SPeter Wemm ** only produce one string-valued result. 102c2aa98e2SPeter Wemm ** Hname: value Define header with field-name 'name' 103c2aa98e2SPeter Wemm ** and value as specified; this will be 104c2aa98e2SPeter Wemm ** macro expanded immediately before 105c2aa98e2SPeter Wemm ** use. 106c2aa98e2SPeter Wemm ** Sn Use rewriting set n. 107c2aa98e2SPeter Wemm ** Rlhs rhs Rewrite addresses that match lhs to 108c2aa98e2SPeter Wemm ** be rhs. 109c2aa98e2SPeter Wemm ** Mn arg=val... Define mailer. n is the internal name. 110c2aa98e2SPeter Wemm ** Args specify mailer parameters. 111c2aa98e2SPeter Wemm ** Oxvalue Set option x to value. 11240266059SGregory Neil Shapiro ** O option value Set option (long name) to value. 113c2aa98e2SPeter Wemm ** Pname=value Set precedence name to value. 11440266059SGregory Neil Shapiro ** Qn arg=val... Define queue groups. n is the internal name. 11540266059SGregory Neil Shapiro ** Args specify queue parameters. 116c2aa98e2SPeter Wemm ** Vversioncode[/vendorcode] 117c2aa98e2SPeter Wemm ** Version level/vendor name of 118c2aa98e2SPeter Wemm ** configuration syntax. 119c2aa98e2SPeter Wemm ** Kmapname mapclass arguments.... 120c2aa98e2SPeter Wemm ** Define keyed lookup of a given class. 121c2aa98e2SPeter Wemm ** Arguments are class dependent. 122c2aa98e2SPeter Wemm ** Eenvar=value Set the environment value to the given value. 123c2aa98e2SPeter Wemm ** 124c2aa98e2SPeter Wemm ** Parameters: 125c2aa98e2SPeter Wemm ** cfname -- configuration file name. 12640266059SGregory Neil Shapiro ** safe -- true if this is the system config file; 12740266059SGregory Neil Shapiro ** false otherwise. 128c2aa98e2SPeter Wemm ** e -- the main envelope. 129c2aa98e2SPeter Wemm ** 130c2aa98e2SPeter Wemm ** Returns: 131c2aa98e2SPeter Wemm ** none. 132c2aa98e2SPeter Wemm ** 133c2aa98e2SPeter Wemm ** Side Effects: 134c2aa98e2SPeter Wemm ** Builds several internal tables. 135c2aa98e2SPeter Wemm */ 136c2aa98e2SPeter Wemm 137c2aa98e2SPeter Wemm void 138c2aa98e2SPeter Wemm readcf(cfname, safe, e) 139c2aa98e2SPeter Wemm char *cfname; 140c2aa98e2SPeter Wemm bool safe; 141c2aa98e2SPeter Wemm register ENVELOPE *e; 142c2aa98e2SPeter Wemm { 14340266059SGregory Neil Shapiro SM_FILE_T *cf; 14406f25ae9SGregory Neil Shapiro int ruleset = -1; 145c2aa98e2SPeter Wemm char *q; 146c2aa98e2SPeter Wemm struct rewrite *rwp = NULL; 147c2aa98e2SPeter Wemm char *bp; 148c2aa98e2SPeter Wemm auto char *ep; 149c2aa98e2SPeter Wemm int nfuzzy; 150c2aa98e2SPeter Wemm char *file; 151c2aa98e2SPeter Wemm bool optional; 15240266059SGregory Neil Shapiro bool ok; 153605302a5SGregory Neil Shapiro bool ismap; 154c2aa98e2SPeter Wemm int mid; 155c2aa98e2SPeter Wemm register char *p; 15606f25ae9SGregory Neil Shapiro long sff = SFF_OPENASROOT; 157c2aa98e2SPeter Wemm struct stat statb; 158c2aa98e2SPeter Wemm char buf[MAXLINE]; 159d0cef73dSGregory Neil Shapiro int bufsize; 160c2aa98e2SPeter Wemm char exbuf[MAXLINE]; 161c2aa98e2SPeter Wemm char pvpbuf[MAXLINE + MAXATOM]; 162c2aa98e2SPeter Wemm static char *null_list[1] = { NULL }; 16340266059SGregory Neil Shapiro extern unsigned char TokTypeNoC[]; 164c2aa98e2SPeter Wemm 165c2aa98e2SPeter Wemm FileName = cfname; 166c2aa98e2SPeter Wemm LineNumber = 0; 167c2aa98e2SPeter Wemm 168c2aa98e2SPeter Wemm if (DontLockReadFiles) 169c2aa98e2SPeter Wemm sff |= SFF_NOLOCK; 170c2aa98e2SPeter Wemm cf = safefopen(cfname, O_RDONLY, 0444, sff); 171c2aa98e2SPeter Wemm if (cf == NULL) 172c2aa98e2SPeter Wemm { 173c2aa98e2SPeter Wemm syserr("cannot open"); 17440266059SGregory Neil Shapiro finis(false, true, EX_OSFILE); 175c2aa98e2SPeter Wemm } 176c2aa98e2SPeter Wemm 17740266059SGregory Neil Shapiro if (fstat(sm_io_getinfo(cf, SM_IO_WHAT_FD, NULL), &statb) < 0) 178c2aa98e2SPeter Wemm { 179c2aa98e2SPeter Wemm syserr("cannot fstat"); 18040266059SGregory Neil Shapiro finis(false, true, EX_OSFILE); 181c2aa98e2SPeter Wemm } 182c2aa98e2SPeter Wemm 183c2aa98e2SPeter Wemm if (!S_ISREG(statb.st_mode)) 184c2aa98e2SPeter Wemm { 185c2aa98e2SPeter Wemm syserr("not a plain file"); 18640266059SGregory Neil Shapiro finis(false, true, EX_OSFILE); 187c2aa98e2SPeter Wemm } 188c2aa98e2SPeter Wemm 189c2aa98e2SPeter Wemm if (OpMode != MD_TEST && bitset(S_IWGRP|S_IWOTH, statb.st_mode)) 190c2aa98e2SPeter Wemm { 1919bd497b8SGregory Neil Shapiro if (OpMode == MD_DAEMON || OpMode == MD_INITALIAS || OpMode == MD_CHECKCONFIG) 19240266059SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 19340266059SGregory Neil Shapiro "%s: WARNING: dangerous write permissions\n", 194c2aa98e2SPeter Wemm FileName); 195c2aa98e2SPeter Wemm if (LogLevel > 0) 196c2aa98e2SPeter Wemm sm_syslog(LOG_CRIT, NOQID, 197c2aa98e2SPeter Wemm "%s: WARNING: dangerous write permissions", 198c2aa98e2SPeter Wemm FileName); 199c2aa98e2SPeter Wemm } 200c2aa98e2SPeter Wemm 20140266059SGregory Neil Shapiro #if XLA 202c2aa98e2SPeter Wemm xla_zero(); 203*5b0945b5SGregory Neil Shapiro #endif 204c2aa98e2SPeter Wemm 205d0cef73dSGregory Neil Shapiro while (bufsize = sizeof(buf), 206d0cef73dSGregory Neil Shapiro (bp = fgetfolded(buf, &bufsize, cf)) != NULL) 207c2aa98e2SPeter Wemm { 208d0cef73dSGregory Neil Shapiro char *nbp; 209d0cef73dSGregory Neil Shapiro 210c2aa98e2SPeter Wemm if (bp[0] == '#') 211c2aa98e2SPeter Wemm { 212c2aa98e2SPeter Wemm if (bp != buf) 21340266059SGregory Neil Shapiro sm_free(bp); /* XXX */ 214c2aa98e2SPeter Wemm continue; 215c2aa98e2SPeter Wemm } 216c2aa98e2SPeter Wemm 217c2aa98e2SPeter Wemm /* do macro expansion mappings */ 218d0cef73dSGregory Neil Shapiro nbp = translate_dollars(bp, bp, &bufsize); 219d0cef73dSGregory Neil Shapiro if (nbp != bp && bp != buf) 220d0cef73dSGregory Neil Shapiro sm_free(bp); 221d0cef73dSGregory Neil Shapiro bp = nbp; 222c2aa98e2SPeter Wemm 223c2aa98e2SPeter Wemm /* interpret this line */ 224c2aa98e2SPeter Wemm errno = 0; 225c2aa98e2SPeter Wemm switch (bp[0]) 226c2aa98e2SPeter Wemm { 227c2aa98e2SPeter Wemm case '\0': 228c2aa98e2SPeter Wemm case '#': /* comment */ 229c2aa98e2SPeter Wemm break; 230c2aa98e2SPeter Wemm 231c2aa98e2SPeter Wemm case 'R': /* rewriting rule */ 23206f25ae9SGregory Neil Shapiro if (ruleset < 0) 23306f25ae9SGregory Neil Shapiro { 23406f25ae9SGregory Neil Shapiro syserr("missing valid ruleset for \"%s\"", bp); 23506f25ae9SGregory Neil Shapiro break; 23606f25ae9SGregory Neil Shapiro } 237c2aa98e2SPeter Wemm for (p = &bp[1]; *p != '\0' && *p != '\t'; p++) 238c2aa98e2SPeter Wemm continue; 239c2aa98e2SPeter Wemm 240c2aa98e2SPeter Wemm if (*p == '\0') 241c2aa98e2SPeter Wemm { 242c2aa98e2SPeter Wemm syserr("invalid rewrite line \"%s\" (tab expected)", bp); 243c2aa98e2SPeter Wemm break; 244c2aa98e2SPeter Wemm } 245c2aa98e2SPeter Wemm 246c2aa98e2SPeter Wemm /* allocate space for the rule header */ 247c2aa98e2SPeter Wemm if (rwp == NULL) 248c2aa98e2SPeter Wemm { 249c2aa98e2SPeter Wemm RewriteRules[ruleset] = rwp = 250d0cef73dSGregory Neil Shapiro (struct rewrite *) xalloc(sizeof(*rwp)); 251c2aa98e2SPeter Wemm } 252c2aa98e2SPeter Wemm else 253c2aa98e2SPeter Wemm { 254d0cef73dSGregory Neil Shapiro rwp->r_next = (struct rewrite *) xalloc(sizeof(*rwp)); 255c2aa98e2SPeter Wemm rwp = rwp->r_next; 256c2aa98e2SPeter Wemm } 257c2aa98e2SPeter Wemm rwp->r_next = NULL; 258c2aa98e2SPeter Wemm 259c2aa98e2SPeter Wemm /* expand and save the LHS */ 260c2aa98e2SPeter Wemm *p = '\0'; 261d0cef73dSGregory Neil Shapiro expand(&bp[1], exbuf, sizeof(exbuf), e); 262c2aa98e2SPeter Wemm rwp->r_lhs = prescan(exbuf, '\t', pvpbuf, 263d0cef73dSGregory Neil Shapiro sizeof(pvpbuf), NULL, 264d0cef73dSGregory Neil Shapiro ConfigLevel >= 9 ? TokTypeNoC : IntTokenTab, 265e92d3f3fSGregory Neil Shapiro true); 266c2aa98e2SPeter Wemm nfuzzy = 0; 267c2aa98e2SPeter Wemm if (rwp->r_lhs != NULL) 268c2aa98e2SPeter Wemm { 269c2aa98e2SPeter Wemm register char **ap; 270c2aa98e2SPeter Wemm 27140266059SGregory Neil Shapiro rwp->r_lhs = copyplist(rwp->r_lhs, true, NULL); 272c2aa98e2SPeter Wemm 273c2aa98e2SPeter Wemm /* count the number of fuzzy matches in LHS */ 274c2aa98e2SPeter Wemm for (ap = rwp->r_lhs; *ap != NULL; ap++) 275c2aa98e2SPeter Wemm { 276c2aa98e2SPeter Wemm char *botch; 277c2aa98e2SPeter Wemm 278c2aa98e2SPeter Wemm botch = NULL; 279d0cef73dSGregory Neil Shapiro switch (ap[0][0] & 0377) 280c2aa98e2SPeter Wemm { 281c2aa98e2SPeter Wemm case MATCHZANY: 282c2aa98e2SPeter Wemm case MATCHANY: 283c2aa98e2SPeter Wemm case MATCHONE: 284c2aa98e2SPeter Wemm case MATCHCLASS: 285c2aa98e2SPeter Wemm case MATCHNCLASS: 286c2aa98e2SPeter Wemm nfuzzy++; 287c2aa98e2SPeter Wemm break; 288c2aa98e2SPeter Wemm 289c2aa98e2SPeter Wemm case MATCHREPL: 290d0cef73dSGregory Neil Shapiro botch = "$1-$9"; 291c2aa98e2SPeter Wemm break; 292c2aa98e2SPeter Wemm 293c2aa98e2SPeter Wemm case CANONUSER: 294c2aa98e2SPeter Wemm botch = "$:"; 295c2aa98e2SPeter Wemm break; 296c2aa98e2SPeter Wemm 297c2aa98e2SPeter Wemm case CALLSUBR: 298c2aa98e2SPeter Wemm botch = "$>"; 299c2aa98e2SPeter Wemm break; 300c2aa98e2SPeter Wemm 301c2aa98e2SPeter Wemm case CONDIF: 302c2aa98e2SPeter Wemm botch = "$?"; 303c2aa98e2SPeter Wemm break; 304c2aa98e2SPeter Wemm 305c2aa98e2SPeter Wemm case CONDFI: 306c2aa98e2SPeter Wemm botch = "$."; 307c2aa98e2SPeter Wemm break; 308c2aa98e2SPeter Wemm 309c2aa98e2SPeter Wemm case HOSTBEGIN: 310c2aa98e2SPeter Wemm botch = "$["; 311c2aa98e2SPeter Wemm break; 312c2aa98e2SPeter Wemm 313c2aa98e2SPeter Wemm case HOSTEND: 314c2aa98e2SPeter Wemm botch = "$]"; 315c2aa98e2SPeter Wemm break; 316c2aa98e2SPeter Wemm 317c2aa98e2SPeter Wemm case LOOKUPBEGIN: 318c2aa98e2SPeter Wemm botch = "$("; 319c2aa98e2SPeter Wemm break; 320c2aa98e2SPeter Wemm 321c2aa98e2SPeter Wemm case LOOKUPEND: 322c2aa98e2SPeter Wemm botch = "$)"; 323c2aa98e2SPeter Wemm break; 324c2aa98e2SPeter Wemm } 325c2aa98e2SPeter Wemm if (botch != NULL) 326c2aa98e2SPeter Wemm syserr("Inappropriate use of %s on LHS", 327c2aa98e2SPeter Wemm botch); 328c2aa98e2SPeter Wemm } 32906f25ae9SGregory Neil Shapiro rwp->r_line = LineNumber; 330c2aa98e2SPeter Wemm } 331c2aa98e2SPeter Wemm else 332c2aa98e2SPeter Wemm { 333c2aa98e2SPeter Wemm syserr("R line: null LHS"); 334c2aa98e2SPeter Wemm rwp->r_lhs = null_list; 335c2aa98e2SPeter Wemm } 336c86d5965SGregory Neil Shapiro if (nfuzzy > MAXMATCH) 337c86d5965SGregory Neil Shapiro { 338c86d5965SGregory Neil Shapiro syserr("R line: too many wildcards"); 339c86d5965SGregory Neil Shapiro rwp->r_lhs = null_list; 340c86d5965SGregory Neil Shapiro } 341c2aa98e2SPeter Wemm 342c2aa98e2SPeter Wemm /* expand and save the RHS */ 343c2aa98e2SPeter Wemm while (*++p == '\t') 344c2aa98e2SPeter Wemm continue; 345c2aa98e2SPeter Wemm q = p; 346c2aa98e2SPeter Wemm while (*p != '\0' && *p != '\t') 347c2aa98e2SPeter Wemm p++; 348c2aa98e2SPeter Wemm *p = '\0'; 349d0cef73dSGregory Neil Shapiro expand(q, exbuf, sizeof(exbuf), e); 350c2aa98e2SPeter Wemm rwp->r_rhs = prescan(exbuf, '\t', pvpbuf, 351d0cef73dSGregory Neil Shapiro sizeof(pvpbuf), NULL, 352d0cef73dSGregory Neil Shapiro ConfigLevel >= 9 ? TokTypeNoC : IntTokenTab, 353e92d3f3fSGregory Neil Shapiro true); 354c2aa98e2SPeter Wemm if (rwp->r_rhs != NULL) 355c2aa98e2SPeter Wemm { 356c2aa98e2SPeter Wemm register char **ap; 357a7ec597cSGregory Neil Shapiro int args, endtoken; 358a7ec597cSGregory Neil Shapiro #if _FFR_EXTRA_MAP_CHECK 359a7ec597cSGregory Neil Shapiro int nexttoken; 360*5b0945b5SGregory Neil Shapiro #endif 361a7ec597cSGregory Neil Shapiro bool inmap; 362c2aa98e2SPeter Wemm 36340266059SGregory Neil Shapiro rwp->r_rhs = copyplist(rwp->r_rhs, true, NULL); 364c2aa98e2SPeter Wemm 365c2aa98e2SPeter Wemm /* check no out-of-bounds replacements */ 366c2aa98e2SPeter Wemm nfuzzy += '0'; 367a7ec597cSGregory Neil Shapiro inmap = false; 368a7ec597cSGregory Neil Shapiro args = 0; 369a7ec597cSGregory Neil Shapiro endtoken = 0; 370c2aa98e2SPeter Wemm for (ap = rwp->r_rhs; *ap != NULL; ap++) 371c2aa98e2SPeter Wemm { 372c2aa98e2SPeter Wemm char *botch; 373c2aa98e2SPeter Wemm 374c2aa98e2SPeter Wemm botch = NULL; 375d0cef73dSGregory Neil Shapiro switch (ap[0][0] & 0377) 376c2aa98e2SPeter Wemm { 377c2aa98e2SPeter Wemm case MATCHREPL: 378d0cef73dSGregory Neil Shapiro if (ap[0][1] <= '0' || 379d0cef73dSGregory Neil Shapiro ap[0][1] > nfuzzy) 380c2aa98e2SPeter Wemm { 381c2aa98e2SPeter Wemm syserr("replacement $%c out of bounds", 382d0cef73dSGregory Neil Shapiro ap[0][1]); 383c2aa98e2SPeter Wemm } 384c2aa98e2SPeter Wemm break; 385c2aa98e2SPeter Wemm 386c2aa98e2SPeter Wemm case MATCHZANY: 387c2aa98e2SPeter Wemm botch = "$*"; 388c2aa98e2SPeter Wemm break; 389c2aa98e2SPeter Wemm 390c2aa98e2SPeter Wemm case MATCHANY: 391c2aa98e2SPeter Wemm botch = "$+"; 392c2aa98e2SPeter Wemm break; 393c2aa98e2SPeter Wemm 394c2aa98e2SPeter Wemm case MATCHONE: 395c2aa98e2SPeter Wemm botch = "$-"; 396c2aa98e2SPeter Wemm break; 397c2aa98e2SPeter Wemm 398c2aa98e2SPeter Wemm case MATCHCLASS: 399c2aa98e2SPeter Wemm botch = "$="; 400c2aa98e2SPeter Wemm break; 401c2aa98e2SPeter Wemm 402c2aa98e2SPeter Wemm case MATCHNCLASS: 403c2aa98e2SPeter Wemm botch = "$~"; 404c2aa98e2SPeter Wemm break; 40540266059SGregory Neil Shapiro 406a7ec597cSGregory Neil Shapiro case CANONHOST: 407a7ec597cSGregory Neil Shapiro if (!inmap) 408a7ec597cSGregory Neil Shapiro break; 409a7ec597cSGregory Neil Shapiro if (++args >= MAX_MAP_ARGS) 410a7ec597cSGregory Neil Shapiro syserr("too many arguments for map lookup"); 411a7ec597cSGregory Neil Shapiro break; 412a7ec597cSGregory Neil Shapiro 413a7ec597cSGregory Neil Shapiro case HOSTBEGIN: 414a7ec597cSGregory Neil Shapiro endtoken = HOSTEND; 415a7ec597cSGregory Neil Shapiro /* FALLTHROUGH */ 416a7ec597cSGregory Neil Shapiro case LOOKUPBEGIN: 417a7ec597cSGregory Neil Shapiro /* see above... */ 418d0cef73dSGregory Neil Shapiro if ((ap[0][0] & 0377) == LOOKUPBEGIN) 419a7ec597cSGregory Neil Shapiro endtoken = LOOKUPEND; 420a7ec597cSGregory Neil Shapiro if (inmap) 421a7ec597cSGregory Neil Shapiro syserr("cannot nest map lookups"); 422a7ec597cSGregory Neil Shapiro inmap = true; 423a7ec597cSGregory Neil Shapiro args = 0; 424a7ec597cSGregory Neil Shapiro #if _FFR_EXTRA_MAP_CHECK 425d0cef73dSGregory Neil Shapiro if (ap[1] == NULL) 426a7ec597cSGregory Neil Shapiro { 427a7ec597cSGregory Neil Shapiro syserr("syntax error in map lookup"); 428a7ec597cSGregory Neil Shapiro break; 429a7ec597cSGregory Neil Shapiro } 430d0cef73dSGregory Neil Shapiro nexttoken = ap[1][0] & 0377; 431a7ec597cSGregory Neil Shapiro if (nexttoken == CANONHOST || 432a7ec597cSGregory Neil Shapiro nexttoken == CANONUSER || 433*5b0945b5SGregory Neil Shapiro nexttoken == endtoken) 434a7ec597cSGregory Neil Shapiro { 435a7ec597cSGregory Neil Shapiro syserr("missing map name for lookup"); 436a7ec597cSGregory Neil Shapiro break; 437a7ec597cSGregory Neil Shapiro } 438d0cef73dSGregory Neil Shapiro if (ap[2] == NULL) 439a7ec597cSGregory Neil Shapiro { 440a7ec597cSGregory Neil Shapiro syserr("syntax error in map lookup"); 441a7ec597cSGregory Neil Shapiro break; 442a7ec597cSGregory Neil Shapiro } 443*5b0945b5SGregory Neil Shapiro if ((unsigned char) ap[0][0] == HOSTBEGIN) 444a7ec597cSGregory Neil Shapiro break; 445d0cef73dSGregory Neil Shapiro nexttoken = ap[2][0] & 0377; 446a7ec597cSGregory Neil Shapiro if (nexttoken == CANONHOST || 447a7ec597cSGregory Neil Shapiro nexttoken == CANONUSER || 448a7ec597cSGregory Neil Shapiro nexttoken == endtoken) 449a7ec597cSGregory Neil Shapiro { 450a7ec597cSGregory Neil Shapiro syserr("missing key name for lookup"); 451a7ec597cSGregory Neil Shapiro break; 452a7ec597cSGregory Neil Shapiro } 453a7ec597cSGregory Neil Shapiro #endif /* _FFR_EXTRA_MAP_CHECK */ 454a7ec597cSGregory Neil Shapiro break; 455a7ec597cSGregory Neil Shapiro 456a7ec597cSGregory Neil Shapiro case HOSTEND: 457a7ec597cSGregory Neil Shapiro case LOOKUPEND: 458d0cef73dSGregory Neil Shapiro if ((ap[0][0] & 0377) != endtoken) 459a7ec597cSGregory Neil Shapiro break; 460a7ec597cSGregory Neil Shapiro inmap = false; 461a7ec597cSGregory Neil Shapiro endtoken = 0; 462a7ec597cSGregory Neil Shapiro break; 463a7ec597cSGregory Neil Shapiro 464a7ec597cSGregory Neil Shapiro 46540266059SGregory Neil Shapiro #if 0 46640266059SGregory Neil Shapiro /* 46740266059SGregory Neil Shapiro ** This doesn't work yet as there are maps defined *after* the cf 46840266059SGregory Neil Shapiro ** is read such as host, user, and alias. So for now, it's removed. 46940266059SGregory Neil Shapiro ** When it comes back, the RELEASE_NOTES entry will be: 47040266059SGregory Neil Shapiro ** Emit warnings for unknown maps when reading the .cf file. Based on 47140266059SGregory Neil Shapiro ** patch from Robert Harker of Harker Systems. 47240266059SGregory Neil Shapiro */ 47340266059SGregory Neil Shapiro 47440266059SGregory Neil Shapiro case LOOKUPBEGIN: 47540266059SGregory Neil Shapiro /* 47640266059SGregory Neil Shapiro ** Got a database lookup, 47740266059SGregory Neil Shapiro ** check if map is defined. 47840266059SGregory Neil Shapiro */ 47940266059SGregory Neil Shapiro 480d0cef73dSGregory Neil Shapiro ep = ap[1]; 481d0cef73dSGregory Neil Shapiro if ((ep[0] & 0377) != MACRODEXPAND && 482d0cef73dSGregory Neil Shapiro stab(ep, ST_MAP, ST_FIND) == NULL) 48340266059SGregory Neil Shapiro { 48440266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, 48540266059SGregory Neil Shapiro SM_TIME_DEFAULT, 48640266059SGregory Neil Shapiro "Warning: %s: line %d: map %s not found\n", 48740266059SGregory Neil Shapiro FileName, 48840266059SGregory Neil Shapiro LineNumber, 48940266059SGregory Neil Shapiro ep); 49040266059SGregory Neil Shapiro } 49140266059SGregory Neil Shapiro break; 49240266059SGregory Neil Shapiro #endif /* 0 */ 493c2aa98e2SPeter Wemm } 494c2aa98e2SPeter Wemm if (botch != NULL) 495c2aa98e2SPeter Wemm syserr("Inappropriate use of %s on RHS", 496c2aa98e2SPeter Wemm botch); 497c2aa98e2SPeter Wemm } 498a7ec597cSGregory Neil Shapiro if (inmap) 499a7ec597cSGregory Neil Shapiro syserr("missing map closing token"); 500c2aa98e2SPeter Wemm } 501c2aa98e2SPeter Wemm else 502c2aa98e2SPeter Wemm { 503c2aa98e2SPeter Wemm syserr("R line: null RHS"); 504c2aa98e2SPeter Wemm rwp->r_rhs = null_list; 505c2aa98e2SPeter Wemm } 506c2aa98e2SPeter Wemm break; 507c2aa98e2SPeter Wemm 508c2aa98e2SPeter Wemm case 'S': /* select rewriting set */ 509d0cef73dSGregory Neil Shapiro expand(&bp[1], exbuf, sizeof(exbuf), e); 510c2aa98e2SPeter Wemm ruleset = strtorwset(exbuf, NULL, ST_ENTER); 511c2aa98e2SPeter Wemm if (ruleset < 0) 512c2aa98e2SPeter Wemm break; 51306f25ae9SGregory Neil Shapiro 514c2aa98e2SPeter Wemm rwp = RewriteRules[ruleset]; 515c2aa98e2SPeter Wemm if (rwp != NULL) 516c2aa98e2SPeter Wemm { 5179bd497b8SGregory Neil Shapiro if (OpMode == MD_TEST || OpMode == MD_CHECKCONFIG) 51840266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, 51940266059SGregory Neil Shapiro SM_TIME_DEFAULT, 52040266059SGregory Neil Shapiro "WARNING: Ruleset %s has multiple definitions\n", 521c2aa98e2SPeter Wemm &bp[1]); 52206f25ae9SGregory Neil Shapiro if (tTd(37, 1)) 52340266059SGregory Neil Shapiro sm_dprintf("WARNING: Ruleset %s has multiple definitions\n", 52406f25ae9SGregory Neil Shapiro &bp[1]); 525c2aa98e2SPeter Wemm while (rwp->r_next != NULL) 526c2aa98e2SPeter Wemm rwp = rwp->r_next; 527c2aa98e2SPeter Wemm } 528c2aa98e2SPeter Wemm break; 529c2aa98e2SPeter Wemm 530c2aa98e2SPeter Wemm case 'D': /* macro definition */ 53140266059SGregory Neil Shapiro mid = macid_parse(&bp[1], &ep); 532193538b7SGregory Neil Shapiro if (mid == 0) 533193538b7SGregory Neil Shapiro break; 534c2aa98e2SPeter Wemm p = munchstring(ep, NULL, '\0'); 53540266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, mid, p); 536c2aa98e2SPeter Wemm break; 537c2aa98e2SPeter Wemm 538c2aa98e2SPeter Wemm case 'H': /* required header line */ 53906f25ae9SGregory Neil Shapiro (void) chompheader(&bp[1], CHHDR_DEF, NULL, e); 540c2aa98e2SPeter Wemm break; 541c2aa98e2SPeter Wemm 542c2aa98e2SPeter Wemm case 'C': /* word class */ 543c2aa98e2SPeter Wemm case 'T': /* trusted user (set class `t') */ 544c2aa98e2SPeter Wemm if (bp[0] == 'C') 545c2aa98e2SPeter Wemm { 54640266059SGregory Neil Shapiro mid = macid_parse(&bp[1], &ep); 547193538b7SGregory Neil Shapiro if (mid == 0) 548193538b7SGregory Neil Shapiro break; 549d0cef73dSGregory Neil Shapiro expand(ep, exbuf, sizeof(exbuf), e); 550c2aa98e2SPeter Wemm p = exbuf; 551c2aa98e2SPeter Wemm } 552c2aa98e2SPeter Wemm else 553c2aa98e2SPeter Wemm { 554c2aa98e2SPeter Wemm mid = 't'; 555c2aa98e2SPeter Wemm p = &bp[1]; 556c2aa98e2SPeter Wemm } 557c2aa98e2SPeter Wemm while (*p != '\0') 558c2aa98e2SPeter Wemm { 559c2aa98e2SPeter Wemm register char *wd; 560c2aa98e2SPeter Wemm char delim; 561c2aa98e2SPeter Wemm 562*5b0945b5SGregory Neil Shapiro while (*p != '\0' && SM_ISSPACE(*p)) 563c2aa98e2SPeter Wemm p++; 564c2aa98e2SPeter Wemm wd = p; 565*5b0945b5SGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p))) 566c2aa98e2SPeter Wemm p++; 567c2aa98e2SPeter Wemm delim = *p; 568c2aa98e2SPeter Wemm *p = '\0'; 569c2aa98e2SPeter Wemm if (wd[0] != '\0') 570c2aa98e2SPeter Wemm setclass(mid, wd); 571c2aa98e2SPeter Wemm *p = delim; 572c2aa98e2SPeter Wemm } 573c2aa98e2SPeter Wemm break; 574c2aa98e2SPeter Wemm 575c2aa98e2SPeter Wemm case 'F': /* word class from file */ 57640266059SGregory Neil Shapiro mid = macid_parse(&bp[1], &ep); 577193538b7SGregory Neil Shapiro if (mid == 0) 578193538b7SGregory Neil Shapiro break; 579*5b0945b5SGregory Neil Shapiro for (p = ep; SM_ISSPACE(*p); ) 580c2aa98e2SPeter Wemm p++; 581c2aa98e2SPeter Wemm if (p[0] == '-' && p[1] == 'o') 582c2aa98e2SPeter Wemm { 58340266059SGregory Neil Shapiro optional = true; 58440266059SGregory Neil Shapiro while (*p != '\0' && 585*5b0945b5SGregory Neil Shapiro !(SM_ISSPACE(*p))) 586c2aa98e2SPeter Wemm p++; 587*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p)) 588c2aa98e2SPeter Wemm p++; 589c2aa98e2SPeter Wemm } 590c2aa98e2SPeter Wemm else 59140266059SGregory Neil Shapiro optional = false; 59206f25ae9SGregory Neil Shapiro 593605302a5SGregory Neil Shapiro /* check if [key]@map:spec */ 594605302a5SGregory Neil Shapiro ismap = false; 595605302a5SGregory Neil Shapiro if (!SM_IS_DIR_DELIM(*p) && 596605302a5SGregory Neil Shapiro *p != '|' && 597605302a5SGregory Neil Shapiro (q = strchr(p, '@')) != NULL) 598605302a5SGregory Neil Shapiro { 599605302a5SGregory Neil Shapiro q++; 600605302a5SGregory Neil Shapiro 601605302a5SGregory Neil Shapiro /* look for @LDAP or @map: in string */ 602605302a5SGregory Neil Shapiro if (strcmp(q, "LDAP") == 0 || 603605302a5SGregory Neil Shapiro (*q != ':' && 604605302a5SGregory Neil Shapiro strchr(q, ':') != NULL)) 605605302a5SGregory Neil Shapiro ismap = true; 606605302a5SGregory Neil Shapiro } 607605302a5SGregory Neil Shapiro 608605302a5SGregory Neil Shapiro if (ismap) 60940266059SGregory Neil Shapiro { 61040266059SGregory Neil Shapiro /* use entire spec */ 611c2aa98e2SPeter Wemm file = p; 61240266059SGregory Neil Shapiro } 61340266059SGregory Neil Shapiro else 61440266059SGregory Neil Shapiro { 61540266059SGregory Neil Shapiro file = extrquotstr(p, &q, " ", &ok); 61640266059SGregory Neil Shapiro if (!ok) 61740266059SGregory Neil Shapiro { 61840266059SGregory Neil Shapiro syserr("illegal filename '%s'", p); 61940266059SGregory Neil Shapiro break; 62040266059SGregory Neil Shapiro } 62140266059SGregory Neil Shapiro } 62240266059SGregory Neil Shapiro 623605302a5SGregory Neil Shapiro if (*file == '|' || ismap) 624c2aa98e2SPeter Wemm p = "%s"; 625c2aa98e2SPeter Wemm else 626c2aa98e2SPeter Wemm { 62706f25ae9SGregory Neil Shapiro p = q; 628c2aa98e2SPeter Wemm if (*p == '\0') 629c2aa98e2SPeter Wemm p = "%s"; 630c2aa98e2SPeter Wemm else 631c2aa98e2SPeter Wemm { 632c2aa98e2SPeter Wemm *p = '\0'; 633c2aa98e2SPeter Wemm while (isascii(*++p) && isspace(*p)) 634c2aa98e2SPeter Wemm continue; 635c2aa98e2SPeter Wemm } 636c2aa98e2SPeter Wemm } 637605302a5SGregory Neil Shapiro fileclass(mid, file, p, ismap, safe, optional); 638c2aa98e2SPeter Wemm break; 639c2aa98e2SPeter Wemm 64040266059SGregory Neil Shapiro #if XLA 641c2aa98e2SPeter Wemm case 'L': /* extended load average description */ 642c2aa98e2SPeter Wemm xla_init(&bp[1]); 643c2aa98e2SPeter Wemm break; 644*5b0945b5SGregory Neil Shapiro #endif 645c2aa98e2SPeter Wemm 646c2aa98e2SPeter Wemm #if defined(SUN_EXTENSIONS) && defined(SUN_LOOKUP_MACRO) 647c2aa98e2SPeter Wemm case 'L': /* lookup macro */ 648c2aa98e2SPeter Wemm case 'G': /* lookup class */ 649c2aa98e2SPeter Wemm /* reserved for Sun -- NIS+ database lookup */ 650c2aa98e2SPeter Wemm if (VendorCode != VENDOR_SUN) 651c2aa98e2SPeter Wemm goto badline; 652c2aa98e2SPeter Wemm sun_lg_config_line(bp, e); 653c2aa98e2SPeter Wemm break; 65406f25ae9SGregory Neil Shapiro #endif /* defined(SUN_EXTENSIONS) && defined(SUN_LOOKUP_MACRO) */ 655c2aa98e2SPeter Wemm 656c2aa98e2SPeter Wemm case 'M': /* define mailer */ 657c2aa98e2SPeter Wemm makemailer(&bp[1]); 658c2aa98e2SPeter Wemm break; 659c2aa98e2SPeter Wemm 660c2aa98e2SPeter Wemm case 'O': /* set option */ 66140266059SGregory Neil Shapiro setoption(bp[1], &bp[2], safe, false, e); 662c2aa98e2SPeter Wemm break; 663c2aa98e2SPeter Wemm 664c2aa98e2SPeter Wemm case 'P': /* set precedence */ 665c2aa98e2SPeter Wemm if (NumPriorities >= MAXPRIORITIES) 666c2aa98e2SPeter Wemm { 667c2aa98e2SPeter Wemm toomany('P', MAXPRIORITIES); 668c2aa98e2SPeter Wemm break; 669c2aa98e2SPeter Wemm } 670c2aa98e2SPeter Wemm for (p = &bp[1]; *p != '\0' && *p != '='; p++) 671c2aa98e2SPeter Wemm continue; 672c2aa98e2SPeter Wemm if (*p == '\0') 673c2aa98e2SPeter Wemm goto badline; 674c2aa98e2SPeter Wemm *p = '\0'; 675c2aa98e2SPeter Wemm Priorities[NumPriorities].pri_name = newstr(&bp[1]); 676c2aa98e2SPeter Wemm Priorities[NumPriorities].pri_val = atoi(++p); 677c2aa98e2SPeter Wemm NumPriorities++; 678c2aa98e2SPeter Wemm break; 679c2aa98e2SPeter Wemm 68040266059SGregory Neil Shapiro case 'Q': /* define queue */ 68140266059SGregory Neil Shapiro makequeue(&bp[1], true); 68240266059SGregory Neil Shapiro break; 68340266059SGregory Neil Shapiro 684c2aa98e2SPeter Wemm case 'V': /* configuration syntax version */ 685*5b0945b5SGregory Neil Shapiro for (p = &bp[1]; SM_ISSPACE(*p); p++) 686c2aa98e2SPeter Wemm continue; 687c2aa98e2SPeter Wemm if (!isascii(*p) || !isdigit(*p)) 688c2aa98e2SPeter Wemm { 689c2aa98e2SPeter Wemm syserr("invalid argument to V line: \"%.20s\"", 690c2aa98e2SPeter Wemm &bp[1]); 691c2aa98e2SPeter Wemm break; 692c2aa98e2SPeter Wemm } 693c2aa98e2SPeter Wemm ConfigLevel = strtol(p, &ep, 10); 694c2aa98e2SPeter Wemm 695c2aa98e2SPeter Wemm /* 696c2aa98e2SPeter Wemm ** Do heuristic tweaking for back compatibility. 697c2aa98e2SPeter Wemm */ 698c2aa98e2SPeter Wemm 699c2aa98e2SPeter Wemm if (ConfigLevel >= 5) 700c2aa98e2SPeter Wemm { 701c2aa98e2SPeter Wemm /* level 5 configs have short name in $w */ 702c2aa98e2SPeter Wemm p = macvalue('w', e); 703c2aa98e2SPeter Wemm if (p != NULL && (p = strchr(p, '.')) != NULL) 70440266059SGregory Neil Shapiro { 705c2aa98e2SPeter Wemm *p = '\0'; 70640266059SGregory Neil Shapiro macdefine(&e->e_macro, A_TEMP, 'w', 70740266059SGregory Neil Shapiro macvalue('w', e)); 70840266059SGregory Neil Shapiro } 709c2aa98e2SPeter Wemm } 710c2aa98e2SPeter Wemm if (ConfigLevel >= 6) 711c2aa98e2SPeter Wemm { 71240266059SGregory Neil Shapiro ColonOkInAddr = false; 713c2aa98e2SPeter Wemm } 714c2aa98e2SPeter Wemm 715c2aa98e2SPeter Wemm /* 716c2aa98e2SPeter Wemm ** Look for vendor code. 717c2aa98e2SPeter Wemm */ 718c2aa98e2SPeter Wemm 719c2aa98e2SPeter Wemm if (*ep++ == '/') 720c2aa98e2SPeter Wemm { 721c2aa98e2SPeter Wemm /* extract vendor code */ 722c2aa98e2SPeter Wemm for (p = ep; isascii(*p) && isalpha(*p); ) 723c2aa98e2SPeter Wemm p++; 724c2aa98e2SPeter Wemm *p = '\0'; 725c2aa98e2SPeter Wemm 726c2aa98e2SPeter Wemm if (!setvendor(ep)) 727c2aa98e2SPeter Wemm syserr("invalid V line vendor code: \"%s\"", 728c2aa98e2SPeter Wemm ep); 729c2aa98e2SPeter Wemm } 730c2aa98e2SPeter Wemm break; 731c2aa98e2SPeter Wemm 732c2aa98e2SPeter Wemm case 'K': 733d0cef73dSGregory Neil Shapiro expand(&bp[1], exbuf, sizeof(exbuf), e); 734c2aa98e2SPeter Wemm (void) makemapentry(exbuf); 735c2aa98e2SPeter Wemm break; 736c2aa98e2SPeter Wemm 737c2aa98e2SPeter Wemm case 'E': 738c2aa98e2SPeter Wemm p = strchr(bp, '='); 739c2aa98e2SPeter Wemm if (p != NULL) 740c2aa98e2SPeter Wemm *p++ = '\0'; 7414e4196cbSGregory Neil Shapiro sm_setuserenv(&bp[1], p); 742c2aa98e2SPeter Wemm break; 743c2aa98e2SPeter Wemm 74406f25ae9SGregory Neil Shapiro case 'X': /* mail filter */ 74540266059SGregory Neil Shapiro #if MILTER 74606f25ae9SGregory Neil Shapiro milter_setup(&bp[1]); 74740266059SGregory Neil Shapiro #else /* MILTER */ 74840266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 74940266059SGregory Neil Shapiro "Warning: Filter usage ('X') requires Milter support (-DMILTER)\n"); 75040266059SGregory Neil Shapiro #endif /* MILTER */ 75106f25ae9SGregory Neil Shapiro break; 75206f25ae9SGregory Neil Shapiro 753c2aa98e2SPeter Wemm default: 754c2aa98e2SPeter Wemm badline: 755c2aa98e2SPeter Wemm syserr("unknown configuration line \"%s\"", bp); 756c2aa98e2SPeter Wemm } 757c2aa98e2SPeter Wemm if (bp != buf) 75840266059SGregory Neil Shapiro sm_free(bp); /* XXX */ 759c2aa98e2SPeter Wemm } 76040266059SGregory Neil Shapiro if (sm_io_error(cf)) 761c2aa98e2SPeter Wemm { 762c2aa98e2SPeter Wemm syserr("I/O read error"); 76340266059SGregory Neil Shapiro finis(false, true, EX_OSFILE); 764c2aa98e2SPeter Wemm } 76540266059SGregory Neil Shapiro (void) sm_io_close(cf, SM_TIME_DEFAULT); 766c2aa98e2SPeter Wemm FileName = NULL; 767c2aa98e2SPeter Wemm 768da7d7b9cSGregory Neil Shapiro #if _FFR_BOUNCE_QUEUE 769da7d7b9cSGregory Neil Shapiro initbouncequeue(); 770da7d7b9cSGregory Neil Shapiro #endif 771da7d7b9cSGregory Neil Shapiro 772c2aa98e2SPeter Wemm /* initialize host maps from local service tables */ 773c2aa98e2SPeter Wemm inithostmaps(); 774c2aa98e2SPeter Wemm 77506f25ae9SGregory Neil Shapiro /* initialize daemon (if not defined yet) */ 77606f25ae9SGregory Neil Shapiro initdaemon(); 77706f25ae9SGregory Neil Shapiro 778c2aa98e2SPeter Wemm /* determine if we need to do special name-server frotz */ 779c2aa98e2SPeter Wemm { 780c2aa98e2SPeter Wemm int nmaps; 781c2aa98e2SPeter Wemm char *maptype[MAXMAPSTACK]; 782c2aa98e2SPeter Wemm short mapreturn[MAXMAPACTIONS]; 783c2aa98e2SPeter Wemm 784c2aa98e2SPeter Wemm nmaps = switch_map_find("hosts", maptype, mapreturn); 78540266059SGregory Neil Shapiro UseNameServer = false; 786c2aa98e2SPeter Wemm if (nmaps > 0 && nmaps <= MAXMAPSTACK) 787c2aa98e2SPeter Wemm { 788c2aa98e2SPeter Wemm register int mapno; 789c2aa98e2SPeter Wemm 79040266059SGregory Neil Shapiro for (mapno = 0; mapno < nmaps && !UseNameServer; 79140266059SGregory Neil Shapiro mapno++) 792c2aa98e2SPeter Wemm { 793c2aa98e2SPeter Wemm if (strcmp(maptype[mapno], "dns") == 0) 79440266059SGregory Neil Shapiro UseNameServer = true; 795c2aa98e2SPeter Wemm } 796c2aa98e2SPeter Wemm } 797c2aa98e2SPeter Wemm } 798da7d7b9cSGregory Neil Shapiro setupdynmailers(); 799c2aa98e2SPeter Wemm } 800d0cef73dSGregory Neil Shapiro 80140266059SGregory Neil Shapiro /* 802c2aa98e2SPeter Wemm ** TRANSLATE_DOLLARS -- convert $x into internal form 803c2aa98e2SPeter Wemm ** 804c2aa98e2SPeter Wemm ** Actually does all appropriate pre-processing of a config line 805c2aa98e2SPeter Wemm ** to turn it into internal form. 806c2aa98e2SPeter Wemm ** 807c2aa98e2SPeter Wemm ** Parameters: 808d0cef73dSGregory Neil Shapiro ** ibp -- the buffer to translate. 809d0cef73dSGregory Neil Shapiro ** obp -- where to put the translation; may be the same as obp 810d0cef73dSGregory Neil Shapiro ** bsp -- a pointer to the size of obp; will be updated if 811d0cef73dSGregory Neil Shapiro ** the buffer needs to be replaced. 812c2aa98e2SPeter Wemm ** 813c2aa98e2SPeter Wemm ** Returns: 814d0cef73dSGregory Neil Shapiro ** The buffer pointer; may differ from obp if the expansion 815d0cef73dSGregory Neil Shapiro ** is larger then *bsp, in which case this will point to 816d0cef73dSGregory Neil Shapiro ** malloc()ed memory which must be free()d by the caller. 817c2aa98e2SPeter Wemm */ 818c2aa98e2SPeter Wemm 819d0cef73dSGregory Neil Shapiro char * 820d0cef73dSGregory Neil Shapiro translate_dollars(ibp, obp, bsp) 821d0cef73dSGregory Neil Shapiro char *ibp; 822d0cef73dSGregory Neil Shapiro char *obp; 823d0cef73dSGregory Neil Shapiro int *bsp; 824c2aa98e2SPeter Wemm { 825c2aa98e2SPeter Wemm register char *p; 826c2aa98e2SPeter Wemm auto char *ep; 827d0cef73dSGregory Neil Shapiro char *bp; 828d0cef73dSGregory Neil Shapiro 829d0cef73dSGregory Neil Shapiro if (tTd(37, 53)) 830d0cef73dSGregory Neil Shapiro { 831d0cef73dSGregory Neil Shapiro sm_dprintf("translate_dollars("); 832d0cef73dSGregory Neil Shapiro xputs(sm_debug_file(), ibp); 833d0cef73dSGregory Neil Shapiro sm_dprintf(")\n"); 834d0cef73dSGregory Neil Shapiro } 835d0cef73dSGregory Neil Shapiro 836d0cef73dSGregory Neil Shapiro bp = quote_internal_chars(ibp, obp, bsp); 837c2aa98e2SPeter Wemm 838c2aa98e2SPeter Wemm for (p = bp; *p != '\0'; p++) 839c2aa98e2SPeter Wemm { 840c2aa98e2SPeter Wemm if (*p == '#' && p > bp && ConfigLevel >= 3) 841c2aa98e2SPeter Wemm { 842c2aa98e2SPeter Wemm register char *e; 843c2aa98e2SPeter Wemm 844c2aa98e2SPeter Wemm switch (*--p & 0377) 845c2aa98e2SPeter Wemm { 846c2aa98e2SPeter Wemm case MACROEXPAND: 847c2aa98e2SPeter Wemm /* it's from $# -- let it go through */ 848c2aa98e2SPeter Wemm p++; 849c2aa98e2SPeter Wemm break; 850c2aa98e2SPeter Wemm 851c2aa98e2SPeter Wemm case '\\': 852c2aa98e2SPeter Wemm /* it's backslash escaped */ 85340266059SGregory Neil Shapiro (void) sm_strlcpy(p, p + 1, strlen(p)); 854c2aa98e2SPeter Wemm break; 855c2aa98e2SPeter Wemm 856c2aa98e2SPeter Wemm default: 85706f25ae9SGregory Neil Shapiro /* delete leading white space */ 858*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p) && 859c2aa98e2SPeter Wemm *p != '\n' && p > bp) 860d0cef73dSGregory Neil Shapiro { 861c2aa98e2SPeter Wemm p--; 862d0cef73dSGregory Neil Shapiro } 863c2aa98e2SPeter Wemm if ((e = strchr(++p, '\n')) != NULL) 86440266059SGregory Neil Shapiro (void) sm_strlcpy(p, e, strlen(p)); 865c2aa98e2SPeter Wemm else 866c2aa98e2SPeter Wemm *p-- = '\0'; 867c2aa98e2SPeter Wemm break; 868c2aa98e2SPeter Wemm } 869c2aa98e2SPeter Wemm continue; 870c2aa98e2SPeter Wemm } 871c2aa98e2SPeter Wemm 872c2aa98e2SPeter Wemm if (*p != '$' || p[1] == '\0') 873c2aa98e2SPeter Wemm continue; 874c2aa98e2SPeter Wemm 875c2aa98e2SPeter Wemm if (p[1] == '$') 876c2aa98e2SPeter Wemm { 877c2aa98e2SPeter Wemm /* actual dollar sign.... */ 87840266059SGregory Neil Shapiro (void) sm_strlcpy(p, p + 1, strlen(p)); 879c2aa98e2SPeter Wemm continue; 880c2aa98e2SPeter Wemm } 881c2aa98e2SPeter Wemm 882c2aa98e2SPeter Wemm /* convert to macro expansion character */ 883c2aa98e2SPeter Wemm *p++ = MACROEXPAND; 884c2aa98e2SPeter Wemm 885c2aa98e2SPeter Wemm /* special handling for $=, $~, $&, and $? */ 886c2aa98e2SPeter Wemm if (*p == '=' || *p == '~' || *p == '&' || *p == '?') 887c2aa98e2SPeter Wemm p++; 888c2aa98e2SPeter Wemm 889c2aa98e2SPeter Wemm /* convert macro name to code */ 89040266059SGregory Neil Shapiro *p = macid_parse(p, &ep); 89106f25ae9SGregory Neil Shapiro if (ep != p + 1) 89240266059SGregory Neil Shapiro (void) sm_strlcpy(p + 1, ep, strlen(p + 1)); 893c2aa98e2SPeter Wemm } 894c2aa98e2SPeter Wemm 895c2aa98e2SPeter Wemm /* strip trailing white space from the line */ 896*5b0945b5SGregory Neil Shapiro while (--p > bp && SM_ISSPACE(*p)) 897c2aa98e2SPeter Wemm *p = '\0'; 898d0cef73dSGregory Neil Shapiro 899d0cef73dSGregory Neil Shapiro if (tTd(37, 53)) 900d0cef73dSGregory Neil Shapiro { 901d0cef73dSGregory Neil Shapiro sm_dprintf(" translate_dollars => "); 902d0cef73dSGregory Neil Shapiro xputs(sm_debug_file(), bp); 903d0cef73dSGregory Neil Shapiro sm_dprintf("\n"); 904d0cef73dSGregory Neil Shapiro } 905d0cef73dSGregory Neil Shapiro 906d0cef73dSGregory Neil Shapiro return bp; 907c2aa98e2SPeter Wemm } 90840266059SGregory Neil Shapiro /* 909c2aa98e2SPeter Wemm ** TOOMANY -- signal too many of some option 910c2aa98e2SPeter Wemm ** 911c2aa98e2SPeter Wemm ** Parameters: 912c2aa98e2SPeter Wemm ** id -- the id of the error line 913c2aa98e2SPeter Wemm ** maxcnt -- the maximum possible values 914c2aa98e2SPeter Wemm ** 915c2aa98e2SPeter Wemm ** Returns: 916c2aa98e2SPeter Wemm ** none. 917c2aa98e2SPeter Wemm ** 918c2aa98e2SPeter Wemm ** Side Effects: 919c2aa98e2SPeter Wemm ** gives a syserr. 920c2aa98e2SPeter Wemm */ 921c2aa98e2SPeter Wemm 92206f25ae9SGregory Neil Shapiro static void 923c2aa98e2SPeter Wemm toomany(id, maxcnt) 924c2aa98e2SPeter Wemm int id; 925c2aa98e2SPeter Wemm int maxcnt; 926c2aa98e2SPeter Wemm { 927c2aa98e2SPeter Wemm syserr("too many %c lines, %d max", id, maxcnt); 928c2aa98e2SPeter Wemm } 92940266059SGregory Neil Shapiro /* 930c2aa98e2SPeter Wemm ** FILECLASS -- read members of a class from a file 931c2aa98e2SPeter Wemm ** 932c2aa98e2SPeter Wemm ** Parameters: 933c2aa98e2SPeter Wemm ** class -- class to define. 934c2aa98e2SPeter Wemm ** filename -- name of file to read. 935c2aa98e2SPeter Wemm ** fmt -- scanf string to use for match. 936605302a5SGregory Neil Shapiro ** ismap -- if set, this is a map lookup. 937c2aa98e2SPeter Wemm ** safe -- if set, this is a safe read. 938c2aa98e2SPeter Wemm ** optional -- if set, it is not an error for the file to 939c2aa98e2SPeter Wemm ** not exist. 940c2aa98e2SPeter Wemm ** 941c2aa98e2SPeter Wemm ** Returns: 942c2aa98e2SPeter Wemm ** none 943c2aa98e2SPeter Wemm ** 944c2aa98e2SPeter Wemm ** Side Effects: 945c2aa98e2SPeter Wemm ** puts all lines in filename that match a scanf into 946c2aa98e2SPeter Wemm ** the named class. 947c2aa98e2SPeter Wemm */ 948c2aa98e2SPeter Wemm 94940266059SGregory Neil Shapiro /* 95040266059SGregory Neil Shapiro ** Break up the match into words and add to class. 95140266059SGregory Neil Shapiro */ 95240266059SGregory Neil Shapiro 95340266059SGregory Neil Shapiro static void 95440266059SGregory Neil Shapiro parse_class_words(class, line) 95540266059SGregory Neil Shapiro int class; 95640266059SGregory Neil Shapiro char *line; 95740266059SGregory Neil Shapiro { 95840266059SGregory Neil Shapiro while (line != NULL && *line != '\0') 95940266059SGregory Neil Shapiro { 96040266059SGregory Neil Shapiro register char *q; 96140266059SGregory Neil Shapiro 96240266059SGregory Neil Shapiro /* strip leading spaces */ 963*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*line)) 96440266059SGregory Neil Shapiro line++; 96540266059SGregory Neil Shapiro if (*line == '\0') 96640266059SGregory Neil Shapiro break; 96740266059SGregory Neil Shapiro 96840266059SGregory Neil Shapiro /* find the end of the word */ 96940266059SGregory Neil Shapiro q = line; 970*5b0945b5SGregory Neil Shapiro while (*line != '\0' && !(SM_ISSPACE(*line))) 97140266059SGregory Neil Shapiro line++; 97240266059SGregory Neil Shapiro if (*line != '\0') 97340266059SGregory Neil Shapiro *line++ = '\0'; 97440266059SGregory Neil Shapiro 97540266059SGregory Neil Shapiro /* enter the word in the symbol table */ 97640266059SGregory Neil Shapiro setclass(class, q); 97740266059SGregory Neil Shapiro } 97840266059SGregory Neil Shapiro } 97940266059SGregory Neil Shapiro 98006f25ae9SGregory Neil Shapiro static void 981605302a5SGregory Neil Shapiro fileclass(class, filename, fmt, ismap, safe, optional) 982c2aa98e2SPeter Wemm int class; 983c2aa98e2SPeter Wemm char *filename; 984c2aa98e2SPeter Wemm char *fmt; 985605302a5SGregory Neil Shapiro bool ismap; 986c2aa98e2SPeter Wemm bool safe; 987c2aa98e2SPeter Wemm bool optional; 988c2aa98e2SPeter Wemm { 98940266059SGregory Neil Shapiro SM_FILE_T *f; 99006f25ae9SGregory Neil Shapiro long sff; 991c2aa98e2SPeter Wemm pid_t pid; 992c2aa98e2SPeter Wemm register char *p; 993c2aa98e2SPeter Wemm char buf[MAXLINE]; 994c2aa98e2SPeter Wemm 995c2aa98e2SPeter Wemm if (tTd(37, 2)) 99640266059SGregory Neil Shapiro sm_dprintf("fileclass(%s, fmt=%s)\n", filename, fmt); 997c2aa98e2SPeter Wemm 99840266059SGregory Neil Shapiro if (*filename == '\0') 99940266059SGregory Neil Shapiro { 100040266059SGregory Neil Shapiro syserr("fileclass: missing file name"); 100140266059SGregory Neil Shapiro return; 100240266059SGregory Neil Shapiro } 1003605302a5SGregory Neil Shapiro else if (ismap) 100440266059SGregory Neil Shapiro { 100540266059SGregory Neil Shapiro int status = 0; 100640266059SGregory Neil Shapiro char *key; 100740266059SGregory Neil Shapiro char *mn; 100840266059SGregory Neil Shapiro char *cl, *spec; 100940266059SGregory Neil Shapiro STAB *mapclass; 101040266059SGregory Neil Shapiro MAP map; 101140266059SGregory Neil Shapiro 101240266059SGregory Neil Shapiro mn = newstr(macname(class)); 101340266059SGregory Neil Shapiro 101440266059SGregory Neil Shapiro key = filename; 101540266059SGregory Neil Shapiro 1016605302a5SGregory Neil Shapiro /* skip past key */ 1017605302a5SGregory Neil Shapiro if ((p = strchr(filename, '@')) == NULL) 1018605302a5SGregory Neil Shapiro { 1019605302a5SGregory Neil Shapiro /* should not happen */ 1020605302a5SGregory Neil Shapiro syserr("fileclass: bogus map specification"); 1021605302a5SGregory Neil Shapiro sm_free(mn); 1022605302a5SGregory Neil Shapiro return; 1023605302a5SGregory Neil Shapiro } 1024605302a5SGregory Neil Shapiro 102540266059SGregory Neil Shapiro /* skip past '@' */ 102640266059SGregory Neil Shapiro *p++ = '\0'; 102740266059SGregory Neil Shapiro cl = p; 102840266059SGregory Neil Shapiro 1029a7ec597cSGregory Neil Shapiro #if LDAPMAP 103040266059SGregory Neil Shapiro if (strcmp(cl, "LDAP") == 0) 103140266059SGregory Neil Shapiro { 103240266059SGregory Neil Shapiro int n; 103340266059SGregory Neil Shapiro char *lc; 103440266059SGregory Neil Shapiro char jbuf[MAXHOSTNAMELEN]; 103540266059SGregory Neil Shapiro char lcbuf[MAXLINE]; 103640266059SGregory Neil Shapiro 103740266059SGregory Neil Shapiro /* Get $j */ 1038d0cef73dSGregory Neil Shapiro expand("\201j", jbuf, sizeof(jbuf), &BlankEnvelope); 103940266059SGregory Neil Shapiro if (jbuf[0] == '\0') 104040266059SGregory Neil Shapiro { 104140266059SGregory Neil Shapiro (void) sm_strlcpy(jbuf, "localhost", 1042d0cef73dSGregory Neil Shapiro sizeof(jbuf)); 104340266059SGregory Neil Shapiro } 104440266059SGregory Neil Shapiro 104540266059SGregory Neil Shapiro /* impose the default schema */ 104640266059SGregory Neil Shapiro lc = macvalue(macid("{sendmailMTACluster}"), CurEnv); 104740266059SGregory Neil Shapiro if (lc == NULL) 104840266059SGregory Neil Shapiro lc = ""; 104940266059SGregory Neil Shapiro else 105040266059SGregory Neil Shapiro { 1051d0cef73dSGregory Neil Shapiro expand(lc, lcbuf, sizeof(lcbuf), CurEnv); 105240266059SGregory Neil Shapiro lc = lcbuf; 105340266059SGregory Neil Shapiro } 105440266059SGregory Neil Shapiro 105540266059SGregory Neil Shapiro cl = "ldap"; 1056d0cef73dSGregory Neil Shapiro n = sm_snprintf(buf, sizeof(buf), 1057e92d3f3fSGregory Neil Shapiro "-k (&(objectClass=sendmailMTAClass)(sendmailMTAClassName=%s)(|(sendmailMTACluster=%s)(sendmailMTAHost=%s))) -v sendmailMTAClassValue,sendmailMTAClassSearch:FILTER:sendmailMTAClass,sendmailMTAClassURL:URL:sendmailMTAClass", 105840266059SGregory Neil Shapiro mn, lc, jbuf); 1059d0cef73dSGregory Neil Shapiro if (n >= sizeof(buf)) 106040266059SGregory Neil Shapiro { 106140266059SGregory Neil Shapiro syserr("fileclass: F{%s}: Default LDAP string too long", 106240266059SGregory Neil Shapiro mn); 106340266059SGregory Neil Shapiro sm_free(mn); 106440266059SGregory Neil Shapiro return; 106540266059SGregory Neil Shapiro } 106640266059SGregory Neil Shapiro spec = buf; 106740266059SGregory Neil Shapiro } 106840266059SGregory Neil Shapiro else 1069a7ec597cSGregory Neil Shapiro #endif /* LDAPMAP */ 107040266059SGregory Neil Shapiro { 107140266059SGregory Neil Shapiro if ((spec = strchr(cl, ':')) == NULL) 107240266059SGregory Neil Shapiro { 107340266059SGregory Neil Shapiro syserr("fileclass: F{%s}: missing map class", 107440266059SGregory Neil Shapiro mn); 107540266059SGregory Neil Shapiro sm_free(mn); 107640266059SGregory Neil Shapiro return; 107740266059SGregory Neil Shapiro } 107840266059SGregory Neil Shapiro *spec++ ='\0'; 107940266059SGregory Neil Shapiro } 108040266059SGregory Neil Shapiro 108140266059SGregory Neil Shapiro /* set up map structure */ 108240266059SGregory Neil Shapiro mapclass = stab(cl, ST_MAPCLASS, ST_FIND); 108340266059SGregory Neil Shapiro if (mapclass == NULL) 108440266059SGregory Neil Shapiro { 108540266059SGregory Neil Shapiro syserr("fileclass: F{%s}: class %s not available", 108640266059SGregory Neil Shapiro mn, cl); 108740266059SGregory Neil Shapiro sm_free(mn); 108840266059SGregory Neil Shapiro return; 108940266059SGregory Neil Shapiro } 1090d0cef73dSGregory Neil Shapiro memset(&map, '\0', sizeof(map)); 109140266059SGregory Neil Shapiro map.map_class = &mapclass->s_mapclass; 109240266059SGregory Neil Shapiro map.map_mname = mn; 109340266059SGregory Neil Shapiro map.map_mflags |= MF_FILECLASS; 109440266059SGregory Neil Shapiro 1095605302a5SGregory Neil Shapiro if (tTd(37, 5)) 1096605302a5SGregory Neil Shapiro sm_dprintf("fileclass: F{%s}: map class %s, key %s, spec %s\n", 1097605302a5SGregory Neil Shapiro mn, cl, key, spec); 1098605302a5SGregory Neil Shapiro 1099605302a5SGregory Neil Shapiro 110040266059SGregory Neil Shapiro /* parse map spec */ 110140266059SGregory Neil Shapiro if (!map.map_class->map_parse(&map, spec)) 110240266059SGregory Neil Shapiro { 110340266059SGregory Neil Shapiro /* map_parse() showed the error already */ 110440266059SGregory Neil Shapiro sm_free(mn); 110540266059SGregory Neil Shapiro return; 110640266059SGregory Neil Shapiro } 110740266059SGregory Neil Shapiro map.map_mflags |= MF_VALID; 110840266059SGregory Neil Shapiro 110940266059SGregory Neil Shapiro /* open map */ 111040266059SGregory Neil Shapiro if (map.map_class->map_open(&map, O_RDONLY)) 111140266059SGregory Neil Shapiro { 111240266059SGregory Neil Shapiro map.map_mflags |= MF_OPEN; 111340266059SGregory Neil Shapiro map.map_pid = getpid(); 111440266059SGregory Neil Shapiro } 111540266059SGregory Neil Shapiro else 111640266059SGregory Neil Shapiro { 111740266059SGregory Neil Shapiro if (!optional && 111840266059SGregory Neil Shapiro !bitset(MF_OPTIONAL, map.map_mflags)) 111940266059SGregory Neil Shapiro syserr("fileclass: F{%s}: map open failed", 112040266059SGregory Neil Shapiro mn); 112140266059SGregory Neil Shapiro sm_free(mn); 112240266059SGregory Neil Shapiro return; 112340266059SGregory Neil Shapiro } 112440266059SGregory Neil Shapiro 112540266059SGregory Neil Shapiro /* lookup */ 112640266059SGregory Neil Shapiro p = (*map.map_class->map_lookup)(&map, key, NULL, &status); 112740266059SGregory Neil Shapiro if (status != EX_OK && status != EX_NOTFOUND) 112840266059SGregory Neil Shapiro { 112940266059SGregory Neil Shapiro if (!optional) 113040266059SGregory Neil Shapiro syserr("fileclass: F{%s}: map lookup failed", 113140266059SGregory Neil Shapiro mn); 113240266059SGregory Neil Shapiro p = NULL; 113340266059SGregory Neil Shapiro } 113440266059SGregory Neil Shapiro 113540266059SGregory Neil Shapiro /* use the results */ 113640266059SGregory Neil Shapiro if (p != NULL) 113740266059SGregory Neil Shapiro parse_class_words(class, p); 113840266059SGregory Neil Shapiro 113940266059SGregory Neil Shapiro /* close map */ 114040266059SGregory Neil Shapiro map.map_mflags |= MF_CLOSING; 114140266059SGregory Neil Shapiro map.map_class->map_close(&map); 114240266059SGregory Neil Shapiro map.map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING); 114340266059SGregory Neil Shapiro sm_free(mn); 114440266059SGregory Neil Shapiro return; 114540266059SGregory Neil Shapiro } 114640266059SGregory Neil Shapiro else if (filename[0] == '|') 1147c2aa98e2SPeter Wemm { 1148c2aa98e2SPeter Wemm auto int fd; 1149c2aa98e2SPeter Wemm int i; 1150c2aa98e2SPeter Wemm char *argv[MAXPV + 1]; 1151c2aa98e2SPeter Wemm 1152c2aa98e2SPeter Wemm i = 0; 115340266059SGregory Neil Shapiro for (p = strtok(&filename[1], " \t"); 115440266059SGregory Neil Shapiro p != NULL && i < MAXPV; 115540266059SGregory Neil Shapiro p = strtok(NULL, " \t")) 1156c2aa98e2SPeter Wemm argv[i++] = p; 1157c2aa98e2SPeter Wemm argv[i] = NULL; 1158c2aa98e2SPeter Wemm pid = prog_open(argv, &fd, CurEnv); 1159c2aa98e2SPeter Wemm if (pid < 0) 1160c2aa98e2SPeter Wemm f = NULL; 1161c2aa98e2SPeter Wemm else 116240266059SGregory Neil Shapiro f = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 116340266059SGregory Neil Shapiro (void *) &fd, SM_IO_RDONLY, NULL); 1164c2aa98e2SPeter Wemm } 1165c2aa98e2SPeter Wemm else 1166c2aa98e2SPeter Wemm { 1167c2aa98e2SPeter Wemm pid = -1; 1168c2aa98e2SPeter Wemm sff = SFF_REGONLY; 116906f25ae9SGregory Neil Shapiro if (!bitnset(DBS_CLASSFILEINUNSAFEDIRPATH, DontBlameSendmail)) 1170c2aa98e2SPeter Wemm sff |= SFF_SAFEDIRPATH; 117106f25ae9SGregory Neil Shapiro if (!bitnset(DBS_LINKEDCLASSFILEINWRITABLEDIR, 117206f25ae9SGregory Neil Shapiro DontBlameSendmail)) 1173c2aa98e2SPeter Wemm sff |= SFF_NOWLINK; 1174c2aa98e2SPeter Wemm if (safe) 1175c2aa98e2SPeter Wemm sff |= SFF_OPENASROOT; 117640266059SGregory Neil Shapiro else if (RealUid == 0) 117740266059SGregory Neil Shapiro sff |= SFF_ROOTOK; 1178c2aa98e2SPeter Wemm if (DontLockReadFiles) 1179c2aa98e2SPeter Wemm sff |= SFF_NOLOCK; 1180c2aa98e2SPeter Wemm f = safefopen(filename, O_RDONLY, 0, sff); 1181c2aa98e2SPeter Wemm } 1182c2aa98e2SPeter Wemm if (f == NULL) 1183c2aa98e2SPeter Wemm { 1184c2aa98e2SPeter Wemm if (!optional) 118506f25ae9SGregory Neil Shapiro syserr("fileclass: cannot open '%s'", filename); 1186c2aa98e2SPeter Wemm return; 1187c2aa98e2SPeter Wemm } 1188c2aa98e2SPeter Wemm 1189552d4955SGregory Neil Shapiro while (sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0) 1190c2aa98e2SPeter Wemm { 1191c2aa98e2SPeter Wemm #if SCANF 1192c2aa98e2SPeter Wemm char wordbuf[MAXLINE + 1]; 1193*5b0945b5SGregory Neil Shapiro #endif 1194c2aa98e2SPeter Wemm 1195c2aa98e2SPeter Wemm if (buf[0] == '#') 1196c2aa98e2SPeter Wemm continue; 1197c2aa98e2SPeter Wemm #if SCANF 119840266059SGregory Neil Shapiro if (sm_io_sscanf(buf, fmt, wordbuf) != 1) 1199c2aa98e2SPeter Wemm continue; 1200c2aa98e2SPeter Wemm p = wordbuf; 1201c2aa98e2SPeter Wemm #else /* SCANF */ 1202c2aa98e2SPeter Wemm p = buf; 1203c2aa98e2SPeter Wemm #endif /* SCANF */ 1204c2aa98e2SPeter Wemm 120540266059SGregory Neil Shapiro parse_class_words(class, p); 120640266059SGregory Neil Shapiro 1207c2aa98e2SPeter Wemm /* 120840266059SGregory Neil Shapiro ** If anything else is added here, 120940266059SGregory Neil Shapiro ** check if the '@' map case above 121040266059SGregory Neil Shapiro ** needs the code as well. 1211c2aa98e2SPeter Wemm */ 1212c2aa98e2SPeter Wemm } 1213c2aa98e2SPeter Wemm 121440266059SGregory Neil Shapiro (void) sm_io_close(f, SM_TIME_DEFAULT); 1215c2aa98e2SPeter Wemm if (pid > 0) 1216c2aa98e2SPeter Wemm (void) waitfor(pid); 1217c2aa98e2SPeter Wemm } 1218da7d7b9cSGregory Neil Shapiro 1219da7d7b9cSGregory Neil Shapiro #if _FFR_RCPTFLAGS 1220da7d7b9cSGregory Neil Shapiro /* first character for dynamically created mailers */ 1221da7d7b9cSGregory Neil Shapiro static char dynmailerp = ' '; 1222da7d7b9cSGregory Neil Shapiro 1223da7d7b9cSGregory Neil Shapiro /* list of first characters for cf defined mailers */ 1224da7d7b9cSGregory Neil Shapiro static char frst[MAXMAILERS + 1]; 1225da7d7b9cSGregory Neil Shapiro 1226da7d7b9cSGregory Neil Shapiro /* 1227da7d7b9cSGregory Neil Shapiro ** SETUPDYNMAILERS -- find a char that isn't used as first element of any 1228da7d7b9cSGregory Neil Shapiro ** mailer name. 1229da7d7b9cSGregory Neil Shapiro ** 1230da7d7b9cSGregory Neil Shapiro ** Parameters: 1231da7d7b9cSGregory Neil Shapiro ** none 1232da7d7b9cSGregory Neil Shapiro ** 1233da7d7b9cSGregory Neil Shapiro ** Returns: 1234da7d7b9cSGregory Neil Shapiro ** none 1235da7d7b9cSGregory Neil Shapiro ** 1236da7d7b9cSGregory Neil Shapiro ** Note: space is not valid in cf defined mailers hence the function 1237da7d7b9cSGregory Neil Shapiro ** will always find a char. It's not nice, but this is for 1238da7d7b9cSGregory Neil Shapiro ** internal names only. 1239da7d7b9cSGregory Neil Shapiro */ 1240da7d7b9cSGregory Neil Shapiro 1241da7d7b9cSGregory Neil Shapiro void 1242da7d7b9cSGregory Neil Shapiro setupdynmailers() 1243da7d7b9cSGregory Neil Shapiro { 1244da7d7b9cSGregory Neil Shapiro int i; 1245da7d7b9cSGregory Neil Shapiro char pp[] = "YXZ0123456789ABCDEFGHIJKLMNOPQRSTUVWyxzabcfghijkmnoqtuvw "; 1246da7d7b9cSGregory Neil Shapiro 1247da7d7b9cSGregory Neil Shapiro frst[MAXMAILERS] = '\0'; 1248da7d7b9cSGregory Neil Shapiro for (i = 0; i < strlen(pp); i++) 1249da7d7b9cSGregory Neil Shapiro { 1250da7d7b9cSGregory Neil Shapiro if (strchr(frst, pp[i]) == NULL) 1251da7d7b9cSGregory Neil Shapiro { 1252da7d7b9cSGregory Neil Shapiro dynmailerp = pp[i]; 1253da7d7b9cSGregory Neil Shapiro if (tTd(25, 8)) 1254da7d7b9cSGregory Neil Shapiro sm_dprintf("dynmailerp=%c\n", dynmailerp); 1255da7d7b9cSGregory Neil Shapiro return; 1256da7d7b9cSGregory Neil Shapiro } 1257da7d7b9cSGregory Neil Shapiro } 1258da7d7b9cSGregory Neil Shapiro 1259da7d7b9cSGregory Neil Shapiro /* NOTREACHED */ 1260da7d7b9cSGregory Neil Shapiro SM_ASSERT(0); 1261da7d7b9cSGregory Neil Shapiro } 1262da7d7b9cSGregory Neil Shapiro 1263da7d7b9cSGregory Neil Shapiro /* 1264da7d7b9cSGregory Neil Shapiro ** NEWMODMAILER -- Create a new mailer with modifications 1265da7d7b9cSGregory Neil Shapiro ** 1266da7d7b9cSGregory Neil Shapiro ** Parameters: 1267da7d7b9cSGregory Neil Shapiro ** rcpt -- current RCPT 1268da7d7b9cSGregory Neil Shapiro ** fl -- flag to set 1269da7d7b9cSGregory Neil Shapiro ** 1270da7d7b9cSGregory Neil Shapiro ** Returns: 1271da7d7b9cSGregory Neil Shapiro ** true iff successful. 1272da7d7b9cSGregory Neil Shapiro ** 1273da7d7b9cSGregory Neil Shapiro ** Note: this creates a copy of the mailer for the rcpt and 1274da7d7b9cSGregory Neil Shapiro ** modifies exactly one flag. It does not work 1275da7d7b9cSGregory Neil Shapiro ** for multiple flags! 1276da7d7b9cSGregory Neil Shapiro */ 1277da7d7b9cSGregory Neil Shapiro 1278da7d7b9cSGregory Neil Shapiro bool 1279da7d7b9cSGregory Neil Shapiro newmodmailer(rcpt, fl) 1280da7d7b9cSGregory Neil Shapiro ADDRESS *rcpt; 1281da7d7b9cSGregory Neil Shapiro int fl; 1282da7d7b9cSGregory Neil Shapiro { 1283da7d7b9cSGregory Neil Shapiro int idx; 1284da7d7b9cSGregory Neil Shapiro struct mailer *m; 1285da7d7b9cSGregory Neil Shapiro STAB *s; 1286da7d7b9cSGregory Neil Shapiro char mname[256]; 1287da7d7b9cSGregory Neil Shapiro 1288da7d7b9cSGregory Neil Shapiro SM_REQUIRE(rcpt != NULL); 1289da7d7b9cSGregory Neil Shapiro if (rcpt->q_mailer == NULL) 1290da7d7b9cSGregory Neil Shapiro return false; 1291da7d7b9cSGregory Neil Shapiro if (tTd(25, 8)) 1292da7d7b9cSGregory Neil Shapiro sm_dprintf("newmodmailer: rcpt=%s\n", rcpt->q_paddr); 1293da7d7b9cSGregory Neil Shapiro SM_REQUIRE(rcpt->q_mailer->m_name != NULL); 1294da7d7b9cSGregory Neil Shapiro SM_REQUIRE(rcpt->q_mailer->m_name[0] != '\0'); 1295da7d7b9cSGregory Neil Shapiro sm_strlcpy(mname, rcpt->q_mailer->m_name, sizeof(mname)); 1296da7d7b9cSGregory Neil Shapiro mname[0] = dynmailerp; 1297da7d7b9cSGregory Neil Shapiro if (tTd(25, 8)) 1298da7d7b9cSGregory Neil Shapiro sm_dprintf("newmodmailer: name=%s\n", mname); 1299da7d7b9cSGregory Neil Shapiro s = stab(mname, ST_MAILER, ST_ENTER); 1300da7d7b9cSGregory Neil Shapiro if (s->s_mailer != NULL) 1301da7d7b9cSGregory Neil Shapiro { 1302da7d7b9cSGregory Neil Shapiro idx = s->s_mailer->m_mno; 1303da7d7b9cSGregory Neil Shapiro if (tTd(25, 6)) 1304da7d7b9cSGregory Neil Shapiro sm_dprintf("newmodmailer: found idx=%d\n", idx); 1305da7d7b9cSGregory Neil Shapiro } 1306da7d7b9cSGregory Neil Shapiro else 1307da7d7b9cSGregory Neil Shapiro { 1308da7d7b9cSGregory Neil Shapiro idx = rcpt->q_mailer->m_mno; 1309da7d7b9cSGregory Neil Shapiro idx += MAXMAILERS; 1310da7d7b9cSGregory Neil Shapiro if (tTd(25, 6)) 1311da7d7b9cSGregory Neil Shapiro sm_dprintf("newmodmailer: idx=%d\n", idx); 1312da7d7b9cSGregory Neil Shapiro if (idx > SM_ARRAY_SIZE(Mailer)) 1313da7d7b9cSGregory Neil Shapiro return false; 1314da7d7b9cSGregory Neil Shapiro } 1315da7d7b9cSGregory Neil Shapiro 1316da7d7b9cSGregory Neil Shapiro m = Mailer[idx]; 1317da7d7b9cSGregory Neil Shapiro if (m == NULL) 1318da7d7b9cSGregory Neil Shapiro m = (struct mailer *) xalloc(sizeof(*m)); 1319da7d7b9cSGregory Neil Shapiro memset((char *) m, '\0', sizeof(*m)); 1320da7d7b9cSGregory Neil Shapiro STRUCTCOPY(*rcpt->q_mailer, *m); 1321da7d7b9cSGregory Neil Shapiro Mailer[idx] = m; 1322da7d7b9cSGregory Neil Shapiro 1323da7d7b9cSGregory Neil Shapiro /* "modify" the mailer */ 1324da7d7b9cSGregory Neil Shapiro setbitn(bitidx(fl), m->m_flags); 1325da7d7b9cSGregory Neil Shapiro rcpt->q_mailer = m; 1326da7d7b9cSGregory Neil Shapiro m->m_mno = idx; 1327da7d7b9cSGregory Neil Shapiro m->m_name = newstr(mname); 1328da7d7b9cSGregory Neil Shapiro if (tTd(25, 1)) 1329da7d7b9cSGregory Neil Shapiro sm_dprintf("newmodmailer: mailer[%d]=%s %p\n", 1330da7d7b9cSGregory Neil Shapiro idx, Mailer[idx]->m_name, Mailer[idx]); 1331da7d7b9cSGregory Neil Shapiro 1332da7d7b9cSGregory Neil Shapiro return true; 1333da7d7b9cSGregory Neil Shapiro } 1334da7d7b9cSGregory Neil Shapiro 1335da7d7b9cSGregory Neil Shapiro #endif /* _FFR_RCPTFLAGS */ 1336da7d7b9cSGregory Neil Shapiro 133740266059SGregory Neil Shapiro /* 1338c2aa98e2SPeter Wemm ** MAKEMAILER -- define a new mailer. 1339c2aa98e2SPeter Wemm ** 1340c2aa98e2SPeter Wemm ** Parameters: 1341c2aa98e2SPeter Wemm ** line -- description of mailer. This is in labeled 1342c2aa98e2SPeter Wemm ** fields. The fields are: 1343c2aa98e2SPeter Wemm ** A -- the argv for this mailer 1344c2aa98e2SPeter Wemm ** C -- the character set for MIME conversions 1345c2aa98e2SPeter Wemm ** D -- the directory to run in 1346c2aa98e2SPeter Wemm ** E -- the eol string 1347c2aa98e2SPeter Wemm ** F -- the flags associated with the mailer 1348c2aa98e2SPeter Wemm ** L -- the maximum line length 1349c2aa98e2SPeter Wemm ** M -- the maximum message size 1350c2aa98e2SPeter Wemm ** N -- the niceness at which to run 1351c2aa98e2SPeter Wemm ** P -- the path to the mailer 135240266059SGregory Neil Shapiro ** Q -- the queue group for the mailer 1353c2aa98e2SPeter Wemm ** R -- the recipient rewriting set 1354c2aa98e2SPeter Wemm ** S -- the sender rewriting set 1355c2aa98e2SPeter Wemm ** T -- the mailer type (for DSNs) 1356c2aa98e2SPeter Wemm ** U -- the uid to run as 135706f25ae9SGregory Neil Shapiro ** W -- the time to wait at the end 1358602a2b1bSGregory Neil Shapiro ** m -- maximum messages per connection 135940266059SGregory Neil Shapiro ** r -- maximum number of recipients per message 1360602a2b1bSGregory Neil Shapiro ** / -- new root directory 1361c2aa98e2SPeter Wemm ** The first word is the canonical name of the mailer. 1362c2aa98e2SPeter Wemm ** 1363c2aa98e2SPeter Wemm ** Returns: 1364c2aa98e2SPeter Wemm ** none. 1365c2aa98e2SPeter Wemm ** 1366c2aa98e2SPeter Wemm ** Side Effects: 1367c2aa98e2SPeter Wemm ** enters the mailer into the mailer table. 1368c2aa98e2SPeter Wemm */ 1369c2aa98e2SPeter Wemm 1370da7d7b9cSGregory Neil Shapiro 1371c2aa98e2SPeter Wemm void 1372c2aa98e2SPeter Wemm makemailer(line) 1373c2aa98e2SPeter Wemm char *line; 1374c2aa98e2SPeter Wemm { 1375c2aa98e2SPeter Wemm register char *p; 1376c2aa98e2SPeter Wemm register struct mailer *m; 1377c2aa98e2SPeter Wemm register STAB *s; 1378c2aa98e2SPeter Wemm int i; 1379c2aa98e2SPeter Wemm char fcode; 1380c2aa98e2SPeter Wemm auto char *endp; 138140266059SGregory Neil Shapiro static int nextmailer = 0; /* "free" index into Mailer struct */ 1382c2aa98e2SPeter Wemm 1383c2aa98e2SPeter Wemm /* allocate a mailer and set up defaults */ 1384d0cef73dSGregory Neil Shapiro m = (struct mailer *) xalloc(sizeof(*m)); 1385d0cef73dSGregory Neil Shapiro memset((char *) m, '\0', sizeof(*m)); 138640266059SGregory Neil Shapiro errno = 0; /* avoid bogus error text */ 1387c2aa98e2SPeter Wemm 1388c2aa98e2SPeter Wemm /* collect the mailer name */ 138940266059SGregory Neil Shapiro for (p = line; 1390*5b0945b5SGregory Neil Shapiro *p != '\0' && *p != ',' && !(SM_ISSPACE(*p)); 139140266059SGregory Neil Shapiro p++) 1392c2aa98e2SPeter Wemm continue; 1393c2aa98e2SPeter Wemm if (*p != '\0') 1394c2aa98e2SPeter Wemm *p++ = '\0'; 1395c2aa98e2SPeter Wemm if (line[0] == '\0') 1396193538b7SGregory Neil Shapiro { 1397c2aa98e2SPeter Wemm syserr("name required for mailer"); 1398193538b7SGregory Neil Shapiro return; 1399193538b7SGregory Neil Shapiro } 1400c2aa98e2SPeter Wemm m->m_name = newstr(line); 1401da7d7b9cSGregory Neil Shapiro #if _FFR_RCPTFLAGS 1402da7d7b9cSGregory Neil Shapiro frst[nextmailer] = line[0]; 1403da7d7b9cSGregory Neil Shapiro #endif 1404605302a5SGregory Neil Shapiro m->m_qgrp = NOQGRP; 1405e92d3f3fSGregory Neil Shapiro m->m_uid = NO_UID; 1406e92d3f3fSGregory Neil Shapiro m->m_gid = NO_GID; 1407c2aa98e2SPeter Wemm 1408c2aa98e2SPeter Wemm /* now scan through and assign info from the fields */ 1409c2aa98e2SPeter Wemm while (*p != '\0') 1410c2aa98e2SPeter Wemm { 1411c2aa98e2SPeter Wemm auto char *delimptr; 1412c2aa98e2SPeter Wemm 141340266059SGregory Neil Shapiro while (*p != '\0' && 1414*5b0945b5SGregory Neil Shapiro (*p == ',' || (SM_ISSPACE(*p)))) 1415c2aa98e2SPeter Wemm p++; 1416c2aa98e2SPeter Wemm 1417c2aa98e2SPeter Wemm /* p now points to field code */ 1418c2aa98e2SPeter Wemm fcode = *p; 1419c2aa98e2SPeter Wemm while (*p != '\0' && *p != '=' && *p != ',') 1420c2aa98e2SPeter Wemm p++; 1421c2aa98e2SPeter Wemm if (*p++ != '=') 1422c2aa98e2SPeter Wemm { 1423c2aa98e2SPeter Wemm syserr("mailer %s: `=' expected", m->m_name); 1424c2aa98e2SPeter Wemm return; 1425c2aa98e2SPeter Wemm } 1426*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p)) 1427c2aa98e2SPeter Wemm p++; 1428c2aa98e2SPeter Wemm 1429c2aa98e2SPeter Wemm /* p now points to the field body */ 1430c2aa98e2SPeter Wemm p = munchstring(p, &delimptr, ','); 1431c2aa98e2SPeter Wemm 1432c2aa98e2SPeter Wemm /* install the field into the mailer struct */ 1433c2aa98e2SPeter Wemm switch (fcode) 1434c2aa98e2SPeter Wemm { 1435c2aa98e2SPeter Wemm case 'P': /* pathname */ 143640266059SGregory Neil Shapiro if (*p != '\0') /* error is issued below */ 1437c2aa98e2SPeter Wemm m->m_mailer = newstr(p); 1438c2aa98e2SPeter Wemm break; 1439c2aa98e2SPeter Wemm 1440c2aa98e2SPeter Wemm case 'F': /* flags */ 1441c2aa98e2SPeter Wemm for (; *p != '\0'; p++) 144240266059SGregory Neil Shapiro { 1443*5b0945b5SGregory Neil Shapiro if (!(SM_ISSPACE(*p))) 144440266059SGregory Neil Shapiro { 144540266059SGregory Neil Shapiro if (*p == M_INTERNAL) 144640266059SGregory Neil Shapiro sm_syslog(LOG_WARNING, NOQID, 144740266059SGregory Neil Shapiro "WARNING: mailer=%s, flag=%c deprecated", 144840266059SGregory Neil Shapiro m->m_name, *p); 1449193538b7SGregory Neil Shapiro setbitn(bitidx(*p), m->m_flags); 145040266059SGregory Neil Shapiro } 145140266059SGregory Neil Shapiro } 1452c2aa98e2SPeter Wemm break; 1453c2aa98e2SPeter Wemm 1454c2aa98e2SPeter Wemm case 'S': /* sender rewriting ruleset */ 1455c2aa98e2SPeter Wemm case 'R': /* recipient rewriting ruleset */ 1456c2aa98e2SPeter Wemm i = strtorwset(p, &endp, ST_ENTER); 1457c2aa98e2SPeter Wemm if (i < 0) 1458c2aa98e2SPeter Wemm return; 1459c2aa98e2SPeter Wemm if (fcode == 'S') 1460c2aa98e2SPeter Wemm m->m_sh_rwset = m->m_se_rwset = i; 1461c2aa98e2SPeter Wemm else 1462c2aa98e2SPeter Wemm m->m_rh_rwset = m->m_re_rwset = i; 1463c2aa98e2SPeter Wemm 1464c2aa98e2SPeter Wemm p = endp; 1465c2aa98e2SPeter Wemm if (*p++ == '/') 1466c2aa98e2SPeter Wemm { 1467c2aa98e2SPeter Wemm i = strtorwset(p, NULL, ST_ENTER); 1468c2aa98e2SPeter Wemm if (i < 0) 1469c2aa98e2SPeter Wemm return; 1470c2aa98e2SPeter Wemm if (fcode == 'S') 1471c2aa98e2SPeter Wemm m->m_sh_rwset = i; 1472c2aa98e2SPeter Wemm else 1473c2aa98e2SPeter Wemm m->m_rh_rwset = i; 1474c2aa98e2SPeter Wemm } 1475c2aa98e2SPeter Wemm break; 1476c2aa98e2SPeter Wemm 1477c2aa98e2SPeter Wemm case 'E': /* end of line string */ 1478c2aa98e2SPeter Wemm if (*p == '\0') 1479c2aa98e2SPeter Wemm syserr("mailer %s: null end-of-line string", 1480c2aa98e2SPeter Wemm m->m_name); 1481193538b7SGregory Neil Shapiro else 1482c2aa98e2SPeter Wemm m->m_eol = newstr(p); 1483c2aa98e2SPeter Wemm break; 1484c2aa98e2SPeter Wemm 1485c2aa98e2SPeter Wemm case 'A': /* argument vector */ 148640266059SGregory Neil Shapiro if (*p != '\0') /* error is issued below */ 1487c2aa98e2SPeter Wemm m->m_argv = makeargv(p); 1488c2aa98e2SPeter Wemm break; 1489c2aa98e2SPeter Wemm 1490c2aa98e2SPeter Wemm case 'M': /* maximum message size */ 1491c2aa98e2SPeter Wemm m->m_maxsize = atol(p); 1492c2aa98e2SPeter Wemm break; 1493c2aa98e2SPeter Wemm 149406f25ae9SGregory Neil Shapiro case 'm': /* maximum messages per connection */ 149506f25ae9SGregory Neil Shapiro m->m_maxdeliveries = atoi(p); 149606f25ae9SGregory Neil Shapiro break; 149706f25ae9SGregory Neil Shapiro 149806f25ae9SGregory Neil Shapiro case 'r': /* max recipient per envelope */ 149906f25ae9SGregory Neil Shapiro m->m_maxrcpt = atoi(p); 150006f25ae9SGregory Neil Shapiro break; 150106f25ae9SGregory Neil Shapiro 1502c2aa98e2SPeter Wemm case 'L': /* maximum line length */ 1503c2aa98e2SPeter Wemm m->m_linelimit = atoi(p); 1504c2aa98e2SPeter Wemm if (m->m_linelimit < 0) 1505c2aa98e2SPeter Wemm m->m_linelimit = 0; 1506c2aa98e2SPeter Wemm break; 1507c2aa98e2SPeter Wemm 1508c2aa98e2SPeter Wemm case 'N': /* run niceness */ 1509c2aa98e2SPeter Wemm m->m_nice = atoi(p); 1510c2aa98e2SPeter Wemm break; 1511c2aa98e2SPeter Wemm 1512c2aa98e2SPeter Wemm case 'D': /* working directory */ 1513c2aa98e2SPeter Wemm if (*p == '\0') 1514c2aa98e2SPeter Wemm syserr("mailer %s: null working directory", 1515c2aa98e2SPeter Wemm m->m_name); 1516193538b7SGregory Neil Shapiro else 1517c2aa98e2SPeter Wemm m->m_execdir = newstr(p); 1518c2aa98e2SPeter Wemm break; 1519c2aa98e2SPeter Wemm 1520c2aa98e2SPeter Wemm case 'C': /* default charset */ 1521c2aa98e2SPeter Wemm if (*p == '\0') 1522c2aa98e2SPeter Wemm syserr("mailer %s: null charset", m->m_name); 1523193538b7SGregory Neil Shapiro else 1524c2aa98e2SPeter Wemm m->m_defcharset = newstr(p); 1525c2aa98e2SPeter Wemm break; 1526c2aa98e2SPeter Wemm 152740266059SGregory Neil Shapiro case 'Q': /* queue for this mailer */ 152840266059SGregory Neil Shapiro if (*p == '\0') 152940266059SGregory Neil Shapiro { 153040266059SGregory Neil Shapiro syserr("mailer %s: null queue", m->m_name); 153140266059SGregory Neil Shapiro break; 153240266059SGregory Neil Shapiro } 153340266059SGregory Neil Shapiro s = stab(p, ST_QUEUE, ST_FIND); 153440266059SGregory Neil Shapiro if (s == NULL) 153540266059SGregory Neil Shapiro syserr("mailer %s: unknown queue %s", 153640266059SGregory Neil Shapiro m->m_name, p); 153740266059SGregory Neil Shapiro else 153840266059SGregory Neil Shapiro m->m_qgrp = s->s_quegrp->qg_index; 153940266059SGregory Neil Shapiro break; 154040266059SGregory Neil Shapiro 1541c2aa98e2SPeter Wemm case 'T': /* MTA-Name/Address/Diagnostic types */ 1542c2aa98e2SPeter Wemm /* extract MTA name type; default to "dns" */ 1543c2aa98e2SPeter Wemm m->m_mtatype = newstr(p); 1544c2aa98e2SPeter Wemm p = strchr(m->m_mtatype, '/'); 1545c2aa98e2SPeter Wemm if (p != NULL) 1546c2aa98e2SPeter Wemm { 1547c2aa98e2SPeter Wemm *p++ = '\0'; 1548c2aa98e2SPeter Wemm if (*p == '\0') 1549c2aa98e2SPeter Wemm p = NULL; 1550c2aa98e2SPeter Wemm } 1551c2aa98e2SPeter Wemm if (*m->m_mtatype == '\0') 1552c2aa98e2SPeter Wemm m->m_mtatype = "dns"; 1553c2aa98e2SPeter Wemm 1554c2aa98e2SPeter Wemm /* extract address type; default to "rfc822" */ 1555c2aa98e2SPeter Wemm m->m_addrtype = p; 1556c2aa98e2SPeter Wemm if (p != NULL) 1557c2aa98e2SPeter Wemm p = strchr(p, '/'); 1558c2aa98e2SPeter Wemm if (p != NULL) 1559c2aa98e2SPeter Wemm { 1560c2aa98e2SPeter Wemm *p++ = '\0'; 1561c2aa98e2SPeter Wemm if (*p == '\0') 1562c2aa98e2SPeter Wemm p = NULL; 1563c2aa98e2SPeter Wemm } 1564c2aa98e2SPeter Wemm if (m->m_addrtype == NULL || *m->m_addrtype == '\0') 1565c2aa98e2SPeter Wemm m->m_addrtype = "rfc822"; 1566c2aa98e2SPeter Wemm 1567c2aa98e2SPeter Wemm /* extract diagnostic type; default to "smtp" */ 1568c2aa98e2SPeter Wemm m->m_diagtype = p; 1569c2aa98e2SPeter Wemm if (m->m_diagtype == NULL || *m->m_diagtype == '\0') 1570c2aa98e2SPeter Wemm m->m_diagtype = "smtp"; 1571c2aa98e2SPeter Wemm break; 1572c2aa98e2SPeter Wemm 1573c2aa98e2SPeter Wemm case 'U': /* user id */ 1574c2aa98e2SPeter Wemm if (isascii(*p) && !isdigit(*p)) 1575c2aa98e2SPeter Wemm { 1576c2aa98e2SPeter Wemm char *q = p; 1577c2aa98e2SPeter Wemm struct passwd *pw; 1578c2aa98e2SPeter Wemm 1579c2aa98e2SPeter Wemm while (*p != '\0' && isascii(*p) && 1580da7d7b9cSGregory Neil Shapiro # if _FFR_DOTTED_USERNAMES 1581da7d7b9cSGregory Neil Shapiro (isalnum(*p) || strchr(SM_PWN_CHARS, *p) != NULL)) 1582*5b0945b5SGregory Neil Shapiro # else 1583c2aa98e2SPeter Wemm (isalnum(*p) || strchr("-_", *p) != NULL)) 1584*5b0945b5SGregory Neil Shapiro # endif 1585c2aa98e2SPeter Wemm p++; 1586*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p)) 1587c2aa98e2SPeter Wemm *p++ = '\0'; 1588c2aa98e2SPeter Wemm if (*p != '\0') 1589c2aa98e2SPeter Wemm *p++ = '\0'; 1590c2aa98e2SPeter Wemm if (*q == '\0') 1591193538b7SGregory Neil Shapiro { 1592c2aa98e2SPeter Wemm syserr("mailer %s: null user name", 1593c2aa98e2SPeter Wemm m->m_name); 1594193538b7SGregory Neil Shapiro break; 1595193538b7SGregory Neil Shapiro } 1596c2aa98e2SPeter Wemm pw = sm_getpwnam(q); 1597c2aa98e2SPeter Wemm if (pw == NULL) 1598193538b7SGregory Neil Shapiro { 1599c2aa98e2SPeter Wemm syserr("readcf: mailer U= flag: unknown user %s", q); 1600193538b7SGregory Neil Shapiro break; 1601193538b7SGregory Neil Shapiro } 1602c2aa98e2SPeter Wemm else 1603c2aa98e2SPeter Wemm { 1604c2aa98e2SPeter Wemm m->m_uid = pw->pw_uid; 1605c2aa98e2SPeter Wemm m->m_gid = pw->pw_gid; 1606c2aa98e2SPeter Wemm } 1607c2aa98e2SPeter Wemm } 1608c2aa98e2SPeter Wemm else 1609c2aa98e2SPeter Wemm { 1610c2aa98e2SPeter Wemm auto char *q; 1611c2aa98e2SPeter Wemm 1612c2aa98e2SPeter Wemm m->m_uid = strtol(p, &q, 0); 1613c2aa98e2SPeter Wemm p = q; 1614*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p)) 1615c2aa98e2SPeter Wemm p++; 1616c2aa98e2SPeter Wemm if (*p != '\0') 1617c2aa98e2SPeter Wemm p++; 1618c2aa98e2SPeter Wemm } 1619*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p)) 1620c2aa98e2SPeter Wemm p++; 1621c2aa98e2SPeter Wemm if (*p == '\0') 1622c2aa98e2SPeter Wemm break; 1623c2aa98e2SPeter Wemm if (isascii(*p) && !isdigit(*p)) 1624c2aa98e2SPeter Wemm { 1625c2aa98e2SPeter Wemm char *q = p; 1626c2aa98e2SPeter Wemm struct group *gr; 1627c2aa98e2SPeter Wemm 1628da7d7b9cSGregory Neil Shapiro while (isascii(*p) && 1629da7d7b9cSGregory Neil Shapiro (isalnum(*p) || strchr(SM_PWN_CHARS, *p) != NULL)) 1630c2aa98e2SPeter Wemm p++; 1631c2aa98e2SPeter Wemm *p++ = '\0'; 1632c2aa98e2SPeter Wemm if (*q == '\0') 1633193538b7SGregory Neil Shapiro { 1634c2aa98e2SPeter Wemm syserr("mailer %s: null group name", 1635c2aa98e2SPeter Wemm m->m_name); 1636193538b7SGregory Neil Shapiro break; 1637193538b7SGregory Neil Shapiro } 1638c2aa98e2SPeter Wemm gr = getgrnam(q); 1639c2aa98e2SPeter Wemm if (gr == NULL) 1640193538b7SGregory Neil Shapiro { 1641c2aa98e2SPeter Wemm syserr("readcf: mailer U= flag: unknown group %s", q); 1642193538b7SGregory Neil Shapiro break; 1643193538b7SGregory Neil Shapiro } 1644c2aa98e2SPeter Wemm else 1645c2aa98e2SPeter Wemm m->m_gid = gr->gr_gid; 1646c2aa98e2SPeter Wemm } 1647c2aa98e2SPeter Wemm else 1648c2aa98e2SPeter Wemm { 1649c2aa98e2SPeter Wemm m->m_gid = strtol(p, NULL, 0); 1650c2aa98e2SPeter Wemm } 1651c2aa98e2SPeter Wemm break; 165206f25ae9SGregory Neil Shapiro 165306f25ae9SGregory Neil Shapiro case 'W': /* wait timeout */ 165406f25ae9SGregory Neil Shapiro m->m_wait = convtime(p, 's'); 165506f25ae9SGregory Neil Shapiro break; 165606f25ae9SGregory Neil Shapiro 165706f25ae9SGregory Neil Shapiro case '/': /* new root directory */ 165806f25ae9SGregory Neil Shapiro if (*p == '\0') 165906f25ae9SGregory Neil Shapiro syserr("mailer %s: null root directory", 166006f25ae9SGregory Neil Shapiro m->m_name); 166106f25ae9SGregory Neil Shapiro else 166206f25ae9SGregory Neil Shapiro m->m_rootdir = newstr(p); 166306f25ae9SGregory Neil Shapiro break; 166406f25ae9SGregory Neil Shapiro 166506f25ae9SGregory Neil Shapiro default: 166606f25ae9SGregory Neil Shapiro syserr("M%s: unknown mailer equate %c=", 166706f25ae9SGregory Neil Shapiro m->m_name, fcode); 166806f25ae9SGregory Neil Shapiro break; 1669c2aa98e2SPeter Wemm } 1670c2aa98e2SPeter Wemm 1671c2aa98e2SPeter Wemm p = delimptr; 1672c2aa98e2SPeter Wemm } 1673c2aa98e2SPeter Wemm 167440266059SGregory Neil Shapiro #if !HASRRESVPORT 167540266059SGregory Neil Shapiro if (bitnset(M_SECURE_PORT, m->m_flags)) 167640266059SGregory Neil Shapiro { 167740266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 167840266059SGregory Neil Shapiro "M%s: Warning: F=%c set on system that doesn't support rresvport()\n", 167940266059SGregory Neil Shapiro m->m_name, M_SECURE_PORT); 168040266059SGregory Neil Shapiro } 168140266059SGregory Neil Shapiro #endif /* !HASRRESVPORT */ 168240266059SGregory Neil Shapiro 168340266059SGregory Neil Shapiro #if !HASNICE 168440266059SGregory Neil Shapiro if (m->m_nice != 0) 168540266059SGregory Neil Shapiro { 168640266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 168740266059SGregory Neil Shapiro "M%s: Warning: N= set on system that doesn't support nice()\n", 168840266059SGregory Neil Shapiro m->m_name); 168940266059SGregory Neil Shapiro } 169040266059SGregory Neil Shapiro #endif /* !HASNICE */ 169140266059SGregory Neil Shapiro 1692c2aa98e2SPeter Wemm /* do some rationality checking */ 1693c2aa98e2SPeter Wemm if (m->m_argv == NULL) 1694c2aa98e2SPeter Wemm { 1695c2aa98e2SPeter Wemm syserr("M%s: A= argument required", m->m_name); 1696c2aa98e2SPeter Wemm return; 1697c2aa98e2SPeter Wemm } 1698c2aa98e2SPeter Wemm if (m->m_mailer == NULL) 1699c2aa98e2SPeter Wemm { 1700c2aa98e2SPeter Wemm syserr("M%s: P= argument required", m->m_name); 1701c2aa98e2SPeter Wemm return; 1702c2aa98e2SPeter Wemm } 1703c2aa98e2SPeter Wemm 170440266059SGregory Neil Shapiro if (nextmailer >= MAXMAILERS) 1705c2aa98e2SPeter Wemm { 1706c2aa98e2SPeter Wemm syserr("too many mailers defined (%d max)", MAXMAILERS); 1707c2aa98e2SPeter Wemm return; 1708c2aa98e2SPeter Wemm } 1709c2aa98e2SPeter Wemm 171006f25ae9SGregory Neil Shapiro if (m->m_maxrcpt <= 0) 171106f25ae9SGregory Neil Shapiro m->m_maxrcpt = DEFAULT_MAX_RCPT; 171206f25ae9SGregory Neil Shapiro 1713c2aa98e2SPeter Wemm /* do some heuristic cleanup for back compatibility */ 1714c2aa98e2SPeter Wemm if (bitnset(M_LIMITS, m->m_flags)) 1715c2aa98e2SPeter Wemm { 1716c2aa98e2SPeter Wemm if (m->m_linelimit == 0) 1717c2aa98e2SPeter Wemm m->m_linelimit = SMTPLINELIM; 1718c2aa98e2SPeter Wemm if (ConfigLevel < 2) 1719c2aa98e2SPeter Wemm setbitn(M_7BITS, m->m_flags); 1720c2aa98e2SPeter Wemm } 1721c2aa98e2SPeter Wemm 172206f25ae9SGregory Neil Shapiro if (strcmp(m->m_mailer, "[TCP]") == 0) 1723c2aa98e2SPeter Wemm { 172440266059SGregory Neil Shapiro syserr("M%s: P=[TCP] must be replaced by P=[IPC]", m->m_name); 1725193538b7SGregory Neil Shapiro return; 1726c2aa98e2SPeter Wemm } 1727c2aa98e2SPeter Wemm 172840266059SGregory Neil Shapiro if (strcmp(m->m_mailer, "[IPC]") == 0) 172906f25ae9SGregory Neil Shapiro { 173006f25ae9SGregory Neil Shapiro /* Use the second argument for host or path to socket */ 173106f25ae9SGregory Neil Shapiro if (m->m_argv[0] == NULL || m->m_argv[1] == NULL || 173206f25ae9SGregory Neil Shapiro m->m_argv[1][0] == '\0') 173306f25ae9SGregory Neil Shapiro { 173406f25ae9SGregory Neil Shapiro syserr("M%s: too few parameters for %s mailer", 173506f25ae9SGregory Neil Shapiro m->m_name, m->m_mailer); 1736193538b7SGregory Neil Shapiro return; 173706f25ae9SGregory Neil Shapiro } 173842e5d165SGregory Neil Shapiro if (strcmp(m->m_argv[0], "TCP") != 0 173906f25ae9SGregory Neil Shapiro #if NETUNIX 174042e5d165SGregory Neil Shapiro && strcmp(m->m_argv[0], "FILE") != 0 1741*5b0945b5SGregory Neil Shapiro #endif 174206f25ae9SGregory Neil Shapiro ) 174306f25ae9SGregory Neil Shapiro { 174440266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 174540266059SGregory Neil Shapiro "M%s: Warning: first argument in %s mailer must be %s\n", 174606f25ae9SGregory Neil Shapiro m->m_name, m->m_mailer, 174706f25ae9SGregory Neil Shapiro #if NETUNIX 174806f25ae9SGregory Neil Shapiro "TCP or FILE" 1749*5b0945b5SGregory Neil Shapiro #else 175006f25ae9SGregory Neil Shapiro "TCP" 1751*5b0945b5SGregory Neil Shapiro #endif 175206f25ae9SGregory Neil Shapiro ); 175306f25ae9SGregory Neil Shapiro } 175440266059SGregory Neil Shapiro if (m->m_mtatype == NULL) 175540266059SGregory Neil Shapiro m->m_mtatype = "dns"; 175640266059SGregory Neil Shapiro if (m->m_addrtype == NULL) 175740266059SGregory Neil Shapiro m->m_addrtype = "rfc822"; 175840266059SGregory Neil Shapiro if (m->m_diagtype == NULL) 175940266059SGregory Neil Shapiro { 176040266059SGregory Neil Shapiro if (m->m_argv[0] != NULL && 176140266059SGregory Neil Shapiro strcmp(m->m_argv[0], "FILE") == 0) 176240266059SGregory Neil Shapiro m->m_diagtype = "x-unix"; 176340266059SGregory Neil Shapiro else 176440266059SGregory Neil Shapiro m->m_diagtype = "smtp"; 176540266059SGregory Neil Shapiro } 176606f25ae9SGregory Neil Shapiro } 176706f25ae9SGregory Neil Shapiro else if (strcmp(m->m_mailer, "[FILE]") == 0) 1768c2aa98e2SPeter Wemm { 1769c2aa98e2SPeter Wemm /* Use the second argument for filename */ 1770c2aa98e2SPeter Wemm if (m->m_argv[0] == NULL || m->m_argv[1] == NULL || 1771c2aa98e2SPeter Wemm m->m_argv[2] != NULL) 1772c2aa98e2SPeter Wemm { 1773c2aa98e2SPeter Wemm syserr("M%s: too %s parameters for [FILE] mailer", 1774c2aa98e2SPeter Wemm m->m_name, 1775c2aa98e2SPeter Wemm (m->m_argv[0] == NULL || 1776c2aa98e2SPeter Wemm m->m_argv[1] == NULL) ? "few" : "many"); 1777193538b7SGregory Neil Shapiro return; 1778c2aa98e2SPeter Wemm } 1779c2aa98e2SPeter Wemm else if (strcmp(m->m_argv[0], "FILE") != 0) 1780c2aa98e2SPeter Wemm { 1781c2aa98e2SPeter Wemm syserr("M%s: first argument in [FILE] mailer must be FILE", 1782c2aa98e2SPeter Wemm m->m_name); 1783193538b7SGregory Neil Shapiro return; 1784c2aa98e2SPeter Wemm } 1785c2aa98e2SPeter Wemm } 1786c2aa98e2SPeter Wemm 1787c2aa98e2SPeter Wemm if (m->m_eol == NULL) 1788c2aa98e2SPeter Wemm { 1789c2aa98e2SPeter Wemm char **pp; 1790c2aa98e2SPeter Wemm 1791c2aa98e2SPeter Wemm /* default for SMTP is \r\n; use \n for local delivery */ 1792c2aa98e2SPeter Wemm for (pp = m->m_argv; *pp != NULL; pp++) 1793c2aa98e2SPeter Wemm { 1794c2aa98e2SPeter Wemm for (p = *pp; *p != '\0'; ) 1795c2aa98e2SPeter Wemm { 1796c2aa98e2SPeter Wemm if ((*p++ & 0377) == MACROEXPAND && *p == 'u') 1797c2aa98e2SPeter Wemm break; 1798c2aa98e2SPeter Wemm } 1799c2aa98e2SPeter Wemm if (*p != '\0') 1800c2aa98e2SPeter Wemm break; 1801c2aa98e2SPeter Wemm } 1802c2aa98e2SPeter Wemm if (*pp == NULL) 1803c2aa98e2SPeter Wemm m->m_eol = "\r\n"; 1804c2aa98e2SPeter Wemm else 1805c2aa98e2SPeter Wemm m->m_eol = "\n"; 1806c2aa98e2SPeter Wemm } 1807c2aa98e2SPeter Wemm 1808c2aa98e2SPeter Wemm /* enter the mailer into the symbol table */ 1809c2aa98e2SPeter Wemm s = stab(m->m_name, ST_MAILER, ST_ENTER); 1810c2aa98e2SPeter Wemm if (s->s_mailer != NULL) 1811c2aa98e2SPeter Wemm { 1812c2aa98e2SPeter Wemm i = s->s_mailer->m_mno; 181340266059SGregory Neil Shapiro sm_free(s->s_mailer); /* XXX */ 1814c2aa98e2SPeter Wemm } 1815c2aa98e2SPeter Wemm else 1816c2aa98e2SPeter Wemm { 181740266059SGregory Neil Shapiro i = nextmailer++; 1818c2aa98e2SPeter Wemm } 1819c2aa98e2SPeter Wemm Mailer[i] = s->s_mailer = m; 1820c2aa98e2SPeter Wemm m->m_mno = i; 1821c2aa98e2SPeter Wemm } 182240266059SGregory Neil Shapiro /* 1823c2aa98e2SPeter Wemm ** MUNCHSTRING -- translate a string into internal form. 1824c2aa98e2SPeter Wemm ** 1825c2aa98e2SPeter Wemm ** Parameters: 1826c2aa98e2SPeter Wemm ** p -- the string to munch. 1827c2aa98e2SPeter Wemm ** delimptr -- if non-NULL, set to the pointer of the 1828c2aa98e2SPeter Wemm ** field delimiter character. 1829c2aa98e2SPeter Wemm ** delim -- the delimiter for the field. 1830c2aa98e2SPeter Wemm ** 1831c2aa98e2SPeter Wemm ** Returns: 1832c2aa98e2SPeter Wemm ** the munched string. 183306f25ae9SGregory Neil Shapiro ** 183406f25ae9SGregory Neil Shapiro ** Side Effects: 183506f25ae9SGregory Neil Shapiro ** the munched string is a local static buffer. 183606f25ae9SGregory Neil Shapiro ** it must be copied before the function is called again. 1837c2aa98e2SPeter Wemm */ 1838c2aa98e2SPeter Wemm 1839c2aa98e2SPeter Wemm char * 1840c2aa98e2SPeter Wemm munchstring(p, delimptr, delim) 1841c2aa98e2SPeter Wemm register char *p; 1842c2aa98e2SPeter Wemm char **delimptr; 1843c2aa98e2SPeter Wemm int delim; 1844c2aa98e2SPeter Wemm { 1845c2aa98e2SPeter Wemm register char *q; 184640266059SGregory Neil Shapiro bool backslash = false; 184740266059SGregory Neil Shapiro bool quotemode = false; 1848c2aa98e2SPeter Wemm static char buf[MAXLINE]; 1849c2aa98e2SPeter Wemm 1850d0cef73dSGregory Neil Shapiro for (q = buf; *p != '\0' && q < &buf[sizeof(buf) - 1]; p++) 1851c2aa98e2SPeter Wemm { 1852c2aa98e2SPeter Wemm if (backslash) 1853c2aa98e2SPeter Wemm { 1854c2aa98e2SPeter Wemm /* everything is roughly literal */ 185540266059SGregory Neil Shapiro backslash = false; 1856c2aa98e2SPeter Wemm switch (*p) 1857c2aa98e2SPeter Wemm { 1858c2aa98e2SPeter Wemm case 'r': /* carriage return */ 1859c2aa98e2SPeter Wemm *q++ = '\r'; 1860c2aa98e2SPeter Wemm continue; 1861c2aa98e2SPeter Wemm 1862c2aa98e2SPeter Wemm case 'n': /* newline */ 1863c2aa98e2SPeter Wemm *q++ = '\n'; 1864c2aa98e2SPeter Wemm continue; 1865c2aa98e2SPeter Wemm 1866c2aa98e2SPeter Wemm case 'f': /* form feed */ 1867c2aa98e2SPeter Wemm *q++ = '\f'; 1868c2aa98e2SPeter Wemm continue; 1869c2aa98e2SPeter Wemm 1870c2aa98e2SPeter Wemm case 'b': /* backspace */ 1871c2aa98e2SPeter Wemm *q++ = '\b'; 1872c2aa98e2SPeter Wemm continue; 1873c2aa98e2SPeter Wemm } 1874c2aa98e2SPeter Wemm *q++ = *p; 1875c2aa98e2SPeter Wemm } 1876c2aa98e2SPeter Wemm else 1877c2aa98e2SPeter Wemm { 1878c2aa98e2SPeter Wemm if (*p == '\\') 187940266059SGregory Neil Shapiro backslash = true; 1880c2aa98e2SPeter Wemm else if (*p == '"') 1881c2aa98e2SPeter Wemm quotemode = !quotemode; 1882c2aa98e2SPeter Wemm else if (quotemode || *p != delim) 1883c2aa98e2SPeter Wemm *q++ = *p; 1884c2aa98e2SPeter Wemm else 1885c2aa98e2SPeter Wemm break; 1886c2aa98e2SPeter Wemm } 1887c2aa98e2SPeter Wemm } 1888c2aa98e2SPeter Wemm 1889c2aa98e2SPeter Wemm if (delimptr != NULL) 1890c2aa98e2SPeter Wemm *delimptr = p; 1891c2aa98e2SPeter Wemm *q++ = '\0'; 189206f25ae9SGregory Neil Shapiro return buf; 1893c2aa98e2SPeter Wemm } 189440266059SGregory Neil Shapiro /* 189540266059SGregory Neil Shapiro ** EXTRQUOTSTR -- extract a (quoted) string. 189640266059SGregory Neil Shapiro ** 189740266059SGregory Neil Shapiro ** This routine deals with quoted (") strings and escaped 189840266059SGregory Neil Shapiro ** spaces (\\ ). 189940266059SGregory Neil Shapiro ** 190040266059SGregory Neil Shapiro ** Parameters: 190140266059SGregory Neil Shapiro ** p -- source string. 190240266059SGregory Neil Shapiro ** delimptr -- if non-NULL, set to the pointer of the 190340266059SGregory Neil Shapiro ** field delimiter character. 190440266059SGregory Neil Shapiro ** delimbuf -- delimiters for the field. 190540266059SGregory Neil Shapiro ** st -- if non-NULL, store the return value (whether the 190640266059SGregory Neil Shapiro ** string was correctly quoted) here. 190740266059SGregory Neil Shapiro ** 190840266059SGregory Neil Shapiro ** Returns: 190940266059SGregory Neil Shapiro ** the extracted string. 191040266059SGregory Neil Shapiro ** 191140266059SGregory Neil Shapiro ** Side Effects: 191240266059SGregory Neil Shapiro ** the returned string is a local static buffer. 191340266059SGregory Neil Shapiro ** it must be copied before the function is called again. 191440266059SGregory Neil Shapiro */ 191540266059SGregory Neil Shapiro 191640266059SGregory Neil Shapiro static char * 191740266059SGregory Neil Shapiro extrquotstr(p, delimptr, delimbuf, st) 191840266059SGregory Neil Shapiro register char *p; 191940266059SGregory Neil Shapiro char **delimptr; 192040266059SGregory Neil Shapiro char *delimbuf; 192140266059SGregory Neil Shapiro bool *st; 192240266059SGregory Neil Shapiro { 192340266059SGregory Neil Shapiro register char *q; 192440266059SGregory Neil Shapiro bool backslash = false; 192540266059SGregory Neil Shapiro bool quotemode = false; 192640266059SGregory Neil Shapiro static char buf[MAXLINE]; 192740266059SGregory Neil Shapiro 1928d0cef73dSGregory Neil Shapiro for (q = buf; *p != '\0' && q < &buf[sizeof(buf) - 1]; p++) 192940266059SGregory Neil Shapiro { 193040266059SGregory Neil Shapiro if (backslash) 193140266059SGregory Neil Shapiro { 193240266059SGregory Neil Shapiro backslash = false; 193340266059SGregory Neil Shapiro if (*p != ' ') 193440266059SGregory Neil Shapiro *q++ = '\\'; 193540266059SGregory Neil Shapiro } 193640266059SGregory Neil Shapiro if (*p == '\\') 193740266059SGregory Neil Shapiro backslash = true; 193840266059SGregory Neil Shapiro else if (*p == '"') 193940266059SGregory Neil Shapiro quotemode = !quotemode; 194040266059SGregory Neil Shapiro else if (quotemode || 194140266059SGregory Neil Shapiro strchr(delimbuf, (int) *p) == NULL) 194240266059SGregory Neil Shapiro *q++ = *p; 194340266059SGregory Neil Shapiro else 194440266059SGregory Neil Shapiro break; 194540266059SGregory Neil Shapiro } 194640266059SGregory Neil Shapiro 194740266059SGregory Neil Shapiro if (delimptr != NULL) 194840266059SGregory Neil Shapiro *delimptr = p; 194940266059SGregory Neil Shapiro *q++ = '\0'; 195040266059SGregory Neil Shapiro if (st != NULL) 195140266059SGregory Neil Shapiro *st = !(quotemode || backslash); 195240266059SGregory Neil Shapiro return buf; 195340266059SGregory Neil Shapiro } 195440266059SGregory Neil Shapiro /* 1955c2aa98e2SPeter Wemm ** MAKEARGV -- break up a string into words 1956c2aa98e2SPeter Wemm ** 1957c2aa98e2SPeter Wemm ** Parameters: 1958c2aa98e2SPeter Wemm ** p -- the string to break up. 1959c2aa98e2SPeter Wemm ** 1960c2aa98e2SPeter Wemm ** Returns: 1961c2aa98e2SPeter Wemm ** a char **argv (dynamically allocated) 1962c2aa98e2SPeter Wemm ** 1963c2aa98e2SPeter Wemm ** Side Effects: 1964c2aa98e2SPeter Wemm ** munges p. 1965c2aa98e2SPeter Wemm */ 1966c2aa98e2SPeter Wemm 196706f25ae9SGregory Neil Shapiro static char ** 1968c2aa98e2SPeter Wemm makeargv(p) 1969c2aa98e2SPeter Wemm register char *p; 1970c2aa98e2SPeter Wemm { 1971c2aa98e2SPeter Wemm char *q; 1972c2aa98e2SPeter Wemm int i; 1973c2aa98e2SPeter Wemm char **avp; 1974c2aa98e2SPeter Wemm char *argv[MAXPV + 1]; 1975c2aa98e2SPeter Wemm 1976c2aa98e2SPeter Wemm /* take apart the words */ 1977c2aa98e2SPeter Wemm i = 0; 1978c2aa98e2SPeter Wemm while (*p != '\0' && i < MAXPV) 1979c2aa98e2SPeter Wemm { 1980c2aa98e2SPeter Wemm q = p; 1981*5b0945b5SGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p))) 1982c2aa98e2SPeter Wemm p++; 1983*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p)) 1984c2aa98e2SPeter Wemm *p++ = '\0'; 1985c2aa98e2SPeter Wemm argv[i++] = newstr(q); 1986c2aa98e2SPeter Wemm } 1987c2aa98e2SPeter Wemm argv[i++] = NULL; 1988c2aa98e2SPeter Wemm 1989c2aa98e2SPeter Wemm /* now make a copy of the argv */ 1990d0cef73dSGregory Neil Shapiro avp = (char **) xalloc(sizeof(*avp) * i); 1991d0cef73dSGregory Neil Shapiro memmove((char *) avp, (char *) argv, sizeof(*avp) * i); 1992c2aa98e2SPeter Wemm 199306f25ae9SGregory Neil Shapiro return avp; 1994c2aa98e2SPeter Wemm } 199540266059SGregory Neil Shapiro /* 1996c2aa98e2SPeter Wemm ** PRINTRULES -- print rewrite rules (for debugging) 1997c2aa98e2SPeter Wemm ** 1998c2aa98e2SPeter Wemm ** Parameters: 1999c2aa98e2SPeter Wemm ** none. 2000c2aa98e2SPeter Wemm ** 2001c2aa98e2SPeter Wemm ** Returns: 2002c2aa98e2SPeter Wemm ** none. 2003c2aa98e2SPeter Wemm ** 2004c2aa98e2SPeter Wemm ** Side Effects: 2005c2aa98e2SPeter Wemm ** prints rewrite rules. 2006c2aa98e2SPeter Wemm */ 2007c2aa98e2SPeter Wemm 2008c2aa98e2SPeter Wemm void 2009c2aa98e2SPeter Wemm printrules() 2010c2aa98e2SPeter Wemm { 2011c2aa98e2SPeter Wemm register struct rewrite *rwp; 2012c2aa98e2SPeter Wemm register int ruleset; 2013c2aa98e2SPeter Wemm 2014c2aa98e2SPeter Wemm for (ruleset = 0; ruleset < 10; ruleset++) 2015c2aa98e2SPeter Wemm { 2016c2aa98e2SPeter Wemm if (RewriteRules[ruleset] == NULL) 2017c2aa98e2SPeter Wemm continue; 2018e92d3f3fSGregory Neil Shapiro sm_dprintf("\n----Rule Set %d:", ruleset); 2019c2aa98e2SPeter Wemm 2020c2aa98e2SPeter Wemm for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next) 2021c2aa98e2SPeter Wemm { 2022e92d3f3fSGregory Neil Shapiro sm_dprintf("\nLHS:"); 2023e92d3f3fSGregory Neil Shapiro printav(sm_debug_file(), rwp->r_lhs); 2024e92d3f3fSGregory Neil Shapiro sm_dprintf("RHS:"); 2025e92d3f3fSGregory Neil Shapiro printav(sm_debug_file(), rwp->r_rhs); 2026c2aa98e2SPeter Wemm } 2027c2aa98e2SPeter Wemm } 2028c2aa98e2SPeter Wemm } 202940266059SGregory Neil Shapiro /* 2030c2aa98e2SPeter Wemm ** PRINTMAILER -- print mailer structure (for debugging) 2031c2aa98e2SPeter Wemm ** 2032c2aa98e2SPeter Wemm ** Parameters: 2033e92d3f3fSGregory Neil Shapiro ** fp -- output file 2034c2aa98e2SPeter Wemm ** m -- the mailer to print 2035c2aa98e2SPeter Wemm ** 2036c2aa98e2SPeter Wemm ** Returns: 2037c2aa98e2SPeter Wemm ** none. 2038c2aa98e2SPeter Wemm */ 2039c2aa98e2SPeter Wemm 2040c2aa98e2SPeter Wemm void 2041e92d3f3fSGregory Neil Shapiro printmailer(fp, m) 2042e92d3f3fSGregory Neil Shapiro SM_FILE_T *fp; 2043c2aa98e2SPeter Wemm register MAILER *m; 2044c2aa98e2SPeter Wemm { 2045c2aa98e2SPeter Wemm int j; 2046c2aa98e2SPeter Wemm 2047e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, 204840266059SGregory Neil Shapiro "mailer %d (%s): P=%s S=", m->m_mno, m->m_name, 204940266059SGregory Neil Shapiro m->m_mailer); 205006f25ae9SGregory Neil Shapiro if (RuleSetNames[m->m_se_rwset] == NULL) 2051e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d/", 205240266059SGregory Neil Shapiro m->m_se_rwset); 205306f25ae9SGregory Neil Shapiro else 2054e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s/", 205540266059SGregory Neil Shapiro RuleSetNames[m->m_se_rwset]); 205606f25ae9SGregory Neil Shapiro if (RuleSetNames[m->m_sh_rwset] == NULL) 2057e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d R=", 205840266059SGregory Neil Shapiro m->m_sh_rwset); 205906f25ae9SGregory Neil Shapiro else 2060e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s R=", 206140266059SGregory Neil Shapiro RuleSetNames[m->m_sh_rwset]); 206206f25ae9SGregory Neil Shapiro if (RuleSetNames[m->m_re_rwset] == NULL) 2063e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d/", 206440266059SGregory Neil Shapiro m->m_re_rwset); 206506f25ae9SGregory Neil Shapiro else 2066e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s/", 206740266059SGregory Neil Shapiro RuleSetNames[m->m_re_rwset]); 206806f25ae9SGregory Neil Shapiro if (RuleSetNames[m->m_rh_rwset] == NULL) 2069e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d ", 207040266059SGregory Neil Shapiro m->m_rh_rwset); 207106f25ae9SGregory Neil Shapiro else 2072e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s ", 207340266059SGregory Neil Shapiro RuleSetNames[m->m_rh_rwset]); 2074e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "M=%ld U=%d:%d F=", 207540266059SGregory Neil Shapiro m->m_maxsize, (int) m->m_uid, (int) m->m_gid); 2076c2aa98e2SPeter Wemm for (j = '\0'; j <= '\177'; j++) 2077c2aa98e2SPeter Wemm if (bitnset(j, m->m_flags)) 2078e92d3f3fSGregory Neil Shapiro (void) sm_io_putc(fp, SM_TIME_DEFAULT, j); 2079e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " L=%d E=", 208040266059SGregory Neil Shapiro m->m_linelimit); 2081e92d3f3fSGregory Neil Shapiro xputs(fp, m->m_eol); 2082c2aa98e2SPeter Wemm if (m->m_defcharset != NULL) 2083e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " C=%s", 208440266059SGregory Neil Shapiro m->m_defcharset); 2085e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " T=%s/%s/%s", 208640266059SGregory Neil Shapiro m->m_mtatype == NULL 208740266059SGregory Neil Shapiro ? "<undefined>" : m->m_mtatype, 208840266059SGregory Neil Shapiro m->m_addrtype == NULL 208940266059SGregory Neil Shapiro ? "<undefined>" : m->m_addrtype, 209040266059SGregory Neil Shapiro m->m_diagtype == NULL 209140266059SGregory Neil Shapiro ? "<undefined>" : m->m_diagtype); 2092e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " r=%d", m->m_maxrcpt); 2093c2aa98e2SPeter Wemm if (m->m_argv != NULL) 2094c2aa98e2SPeter Wemm { 2095c2aa98e2SPeter Wemm char **a = m->m_argv; 2096c2aa98e2SPeter Wemm 2097e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " A="); 2098c2aa98e2SPeter Wemm while (*a != NULL) 2099c2aa98e2SPeter Wemm { 2100c2aa98e2SPeter Wemm if (a != m->m_argv) 2101e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, 210240266059SGregory Neil Shapiro " "); 2103e92d3f3fSGregory Neil Shapiro xputs(fp, *a++); 2104c2aa98e2SPeter Wemm } 2105c2aa98e2SPeter Wemm } 2106e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\n"); 2107c2aa98e2SPeter Wemm } 2108da7d7b9cSGregory Neil Shapiro 2109da7d7b9cSGregory Neil Shapiro #if STARTTLS 2110da7d7b9cSGregory Neil Shapiro static struct ssl_options 2111da7d7b9cSGregory Neil Shapiro { 2112da7d7b9cSGregory Neil Shapiro const char *sslopt_name; /* name of the flag */ 2113da7d7b9cSGregory Neil Shapiro long sslopt_bits; /* bits to set/clear */ 2114da7d7b9cSGregory Neil Shapiro } SSL_Option[] = 2115da7d7b9cSGregory Neil Shapiro { 2116da7d7b9cSGregory Neil Shapiro /* Workaround for bugs are turned on by default (as well as some others) */ 2117da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_MICROSOFT_SESS_ID_BUG 2118da7d7b9cSGregory Neil Shapiro { "SSL_OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG }, 2119da7d7b9cSGregory Neil Shapiro #endif 2120da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG 2121da7d7b9cSGregory Neil Shapiro { "SSL_OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG }, 2122da7d7b9cSGregory Neil Shapiro #endif 2123da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_LEGACY_SERVER_CONNECT 2124da7d7b9cSGregory Neil Shapiro { "SSL_OP_LEGACY_SERVER_CONNECT", SSL_OP_LEGACY_SERVER_CONNECT }, 2125da7d7b9cSGregory Neil Shapiro #endif 2126da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 2127da7d7b9cSGregory Neil Shapiro { "SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG }, 2128da7d7b9cSGregory Neil Shapiro #endif 2129da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 2130da7d7b9cSGregory Neil Shapiro { "SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG }, 2131da7d7b9cSGregory Neil Shapiro #endif 2132da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 2133da7d7b9cSGregory Neil Shapiro { "SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER }, 2134da7d7b9cSGregory Neil Shapiro #endif 2135da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING 2136da7d7b9cSGregory Neil Shapiro { "SSL_OP_MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING }, 2137da7d7b9cSGregory Neil Shapiro #endif 2138da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG 2139da7d7b9cSGregory Neil Shapiro { "SSL_OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG }, 2140da7d7b9cSGregory Neil Shapiro #endif 2141da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_TLS_D5_BUG 2142da7d7b9cSGregory Neil Shapiro { "SSL_OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG }, 2143da7d7b9cSGregory Neil Shapiro #endif 2144da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_TLS_BLOCK_PADDING_BUG 2145da7d7b9cSGregory Neil Shapiro { "SSL_OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG }, 2146da7d7b9cSGregory Neil Shapiro #endif 2147da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 2148da7d7b9cSGregory Neil Shapiro { "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS }, 2149da7d7b9cSGregory Neil Shapiro #endif 2150da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_ALL 2151da7d7b9cSGregory Neil Shapiro { "SSL_OP_ALL", SSL_OP_ALL }, 2152da7d7b9cSGregory Neil Shapiro #endif 2153da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NO_QUERY_MTU 2154da7d7b9cSGregory Neil Shapiro { "SSL_OP_NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU }, 2155da7d7b9cSGregory Neil Shapiro #endif 2156da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_COOKIE_EXCHANGE 2157da7d7b9cSGregory Neil Shapiro { "SSL_OP_COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE }, 2158da7d7b9cSGregory Neil Shapiro #endif 2159da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NO_TICKET 2160da7d7b9cSGregory Neil Shapiro { "SSL_OP_NO_TICKET", SSL_OP_NO_TICKET }, 2161da7d7b9cSGregory Neil Shapiro #endif 2162da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_CISCO_ANYCONNECT 2163da7d7b9cSGregory Neil Shapiro { "SSL_OP_CISCO_ANYCONNECT", SSL_OP_CISCO_ANYCONNECT }, 2164da7d7b9cSGregory Neil Shapiro #endif 2165da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 2166da7d7b9cSGregory Neil Shapiro { "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION }, 2167da7d7b9cSGregory Neil Shapiro #endif 2168da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NO_COMPRESSION 2169da7d7b9cSGregory Neil Shapiro { "SSL_OP_NO_COMPRESSION", SSL_OP_NO_COMPRESSION }, 2170da7d7b9cSGregory Neil Shapiro #endif 2171da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 2172da7d7b9cSGregory Neil Shapiro { "SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION }, 2173da7d7b9cSGregory Neil Shapiro #endif 2174da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_SINGLE_ECDH_USE 2175da7d7b9cSGregory Neil Shapiro { "SSL_OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE }, 2176da7d7b9cSGregory Neil Shapiro #endif 2177da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_SINGLE_DH_USE 2178da7d7b9cSGregory Neil Shapiro { "SSL_OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE }, 2179da7d7b9cSGregory Neil Shapiro #endif 2180da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_EPHEMERAL_RSA 2181da7d7b9cSGregory Neil Shapiro { "SSL_OP_EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA }, 2182da7d7b9cSGregory Neil Shapiro #endif 2183da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE 2184da7d7b9cSGregory Neil Shapiro { "SSL_OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE }, 2185da7d7b9cSGregory Neil Shapiro #endif 2186da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_TLS_ROLLBACK_BUG 2187da7d7b9cSGregory Neil Shapiro { "SSL_OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG }, 2188da7d7b9cSGregory Neil Shapiro #endif 2189da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NO_SSLv2 2190da7d7b9cSGregory Neil Shapiro { "SSL_OP_NO_SSLv2", SSL_OP_NO_SSLv2 }, 2191da7d7b9cSGregory Neil Shapiro #endif 2192da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NO_SSLv3 2193da7d7b9cSGregory Neil Shapiro { "SSL_OP_NO_SSLv3", SSL_OP_NO_SSLv3 }, 2194da7d7b9cSGregory Neil Shapiro #endif 2195da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NO_TLSv1 2196da7d7b9cSGregory Neil Shapiro { "SSL_OP_NO_TLSv1", SSL_OP_NO_TLSv1 }, 2197da7d7b9cSGregory Neil Shapiro #endif 2198*5b0945b5SGregory Neil Shapiro #ifdef SSL_OP_NO_TLSv1_3 2199*5b0945b5SGregory Neil Shapiro { "SSL_OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3 }, 2200*5b0945b5SGregory Neil Shapiro #endif 2201da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NO_TLSv1_2 2202da7d7b9cSGregory Neil Shapiro { "SSL_OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2 }, 2203da7d7b9cSGregory Neil Shapiro #endif 2204da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NO_TLSv1_1 2205da7d7b9cSGregory Neil Shapiro { "SSL_OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1 }, 2206da7d7b9cSGregory Neil Shapiro #endif 2207da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_PKCS1_CHECK_1 2208da7d7b9cSGregory Neil Shapiro { "SSL_OP_PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1 }, 2209da7d7b9cSGregory Neil Shapiro #endif 2210da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_PKCS1_CHECK_2 2211da7d7b9cSGregory Neil Shapiro { "SSL_OP_PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2 }, 2212da7d7b9cSGregory Neil Shapiro #endif 2213da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NETSCAPE_CA_DN_BUG 2214da7d7b9cSGregory Neil Shapiro { "SSL_OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG }, 2215da7d7b9cSGregory Neil Shapiro #endif 2216da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 2217da7d7b9cSGregory Neil Shapiro { "SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG }, 2218da7d7b9cSGregory Neil Shapiro #endif 2219da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG 2220da7d7b9cSGregory Neil Shapiro { "SSL_OP_CRYPTOPRO_TLSEXT_BUG", SSL_OP_CRYPTOPRO_TLSEXT_BUG }, 2221da7d7b9cSGregory Neil Shapiro #endif 2222da7d7b9cSGregory Neil Shapiro #ifdef SSL_OP_TLSEXT_PADDING 2223da7d7b9cSGregory Neil Shapiro { "SSL_OP_TLSEXT_PADDING", SSL_OP_TLSEXT_PADDING }, 2224da7d7b9cSGregory Neil Shapiro #endif 2225*5b0945b5SGregory Neil Shapiro #ifdef SSL_OP_NO_RENEGOTIATION 2226*5b0945b5SGregory Neil Shapiro { "SSL_OP_NO_RENEGOTIATION", SSL_OP_NO_RENEGOTIATION }, 2227*5b0945b5SGregory Neil Shapiro #endif 2228*5b0945b5SGregory Neil Shapiro #ifdef SSL_OP_NO_ANTI_REPLAY 2229*5b0945b5SGregory Neil Shapiro { "SSL_OP_NO_ANTI_REPLAY", SSL_OP_NO_ANTI_REPLAY }, 2230*5b0945b5SGregory Neil Shapiro #endif 2231*5b0945b5SGregory Neil Shapiro #ifdef SSL_OP_ALLOW_NO_DHE_KEX 2232*5b0945b5SGregory Neil Shapiro { "SSL_OP_ALLOW_NO_DHE_KEX", SSL_OP_ALLOW_NO_DHE_KEX }, 2233*5b0945b5SGregory Neil Shapiro #endif 2234*5b0945b5SGregory Neil Shapiro #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC 2235*5b0945b5SGregory Neil Shapiro { "SSL_OP_NO_ENCRYPT_THEN_MAC", SSL_OP_NO_ENCRYPT_THEN_MAC }, 2236*5b0945b5SGregory Neil Shapiro #endif 2237*5b0945b5SGregory Neil Shapiro #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT 2238*5b0945b5SGregory Neil Shapiro { "SSL_OP_ENABLE_MIDDLEBOX_COMPAT", SSL_OP_ENABLE_MIDDLEBOX_COMPAT }, 2239*5b0945b5SGregory Neil Shapiro #endif 2240*5b0945b5SGregory Neil Shapiro #ifdef SSL_OP_PRIORITIZE_CHACHA 2241*5b0945b5SGregory Neil Shapiro { "SSL_OP_PRIORITIZE_CHACHA", SSL_OP_PRIORITIZE_CHACHA }, 2242*5b0945b5SGregory Neil Shapiro #endif 2243da7d7b9cSGregory Neil Shapiro { NULL, 0 } 2244da7d7b9cSGregory Neil Shapiro }; 2245da7d7b9cSGregory Neil Shapiro 2246da7d7b9cSGregory Neil Shapiro /* 2247da7d7b9cSGregory Neil Shapiro ** READSSLOPTIONS -- read SSL_OP_* values 2248da7d7b9cSGregory Neil Shapiro ** 2249da7d7b9cSGregory Neil Shapiro ** Parameters: 2250da7d7b9cSGregory Neil Shapiro ** opt -- name of option (can be NULL) 2251da7d7b9cSGregory Neil Shapiro ** val -- string with SSL_OP_* values or hex value 2252da7d7b9cSGregory Neil Shapiro ** delim -- end of string (e.g., '\0' or ';') 2253da7d7b9cSGregory Neil Shapiro ** pssloptions -- return value (output) 2254da7d7b9cSGregory Neil Shapiro ** 2255da7d7b9cSGregory Neil Shapiro ** Returns: 2256da7d7b9cSGregory Neil Shapiro ** 0 on success. 2257da7d7b9cSGregory Neil Shapiro */ 2258da7d7b9cSGregory Neil Shapiro 2259da7d7b9cSGregory Neil Shapiro #define SSLOPERR_NAN 1 2260da7d7b9cSGregory Neil Shapiro #define SSLOPERR_NOTFOUND 2 2261*5b0945b5SGregory Neil Shapiro 2262*5b0945b5SGregory Neil Shapiro static int readssloptions __P((char *, char *, unsigned long *, int )); 2263da7d7b9cSGregory Neil Shapiro 2264da7d7b9cSGregory Neil Shapiro static int 2265da7d7b9cSGregory Neil Shapiro readssloptions(opt, val, pssloptions, delim) 2266da7d7b9cSGregory Neil Shapiro char *opt; 2267da7d7b9cSGregory Neil Shapiro char *val; 2268da7d7b9cSGregory Neil Shapiro unsigned long *pssloptions; 2269da7d7b9cSGregory Neil Shapiro int delim; 2270da7d7b9cSGregory Neil Shapiro { 2271da7d7b9cSGregory Neil Shapiro char *p; 2272da7d7b9cSGregory Neil Shapiro int ret; 2273da7d7b9cSGregory Neil Shapiro 2274da7d7b9cSGregory Neil Shapiro ret = 0; 2275da7d7b9cSGregory Neil Shapiro for (p = val; *p != '\0' && *p != delim; ) 2276da7d7b9cSGregory Neil Shapiro { 2277da7d7b9cSGregory Neil Shapiro bool clearmode; 2278da7d7b9cSGregory Neil Shapiro char *q; 2279da7d7b9cSGregory Neil Shapiro unsigned long sslopt_val; 2280da7d7b9cSGregory Neil Shapiro struct ssl_options *sslopts; 2281da7d7b9cSGregory Neil Shapiro 2282da7d7b9cSGregory Neil Shapiro while (*p == ' ') 2283da7d7b9cSGregory Neil Shapiro p++; 2284da7d7b9cSGregory Neil Shapiro if (*p == '\0') 2285da7d7b9cSGregory Neil Shapiro break; 2286da7d7b9cSGregory Neil Shapiro clearmode = false; 2287da7d7b9cSGregory Neil Shapiro if (*p == '-' || *p == '+') 2288da7d7b9cSGregory Neil Shapiro clearmode = *p++ == '-'; 2289da7d7b9cSGregory Neil Shapiro q = p; 2290da7d7b9cSGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p)) && *p != ',') 2291da7d7b9cSGregory Neil Shapiro p++; 2292da7d7b9cSGregory Neil Shapiro if (*p != '\0') 2293da7d7b9cSGregory Neil Shapiro *p++ = '\0'; 2294da7d7b9cSGregory Neil Shapiro sslopt_val = 0; 2295da7d7b9cSGregory Neil Shapiro if (isdigit(*q)) 2296da7d7b9cSGregory Neil Shapiro { 2297da7d7b9cSGregory Neil Shapiro char *end; 2298da7d7b9cSGregory Neil Shapiro 2299da7d7b9cSGregory Neil Shapiro sslopt_val = strtoul(q, &end, 0); 2300da7d7b9cSGregory Neil Shapiro 2301da7d7b9cSGregory Neil Shapiro /* not a complete "syntax" check but good enough */ 2302da7d7b9cSGregory Neil Shapiro if (end == q) 2303da7d7b9cSGregory Neil Shapiro { 2304da7d7b9cSGregory Neil Shapiro errno = 0; 2305da7d7b9cSGregory Neil Shapiro ret = SSLOPERR_NAN; 2306da7d7b9cSGregory Neil Shapiro if (opt != NULL) 2307da7d7b9cSGregory Neil Shapiro syserr("readcf: %s option value %s not a number", 2308da7d7b9cSGregory Neil Shapiro opt, q); 2309da7d7b9cSGregory Neil Shapiro sslopt_val = 0; 2310da7d7b9cSGregory Neil Shapiro } 2311da7d7b9cSGregory Neil Shapiro } 2312da7d7b9cSGregory Neil Shapiro else 2313da7d7b9cSGregory Neil Shapiro { 2314da7d7b9cSGregory Neil Shapiro for (sslopts = SSL_Option; 2315da7d7b9cSGregory Neil Shapiro sslopts->sslopt_name != NULL; sslopts++) 2316da7d7b9cSGregory Neil Shapiro { 2317da7d7b9cSGregory Neil Shapiro if (sm_strcasecmp(q, sslopts->sslopt_name) == 0) 2318da7d7b9cSGregory Neil Shapiro { 2319da7d7b9cSGregory Neil Shapiro sslopt_val = sslopts->sslopt_bits; 2320da7d7b9cSGregory Neil Shapiro break; 2321da7d7b9cSGregory Neil Shapiro } 2322da7d7b9cSGregory Neil Shapiro } 2323da7d7b9cSGregory Neil Shapiro if (sslopts->sslopt_name == NULL) 2324da7d7b9cSGregory Neil Shapiro { 2325da7d7b9cSGregory Neil Shapiro errno = 0; 2326da7d7b9cSGregory Neil Shapiro ret = SSLOPERR_NOTFOUND; 2327da7d7b9cSGregory Neil Shapiro if (opt != NULL) 2328da7d7b9cSGregory Neil Shapiro syserr("readcf: %s option value %s unrecognized", 2329da7d7b9cSGregory Neil Shapiro opt, q); 2330da7d7b9cSGregory Neil Shapiro } 2331da7d7b9cSGregory Neil Shapiro } 2332da7d7b9cSGregory Neil Shapiro if (sslopt_val != 0) 2333da7d7b9cSGregory Neil Shapiro { 2334da7d7b9cSGregory Neil Shapiro if (clearmode) 2335da7d7b9cSGregory Neil Shapiro *pssloptions &= ~sslopt_val; 2336da7d7b9cSGregory Neil Shapiro else 2337da7d7b9cSGregory Neil Shapiro *pssloptions |= sslopt_val; 2338da7d7b9cSGregory Neil Shapiro } 2339da7d7b9cSGregory Neil Shapiro } 2340da7d7b9cSGregory Neil Shapiro return ret; 2341da7d7b9cSGregory Neil Shapiro } 2342da7d7b9cSGregory Neil Shapiro 2343da7d7b9cSGregory Neil Shapiro /* 2344da7d7b9cSGregory Neil Shapiro ** GET_TLS_SE_OPTIONS -- get TLS session options (from ruleset) 2345da7d7b9cSGregory Neil Shapiro ** 2346da7d7b9cSGregory Neil Shapiro ** Parameters: 2347da7d7b9cSGregory Neil Shapiro ** e -- envelope 2348da7d7b9cSGregory Neil Shapiro ** ssl -- TLS session context 2349*5b0945b5SGregory Neil Shapiro ** tlsi_ctx -- TLS info context 2350da7d7b9cSGregory Neil Shapiro ** srv -- server? 2351da7d7b9cSGregory Neil Shapiro ** 2352da7d7b9cSGregory Neil Shapiro ** Returns: 2353da7d7b9cSGregory Neil Shapiro ** 0 on success. 2354da7d7b9cSGregory Neil Shapiro */ 2355da7d7b9cSGregory Neil Shapiro 2356da7d7b9cSGregory Neil Shapiro int 2357*5b0945b5SGregory Neil Shapiro get_tls_se_options(e, ssl, tlsi_ctx, srv) 2358da7d7b9cSGregory Neil Shapiro ENVELOPE *e; 2359da7d7b9cSGregory Neil Shapiro SSL *ssl; 2360*5b0945b5SGregory Neil Shapiro tlsi_ctx_T *tlsi_ctx; 2361da7d7b9cSGregory Neil Shapiro bool srv; 2362da7d7b9cSGregory Neil Shapiro { 2363da7d7b9cSGregory Neil Shapiro bool saveQuickAbort, saveSuprErrs, ok; 2364da7d7b9cSGregory Neil Shapiro char *optionlist, *opt, *val; 2365da7d7b9cSGregory Neil Shapiro char *keyfile, *certfile; 2366da7d7b9cSGregory Neil Shapiro size_t len, i; 2367da7d7b9cSGregory Neil Shapiro int ret; 2368da7d7b9cSGregory Neil Shapiro 2369da7d7b9cSGregory Neil Shapiro # define who (srv ? "server" : "client") 2370da7d7b9cSGregory Neil Shapiro # define NAME_C_S macvalue(macid(srv ? "{client_name}" : "{server_name}"), e) 2371da7d7b9cSGregory Neil Shapiro # define ADDR_C_S macvalue(macid(srv ? "{client_addr}" : "{server_addr}"), e) 2372da7d7b9cSGregory Neil Shapiro # define WHICH srv ? "srv" : "clt" 2373da7d7b9cSGregory Neil Shapiro 2374da7d7b9cSGregory Neil Shapiro ret = 0; 2375da7d7b9cSGregory Neil Shapiro keyfile = certfile = opt = val = NULL; 2376da7d7b9cSGregory Neil Shapiro saveQuickAbort = QuickAbort; 2377da7d7b9cSGregory Neil Shapiro saveSuprErrs = SuprErrs; 2378da7d7b9cSGregory Neil Shapiro SuprErrs = true; 2379da7d7b9cSGregory Neil Shapiro QuickAbort = false; 2380da7d7b9cSGregory Neil Shapiro 2381da7d7b9cSGregory Neil Shapiro optionlist = NULL; 2382da7d7b9cSGregory Neil Shapiro ok = rscheck(srv ? "tls_srv_features" : "tls_clt_features", 2383da7d7b9cSGregory Neil Shapiro NAME_C_S, ADDR_C_S, e, 2384da7d7b9cSGregory Neil Shapiro RSF_RMCOMM|RSF_ADDR|RSF_STRING, 2385da7d7b9cSGregory Neil Shapiro 5, NULL, NOQID, NULL, &optionlist) == EX_OK; 2386da7d7b9cSGregory Neil Shapiro if (!ok && LogLevel > 8) 2387da7d7b9cSGregory Neil Shapiro { 2388da7d7b9cSGregory Neil Shapiro sm_syslog(LOG_NOTICE, NOQID, 2389da7d7b9cSGregory Neil Shapiro "rscheck(tls_%s_features)=failed, relay=%s [%s], errors=%d", 2390da7d7b9cSGregory Neil Shapiro WHICH, NAME_C_S, ADDR_C_S, 2391da7d7b9cSGregory Neil Shapiro Errors); 2392da7d7b9cSGregory Neil Shapiro } 2393da7d7b9cSGregory Neil Shapiro QuickAbort = saveQuickAbort; 2394da7d7b9cSGregory Neil Shapiro SuprErrs = saveSuprErrs; 2395da7d7b9cSGregory Neil Shapiro if (ok && LogLevel > 9) 2396da7d7b9cSGregory Neil Shapiro { 2397da7d7b9cSGregory Neil Shapiro sm_syslog(LOG_INFO, NOQID, 2398da7d7b9cSGregory Neil Shapiro "tls_%s_features=%s, relay=%s [%s]", 2399da7d7b9cSGregory Neil Shapiro WHICH, optionlist, NAME_C_S, ADDR_C_S); 2400da7d7b9cSGregory Neil Shapiro } 2401da7d7b9cSGregory Neil Shapiro if (!ok || optionlist == NULL || (len = strlen(optionlist)) < 2) 2402da7d7b9cSGregory Neil Shapiro { 2403da7d7b9cSGregory Neil Shapiro if (LogLevel > 9) 2404da7d7b9cSGregory Neil Shapiro sm_syslog(LOG_INFO, NOQID, 2405da7d7b9cSGregory Neil Shapiro "tls_%s_features=empty, relay=%s [%s]", 2406da7d7b9cSGregory Neil Shapiro WHICH, NAME_C_S, ADDR_C_S); 2407da7d7b9cSGregory Neil Shapiro 2408da7d7b9cSGregory Neil Shapiro return ok ? 0 : 1; 2409da7d7b9cSGregory Neil Shapiro } 2410da7d7b9cSGregory Neil Shapiro 2411da7d7b9cSGregory Neil Shapiro i = 0; 2412da7d7b9cSGregory Neil Shapiro if (optionlist[0] == '"' && optionlist[len - 1] == '"') 2413da7d7b9cSGregory Neil Shapiro { 2414da7d7b9cSGregory Neil Shapiro optionlist[0] = ' '; 2415da7d7b9cSGregory Neil Shapiro optionlist[--len] = '\0'; 2416da7d7b9cSGregory Neil Shapiro if (len <= 2) 2417da7d7b9cSGregory Neil Shapiro { 2418da7d7b9cSGregory Neil Shapiro if (LogLevel > 9 && len > 1) 2419da7d7b9cSGregory Neil Shapiro sm_syslog(LOG_INFO, NOQID, 2420da7d7b9cSGregory Neil Shapiro "tls_%s_features=too_short, relay=%s [%s]", 2421da7d7b9cSGregory Neil Shapiro WHICH, NAME_C_S, ADDR_C_S); 2422da7d7b9cSGregory Neil Shapiro 2423da7d7b9cSGregory Neil Shapiro /* this is not treated as error! */ 2424da7d7b9cSGregory Neil Shapiro return 0; 2425da7d7b9cSGregory Neil Shapiro } 2426da7d7b9cSGregory Neil Shapiro i = 1; 2427da7d7b9cSGregory Neil Shapiro } 2428da7d7b9cSGregory Neil Shapiro 2429da7d7b9cSGregory Neil Shapiro # define INVALIDSYNTAX \ 2430da7d7b9cSGregory Neil Shapiro do { \ 2431da7d7b9cSGregory Neil Shapiro if (LogLevel > 7) \ 2432da7d7b9cSGregory Neil Shapiro sm_syslog(LOG_INFO, NOQID, \ 2433da7d7b9cSGregory Neil Shapiro "tls_%s_features=invalid_syntax, opt=%s, relay=%s [%s]", \ 2434da7d7b9cSGregory Neil Shapiro WHICH, opt, NAME_C_S, ADDR_C_S); \ 2435da7d7b9cSGregory Neil Shapiro return -1; \ 2436da7d7b9cSGregory Neil Shapiro } while (0) 2437da7d7b9cSGregory Neil Shapiro 2438da7d7b9cSGregory Neil Shapiro # define CHECKLEN \ 2439da7d7b9cSGregory Neil Shapiro do { \ 2440da7d7b9cSGregory Neil Shapiro if (i >= len) \ 2441da7d7b9cSGregory Neil Shapiro INVALIDSYNTAX; \ 2442da7d7b9cSGregory Neil Shapiro } while (0) 2443da7d7b9cSGregory Neil Shapiro 2444da7d7b9cSGregory Neil Shapiro # define SKIPWS \ 2445da7d7b9cSGregory Neil Shapiro do { \ 2446da7d7b9cSGregory Neil Shapiro while (i < len && SM_ISSPACE(optionlist[i])) \ 2447da7d7b9cSGregory Neil Shapiro ++i; \ 2448da7d7b9cSGregory Neil Shapiro CHECKLEN; \ 2449da7d7b9cSGregory Neil Shapiro } while (0) 2450da7d7b9cSGregory Neil Shapiro 2451da7d7b9cSGregory Neil Shapiro /* parse and handle opt=val; */ 2452da7d7b9cSGregory Neil Shapiro do { 2453da7d7b9cSGregory Neil Shapiro char sep; 2454da7d7b9cSGregory Neil Shapiro 2455da7d7b9cSGregory Neil Shapiro SKIPWS; 2456da7d7b9cSGregory Neil Shapiro opt = optionlist + i; 2457da7d7b9cSGregory Neil Shapiro sep = '='; 2458da7d7b9cSGregory Neil Shapiro while (i < len && optionlist[i] != sep 2459da7d7b9cSGregory Neil Shapiro && optionlist[i] != '\0' && !SM_ISSPACE(optionlist[i])) 2460da7d7b9cSGregory Neil Shapiro ++i; 2461da7d7b9cSGregory Neil Shapiro CHECKLEN; 2462da7d7b9cSGregory Neil Shapiro while (i < len && SM_ISSPACE(optionlist[i])) 2463da7d7b9cSGregory Neil Shapiro optionlist[i++] = '\0'; 2464da7d7b9cSGregory Neil Shapiro CHECKLEN; 2465da7d7b9cSGregory Neil Shapiro if (optionlist[i] != sep) 2466da7d7b9cSGregory Neil Shapiro INVALIDSYNTAX; 2467da7d7b9cSGregory Neil Shapiro optionlist[i++] = '\0'; 2468da7d7b9cSGregory Neil Shapiro 2469da7d7b9cSGregory Neil Shapiro SKIPWS; 2470da7d7b9cSGregory Neil Shapiro val = optionlist + i; 2471da7d7b9cSGregory Neil Shapiro sep = ';'; 2472da7d7b9cSGregory Neil Shapiro while (i < len && optionlist[i] != sep && optionlist[i] != '\0') 2473da7d7b9cSGregory Neil Shapiro ++i; 2474da7d7b9cSGregory Neil Shapiro if (optionlist[i] != '\0') 2475da7d7b9cSGregory Neil Shapiro { 2476da7d7b9cSGregory Neil Shapiro CHECKLEN; 2477da7d7b9cSGregory Neil Shapiro optionlist[i++] = '\0'; 2478da7d7b9cSGregory Neil Shapiro } 2479da7d7b9cSGregory Neil Shapiro 2480da7d7b9cSGregory Neil Shapiro if (LogLevel > 13) 2481da7d7b9cSGregory Neil Shapiro sm_syslog(LOG_DEBUG, NOQID, 2482da7d7b9cSGregory Neil Shapiro "tls_%s_features=parsed, %s=%s, relay=%s [%s]", 2483da7d7b9cSGregory Neil Shapiro WHICH, opt, val, NAME_C_S, ADDR_C_S); 2484da7d7b9cSGregory Neil Shapiro 2485da7d7b9cSGregory Neil Shapiro if (sm_strcasecmp(opt, "options") == 0) 2486da7d7b9cSGregory Neil Shapiro { 2487da7d7b9cSGregory Neil Shapiro unsigned long ssloptions; 2488da7d7b9cSGregory Neil Shapiro 2489da7d7b9cSGregory Neil Shapiro ssloptions = 0; 2490da7d7b9cSGregory Neil Shapiro ret = readssloptions(NULL, val, &ssloptions, ';'); 2491da7d7b9cSGregory Neil Shapiro if (ret == 0) 2492da7d7b9cSGregory Neil Shapiro (void) SSL_set_options(ssl, (long) ssloptions); 2493da7d7b9cSGregory Neil Shapiro else if (LogLevel > 8) 2494da7d7b9cSGregory Neil Shapiro { 2495da7d7b9cSGregory Neil Shapiro sm_syslog(LOG_WARNING, NOQID, 2496da7d7b9cSGregory Neil Shapiro "tls_%s_features=%s, error=%s, relay=%s [%s]", 2497da7d7b9cSGregory Neil Shapiro WHICH, val, 2498da7d7b9cSGregory Neil Shapiro (ret == SSLOPERR_NAN) ? "not a number" : 2499da7d7b9cSGregory Neil Shapiro ((ret == SSLOPERR_NOTFOUND) ? "SSL_OP not found" : 2500da7d7b9cSGregory Neil Shapiro "unknown"), 2501da7d7b9cSGregory Neil Shapiro NAME_C_S, ADDR_C_S); 2502da7d7b9cSGregory Neil Shapiro } 2503da7d7b9cSGregory Neil Shapiro } 2504da7d7b9cSGregory Neil Shapiro else if (sm_strcasecmp(opt, "cipherlist") == 0) 2505da7d7b9cSGregory Neil Shapiro { 2506da7d7b9cSGregory Neil Shapiro if (SSL_set_cipher_list(ssl, val) <= 0) 2507da7d7b9cSGregory Neil Shapiro { 2508da7d7b9cSGregory Neil Shapiro ret = 1; 2509da7d7b9cSGregory Neil Shapiro if (LogLevel > 7) 2510da7d7b9cSGregory Neil Shapiro { 2511da7d7b9cSGregory Neil Shapiro sm_syslog(LOG_WARNING, NOQID, 2512da7d7b9cSGregory Neil Shapiro "STARTTLS=%s, error: SSL_set_cipher_list(%s) failed", 2513da7d7b9cSGregory Neil Shapiro who, val); 2514da7d7b9cSGregory Neil Shapiro 2515*5b0945b5SGregory Neil Shapiro tlslogerr(LOG_WARNING, 9, who); 2516da7d7b9cSGregory Neil Shapiro } 2517da7d7b9cSGregory Neil Shapiro } 2518da7d7b9cSGregory Neil Shapiro } 2519*5b0945b5SGregory Neil Shapiro else if (sm_strcasecmp(opt, "flags") == 0) 2520*5b0945b5SGregory Neil Shapiro { 2521*5b0945b5SGregory Neil Shapiro char *p; 2522*5b0945b5SGregory Neil Shapiro 2523*5b0945b5SGregory Neil Shapiro for (p = val; *p != '\0'; p++) 2524*5b0945b5SGregory Neil Shapiro { 2525*5b0945b5SGregory Neil Shapiro if (isascii(*p) && isalnum(*p)) 2526*5b0945b5SGregory Neil Shapiro setbitn(bitidx(*p), tlsi_ctx->tlsi_flags); 2527*5b0945b5SGregory Neil Shapiro } 2528*5b0945b5SGregory Neil Shapiro } 2529da7d7b9cSGregory Neil Shapiro else if (sm_strcasecmp(opt, "keyfile") == 0) 2530da7d7b9cSGregory Neil Shapiro keyfile = val; 2531da7d7b9cSGregory Neil Shapiro else if (sm_strcasecmp(opt, "certfile") == 0) 2532da7d7b9cSGregory Neil Shapiro certfile = val; 2533da7d7b9cSGregory Neil Shapiro else 2534da7d7b9cSGregory Neil Shapiro { 2535da7d7b9cSGregory Neil Shapiro ret = 1; 2536da7d7b9cSGregory Neil Shapiro if (LogLevel > 7) 2537da7d7b9cSGregory Neil Shapiro { 2538da7d7b9cSGregory Neil Shapiro sm_syslog(LOG_INFO, NOQID, 2539da7d7b9cSGregory Neil Shapiro "tls_%s_features=unknown_option, opt=%s, relay=%s [%s]", 2540da7d7b9cSGregory Neil Shapiro WHICH, opt, NAME_C_S, ADDR_C_S); 2541da7d7b9cSGregory Neil Shapiro } 2542da7d7b9cSGregory Neil Shapiro } 2543da7d7b9cSGregory Neil Shapiro 2544da7d7b9cSGregory Neil Shapiro } while (optionlist[i] != '\0' && i < len); 2545da7d7b9cSGregory Neil Shapiro 2546da7d7b9cSGregory Neil Shapiro /* need cert and key before we can use the options */ 2547da7d7b9cSGregory Neil Shapiro /* does not implement the "," hack for 2nd cert/key pair */ 2548da7d7b9cSGregory Neil Shapiro if (keyfile != NULL && certfile != NULL) 2549da7d7b9cSGregory Neil Shapiro { 2550da7d7b9cSGregory Neil Shapiro load_certkey(ssl, srv, certfile, keyfile); 2551da7d7b9cSGregory Neil Shapiro keyfile = certfile = NULL; 2552da7d7b9cSGregory Neil Shapiro } 2553da7d7b9cSGregory Neil Shapiro else if (keyfile != NULL || certfile != NULL) 2554da7d7b9cSGregory Neil Shapiro { 2555da7d7b9cSGregory Neil Shapiro ret = 1; 2556da7d7b9cSGregory Neil Shapiro if (LogLevel > 7) 2557da7d7b9cSGregory Neil Shapiro { 2558da7d7b9cSGregory Neil Shapiro sm_syslog(LOG_INFO, NOQID, 2559da7d7b9cSGregory Neil Shapiro "tls_%s_features=only_one_of_CertFile/KeyFile_specified, relay=%s [%s]", 2560da7d7b9cSGregory Neil Shapiro WHICH, NAME_C_S, ADDR_C_S); 2561da7d7b9cSGregory Neil Shapiro } 2562da7d7b9cSGregory Neil Shapiro } 2563da7d7b9cSGregory Neil Shapiro 2564da7d7b9cSGregory Neil Shapiro return ret; 2565da7d7b9cSGregory Neil Shapiro # undef who 2566da7d7b9cSGregory Neil Shapiro # undef NAME_C_S 2567da7d7b9cSGregory Neil Shapiro # undef ADDR_C_S 2568da7d7b9cSGregory Neil Shapiro # undef WHICH 2569da7d7b9cSGregory Neil Shapiro } 2570da7d7b9cSGregory Neil Shapiro #endif /* STARTTLS */ 2571da7d7b9cSGregory Neil Shapiro 257240266059SGregory Neil Shapiro /* 2573c2aa98e2SPeter Wemm ** SETOPTION -- set global processing option 2574c2aa98e2SPeter Wemm ** 2575c2aa98e2SPeter Wemm ** Parameters: 2576c2aa98e2SPeter Wemm ** opt -- option name. 2577c2aa98e2SPeter Wemm ** val -- option value (as a text string). 2578c2aa98e2SPeter Wemm ** safe -- set if this came from a configuration file. 2579c2aa98e2SPeter Wemm ** Some options (if set from the command line) will 2580c2aa98e2SPeter Wemm ** reset the user id to avoid security problems. 2581c2aa98e2SPeter Wemm ** sticky -- if set, don't let other setoptions override 2582c2aa98e2SPeter Wemm ** this value. 2583c2aa98e2SPeter Wemm ** e -- the main envelope. 2584c2aa98e2SPeter Wemm ** 2585c2aa98e2SPeter Wemm ** Returns: 2586c2aa98e2SPeter Wemm ** none. 2587c2aa98e2SPeter Wemm ** 2588c2aa98e2SPeter Wemm ** Side Effects: 2589c2aa98e2SPeter Wemm ** Sets options as implied by the arguments. 2590c2aa98e2SPeter Wemm */ 2591c2aa98e2SPeter Wemm 259206f25ae9SGregory Neil Shapiro static BITMAP256 StickyOpt; /* set if option is stuck */ 2593c2aa98e2SPeter Wemm 2594c2aa98e2SPeter Wemm #if NAMED_BIND 2595c2aa98e2SPeter Wemm 259606f25ae9SGregory Neil Shapiro static struct resolverflags 2597c2aa98e2SPeter Wemm { 2598c2aa98e2SPeter Wemm char *rf_name; /* name of the flag */ 2599c2aa98e2SPeter Wemm long rf_bits; /* bits to set/clear */ 2600c2aa98e2SPeter Wemm } ResolverFlags[] = 2601c2aa98e2SPeter Wemm { 2602c2aa98e2SPeter Wemm { "debug", RES_DEBUG }, 2603c2aa98e2SPeter Wemm { "aaonly", RES_AAONLY }, 2604c2aa98e2SPeter Wemm { "usevc", RES_USEVC }, 2605c2aa98e2SPeter Wemm { "primary", RES_PRIMARY }, 2606c2aa98e2SPeter Wemm { "igntc", RES_IGNTC }, 2607c2aa98e2SPeter Wemm { "recurse", RES_RECURSE }, 2608c2aa98e2SPeter Wemm { "defnames", RES_DEFNAMES }, 2609c2aa98e2SPeter Wemm { "stayopen", RES_STAYOPEN }, 2610c2aa98e2SPeter Wemm { "dnsrch", RES_DNSRCH }, 261140266059SGregory Neil Shapiro # ifdef RES_USE_INET6 261240266059SGregory Neil Shapiro { "use_inet6", RES_USE_INET6 }, 2613*5b0945b5SGregory Neil Shapiro # endif 2614*5b0945b5SGregory Neil Shapiro # ifdef RES_USE_EDNS0 2615*5b0945b5SGregory Neil Shapiro { "use_edns0", RES_USE_EDNS0 }, 2616*5b0945b5SGregory Neil Shapiro # endif 2617*5b0945b5SGregory Neil Shapiro # ifdef RES_USE_DNSSEC 2618*5b0945b5SGregory Neil Shapiro { "use_dnssec", RES_USE_DNSSEC }, 2619*5b0945b5SGregory Neil Shapiro # endif 2620*5b0945b5SGregory Neil Shapiro # if RES_TRUSTAD 2621*5b0945b5SGregory Neil Shapiro { "trustad", RES_TRUSTAD }, 2622*5b0945b5SGregory Neil Shapiro # endif 2623*5b0945b5SGregory Neil Shapiro { "true", 0 }, /* avoid error on old syntax */ 2624c2aa98e2SPeter Wemm { "true", 0 }, /* avoid error on old syntax */ 2625c2aa98e2SPeter Wemm { NULL, 0 } 2626c2aa98e2SPeter Wemm }; 2627c2aa98e2SPeter Wemm 262806f25ae9SGregory Neil Shapiro #endif /* NAMED_BIND */ 2629c2aa98e2SPeter Wemm 263006f25ae9SGregory Neil Shapiro #define OI_NONE 0 /* no special treatment */ 263106f25ae9SGregory Neil Shapiro #define OI_SAFE 0x0001 /* safe for random people to use */ 263206f25ae9SGregory Neil Shapiro #define OI_SUBOPT 0x0002 /* option has suboptions */ 263306f25ae9SGregory Neil Shapiro 263406f25ae9SGregory Neil Shapiro static struct optioninfo 2635c2aa98e2SPeter Wemm { 2636c2aa98e2SPeter Wemm char *o_name; /* long name of option */ 263740266059SGregory Neil Shapiro unsigned char o_code; /* short name of option */ 263840266059SGregory Neil Shapiro unsigned short o_flags; /* option flags */ 2639c2aa98e2SPeter Wemm } OptionTab[] = 2640c2aa98e2SPeter Wemm { 264106f25ae9SGregory Neil Shapiro #if defined(SUN_EXTENSIONS) && defined(REMOTE_MODE) 264206f25ae9SGregory Neil Shapiro { "RemoteMode", '>', OI_NONE }, 2643*5b0945b5SGregory Neil Shapiro #endif 264406f25ae9SGregory Neil Shapiro { "SevenBitInput", '7', OI_SAFE }, 264506f25ae9SGregory Neil Shapiro { "EightBitMode", '8', OI_SAFE }, 264606f25ae9SGregory Neil Shapiro { "AliasFile", 'A', OI_NONE }, 264706f25ae9SGregory Neil Shapiro { "AliasWait", 'a', OI_NONE }, 264806f25ae9SGregory Neil Shapiro { "BlankSub", 'B', OI_NONE }, 264906f25ae9SGregory Neil Shapiro { "MinFreeBlocks", 'b', OI_SAFE }, 265006f25ae9SGregory Neil Shapiro { "CheckpointInterval", 'C', OI_SAFE }, 265106f25ae9SGregory Neil Shapiro { "HoldExpensive", 'c', OI_NONE }, 265206f25ae9SGregory Neil Shapiro { "DeliveryMode", 'd', OI_SAFE }, 265306f25ae9SGregory Neil Shapiro { "ErrorHeader", 'E', OI_NONE }, 265406f25ae9SGregory Neil Shapiro { "ErrorMode", 'e', OI_SAFE }, 265506f25ae9SGregory Neil Shapiro { "TempFileMode", 'F', OI_NONE }, 265606f25ae9SGregory Neil Shapiro { "SaveFromLine", 'f', OI_NONE }, 265706f25ae9SGregory Neil Shapiro { "MatchGECOS", 'G', OI_NONE }, 265840266059SGregory Neil Shapiro 265940266059SGregory Neil Shapiro /* no long name, just here to avoid problems in setoption */ 266040266059SGregory Neil Shapiro { "", 'g', OI_NONE }, 266106f25ae9SGregory Neil Shapiro { "HelpFile", 'H', OI_NONE }, 266206f25ae9SGregory Neil Shapiro { "MaxHopCount", 'h', OI_NONE }, 266306f25ae9SGregory Neil Shapiro { "ResolverOptions", 'I', OI_NONE }, 266406f25ae9SGregory Neil Shapiro { "IgnoreDots", 'i', OI_SAFE }, 266506f25ae9SGregory Neil Shapiro { "ForwardPath", 'J', OI_NONE }, 266606f25ae9SGregory Neil Shapiro { "SendMimeErrors", 'j', OI_SAFE }, 266706f25ae9SGregory Neil Shapiro { "ConnectionCacheSize", 'k', OI_NONE }, 266806f25ae9SGregory Neil Shapiro { "ConnectionCacheTimeout", 'K', OI_NONE }, 266906f25ae9SGregory Neil Shapiro { "UseErrorsTo", 'l', OI_NONE }, 267006f25ae9SGregory Neil Shapiro { "LogLevel", 'L', OI_SAFE }, 267106f25ae9SGregory Neil Shapiro { "MeToo", 'm', OI_SAFE }, 267240266059SGregory Neil Shapiro 267340266059SGregory Neil Shapiro /* no long name, just here to avoid problems in setoption */ 267440266059SGregory Neil Shapiro { "", 'M', OI_NONE }, 267506f25ae9SGregory Neil Shapiro { "CheckAliases", 'n', OI_NONE }, 267606f25ae9SGregory Neil Shapiro { "OldStyleHeaders", 'o', OI_SAFE }, 267706f25ae9SGregory Neil Shapiro { "DaemonPortOptions", 'O', OI_NONE }, 267806f25ae9SGregory Neil Shapiro { "PrivacyOptions", 'p', OI_SAFE }, 267906f25ae9SGregory Neil Shapiro { "PostmasterCopy", 'P', OI_NONE }, 268006f25ae9SGregory Neil Shapiro { "QueueFactor", 'q', OI_NONE }, 268106f25ae9SGregory Neil Shapiro { "QueueDirectory", 'Q', OI_NONE }, 268206f25ae9SGregory Neil Shapiro { "DontPruneRoutes", 'R', OI_NONE }, 268306f25ae9SGregory Neil Shapiro { "Timeout", 'r', OI_SUBOPT }, 268406f25ae9SGregory Neil Shapiro { "StatusFile", 'S', OI_NONE }, 268506f25ae9SGregory Neil Shapiro { "SuperSafe", 's', OI_SAFE }, 268606f25ae9SGregory Neil Shapiro { "QueueTimeout", 'T', OI_NONE }, 268706f25ae9SGregory Neil Shapiro { "TimeZoneSpec", 't', OI_NONE }, 268806f25ae9SGregory Neil Shapiro { "UserDatabaseSpec", 'U', OI_NONE }, 268906f25ae9SGregory Neil Shapiro { "DefaultUser", 'u', OI_NONE }, 269006f25ae9SGregory Neil Shapiro { "FallbackMXhost", 'V', OI_NONE }, 269106f25ae9SGregory Neil Shapiro { "Verbose", 'v', OI_SAFE }, 269206f25ae9SGregory Neil Shapiro { "TryNullMXList", 'w', OI_NONE }, 269306f25ae9SGregory Neil Shapiro { "QueueLA", 'x', OI_NONE }, 269406f25ae9SGregory Neil Shapiro { "RefuseLA", 'X', OI_NONE }, 269506f25ae9SGregory Neil Shapiro { "RecipientFactor", 'y', OI_NONE }, 269606f25ae9SGregory Neil Shapiro { "ForkEachJob", 'Y', OI_NONE }, 269706f25ae9SGregory Neil Shapiro { "ClassFactor", 'z', OI_NONE }, 269806f25ae9SGregory Neil Shapiro { "RetryFactor", 'Z', OI_NONE }, 2699c2aa98e2SPeter Wemm #define O_QUEUESORTORD 0x81 270006f25ae9SGregory Neil Shapiro { "QueueSortOrder", O_QUEUESORTORD, OI_SAFE }, 2701c2aa98e2SPeter Wemm #define O_HOSTSFILE 0x82 270206f25ae9SGregory Neil Shapiro { "HostsFile", O_HOSTSFILE, OI_NONE }, 2703c2aa98e2SPeter Wemm #define O_MQA 0x83 270406f25ae9SGregory Neil Shapiro { "MinQueueAge", O_MQA, OI_SAFE }, 2705c2aa98e2SPeter Wemm #define O_DEFCHARSET 0x85 270606f25ae9SGregory Neil Shapiro { "DefaultCharSet", O_DEFCHARSET, OI_SAFE }, 2707c2aa98e2SPeter Wemm #define O_SSFILE 0x86 270806f25ae9SGregory Neil Shapiro { "ServiceSwitchFile", O_SSFILE, OI_NONE }, 2709c2aa98e2SPeter Wemm #define O_DIALDELAY 0x87 271006f25ae9SGregory Neil Shapiro { "DialDelay", O_DIALDELAY, OI_SAFE }, 2711c2aa98e2SPeter Wemm #define O_NORCPTACTION 0x88 271206f25ae9SGregory Neil Shapiro { "NoRecipientAction", O_NORCPTACTION, OI_SAFE }, 2713c2aa98e2SPeter Wemm #define O_SAFEFILEENV 0x89 271406f25ae9SGregory Neil Shapiro { "SafeFileEnvironment", O_SAFEFILEENV, OI_NONE }, 2715c2aa98e2SPeter Wemm #define O_MAXMSGSIZE 0x8a 271606f25ae9SGregory Neil Shapiro { "MaxMessageSize", O_MAXMSGSIZE, OI_NONE }, 2717c2aa98e2SPeter Wemm #define O_COLONOKINADDR 0x8b 271806f25ae9SGregory Neil Shapiro { "ColonOkInAddr", O_COLONOKINADDR, OI_SAFE }, 2719c2aa98e2SPeter Wemm #define O_MAXQUEUERUN 0x8c 272006f25ae9SGregory Neil Shapiro { "MaxQueueRunSize", O_MAXQUEUERUN, OI_SAFE }, 2721c2aa98e2SPeter Wemm #define O_MAXCHILDREN 0x8d 272206f25ae9SGregory Neil Shapiro { "MaxDaemonChildren", O_MAXCHILDREN, OI_NONE }, 2723c2aa98e2SPeter Wemm #define O_KEEPCNAMES 0x8e 272406f25ae9SGregory Neil Shapiro { "DontExpandCnames", O_KEEPCNAMES, OI_NONE }, 2725c2aa98e2SPeter Wemm #define O_MUSTQUOTE 0x8f 272606f25ae9SGregory Neil Shapiro { "MustQuoteChars", O_MUSTQUOTE, OI_NONE }, 2727c2aa98e2SPeter Wemm #define O_SMTPGREETING 0x90 272806f25ae9SGregory Neil Shapiro { "SmtpGreetingMessage", O_SMTPGREETING, OI_NONE }, 2729c2aa98e2SPeter Wemm #define O_UNIXFROM 0x91 273006f25ae9SGregory Neil Shapiro { "UnixFromLine", O_UNIXFROM, OI_NONE }, 2731c2aa98e2SPeter Wemm #define O_OPCHARS 0x92 273206f25ae9SGregory Neil Shapiro { "OperatorChars", O_OPCHARS, OI_NONE }, 2733c2aa98e2SPeter Wemm #define O_DONTINITGRPS 0x93 273406f25ae9SGregory Neil Shapiro { "DontInitGroups", O_DONTINITGRPS, OI_NONE }, 2735c2aa98e2SPeter Wemm #define O_SLFH 0x94 273606f25ae9SGregory Neil Shapiro { "SingleLineFromHeader", O_SLFH, OI_SAFE }, 2737c2aa98e2SPeter Wemm #define O_ABH 0x95 273806f25ae9SGregory Neil Shapiro { "AllowBogusHELO", O_ABH, OI_SAFE }, 2739c2aa98e2SPeter Wemm #define O_CONNTHROT 0x97 274006f25ae9SGregory Neil Shapiro { "ConnectionRateThrottle", O_CONNTHROT, OI_NONE }, 2741c2aa98e2SPeter Wemm #define O_UGW 0x99 274206f25ae9SGregory Neil Shapiro { "UnsafeGroupWrites", O_UGW, OI_NONE }, 2743c2aa98e2SPeter Wemm #define O_DBLBOUNCE 0x9a 274406f25ae9SGregory Neil Shapiro { "DoubleBounceAddress", O_DBLBOUNCE, OI_NONE }, 2745c2aa98e2SPeter Wemm #define O_HSDIR 0x9b 274606f25ae9SGregory Neil Shapiro { "HostStatusDirectory", O_HSDIR, OI_NONE }, 2747c2aa98e2SPeter Wemm #define O_SINGTHREAD 0x9c 274806f25ae9SGregory Neil Shapiro { "SingleThreadDelivery", O_SINGTHREAD, OI_NONE }, 2749c2aa98e2SPeter Wemm #define O_RUNASUSER 0x9d 275006f25ae9SGregory Neil Shapiro { "RunAsUser", O_RUNASUSER, OI_NONE }, 2751c2aa98e2SPeter Wemm #define O_DSN_RRT 0x9e 275206f25ae9SGregory Neil Shapiro { "RrtImpliesDsn", O_DSN_RRT, OI_NONE }, 2753c2aa98e2SPeter Wemm #define O_PIDFILE 0x9f 275406f25ae9SGregory Neil Shapiro { "PidFile", O_PIDFILE, OI_NONE }, 2755c2aa98e2SPeter Wemm #define O_DONTBLAMESENDMAIL 0xa0 275606f25ae9SGregory Neil Shapiro { "DontBlameSendmail", O_DONTBLAMESENDMAIL, OI_NONE }, 2757c2aa98e2SPeter Wemm #define O_DPI 0xa1 275806f25ae9SGregory Neil Shapiro { "DontProbeInterfaces", O_DPI, OI_NONE }, 2759c2aa98e2SPeter Wemm #define O_MAXRCPT 0xa2 276006f25ae9SGregory Neil Shapiro { "MaxRecipientsPerMessage", O_MAXRCPT, OI_SAFE }, 2761c2aa98e2SPeter Wemm #define O_DEADLETTER 0xa3 276206f25ae9SGregory Neil Shapiro { "DeadLetterDrop", O_DEADLETTER, OI_NONE }, 2763c2aa98e2SPeter Wemm #if _FFR_DONTLOCKFILESFORREAD_OPTION 2764c2aa98e2SPeter Wemm # define O_DONTLOCK 0xa4 276506f25ae9SGregory Neil Shapiro { "DontLockFilesForRead", O_DONTLOCK, OI_NONE }, 2766*5b0945b5SGregory Neil Shapiro #endif 2767c2aa98e2SPeter Wemm #define O_MAXALIASRCSN 0xa5 276806f25ae9SGregory Neil Shapiro { "MaxAliasRecursion", O_MAXALIASRCSN, OI_NONE }, 2769c2aa98e2SPeter Wemm #define O_CNCTONLYTO 0xa6 277006f25ae9SGregory Neil Shapiro { "ConnectOnlyTo", O_CNCTONLYTO, OI_NONE }, 2771065a643dSPeter Wemm #define O_TRUSTUSER 0xa7 277206f25ae9SGregory Neil Shapiro { "TrustedUser", O_TRUSTUSER, OI_NONE }, 2773065a643dSPeter Wemm #define O_MAXMIMEHDRLEN 0xa8 277406f25ae9SGregory Neil Shapiro { "MaxMimeHeaderLength", O_MAXMIMEHDRLEN, OI_NONE }, 2775065a643dSPeter Wemm #define O_CONTROLSOCKET 0xa9 277606f25ae9SGregory Neil Shapiro { "ControlSocketName", O_CONTROLSOCKET, OI_NONE }, 27772e43090eSPeter Wemm #define O_MAXHDRSLEN 0xaa 277806f25ae9SGregory Neil Shapiro { "MaxHeadersLength", O_MAXHDRSLEN, OI_NONE }, 277906f25ae9SGregory Neil Shapiro #if _FFR_MAX_FORWARD_ENTRIES 278006f25ae9SGregory Neil Shapiro # define O_MAXFORWARD 0xab 278106f25ae9SGregory Neil Shapiro { "MaxForwardEntries", O_MAXFORWARD, OI_NONE }, 2782*5b0945b5SGregory Neil Shapiro #endif 278306f25ae9SGregory Neil Shapiro #define O_PROCTITLEPREFIX 0xac 278406f25ae9SGregory Neil Shapiro { "ProcessTitlePrefix", O_PROCTITLEPREFIX, OI_NONE }, 278506f25ae9SGregory Neil Shapiro #define O_SASLINFO 0xad 278606f25ae9SGregory Neil Shapiro #if _FFR_ALLOW_SASLINFO 278706f25ae9SGregory Neil Shapiro { "DefaultAuthInfo", O_SASLINFO, OI_SAFE }, 2788*5b0945b5SGregory Neil Shapiro #else 278906f25ae9SGregory Neil Shapiro { "DefaultAuthInfo", O_SASLINFO, OI_NONE }, 2790*5b0945b5SGregory Neil Shapiro #endif 279106f25ae9SGregory Neil Shapiro #define O_SASLMECH 0xae 279206f25ae9SGregory Neil Shapiro { "AuthMechanisms", O_SASLMECH, OI_NONE }, 279306f25ae9SGregory Neil Shapiro #define O_CLIENTPORT 0xaf 279406f25ae9SGregory Neil Shapiro { "ClientPortOptions", O_CLIENTPORT, OI_NONE }, 279506f25ae9SGregory Neil Shapiro #define O_DF_BUFSIZE 0xb0 279606f25ae9SGregory Neil Shapiro { "DataFileBufferSize", O_DF_BUFSIZE, OI_NONE }, 279706f25ae9SGregory Neil Shapiro #define O_XF_BUFSIZE 0xb1 279806f25ae9SGregory Neil Shapiro { "XscriptFileBufferSize", O_XF_BUFSIZE, OI_NONE }, 279906f25ae9SGregory Neil Shapiro #define O_LDAPDEFAULTSPEC 0xb2 280006f25ae9SGregory Neil Shapiro { "LDAPDefaultSpec", O_LDAPDEFAULTSPEC, OI_NONE }, 280106f25ae9SGregory Neil Shapiro #define O_SRVCERTFILE 0xb4 280206f25ae9SGregory Neil Shapiro { "ServerCertFile", O_SRVCERTFILE, OI_NONE }, 280306f25ae9SGregory Neil Shapiro #define O_SRVKEYFILE 0xb5 2804959366dcSGregory Neil Shapiro { "ServerKeyFile", O_SRVKEYFILE, OI_NONE }, 280506f25ae9SGregory Neil Shapiro #define O_CLTCERTFILE 0xb6 280606f25ae9SGregory Neil Shapiro { "ClientCertFile", O_CLTCERTFILE, OI_NONE }, 280706f25ae9SGregory Neil Shapiro #define O_CLTKEYFILE 0xb7 2808959366dcSGregory Neil Shapiro { "ClientKeyFile", O_CLTKEYFILE, OI_NONE }, 280906f25ae9SGregory Neil Shapiro #define O_CACERTFILE 0xb8 281013bd1963SGregory Neil Shapiro { "CACertFile", O_CACERTFILE, OI_NONE }, 281106f25ae9SGregory Neil Shapiro #define O_CACERTPATH 0xb9 281213bd1963SGregory Neil Shapiro { "CACertPath", O_CACERTPATH, OI_NONE }, 281306f25ae9SGregory Neil Shapiro #define O_DHPARAMS 0xba 281406f25ae9SGregory Neil Shapiro { "DHParameters", O_DHPARAMS, OI_NONE }, 281506f25ae9SGregory Neil Shapiro #define O_INPUTMILTER 0xbb 281606f25ae9SGregory Neil Shapiro { "InputMailFilters", O_INPUTMILTER, OI_NONE }, 281706f25ae9SGregory Neil Shapiro #define O_MILTER 0xbc 281806f25ae9SGregory Neil Shapiro { "Milter", O_MILTER, OI_SUBOPT }, 281906f25ae9SGregory Neil Shapiro #define O_SASLOPTS 0xbd 282006f25ae9SGregory Neil Shapiro { "AuthOptions", O_SASLOPTS, OI_NONE }, 282106f25ae9SGregory Neil Shapiro #define O_QUEUE_FILE_MODE 0xbe 282206f25ae9SGregory Neil Shapiro { "QueueFileMode", O_QUEUE_FILE_MODE, OI_NONE }, 2823da7d7b9cSGregory Neil Shapiro #define O_DIG_ALG 0xbf 2824da7d7b9cSGregory Neil Shapiro { "CertFingerprintAlgorithm", O_DIG_ALG, OI_NONE }, 282506f25ae9SGregory Neil Shapiro #define O_CIPHERLIST 0xc0 282606f25ae9SGregory Neil Shapiro { "CipherList", O_CIPHERLIST, OI_NONE }, 282706f25ae9SGregory Neil Shapiro #define O_RANDFILE 0xc1 282806f25ae9SGregory Neil Shapiro { "RandFile", O_RANDFILE, OI_NONE }, 282940266059SGregory Neil Shapiro #define O_TLS_SRV_OPTS 0xc2 283040266059SGregory Neil Shapiro { "TLSSrvOptions", O_TLS_SRV_OPTS, OI_NONE }, 283140266059SGregory Neil Shapiro #define O_RCPTTHROT 0xc3 283240266059SGregory Neil Shapiro { "BadRcptThrottle", O_RCPTTHROT, OI_SAFE }, 283340266059SGregory Neil Shapiro #define O_DLVR_MIN 0xc4 283440266059SGregory Neil Shapiro { "DeliverByMin", O_DLVR_MIN, OI_NONE }, 283540266059SGregory Neil Shapiro #define O_MAXQUEUECHILDREN 0xc5 283640266059SGregory Neil Shapiro { "MaxQueueChildren", O_MAXQUEUECHILDREN, OI_NONE }, 283740266059SGregory Neil Shapiro #define O_MAXRUNNERSPERQUEUE 0xc6 283840266059SGregory Neil Shapiro { "MaxRunnersPerQueue", O_MAXRUNNERSPERQUEUE, OI_NONE }, 283940266059SGregory Neil Shapiro #define O_DIRECTSUBMODIFIERS 0xc7 284040266059SGregory Neil Shapiro { "DirectSubmissionModifiers", O_DIRECTSUBMODIFIERS, OI_NONE }, 284140266059SGregory Neil Shapiro #define O_NICEQUEUERUN 0xc8 284240266059SGregory Neil Shapiro { "NiceQueueRun", O_NICEQUEUERUN, OI_NONE }, 284340266059SGregory Neil Shapiro #define O_SHMKEY 0xc9 284440266059SGregory Neil Shapiro { "SharedMemoryKey", O_SHMKEY, OI_NONE }, 284540266059SGregory Neil Shapiro #define O_SASLBITS 0xca 284640266059SGregory Neil Shapiro { "AuthMaxBits", O_SASLBITS, OI_NONE }, 284740266059SGregory Neil Shapiro #define O_MBDB 0xcb 284840266059SGregory Neil Shapiro { "MailboxDatabase", O_MBDB, OI_NONE }, 284940266059SGregory Neil Shapiro #define O_MSQ 0xcc 285040266059SGregory Neil Shapiro { "UseMSP", O_MSQ, OI_NONE }, 285140266059SGregory Neil Shapiro #define O_DELAY_LA 0xcd 285240266059SGregory Neil Shapiro { "DelayLA", O_DELAY_LA, OI_NONE }, 285340266059SGregory Neil Shapiro #define O_FASTSPLIT 0xce 285440266059SGregory Neil Shapiro { "FastSplit", O_FASTSPLIT, OI_NONE }, 285540266059SGregory Neil Shapiro #define O_SOFTBOUNCE 0xcf 285640266059SGregory Neil Shapiro { "SoftBounce", O_SOFTBOUNCE, OI_NONE }, 2857605302a5SGregory Neil Shapiro #define O_SHMKEYFILE 0xd0 2858605302a5SGregory Neil Shapiro { "SharedMemoryKeyFile", O_SHMKEYFILE, OI_NONE }, 285913bd1963SGregory Neil Shapiro #define O_REJECTLOGINTERVAL 0xd1 286013bd1963SGregory Neil Shapiro { "RejectLogInterval", O_REJECTLOGINTERVAL, OI_NONE }, 286113bd1963SGregory Neil Shapiro #define O_REQUIRES_DIR_FSYNC 0xd2 286213bd1963SGregory Neil Shapiro { "RequiresDirfsync", O_REQUIRES_DIR_FSYNC, OI_NONE }, 2863e92d3f3fSGregory Neil Shapiro #define O_CONNECTION_RATE_WINDOW_SIZE 0xd3 2864e92d3f3fSGregory Neil Shapiro { "ConnectionRateWindowSize", O_CONNECTION_RATE_WINDOW_SIZE, OI_NONE }, 2865e92d3f3fSGregory Neil Shapiro #define O_CRLFILE 0xd4 2866e92d3f3fSGregory Neil Shapiro { "CRLFile", O_CRLFILE, OI_NONE }, 2867e92d3f3fSGregory Neil Shapiro #define O_FALLBACKSMARTHOST 0xd5 2868e92d3f3fSGregory Neil Shapiro { "FallbackSmartHost", O_FALLBACKSMARTHOST, OI_NONE }, 2869e92d3f3fSGregory Neil Shapiro #define O_SASLREALM 0xd6 2870e92d3f3fSGregory Neil Shapiro { "AuthRealm", O_SASLREALM, OI_NONE }, 2871e92d3f3fSGregory Neil Shapiro #define O_CRLPATH 0xd7 2872e92d3f3fSGregory Neil Shapiro { "CRLPath", O_CRLPATH, OI_NONE }, 2873e92d3f3fSGregory Neil Shapiro #define O_HELONAME 0xd8 2874e92d3f3fSGregory Neil Shapiro { "HeloName", O_HELONAME, OI_NONE }, 28754e4196cbSGregory Neil Shapiro #if _FFR_MEMSTAT 28764e4196cbSGregory Neil Shapiro # define O_REFUSELOWMEM 0xd9 28774e4196cbSGregory Neil Shapiro { "RefuseLowMem", O_REFUSELOWMEM, OI_NONE }, 28784e4196cbSGregory Neil Shapiro # define O_QUEUELOWMEM 0xda 28794e4196cbSGregory Neil Shapiro { "QueueLowMem", O_QUEUELOWMEM, OI_NONE }, 28804e4196cbSGregory Neil Shapiro # define O_MEMRESOURCE 0xdb 28814e4196cbSGregory Neil Shapiro { "MemoryResource", O_MEMRESOURCE, OI_NONE }, 28824e4196cbSGregory Neil Shapiro #endif /* _FFR_MEMSTAT */ 28834e4196cbSGregory Neil Shapiro #define O_MAXNOOPCOMMANDS 0xdc 28844e4196cbSGregory Neil Shapiro { "MaxNOOPCommands", O_MAXNOOPCOMMANDS, OI_NONE }, 28854e4196cbSGregory Neil Shapiro #if _FFR_MSG_ACCEPT 28864e4196cbSGregory Neil Shapiro # define O_MSG_ACCEPT 0xdd 28874e4196cbSGregory Neil Shapiro { "MessageAccept", O_MSG_ACCEPT, OI_NONE }, 2888*5b0945b5SGregory Neil Shapiro #endif 28894e4196cbSGregory Neil Shapiro #if _FFR_QUEUE_RUN_PARANOIA 28904e4196cbSGregory Neil Shapiro # define O_CHK_Q_RUNNERS 0xde 28914e4196cbSGregory Neil Shapiro { "CheckQueueRunners", O_CHK_Q_RUNNERS, OI_NONE }, 2892*5b0945b5SGregory Neil Shapiro #endif 2893d0cef73dSGregory Neil Shapiro #if _FFR_EIGHT_BIT_ADDR_OK 2894d0cef73dSGregory Neil Shapiro # if !ALLOW_255 2895d0cef73dSGregory Neil Shapiro # ERROR FFR_EIGHT_BIT_ADDR_OK requires _ALLOW_255 2896*5b0945b5SGregory Neil Shapiro # endif 2897d0cef73dSGregory Neil Shapiro # define O_EIGHT_BIT_ADDR_OK 0xdf 2898d0cef73dSGregory Neil Shapiro { "EightBitAddrOK", O_EIGHT_BIT_ADDR_OK, OI_NONE }, 2899d0cef73dSGregory Neil Shapiro #endif /* _FFR_EIGHT_BIT_ADDR_OK */ 2900ffb83623SGregory Neil Shapiro #if _FFR_ADDR_TYPE_MODES 2901ffb83623SGregory Neil Shapiro # define O_ADDR_TYPE_MODES 0xe0 2902ffb83623SGregory Neil Shapiro { "AddrTypeModes", O_ADDR_TYPE_MODES, OI_NONE }, 2903*5b0945b5SGregory Neil Shapiro #endif 2904e3793f76SGregory Neil Shapiro #if _FFR_BADRCPT_SHUTDOWN 2905e3793f76SGregory Neil Shapiro # define O_RCPTSHUTD 0xe1 2906e3793f76SGregory Neil Shapiro { "BadRcptShutdown", O_RCPTSHUTD, OI_SAFE }, 2907e3793f76SGregory Neil Shapiro # define O_RCPTSHUTDG 0xe2 2908e3793f76SGregory Neil Shapiro { "BadRcptShutdownGood", O_RCPTSHUTDG, OI_SAFE }, 2909e3793f76SGregory Neil Shapiro #endif /* _FFR_BADRCPT_SHUTDOWN */ 29109bd497b8SGregory Neil Shapiro #define O_SRV_SSL_OPTIONS 0xe3 29119bd497b8SGregory Neil Shapiro { "ServerSSLOptions", O_SRV_SSL_OPTIONS, OI_NONE }, 29129bd497b8SGregory Neil Shapiro #define O_CLT_SSL_OPTIONS 0xe4 29139bd497b8SGregory Neil Shapiro { "ClientSSLOptions", O_CLT_SSL_OPTIONS, OI_NONE }, 29149bd497b8SGregory Neil Shapiro #define O_MAX_QUEUE_AGE 0xe5 29159bd497b8SGregory Neil Shapiro { "MaxQueueAge", O_MAX_QUEUE_AGE, OI_NONE }, 29169bd497b8SGregory Neil Shapiro #if _FFR_RCPTTHROTDELAY 29179bd497b8SGregory Neil Shapiro # define O_RCPTTHROTDELAY 0xe6 29189bd497b8SGregory Neil Shapiro { "BadRcptThrottleDelay", O_RCPTTHROTDELAY, OI_SAFE }, 2919*5b0945b5SGregory Neil Shapiro #endif 29206f9c8e5bSGregory Neil Shapiro #if 0 && _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) 29216f9c8e5bSGregory Neil Shapiro # define O_INETQOS 0xe7 /* reserved for FFR_QOS */ 29226f9c8e5bSGregory Neil Shapiro { "InetQoS", O_INETQOS, OI_NONE }, 29236f9c8e5bSGregory Neil Shapiro #endif 2924552d4955SGregory Neil Shapiro #if STARTTLS && _FFR_FIPSMODE 2925552d4955SGregory Neil Shapiro # define O_FIPSMODE 0xe8 2926552d4955SGregory Neil Shapiro { "FIPSMode", O_FIPSMODE, OI_NONE }, 2927*5b0945b5SGregory Neil Shapiro #endif 2928552d4955SGregory Neil Shapiro #if _FFR_REJECT_NUL_BYTE 2929552d4955SGregory Neil Shapiro # define O_REJECTNUL 0xe9 2930552d4955SGregory Neil Shapiro { "RejectNUL", O_REJECTNUL, OI_SAFE }, 2931*5b0945b5SGregory Neil Shapiro #endif 2932da7d7b9cSGregory Neil Shapiro #if _FFR_BOUNCE_QUEUE 2933da7d7b9cSGregory Neil Shapiro # define O_BOUNCEQUEUE 0xea 2934da7d7b9cSGregory Neil Shapiro { "BounceQueue", O_BOUNCEQUEUE, OI_NONE }, 2935*5b0945b5SGregory Neil Shapiro #endif 2936da7d7b9cSGregory Neil Shapiro #if _FFR_ADD_BCC 2937da7d7b9cSGregory Neil Shapiro # define O_ADDBCC 0xeb 2938da7d7b9cSGregory Neil Shapiro { "AddBcc", O_ADDBCC, OI_NONE }, 2939da7d7b9cSGregory Neil Shapiro #endif 2940da7d7b9cSGregory Neil Shapiro #define O_USECOMPRESSEDIPV6ADDRESSES 0xec 2941da7d7b9cSGregory Neil Shapiro { "UseCompressedIPv6Addresses", O_USECOMPRESSEDIPV6ADDRESSES, OI_NONE }, 2942*5b0945b5SGregory Neil Shapiro #if STARTTLS 2943*5b0945b5SGregory Neil Shapiro # define O_SSLENGINE 0xed 2944*5b0945b5SGregory Neil Shapiro { "SSLEngine", O_SSLENGINE, OI_NONE }, 2945*5b0945b5SGregory Neil Shapiro # define O_SSLENGINEPATH 0xee 2946*5b0945b5SGregory Neil Shapiro { "SSLEnginePath", O_SSLENGINEPATH, OI_NONE }, 2947*5b0945b5SGregory Neil Shapiro # define O_TLSFB2CLEAR 0xef 2948*5b0945b5SGregory Neil Shapiro { "TLSFallbacktoClear", O_TLSFB2CLEAR, OI_NONE }, 2949*5b0945b5SGregory Neil Shapiro #endif 2950*5b0945b5SGregory Neil Shapiro #if DNSSEC_TEST 2951*5b0945b5SGregory Neil Shapiro # define O_NSPORTIP 0xf0 2952*5b0945b5SGregory Neil Shapiro { "NameServer", O_NSPORTIP, OI_NONE }, 2953*5b0945b5SGregory Neil Shapiro #endif 2954*5b0945b5SGregory Neil Shapiro #if DANE 2955*5b0945b5SGregory Neil Shapiro # define O_DANE 0xf1 2956*5b0945b5SGregory Neil Shapiro { "DANE", O_DANE, OI_NONE }, 2957*5b0945b5SGregory Neil Shapiro #endif 2958*5b0945b5SGregory Neil Shapiro #if DNSSEC_TEST 2959*5b0945b5SGregory Neil Shapiro # define O_NSSRCHLIST 0xf2 2960*5b0945b5SGregory Neil Shapiro { "NameSearchList", O_NSSRCHLIST, OI_NONE }, 2961*5b0945b5SGregory Neil Shapiro #endif 2962*5b0945b5SGregory Neil Shapiro #if _FFR_BLANKENV_MACV 2963*5b0945b5SGregory Neil Shapiro # define O_HACKS 0xf4 2964*5b0945b5SGregory Neil Shapiro { "Hacks", O_HACKS, OI_NONE }, 2965*5b0945b5SGregory Neil Shapiro #endif 2966*5b0945b5SGregory Neil Shapiro #if _FFR_KEEPBCC 2967*5b0945b5SGregory Neil Shapiro # define O_KEEPBCC 0xf3 2968*5b0945b5SGregory Neil Shapiro { "KeepBcc", O_KEEPBCC, OI_NONE }, 2969*5b0945b5SGregory Neil Shapiro #endif 2970*5b0945b5SGregory Neil Shapiro 2971*5b0945b5SGregory Neil Shapiro #if _FFR_CLIENTCA 2972*5b0945b5SGregory Neil Shapiro #define O_CLTCACERTFILE 0xf5 2973*5b0945b5SGregory Neil Shapiro { "ClientCACertFile", O_CLTCACERTFILE, OI_NONE }, 2974*5b0945b5SGregory Neil Shapiro #define O_CLTCACERTPATH 0xf6 2975*5b0945b5SGregory Neil Shapiro { "ClientCACertPath", O_CLTCACERTPATH, OI_NONE }, 2976*5b0945b5SGregory Neil Shapiro #endif 2977*5b0945b5SGregory Neil Shapiro #if _FFR_TLS_ALTNAMES 2978*5b0945b5SGregory Neil Shapiro # define O_CHECKALTNAMES 0xf7 2979*5b0945b5SGregory Neil Shapiro { "SetCertAltnames", O_CHECKALTNAMES, OI_NONE }, 2980*5b0945b5SGregory Neil Shapiro #endif 2981e92d3f3fSGregory Neil Shapiro 298206f25ae9SGregory Neil Shapiro { NULL, '\0', OI_NONE } 2983c2aa98e2SPeter Wemm }; 2984c2aa98e2SPeter Wemm 298540266059SGregory Neil Shapiro # define CANONIFY(val) 298640266059SGregory Neil Shapiro 298740266059SGregory Neil Shapiro # define SET_OPT_DEFAULT(opt, val) opt = val 298840266059SGregory Neil Shapiro 298940266059SGregory Neil Shapiro /* set a string option by expanding the value and assigning it */ 299040266059SGregory Neil Shapiro /* WARNING this belongs ONLY into a case statement! */ 299140266059SGregory Neil Shapiro #define SET_STRING_EXP(str) \ 2992d0cef73dSGregory Neil Shapiro expand(val, exbuf, sizeof(exbuf), e); \ 299340266059SGregory Neil Shapiro newval = sm_pstrdup_x(exbuf); \ 299440266059SGregory Neil Shapiro if (str != NULL) \ 299540266059SGregory Neil Shapiro sm_free(str); \ 299640266059SGregory Neil Shapiro CANONIFY(newval); \ 299740266059SGregory Neil Shapiro str = newval; \ 299840266059SGregory Neil Shapiro break 299940266059SGregory Neil Shapiro 300040266059SGregory Neil Shapiro #define OPTNAME o->o_name == NULL ? "<unknown>" : o->o_name 300140266059SGregory Neil Shapiro 3002c2aa98e2SPeter Wemm void 3003c2aa98e2SPeter Wemm setoption(opt, val, safe, sticky, e) 3004c2aa98e2SPeter Wemm int opt; 3005c2aa98e2SPeter Wemm char *val; 3006c2aa98e2SPeter Wemm bool safe; 3007c2aa98e2SPeter Wemm bool sticky; 3008c2aa98e2SPeter Wemm register ENVELOPE *e; 3009c2aa98e2SPeter Wemm { 3010c2aa98e2SPeter Wemm register char *p; 3011c2aa98e2SPeter Wemm register struct optioninfo *o; 3012c2aa98e2SPeter Wemm char *subopt; 3013*5b0945b5SGregory Neil Shapiro int i; 3014c2aa98e2SPeter Wemm bool can_setuid = RunAsUid == 0; 3015c2aa98e2SPeter Wemm auto char *ep; 3016c2aa98e2SPeter Wemm char buf[50]; 3017c2aa98e2SPeter Wemm extern bool Warn_Q_option; 301806f25ae9SGregory Neil Shapiro #if _FFR_ALLOW_SASLINFO 301940266059SGregory Neil Shapiro extern unsigned int SubmitMode; 3020*5b0945b5SGregory Neil Shapiro #endif 3021d0cef73dSGregory Neil Shapiro #if STARTTLS || SM_CONF_SHM 302240266059SGregory Neil Shapiro char *newval; 302340266059SGregory Neil Shapiro char exbuf[MAXLINE]; 3024*5b0945b5SGregory Neil Shapiro #endif 3025da7d7b9cSGregory Neil Shapiro #if STARTTLS 3026da7d7b9cSGregory Neil Shapiro unsigned long *pssloptions = NULL; 3027da7d7b9cSGregory Neil Shapiro #endif 3028c2aa98e2SPeter Wemm 3029c2aa98e2SPeter Wemm errno = 0; 3030c2aa98e2SPeter Wemm if (opt == ' ') 3031c2aa98e2SPeter Wemm { 3032c2aa98e2SPeter Wemm /* full word options */ 3033c2aa98e2SPeter Wemm struct optioninfo *sel; 3034c2aa98e2SPeter Wemm 3035c2aa98e2SPeter Wemm p = strchr(val, '='); 3036c2aa98e2SPeter Wemm if (p == NULL) 3037c2aa98e2SPeter Wemm p = &val[strlen(val)]; 3038c2aa98e2SPeter Wemm while (*--p == ' ') 3039c2aa98e2SPeter Wemm continue; 3040c2aa98e2SPeter Wemm while (*++p == ' ') 3041c2aa98e2SPeter Wemm *p = '\0'; 3042c2aa98e2SPeter Wemm if (p == val) 3043c2aa98e2SPeter Wemm { 3044c2aa98e2SPeter Wemm syserr("readcf: null option name"); 3045c2aa98e2SPeter Wemm return; 3046c2aa98e2SPeter Wemm } 3047c2aa98e2SPeter Wemm if (*p == '=') 3048c2aa98e2SPeter Wemm *p++ = '\0'; 3049c2aa98e2SPeter Wemm while (*p == ' ') 3050c2aa98e2SPeter Wemm p++; 3051c2aa98e2SPeter Wemm subopt = strchr(val, '.'); 3052c2aa98e2SPeter Wemm if (subopt != NULL) 3053c2aa98e2SPeter Wemm *subopt++ = '\0'; 3054c2aa98e2SPeter Wemm sel = NULL; 3055c2aa98e2SPeter Wemm for (o = OptionTab; o->o_name != NULL; o++) 3056c2aa98e2SPeter Wemm { 305740266059SGregory Neil Shapiro if (sm_strncasecmp(o->o_name, val, strlen(val)) != 0) 3058c2aa98e2SPeter Wemm continue; 3059c2aa98e2SPeter Wemm if (strlen(o->o_name) == strlen(val)) 3060c2aa98e2SPeter Wemm { 3061c2aa98e2SPeter Wemm /* completely specified -- this must be it */ 3062c2aa98e2SPeter Wemm sel = NULL; 3063c2aa98e2SPeter Wemm break; 3064c2aa98e2SPeter Wemm } 3065c2aa98e2SPeter Wemm if (sel != NULL) 3066c2aa98e2SPeter Wemm break; 3067c2aa98e2SPeter Wemm sel = o; 3068c2aa98e2SPeter Wemm } 3069c2aa98e2SPeter Wemm if (sel != NULL && o->o_name == NULL) 3070c2aa98e2SPeter Wemm o = sel; 3071c2aa98e2SPeter Wemm else if (o->o_name == NULL) 3072c2aa98e2SPeter Wemm { 3073c2aa98e2SPeter Wemm syserr("readcf: unknown option name %s", val); 3074c2aa98e2SPeter Wemm return; 3075c2aa98e2SPeter Wemm } 3076c2aa98e2SPeter Wemm else if (sel != NULL) 3077c2aa98e2SPeter Wemm { 3078c2aa98e2SPeter Wemm syserr("readcf: ambiguous option name %s (matches %s and %s)", 3079c2aa98e2SPeter Wemm val, sel->o_name, o->o_name); 3080c2aa98e2SPeter Wemm return; 3081c2aa98e2SPeter Wemm } 3082c2aa98e2SPeter Wemm if (strlen(val) != strlen(o->o_name)) 3083c2aa98e2SPeter Wemm { 3084c2aa98e2SPeter Wemm int oldVerbose = Verbose; 3085c2aa98e2SPeter Wemm 3086c2aa98e2SPeter Wemm Verbose = 1; 3087c2aa98e2SPeter Wemm message("Option %s used as abbreviation for %s", 3088c2aa98e2SPeter Wemm val, o->o_name); 3089c2aa98e2SPeter Wemm Verbose = oldVerbose; 3090c2aa98e2SPeter Wemm } 3091c2aa98e2SPeter Wemm opt = o->o_code; 3092c2aa98e2SPeter Wemm val = p; 3093c2aa98e2SPeter Wemm } 3094c2aa98e2SPeter Wemm else 3095c2aa98e2SPeter Wemm { 3096c2aa98e2SPeter Wemm for (o = OptionTab; o->o_name != NULL; o++) 3097c2aa98e2SPeter Wemm { 3098c2aa98e2SPeter Wemm if (o->o_code == opt) 3099c2aa98e2SPeter Wemm break; 3100c2aa98e2SPeter Wemm } 310140266059SGregory Neil Shapiro if (o->o_name == NULL) 310240266059SGregory Neil Shapiro { 310340266059SGregory Neil Shapiro syserr("readcf: unknown option name 0x%x", opt & 0xff); 310440266059SGregory Neil Shapiro return; 310540266059SGregory Neil Shapiro } 3106c2aa98e2SPeter Wemm subopt = NULL; 3107c2aa98e2SPeter Wemm } 3108c2aa98e2SPeter Wemm 310906f25ae9SGregory Neil Shapiro if (subopt != NULL && !bitset(OI_SUBOPT, o->o_flags)) 311006f25ae9SGregory Neil Shapiro { 311106f25ae9SGregory Neil Shapiro if (tTd(37, 1)) 311240266059SGregory Neil Shapiro sm_dprintf("setoption: %s does not support suboptions, ignoring .%s\n", 311340266059SGregory Neil Shapiro OPTNAME, subopt); 311406f25ae9SGregory Neil Shapiro subopt = NULL; 311506f25ae9SGregory Neil Shapiro } 311606f25ae9SGregory Neil Shapiro 3117c2aa98e2SPeter Wemm if (tTd(37, 1)) 3118c2aa98e2SPeter Wemm { 311940266059SGregory Neil Shapiro sm_dprintf(isascii(opt) && isprint(opt) ? 312006f25ae9SGregory Neil Shapiro "setoption %s (%c)%s%s=" : 312106f25ae9SGregory Neil Shapiro "setoption %s (0x%x)%s%s=", 312240266059SGregory Neil Shapiro OPTNAME, opt, subopt == NULL ? "" : ".", 3123c2aa98e2SPeter Wemm subopt == NULL ? "" : subopt); 3124e92d3f3fSGregory Neil Shapiro xputs(sm_debug_file(), val); 3125c2aa98e2SPeter Wemm } 3126c2aa98e2SPeter Wemm 3127c2aa98e2SPeter Wemm /* 3128c2aa98e2SPeter Wemm ** See if this option is preset for us. 3129c2aa98e2SPeter Wemm */ 3130c2aa98e2SPeter Wemm 3131c2aa98e2SPeter Wemm if (!sticky && bitnset(opt, StickyOpt)) 3132c2aa98e2SPeter Wemm { 3133c2aa98e2SPeter Wemm if (tTd(37, 1)) 313440266059SGregory Neil Shapiro sm_dprintf(" (ignored)\n"); 3135c2aa98e2SPeter Wemm return; 3136c2aa98e2SPeter Wemm } 3137c2aa98e2SPeter Wemm 3138c2aa98e2SPeter Wemm /* 3139c2aa98e2SPeter Wemm ** Check to see if this option can be specified by this user. 3140c2aa98e2SPeter Wemm */ 3141c2aa98e2SPeter Wemm 3142c2aa98e2SPeter Wemm if (!safe && RealUid == 0) 314340266059SGregory Neil Shapiro safe = true; 314406f25ae9SGregory Neil Shapiro if (!safe && !bitset(OI_SAFE, o->o_flags)) 3145c2aa98e2SPeter Wemm { 3146c2aa98e2SPeter Wemm if (opt != 'M' || (val[0] != 'r' && val[0] != 's')) 3147c2aa98e2SPeter Wemm { 314806f25ae9SGregory Neil Shapiro int dp; 314906f25ae9SGregory Neil Shapiro 3150c2aa98e2SPeter Wemm if (tTd(37, 1)) 315140266059SGregory Neil Shapiro sm_dprintf(" (unsafe)"); 315240266059SGregory Neil Shapiro dp = drop_privileges(true); 315306f25ae9SGregory Neil Shapiro setstat(dp); 3154c2aa98e2SPeter Wemm } 3155c2aa98e2SPeter Wemm } 3156c2aa98e2SPeter Wemm if (tTd(37, 1)) 315740266059SGregory Neil Shapiro sm_dprintf("\n"); 3158c2aa98e2SPeter Wemm 3159c2aa98e2SPeter Wemm switch (opt & 0xff) 3160c2aa98e2SPeter Wemm { 3161c2aa98e2SPeter Wemm case '7': /* force seven-bit input */ 3162c2aa98e2SPeter Wemm SevenBitInput = atobool(val); 3163c2aa98e2SPeter Wemm break; 3164c2aa98e2SPeter Wemm 3165c2aa98e2SPeter Wemm case '8': /* handling of 8-bit input */ 31668774250cSGregory Neil Shapiro #if MIME8TO7 3167c2aa98e2SPeter Wemm switch (*val) 3168c2aa98e2SPeter Wemm { 3169c2aa98e2SPeter Wemm case 'p': /* pass 8 bit, convert MIME */ 3170c2aa98e2SPeter Wemm MimeMode = MM_CVTMIME|MM_PASS8BIT; 3171c2aa98e2SPeter Wemm break; 3172c2aa98e2SPeter Wemm 317340266059SGregory Neil Shapiro case 'm': /* convert 8-bit, convert MIME */ 317440266059SGregory Neil Shapiro MimeMode = MM_CVTMIME|MM_MIME8BIT; 317540266059SGregory Neil Shapiro break; 317640266059SGregory Neil Shapiro 3177c2aa98e2SPeter Wemm case 's': /* strict adherence */ 3178c2aa98e2SPeter Wemm MimeMode = MM_CVTMIME; 3179c2aa98e2SPeter Wemm break; 3180c2aa98e2SPeter Wemm 3181c2aa98e2SPeter Wemm # if 0 3182c2aa98e2SPeter Wemm case 'r': /* reject 8-bit, don't convert MIME */ 3183c2aa98e2SPeter Wemm MimeMode = 0; 3184c2aa98e2SPeter Wemm break; 3185c2aa98e2SPeter Wemm 3186c2aa98e2SPeter Wemm case 'j': /* "just send 8" */ 3187c2aa98e2SPeter Wemm MimeMode = MM_PASS8BIT; 3188c2aa98e2SPeter Wemm break; 3189c2aa98e2SPeter Wemm 3190c2aa98e2SPeter Wemm case 'a': /* encode 8 bit if available */ 3191c2aa98e2SPeter Wemm MimeMode = MM_MIME8BIT|MM_PASS8BIT|MM_CVTMIME; 3192c2aa98e2SPeter Wemm break; 3193c2aa98e2SPeter Wemm 3194c2aa98e2SPeter Wemm case 'c': /* convert 8 bit to MIME, never 7 bit */ 3195c2aa98e2SPeter Wemm MimeMode = MM_MIME8BIT; 3196c2aa98e2SPeter Wemm break; 319706f25ae9SGregory Neil Shapiro # endif /* 0 */ 3198c2aa98e2SPeter Wemm 3199c2aa98e2SPeter Wemm default: 3200c2aa98e2SPeter Wemm syserr("Unknown 8-bit mode %c", *val); 320140266059SGregory Neil Shapiro finis(false, true, EX_USAGE); 3202c2aa98e2SPeter Wemm } 32038774250cSGregory Neil Shapiro #else /* MIME8TO7 */ 320440266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 320540266059SGregory Neil Shapiro "Warning: Option: %s requires MIME8TO7 support\n", 320640266059SGregory Neil Shapiro OPTNAME); 320706f25ae9SGregory Neil Shapiro #endif /* MIME8TO7 */ 32088774250cSGregory Neil Shapiro break; 3209c2aa98e2SPeter Wemm 3210c2aa98e2SPeter Wemm case 'A': /* set default alias file */ 3211c2aa98e2SPeter Wemm if (val[0] == '\0') 321240266059SGregory Neil Shapiro { 321340266059SGregory Neil Shapiro char *al; 321440266059SGregory Neil Shapiro 321540266059SGregory Neil Shapiro SET_OPT_DEFAULT(al, "aliases"); 321640266059SGregory Neil Shapiro setalias(al); 321740266059SGregory Neil Shapiro } 3218c2aa98e2SPeter Wemm else 3219c2aa98e2SPeter Wemm setalias(val); 3220c2aa98e2SPeter Wemm break; 3221c2aa98e2SPeter Wemm 3222c2aa98e2SPeter Wemm case 'a': /* look N minutes for "@:@" in alias file */ 3223c2aa98e2SPeter Wemm if (val[0] == '\0') 322440266059SGregory Neil Shapiro SafeAlias = 5 MINUTES; 3225c2aa98e2SPeter Wemm else 3226c2aa98e2SPeter Wemm SafeAlias = convtime(val, 'm'); 3227c2aa98e2SPeter Wemm break; 3228c2aa98e2SPeter Wemm 3229c2aa98e2SPeter Wemm case 'B': /* substitution for blank character */ 3230c2aa98e2SPeter Wemm SpaceSub = val[0]; 3231c2aa98e2SPeter Wemm if (SpaceSub == '\0') 3232c2aa98e2SPeter Wemm SpaceSub = ' '; 3233c2aa98e2SPeter Wemm break; 3234c2aa98e2SPeter Wemm 3235c2aa98e2SPeter Wemm case 'b': /* min blocks free on queue fs/max msg size */ 3236c2aa98e2SPeter Wemm p = strchr(val, '/'); 3237c2aa98e2SPeter Wemm if (p != NULL) 3238c2aa98e2SPeter Wemm { 3239c2aa98e2SPeter Wemm *p++ = '\0'; 3240c2aa98e2SPeter Wemm MaxMessageSize = atol(p); 3241c2aa98e2SPeter Wemm } 3242c2aa98e2SPeter Wemm MinBlocksFree = atol(val); 3243c2aa98e2SPeter Wemm break; 3244c2aa98e2SPeter Wemm 3245c2aa98e2SPeter Wemm case 'c': /* don't connect to "expensive" mailers */ 3246c2aa98e2SPeter Wemm NoConnect = atobool(val); 3247c2aa98e2SPeter Wemm break; 3248c2aa98e2SPeter Wemm 3249c2aa98e2SPeter Wemm case 'C': /* checkpoint every N addresses */ 3250e92d3f3fSGregory Neil Shapiro if (safe || CheckpointInterval > atoi(val)) 3251c2aa98e2SPeter Wemm CheckpointInterval = atoi(val); 3252c2aa98e2SPeter Wemm break; 3253c2aa98e2SPeter Wemm 3254c2aa98e2SPeter Wemm case 'd': /* delivery mode */ 3255c2aa98e2SPeter Wemm switch (*val) 3256c2aa98e2SPeter Wemm { 3257c2aa98e2SPeter Wemm case '\0': 325806f25ae9SGregory Neil Shapiro set_delivery_mode(SM_DELIVER, e); 3259c2aa98e2SPeter Wemm break; 3260c2aa98e2SPeter Wemm 3261c2aa98e2SPeter Wemm case SM_QUEUE: /* queue only */ 3262c2aa98e2SPeter Wemm case SM_DEFER: /* queue only and defer map lookups */ 3263c2aa98e2SPeter Wemm case SM_DELIVER: /* do everything */ 3264c2aa98e2SPeter Wemm case SM_FORK: /* fork after verification */ 32654e4196cbSGregory Neil Shapiro #if _FFR_DM_ONE 32664e4196cbSGregory Neil Shapiro /* deliver first TA in background, then queue */ 32674e4196cbSGregory Neil Shapiro case SM_DM_ONE: 3268*5b0945b5SGregory Neil Shapiro #endif 326906f25ae9SGregory Neil Shapiro set_delivery_mode(*val, e); 3270c2aa98e2SPeter Wemm break; 3271c2aa98e2SPeter Wemm 3272da7d7b9cSGregory Neil Shapiro #if _FFR_PROXY 3273da7d7b9cSGregory Neil Shapiro case SM_PROXY_REQ: 3274da7d7b9cSGregory Neil Shapiro set_delivery_mode(*val, e); 3275da7d7b9cSGregory Neil Shapiro break; 3276da7d7b9cSGregory Neil Shapiro #endif /* _FFR_PROXY */ 32776f9c8e5bSGregory Neil Shapiro 3278c2aa98e2SPeter Wemm default: 3279c2aa98e2SPeter Wemm syserr("Unknown delivery mode %c", *val); 328040266059SGregory Neil Shapiro finis(false, true, EX_USAGE); 3281c2aa98e2SPeter Wemm } 3282c2aa98e2SPeter Wemm break; 3283c2aa98e2SPeter Wemm 3284c2aa98e2SPeter Wemm case 'E': /* error message header/header file */ 3285c2aa98e2SPeter Wemm if (*val != '\0') 3286c2aa98e2SPeter Wemm ErrMsgFile = newstr(val); 3287c2aa98e2SPeter Wemm break; 3288c2aa98e2SPeter Wemm 3289c2aa98e2SPeter Wemm case 'e': /* set error processing mode */ 3290c2aa98e2SPeter Wemm switch (*val) 3291c2aa98e2SPeter Wemm { 3292c2aa98e2SPeter Wemm case EM_QUIET: /* be silent about it */ 3293c2aa98e2SPeter Wemm case EM_MAIL: /* mail back */ 3294c2aa98e2SPeter Wemm case EM_BERKNET: /* do berknet error processing */ 3295c2aa98e2SPeter Wemm case EM_WRITE: /* write back (or mail) */ 3296c2aa98e2SPeter Wemm case EM_PRINT: /* print errors normally (default) */ 3297c2aa98e2SPeter Wemm e->e_errormode = *val; 3298c2aa98e2SPeter Wemm break; 3299c2aa98e2SPeter Wemm } 3300c2aa98e2SPeter Wemm break; 3301c2aa98e2SPeter Wemm 3302c2aa98e2SPeter Wemm case 'F': /* file mode */ 3303c2aa98e2SPeter Wemm FileMode = atooct(val) & 0777; 3304c2aa98e2SPeter Wemm break; 3305c2aa98e2SPeter Wemm 3306c2aa98e2SPeter Wemm case 'f': /* save Unix-style From lines on front */ 3307c2aa98e2SPeter Wemm SaveFrom = atobool(val); 3308c2aa98e2SPeter Wemm break; 3309c2aa98e2SPeter Wemm 3310c2aa98e2SPeter Wemm case 'G': /* match recipients against GECOS field */ 3311c2aa98e2SPeter Wemm MatchGecos = atobool(val); 3312c2aa98e2SPeter Wemm break; 3313c2aa98e2SPeter Wemm 3314c2aa98e2SPeter Wemm case 'g': /* default gid */ 3315c2aa98e2SPeter Wemm g_opt: 3316c2aa98e2SPeter Wemm if (isascii(*val) && isdigit(*val)) 3317c2aa98e2SPeter Wemm DefGid = atoi(val); 3318c2aa98e2SPeter Wemm else 3319c2aa98e2SPeter Wemm { 3320c2aa98e2SPeter Wemm register struct group *gr; 3321c2aa98e2SPeter Wemm 3322c2aa98e2SPeter Wemm DefGid = -1; 3323c2aa98e2SPeter Wemm gr = getgrnam(val); 3324c2aa98e2SPeter Wemm if (gr == NULL) 3325c2aa98e2SPeter Wemm syserr("readcf: option %c: unknown group %s", 3326c2aa98e2SPeter Wemm opt, val); 3327c2aa98e2SPeter Wemm else 3328c2aa98e2SPeter Wemm DefGid = gr->gr_gid; 3329c2aa98e2SPeter Wemm } 3330c2aa98e2SPeter Wemm break; 3331c2aa98e2SPeter Wemm 3332c2aa98e2SPeter Wemm case 'H': /* help file */ 3333c2aa98e2SPeter Wemm if (val[0] == '\0') 333440266059SGregory Neil Shapiro { 333540266059SGregory Neil Shapiro SET_OPT_DEFAULT(HelpFile, "helpfile"); 333640266059SGregory Neil Shapiro } 3337c2aa98e2SPeter Wemm else 3338602a2b1bSGregory Neil Shapiro { 333940266059SGregory Neil Shapiro CANONIFY(val); 3340c2aa98e2SPeter Wemm HelpFile = newstr(val); 3341602a2b1bSGregory Neil Shapiro } 3342c2aa98e2SPeter Wemm break; 3343c2aa98e2SPeter Wemm 3344c2aa98e2SPeter Wemm case 'h': /* maximum hop count */ 3345c2aa98e2SPeter Wemm MaxHopCount = atoi(val); 3346c2aa98e2SPeter Wemm break; 3347c2aa98e2SPeter Wemm 3348c2aa98e2SPeter Wemm case 'I': /* use internet domain name server */ 3349c2aa98e2SPeter Wemm #if NAMED_BIND 3350c2aa98e2SPeter Wemm for (p = val; *p != 0; ) 3351c2aa98e2SPeter Wemm { 3352c2aa98e2SPeter Wemm bool clearmode; 3353c2aa98e2SPeter Wemm char *q; 3354c2aa98e2SPeter Wemm struct resolverflags *rfp; 3355c2aa98e2SPeter Wemm 3356c2aa98e2SPeter Wemm while (*p == ' ') 3357c2aa98e2SPeter Wemm p++; 3358c2aa98e2SPeter Wemm if (*p == '\0') 3359c2aa98e2SPeter Wemm break; 336040266059SGregory Neil Shapiro clearmode = false; 3361c2aa98e2SPeter Wemm if (*p == '-') 336240266059SGregory Neil Shapiro clearmode = true; 3363c2aa98e2SPeter Wemm else if (*p != '+') 3364c2aa98e2SPeter Wemm p--; 3365c2aa98e2SPeter Wemm p++; 3366c2aa98e2SPeter Wemm q = p; 3367*5b0945b5SGregory Neil Shapiro while (*p != '\0' && !(SM_ISSPACE(*p))) 3368c2aa98e2SPeter Wemm p++; 3369c2aa98e2SPeter Wemm if (*p != '\0') 3370c2aa98e2SPeter Wemm *p++ = '\0'; 337140266059SGregory Neil Shapiro if (sm_strcasecmp(q, "HasWildcardMX") == 0) 3372c2aa98e2SPeter Wemm { 3373c2aa98e2SPeter Wemm HasWildcardMX = !clearmode; 3374c2aa98e2SPeter Wemm continue; 3375c2aa98e2SPeter Wemm } 3376602a2b1bSGregory Neil Shapiro if (sm_strcasecmp(q, "WorkAroundBrokenAAAA") == 0) 3377602a2b1bSGregory Neil Shapiro { 3378602a2b1bSGregory Neil Shapiro WorkAroundBrokenAAAA = !clearmode; 3379602a2b1bSGregory Neil Shapiro continue; 3380602a2b1bSGregory Neil Shapiro } 3381c2aa98e2SPeter Wemm for (rfp = ResolverFlags; rfp->rf_name != NULL; rfp++) 3382c2aa98e2SPeter Wemm { 338340266059SGregory Neil Shapiro if (sm_strcasecmp(q, rfp->rf_name) == 0) 3384c2aa98e2SPeter Wemm break; 3385c2aa98e2SPeter Wemm } 3386c2aa98e2SPeter Wemm if (rfp->rf_name == NULL) 3387c2aa98e2SPeter Wemm syserr("readcf: I option value %s unrecognized", q); 3388c2aa98e2SPeter Wemm else if (clearmode) 3389c2aa98e2SPeter Wemm _res.options &= ~rfp->rf_bits; 3390c2aa98e2SPeter Wemm else 3391c2aa98e2SPeter Wemm _res.options |= rfp->rf_bits; 3392c2aa98e2SPeter Wemm } 3393c2aa98e2SPeter Wemm if (tTd(8, 2)) 339440266059SGregory Neil Shapiro sm_dprintf("_res.options = %x, HasWildcardMX = %d\n", 339540266059SGregory Neil Shapiro (unsigned int) _res.options, HasWildcardMX); 339606f25ae9SGregory Neil Shapiro #else /* NAMED_BIND */ 3397c2aa98e2SPeter Wemm usrerr("name server (I option) specified but BIND not compiled in"); 339806f25ae9SGregory Neil Shapiro #endif /* NAMED_BIND */ 3399c2aa98e2SPeter Wemm break; 3400c2aa98e2SPeter Wemm 3401c2aa98e2SPeter Wemm case 'i': /* ignore dot lines in message */ 3402c2aa98e2SPeter Wemm IgnrDot = atobool(val); 3403c2aa98e2SPeter Wemm break; 3404c2aa98e2SPeter Wemm 3405c2aa98e2SPeter Wemm case 'j': /* send errors in MIME (RFC 1341) format */ 3406c2aa98e2SPeter Wemm SendMIMEErrors = atobool(val); 3407c2aa98e2SPeter Wemm break; 3408c2aa98e2SPeter Wemm 3409c2aa98e2SPeter Wemm case 'J': /* .forward search path */ 341040266059SGregory Neil Shapiro CANONIFY(val); 3411c2aa98e2SPeter Wemm ForwardPath = newstr(val); 3412c2aa98e2SPeter Wemm break; 3413c2aa98e2SPeter Wemm 3414c2aa98e2SPeter Wemm case 'k': /* connection cache size */ 3415c2aa98e2SPeter Wemm MaxMciCache = atoi(val); 3416c2aa98e2SPeter Wemm if (MaxMciCache < 0) 3417c2aa98e2SPeter Wemm MaxMciCache = 0; 3418c2aa98e2SPeter Wemm break; 3419c2aa98e2SPeter Wemm 3420c2aa98e2SPeter Wemm case 'K': /* connection cache timeout */ 3421c2aa98e2SPeter Wemm MciCacheTimeout = convtime(val, 'm'); 3422c2aa98e2SPeter Wemm break; 3423c2aa98e2SPeter Wemm 3424c2aa98e2SPeter Wemm case 'l': /* use Errors-To: header */ 3425c2aa98e2SPeter Wemm UseErrorsTo = atobool(val); 3426c2aa98e2SPeter Wemm break; 3427c2aa98e2SPeter Wemm 3428c2aa98e2SPeter Wemm case 'L': /* log level */ 3429c2aa98e2SPeter Wemm if (safe || LogLevel < atoi(val)) 3430c2aa98e2SPeter Wemm LogLevel = atoi(val); 3431c2aa98e2SPeter Wemm break; 3432c2aa98e2SPeter Wemm 3433c2aa98e2SPeter Wemm case 'M': /* define macro */ 343440266059SGregory Neil Shapiro sticky = false; 3435*5b0945b5SGregory Neil Shapiro i = macid_parse(val, &ep); 3436*5b0945b5SGregory Neil Shapiro if (i == 0) 3437193538b7SGregory Neil Shapiro break; 3438c2aa98e2SPeter Wemm p = newstr(ep); 3439c2aa98e2SPeter Wemm if (!safe) 3440a7ec597cSGregory Neil Shapiro cleanstrcpy(p, p, strlen(p) + 1); 3441*5b0945b5SGregory Neil Shapiro macdefine(&CurEnv->e_macro, A_TEMP, i, p); 3442c2aa98e2SPeter Wemm break; 3443c2aa98e2SPeter Wemm 3444c2aa98e2SPeter Wemm case 'm': /* send to me too */ 3445c2aa98e2SPeter Wemm MeToo = atobool(val); 3446c2aa98e2SPeter Wemm break; 3447c2aa98e2SPeter Wemm 3448c2aa98e2SPeter Wemm case 'n': /* validate RHS in newaliases */ 3449c2aa98e2SPeter Wemm CheckAliases = atobool(val); 3450c2aa98e2SPeter Wemm break; 3451c2aa98e2SPeter Wemm 3452c2aa98e2SPeter Wemm /* 'N' available -- was "net name" */ 3453c2aa98e2SPeter Wemm 3454c2aa98e2SPeter Wemm case 'O': /* daemon options */ 345506f25ae9SGregory Neil Shapiro if (!setdaemonoptions(val)) 345606f25ae9SGregory Neil Shapiro syserr("too many daemons defined (%d max)", MAXDAEMONS); 3457c2aa98e2SPeter Wemm break; 3458c2aa98e2SPeter Wemm 3459c2aa98e2SPeter Wemm case 'o': /* assume old style headers */ 3460c2aa98e2SPeter Wemm if (atobool(val)) 3461c2aa98e2SPeter Wemm CurEnv->e_flags |= EF_OLDSTYLE; 3462c2aa98e2SPeter Wemm else 3463c2aa98e2SPeter Wemm CurEnv->e_flags &= ~EF_OLDSTYLE; 3464c2aa98e2SPeter Wemm break; 3465c2aa98e2SPeter Wemm 3466c2aa98e2SPeter Wemm case 'p': /* select privacy level */ 3467c2aa98e2SPeter Wemm p = val; 3468c2aa98e2SPeter Wemm for (;;) 3469c2aa98e2SPeter Wemm { 3470c2aa98e2SPeter Wemm register struct prival *pv; 3471c2aa98e2SPeter Wemm extern struct prival PrivacyValues[]; 3472c2aa98e2SPeter Wemm 3473c2aa98e2SPeter Wemm while (isascii(*p) && (isspace(*p) || ispunct(*p))) 3474c2aa98e2SPeter Wemm p++; 3475c2aa98e2SPeter Wemm if (*p == '\0') 3476c2aa98e2SPeter Wemm break; 3477c2aa98e2SPeter Wemm val = p; 3478c2aa98e2SPeter Wemm while (isascii(*p) && isalnum(*p)) 3479c2aa98e2SPeter Wemm p++; 3480c2aa98e2SPeter Wemm if (*p != '\0') 3481c2aa98e2SPeter Wemm *p++ = '\0'; 3482c2aa98e2SPeter Wemm 3483c2aa98e2SPeter Wemm for (pv = PrivacyValues; pv->pv_name != NULL; pv++) 3484c2aa98e2SPeter Wemm { 348540266059SGregory Neil Shapiro if (sm_strcasecmp(val, pv->pv_name) == 0) 3486c2aa98e2SPeter Wemm break; 3487c2aa98e2SPeter Wemm } 3488c2aa98e2SPeter Wemm if (pv->pv_name == NULL) 3489c2aa98e2SPeter Wemm syserr("readcf: Op line: %s unrecognized", val); 3490193538b7SGregory Neil Shapiro else 3491c2aa98e2SPeter Wemm PrivacyFlags |= pv->pv_flag; 3492c2aa98e2SPeter Wemm } 349340266059SGregory Neil Shapiro sticky = false; 3494c2aa98e2SPeter Wemm break; 3495c2aa98e2SPeter Wemm 3496c2aa98e2SPeter Wemm case 'P': /* postmaster copy address for returned mail */ 3497c2aa98e2SPeter Wemm PostMasterCopy = newstr(val); 3498c2aa98e2SPeter Wemm break; 3499c2aa98e2SPeter Wemm 3500c2aa98e2SPeter Wemm case 'q': /* slope of queue only function */ 3501c2aa98e2SPeter Wemm QueueFactor = atoi(val); 3502c2aa98e2SPeter Wemm break; 3503c2aa98e2SPeter Wemm 3504c2aa98e2SPeter Wemm case 'Q': /* queue directory */ 3505c2aa98e2SPeter Wemm if (val[0] == '\0') 350642e5d165SGregory Neil Shapiro { 3507c2aa98e2SPeter Wemm QueueDir = "mqueue"; 350842e5d165SGregory Neil Shapiro } 3509c2aa98e2SPeter Wemm else 351042e5d165SGregory Neil Shapiro { 3511c2aa98e2SPeter Wemm QueueDir = newstr(val); 351242e5d165SGregory Neil Shapiro } 3513c2aa98e2SPeter Wemm if (RealUid != 0 && !safe) 351440266059SGregory Neil Shapiro Warn_Q_option = true; 3515c2aa98e2SPeter Wemm break; 3516c2aa98e2SPeter Wemm 3517c2aa98e2SPeter Wemm case 'R': /* don't prune routes */ 3518c2aa98e2SPeter Wemm DontPruneRoutes = atobool(val); 3519c2aa98e2SPeter Wemm break; 3520c2aa98e2SPeter Wemm 3521c2aa98e2SPeter Wemm case 'r': /* read timeout */ 3522c2aa98e2SPeter Wemm if (subopt == NULL) 352306f25ae9SGregory Neil Shapiro inittimeouts(val, sticky); 3524c2aa98e2SPeter Wemm else 352506f25ae9SGregory Neil Shapiro settimeout(subopt, val, sticky); 3526c2aa98e2SPeter Wemm break; 3527c2aa98e2SPeter Wemm 3528c2aa98e2SPeter Wemm case 'S': /* status file */ 3529c2aa98e2SPeter Wemm if (val[0] == '\0') 353040266059SGregory Neil Shapiro { 353140266059SGregory Neil Shapiro SET_OPT_DEFAULT(StatFile, "statistics"); 353240266059SGregory Neil Shapiro } 3533c2aa98e2SPeter Wemm else 3534602a2b1bSGregory Neil Shapiro { 353540266059SGregory Neil Shapiro CANONIFY(val); 3536c2aa98e2SPeter Wemm StatFile = newstr(val); 3537602a2b1bSGregory Neil Shapiro } 3538c2aa98e2SPeter Wemm break; 3539c2aa98e2SPeter Wemm 3540c2aa98e2SPeter Wemm case 's': /* be super safe, even if expensive */ 354140266059SGregory Neil Shapiro if (tolower(*val) == 'i') 354240266059SGregory Neil Shapiro SuperSafe = SAFE_INTERACTIVE; 3543e92d3f3fSGregory Neil Shapiro else if (tolower(*val) == 'p') 3544e92d3f3fSGregory Neil Shapiro #if MILTER 3545e92d3f3fSGregory Neil Shapiro SuperSafe = SAFE_REALLY_POSTMILTER; 3546e92d3f3fSGregory Neil Shapiro #else /* MILTER */ 3547e92d3f3fSGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3548e92d3f3fSGregory Neil Shapiro "Warning: SuperSafe=PostMilter requires Milter support (-DMILTER)\n"); 3549e92d3f3fSGregory Neil Shapiro #endif /* MILTER */ 355040266059SGregory Neil Shapiro else 355140266059SGregory Neil Shapiro SuperSafe = atobool(val) ? SAFE_REALLY : SAFE_NO; 3552c2aa98e2SPeter Wemm break; 3553c2aa98e2SPeter Wemm 3554c2aa98e2SPeter Wemm case 'T': /* queue timeout */ 3555c2aa98e2SPeter Wemm p = strchr(val, '/'); 3556c2aa98e2SPeter Wemm if (p != NULL) 3557c2aa98e2SPeter Wemm { 3558c2aa98e2SPeter Wemm *p++ = '\0'; 355906f25ae9SGregory Neil Shapiro settimeout("queuewarn", p, sticky); 3560c2aa98e2SPeter Wemm } 356106f25ae9SGregory Neil Shapiro settimeout("queuereturn", val, sticky); 3562c2aa98e2SPeter Wemm break; 3563c2aa98e2SPeter Wemm 3564c2aa98e2SPeter Wemm case 't': /* time zone name */ 3565c2aa98e2SPeter Wemm TimeZoneSpec = newstr(val); 3566c2aa98e2SPeter Wemm break; 3567c2aa98e2SPeter Wemm 3568c2aa98e2SPeter Wemm case 'U': /* location of user database */ 3569c2aa98e2SPeter Wemm UdbSpec = newstr(val); 3570c2aa98e2SPeter Wemm break; 3571c2aa98e2SPeter Wemm 3572c2aa98e2SPeter Wemm case 'u': /* set default uid */ 3573c2aa98e2SPeter Wemm for (p = val; *p != '\0'; p++) 3574c2aa98e2SPeter Wemm { 357540266059SGregory Neil Shapiro # if _FFR_DOTTED_USERNAMES 357640266059SGregory Neil Shapiro if (*p == '/' || *p == ':') 3577*5b0945b5SGregory Neil Shapiro # else 3578c2aa98e2SPeter Wemm if (*p == '.' || *p == '/' || *p == ':') 3579*5b0945b5SGregory Neil Shapiro # endif 3580c2aa98e2SPeter Wemm { 3581c2aa98e2SPeter Wemm *p++ = '\0'; 3582c2aa98e2SPeter Wemm break; 3583c2aa98e2SPeter Wemm } 3584c2aa98e2SPeter Wemm } 3585c2aa98e2SPeter Wemm if (isascii(*val) && isdigit(*val)) 3586c2aa98e2SPeter Wemm { 3587c2aa98e2SPeter Wemm DefUid = atoi(val); 3588c2aa98e2SPeter Wemm setdefuser(); 3589c2aa98e2SPeter Wemm } 3590c2aa98e2SPeter Wemm else 3591c2aa98e2SPeter Wemm { 3592c2aa98e2SPeter Wemm register struct passwd *pw; 3593c2aa98e2SPeter Wemm 3594c2aa98e2SPeter Wemm DefUid = -1; 3595c2aa98e2SPeter Wemm pw = sm_getpwnam(val); 3596c2aa98e2SPeter Wemm if (pw == NULL) 3597193538b7SGregory Neil Shapiro { 3598c2aa98e2SPeter Wemm syserr("readcf: option u: unknown user %s", val); 3599193538b7SGregory Neil Shapiro break; 3600193538b7SGregory Neil Shapiro } 3601c2aa98e2SPeter Wemm else 3602c2aa98e2SPeter Wemm { 3603c2aa98e2SPeter Wemm DefUid = pw->pw_uid; 3604c2aa98e2SPeter Wemm DefGid = pw->pw_gid; 3605c2aa98e2SPeter Wemm DefUser = newstr(pw->pw_name); 3606c2aa98e2SPeter Wemm } 3607c2aa98e2SPeter Wemm } 3608c2aa98e2SPeter Wemm 3609c2aa98e2SPeter Wemm # ifdef UID_MAX 3610c2aa98e2SPeter Wemm if (DefUid > UID_MAX) 3611c2aa98e2SPeter Wemm { 3612c2aa98e2SPeter Wemm syserr("readcf: option u: uid value (%ld) > UID_MAX (%ld); ignored", 3613193538b7SGregory Neil Shapiro (long)DefUid, (long)UID_MAX); 3614193538b7SGregory Neil Shapiro break; 3615c2aa98e2SPeter Wemm } 361606f25ae9SGregory Neil Shapiro # endif /* UID_MAX */ 3617c2aa98e2SPeter Wemm 3618c2aa98e2SPeter Wemm /* handle the group if it is there */ 3619c2aa98e2SPeter Wemm if (*p == '\0') 3620c2aa98e2SPeter Wemm break; 3621c2aa98e2SPeter Wemm val = p; 3622c2aa98e2SPeter Wemm goto g_opt; 3623c2aa98e2SPeter Wemm 3624c2aa98e2SPeter Wemm case 'V': /* fallback MX host */ 3625c2aa98e2SPeter Wemm if (val[0] != '\0') 3626e92d3f3fSGregory Neil Shapiro FallbackMX = newstr(val); 3627c2aa98e2SPeter Wemm break; 3628c2aa98e2SPeter Wemm 3629c2aa98e2SPeter Wemm case 'v': /* run in verbose mode */ 3630c2aa98e2SPeter Wemm Verbose = atobool(val) ? 1 : 0; 3631c2aa98e2SPeter Wemm break; 3632c2aa98e2SPeter Wemm 3633c2aa98e2SPeter Wemm case 'w': /* if we are best MX, try host directly */ 3634c2aa98e2SPeter Wemm TryNullMXList = atobool(val); 3635c2aa98e2SPeter Wemm break; 3636c2aa98e2SPeter Wemm 3637c2aa98e2SPeter Wemm /* 'W' available -- was wizard password */ 3638c2aa98e2SPeter Wemm 3639c2aa98e2SPeter Wemm case 'x': /* load avg at which to auto-queue msgs */ 3640c2aa98e2SPeter Wemm QueueLA = atoi(val); 3641c2aa98e2SPeter Wemm break; 3642c2aa98e2SPeter Wemm 3643c2aa98e2SPeter Wemm case 'X': /* load avg at which to auto-reject connections */ 3644c2aa98e2SPeter Wemm RefuseLA = atoi(val); 3645c2aa98e2SPeter Wemm break; 3646c2aa98e2SPeter Wemm 364740266059SGregory Neil Shapiro case O_DELAY_LA: /* load avg at which to delay connections */ 364840266059SGregory Neil Shapiro DelayLA = atoi(val); 364940266059SGregory Neil Shapiro break; 365040266059SGregory Neil Shapiro 3651c2aa98e2SPeter Wemm case 'y': /* work recipient factor */ 3652c2aa98e2SPeter Wemm WkRecipFact = atoi(val); 3653c2aa98e2SPeter Wemm break; 3654c2aa98e2SPeter Wemm 3655c2aa98e2SPeter Wemm case 'Y': /* fork jobs during queue runs */ 3656c2aa98e2SPeter Wemm ForkQueueRuns = atobool(val); 3657c2aa98e2SPeter Wemm break; 3658c2aa98e2SPeter Wemm 3659c2aa98e2SPeter Wemm case 'z': /* work message class factor */ 3660c2aa98e2SPeter Wemm WkClassFact = atoi(val); 3661c2aa98e2SPeter Wemm break; 3662c2aa98e2SPeter Wemm 3663c2aa98e2SPeter Wemm case 'Z': /* work time factor */ 3664c2aa98e2SPeter Wemm WkTimeFact = atoi(val); 3665c2aa98e2SPeter Wemm break; 3666c2aa98e2SPeter Wemm 366706f25ae9SGregory Neil Shapiro 3668605302a5SGregory Neil Shapiro #if _FFR_QUEUE_GROUP_SORTORDER 3669605302a5SGregory Neil Shapiro /* coordinate this with makequeue() */ 3670*5b0945b5SGregory Neil Shapiro #endif 3671c2aa98e2SPeter Wemm case O_QUEUESORTORD: /* queue sorting order */ 3672c2aa98e2SPeter Wemm switch (*val) 3673c2aa98e2SPeter Wemm { 367440266059SGregory Neil Shapiro case 'f': /* File Name */ 367540266059SGregory Neil Shapiro case 'F': 367640266059SGregory Neil Shapiro QueueSortOrder = QSO_BYFILENAME; 367740266059SGregory Neil Shapiro break; 367840266059SGregory Neil Shapiro 3679c2aa98e2SPeter Wemm case 'h': /* Host first */ 3680c2aa98e2SPeter Wemm case 'H': 368106f25ae9SGregory Neil Shapiro QueueSortOrder = QSO_BYHOST; 3682c2aa98e2SPeter Wemm break; 3683c2aa98e2SPeter Wemm 368440266059SGregory Neil Shapiro case 'm': /* Modification time */ 368540266059SGregory Neil Shapiro case 'M': 368640266059SGregory Neil Shapiro QueueSortOrder = QSO_BYMODTIME; 368740266059SGregory Neil Shapiro break; 368840266059SGregory Neil Shapiro 3689c2aa98e2SPeter Wemm case 'p': /* Priority order */ 3690c2aa98e2SPeter Wemm case 'P': 369106f25ae9SGregory Neil Shapiro QueueSortOrder = QSO_BYPRIORITY; 3692c2aa98e2SPeter Wemm break; 3693c2aa98e2SPeter Wemm 3694c2aa98e2SPeter Wemm case 't': /* Submission time */ 3695c2aa98e2SPeter Wemm case 'T': 369606f25ae9SGregory Neil Shapiro QueueSortOrder = QSO_BYTIME; 369706f25ae9SGregory Neil Shapiro break; 369806f25ae9SGregory Neil Shapiro 369940266059SGregory Neil Shapiro case 'r': /* Random */ 370040266059SGregory Neil Shapiro case 'R': 370140266059SGregory Neil Shapiro QueueSortOrder = QSO_RANDOM; 3702c2aa98e2SPeter Wemm break; 3703c2aa98e2SPeter Wemm 370440266059SGregory Neil Shapiro #if _FFR_RHS 370540266059SGregory Neil Shapiro case 's': /* Shuffled host name */ 370640266059SGregory Neil Shapiro case 'S': 370740266059SGregory Neil Shapiro QueueSortOrder = QSO_BYSHUFFLE; 370840266059SGregory Neil Shapiro break; 370940266059SGregory Neil Shapiro #endif /* _FFR_RHS */ 371040266059SGregory Neil Shapiro 3711e92d3f3fSGregory Neil Shapiro case 'n': /* none */ 3712e92d3f3fSGregory Neil Shapiro case 'N': 3713e92d3f3fSGregory Neil Shapiro QueueSortOrder = QSO_NONE; 3714e92d3f3fSGregory Neil Shapiro break; 3715e92d3f3fSGregory Neil Shapiro 3716c2aa98e2SPeter Wemm default: 3717c2aa98e2SPeter Wemm syserr("Invalid queue sort order \"%s\"", val); 3718c2aa98e2SPeter Wemm } 3719c2aa98e2SPeter Wemm break; 3720c2aa98e2SPeter Wemm 3721c2aa98e2SPeter Wemm case O_HOSTSFILE: /* pathname of /etc/hosts file */ 372240266059SGregory Neil Shapiro CANONIFY(val); 3723c2aa98e2SPeter Wemm HostsFile = newstr(val); 3724c2aa98e2SPeter Wemm break; 3725c2aa98e2SPeter Wemm 3726c2aa98e2SPeter Wemm case O_MQA: /* minimum queue age between deliveries */ 3727c2aa98e2SPeter Wemm MinQueueAge = convtime(val, 'm'); 3728c2aa98e2SPeter Wemm break; 3729c2aa98e2SPeter Wemm 37309bd497b8SGregory Neil Shapiro case O_MAX_QUEUE_AGE: 37319bd497b8SGregory Neil Shapiro MaxQueueAge = convtime(val, 'm'); 37329bd497b8SGregory Neil Shapiro break; 37339bd497b8SGregory Neil Shapiro 3734c2aa98e2SPeter Wemm case O_DEFCHARSET: /* default character set for mimefying */ 373540266059SGregory Neil Shapiro DefaultCharSet = newstr(denlstring(val, true, true)); 3736c2aa98e2SPeter Wemm break; 3737c2aa98e2SPeter Wemm 3738c2aa98e2SPeter Wemm case O_SSFILE: /* service switch file */ 373940266059SGregory Neil Shapiro CANONIFY(val); 3740c2aa98e2SPeter Wemm ServiceSwitchFile = newstr(val); 3741c2aa98e2SPeter Wemm break; 3742c2aa98e2SPeter Wemm 3743c2aa98e2SPeter Wemm case O_DIALDELAY: /* delay for dial-on-demand operation */ 3744c2aa98e2SPeter Wemm DialDelay = convtime(val, 's'); 3745c2aa98e2SPeter Wemm break; 3746c2aa98e2SPeter Wemm 3747c2aa98e2SPeter Wemm case O_NORCPTACTION: /* what to do if no recipient */ 374840266059SGregory Neil Shapiro if (sm_strcasecmp(val, "none") == 0) 3749c2aa98e2SPeter Wemm NoRecipientAction = NRA_NO_ACTION; 375040266059SGregory Neil Shapiro else if (sm_strcasecmp(val, "add-to") == 0) 3751c2aa98e2SPeter Wemm NoRecipientAction = NRA_ADD_TO; 375240266059SGregory Neil Shapiro else if (sm_strcasecmp(val, "add-apparently-to") == 0) 3753c2aa98e2SPeter Wemm NoRecipientAction = NRA_ADD_APPARENTLY_TO; 375440266059SGregory Neil Shapiro else if (sm_strcasecmp(val, "add-bcc") == 0) 3755c2aa98e2SPeter Wemm NoRecipientAction = NRA_ADD_BCC; 375640266059SGregory Neil Shapiro else if (sm_strcasecmp(val, "add-to-undisclosed") == 0) 3757c2aa98e2SPeter Wemm NoRecipientAction = NRA_ADD_TO_UNDISCLOSED; 3758c2aa98e2SPeter Wemm else 3759c2aa98e2SPeter Wemm syserr("Invalid NoRecipientAction: %s", val); 3760c2aa98e2SPeter Wemm break; 3761c2aa98e2SPeter Wemm 3762c2aa98e2SPeter Wemm case O_SAFEFILEENV: /* chroot() environ for writing to files */ 3763605302a5SGregory Neil Shapiro if (*val == '\0') 3764605302a5SGregory Neil Shapiro break; 3765605302a5SGregory Neil Shapiro 3766605302a5SGregory Neil Shapiro /* strip trailing slashes */ 3767605302a5SGregory Neil Shapiro p = val + strlen(val) - 1; 3768605302a5SGregory Neil Shapiro while (p >= val && *p == '/') 3769605302a5SGregory Neil Shapiro *p-- = '\0'; 3770605302a5SGregory Neil Shapiro 3771605302a5SGregory Neil Shapiro if (*val == '\0') 3772605302a5SGregory Neil Shapiro break; 3773605302a5SGregory Neil Shapiro 3774c2aa98e2SPeter Wemm SafeFileEnv = newstr(val); 3775c2aa98e2SPeter Wemm break; 3776c2aa98e2SPeter Wemm 3777c2aa98e2SPeter Wemm case O_MAXMSGSIZE: /* maximum message size */ 3778c2aa98e2SPeter Wemm MaxMessageSize = atol(val); 3779c2aa98e2SPeter Wemm break; 3780c2aa98e2SPeter Wemm 3781c2aa98e2SPeter Wemm case O_COLONOKINADDR: /* old style handling of colon addresses */ 3782c2aa98e2SPeter Wemm ColonOkInAddr = atobool(val); 3783c2aa98e2SPeter Wemm break; 3784c2aa98e2SPeter Wemm 3785c2aa98e2SPeter Wemm case O_MAXQUEUERUN: /* max # of jobs in a single queue run */ 378640266059SGregory Neil Shapiro MaxQueueRun = atoi(val); 3787c2aa98e2SPeter Wemm break; 3788c2aa98e2SPeter Wemm 3789c2aa98e2SPeter Wemm case O_MAXCHILDREN: /* max # of children of daemon */ 3790c2aa98e2SPeter Wemm MaxChildren = atoi(val); 3791c2aa98e2SPeter Wemm break; 3792c2aa98e2SPeter Wemm 379340266059SGregory Neil Shapiro case O_MAXQUEUECHILDREN: /* max # of children of daemon */ 379440266059SGregory Neil Shapiro MaxQueueChildren = atoi(val); 379540266059SGregory Neil Shapiro break; 379640266059SGregory Neil Shapiro 379740266059SGregory Neil Shapiro case O_MAXRUNNERSPERQUEUE: /* max # runners in a queue group */ 379840266059SGregory Neil Shapiro MaxRunnersPerQueue = atoi(val); 379940266059SGregory Neil Shapiro break; 380040266059SGregory Neil Shapiro 380140266059SGregory Neil Shapiro case O_NICEQUEUERUN: /* nice queue runs */ 380240266059SGregory Neil Shapiro #if !HASNICE 380340266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 380440266059SGregory Neil Shapiro "Warning: NiceQueueRun set on system that doesn't support nice()\n"); 3805*5b0945b5SGregory Neil Shapiro #endif 380640266059SGregory Neil Shapiro 380740266059SGregory Neil Shapiro /* XXX do we want to check the range? > 0 ? */ 380840266059SGregory Neil Shapiro NiceQueueRun = atoi(val); 380940266059SGregory Neil Shapiro break; 381040266059SGregory Neil Shapiro 381140266059SGregory Neil Shapiro case O_SHMKEY: /* shared memory key */ 381240266059SGregory Neil Shapiro #if SM_CONF_SHM 381340266059SGregory Neil Shapiro ShmKey = atol(val); 381440266059SGregory Neil Shapiro #else /* SM_CONF_SHM */ 381540266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 381640266059SGregory Neil Shapiro "Warning: Option: %s requires shared memory support (-DSM_CONF_SHM)\n", 381740266059SGregory Neil Shapiro OPTNAME); 381840266059SGregory Neil Shapiro #endif /* SM_CONF_SHM */ 381940266059SGregory Neil Shapiro break; 382040266059SGregory Neil Shapiro 3821605302a5SGregory Neil Shapiro case O_SHMKEYFILE: /* shared memory key file */ 3822605302a5SGregory Neil Shapiro #if SM_CONF_SHM 3823739ac4d4SGregory Neil Shapiro SET_STRING_EXP(ShmKeyFile); 3824605302a5SGregory Neil Shapiro #else /* SM_CONF_SHM */ 3825605302a5SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3826605302a5SGregory Neil Shapiro "Warning: Option: %s requires shared memory support (-DSM_CONF_SHM)\n", 3827605302a5SGregory Neil Shapiro OPTNAME); 3828605302a5SGregory Neil Shapiro break; 3829739ac4d4SGregory Neil Shapiro #endif /* SM_CONF_SHM */ 3830605302a5SGregory Neil Shapiro 383106f25ae9SGregory Neil Shapiro #if _FFR_MAX_FORWARD_ENTRIES 383206f25ae9SGregory Neil Shapiro case O_MAXFORWARD: /* max # of forward entries */ 383306f25ae9SGregory Neil Shapiro MaxForwardEntries = atoi(val); 383406f25ae9SGregory Neil Shapiro break; 3835*5b0945b5SGregory Neil Shapiro #endif 383606f25ae9SGregory Neil Shapiro 3837c2aa98e2SPeter Wemm case O_KEEPCNAMES: /* don't expand CNAME records */ 3838c2aa98e2SPeter Wemm DontExpandCnames = atobool(val); 3839c2aa98e2SPeter Wemm break; 3840c2aa98e2SPeter Wemm 3841c2aa98e2SPeter Wemm case O_MUSTQUOTE: /* must quote these characters in phrases */ 3842d0cef73dSGregory Neil Shapiro (void) sm_strlcpy(buf, "@,;:\\()[]", sizeof(buf)); 3843d0cef73dSGregory Neil Shapiro if (strlen(val) < sizeof(buf) - 10) 3844d0cef73dSGregory Neil Shapiro (void) sm_strlcat(buf, val, sizeof(buf)); 384506f25ae9SGregory Neil Shapiro else 384640266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 384740266059SGregory Neil Shapiro "Warning: MustQuoteChars too long, ignored.\n"); 3848c2aa98e2SPeter Wemm MustQuoteChars = newstr(buf); 3849c2aa98e2SPeter Wemm break; 3850c2aa98e2SPeter Wemm 3851c2aa98e2SPeter Wemm case O_SMTPGREETING: /* SMTP greeting message (old $e macro) */ 3852c2aa98e2SPeter Wemm SmtpGreeting = newstr(munchstring(val, NULL, '\0')); 3853c2aa98e2SPeter Wemm break; 3854c2aa98e2SPeter Wemm 3855c2aa98e2SPeter Wemm case O_UNIXFROM: /* UNIX From_ line (old $l macro) */ 3856c2aa98e2SPeter Wemm UnixFromLine = newstr(munchstring(val, NULL, '\0')); 3857c2aa98e2SPeter Wemm break; 3858c2aa98e2SPeter Wemm 3859c2aa98e2SPeter Wemm case O_OPCHARS: /* operator characters (old $o macro) */ 386006f25ae9SGregory Neil Shapiro if (OperatorChars != NULL) 386140266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 386240266059SGregory Neil Shapiro "Warning: OperatorChars is being redefined.\n It should only be set before ruleset definitions.\n"); 3863c2aa98e2SPeter Wemm OperatorChars = newstr(munchstring(val, NULL, '\0')); 3864c2aa98e2SPeter Wemm break; 3865c2aa98e2SPeter Wemm 3866c2aa98e2SPeter Wemm case O_DONTINITGRPS: /* don't call initgroups(3) */ 3867c2aa98e2SPeter Wemm DontInitGroups = atobool(val); 3868c2aa98e2SPeter Wemm break; 3869c2aa98e2SPeter Wemm 3870c2aa98e2SPeter Wemm case O_SLFH: /* make sure from fits on one line */ 3871c2aa98e2SPeter Wemm SingleLineFromHeader = atobool(val); 3872c2aa98e2SPeter Wemm break; 3873c2aa98e2SPeter Wemm 3874c2aa98e2SPeter Wemm case O_ABH: /* allow HELO commands with syntax errors */ 3875c2aa98e2SPeter Wemm AllowBogusHELO = atobool(val); 3876c2aa98e2SPeter Wemm break; 3877c2aa98e2SPeter Wemm 3878c2aa98e2SPeter Wemm case O_CONNTHROT: /* connection rate throttle */ 3879c2aa98e2SPeter Wemm ConnRateThrottle = atoi(val); 3880c2aa98e2SPeter Wemm break; 3881c2aa98e2SPeter Wemm 3882c2aa98e2SPeter Wemm case O_UGW: /* group writable files are unsafe */ 3883c2aa98e2SPeter Wemm if (!atobool(val)) 388406f25ae9SGregory Neil Shapiro { 388506f25ae9SGregory Neil Shapiro setbitn(DBS_GROUPWRITABLEFORWARDFILESAFE, 388606f25ae9SGregory Neil Shapiro DontBlameSendmail); 388706f25ae9SGregory Neil Shapiro setbitn(DBS_GROUPWRITABLEINCLUDEFILESAFE, 388806f25ae9SGregory Neil Shapiro DontBlameSendmail); 388906f25ae9SGregory Neil Shapiro } 3890c2aa98e2SPeter Wemm break; 3891c2aa98e2SPeter Wemm 3892c2aa98e2SPeter Wemm case O_DBLBOUNCE: /* address to which to send double bounces */ 3893c2aa98e2SPeter Wemm DoubleBounceAddr = newstr(val); 3894c2aa98e2SPeter Wemm break; 3895c2aa98e2SPeter Wemm 3896c2aa98e2SPeter Wemm case O_HSDIR: /* persistent host status directory */ 3897c2aa98e2SPeter Wemm if (val[0] != '\0') 3898602a2b1bSGregory Neil Shapiro { 389940266059SGregory Neil Shapiro CANONIFY(val); 3900c2aa98e2SPeter Wemm HostStatDir = newstr(val); 3901602a2b1bSGregory Neil Shapiro } 3902c2aa98e2SPeter Wemm break; 3903c2aa98e2SPeter Wemm 3904c2aa98e2SPeter Wemm case O_SINGTHREAD: /* single thread deliveries (requires hsdir) */ 3905c2aa98e2SPeter Wemm SingleThreadDelivery = atobool(val); 3906c2aa98e2SPeter Wemm break; 3907c2aa98e2SPeter Wemm 3908c2aa98e2SPeter Wemm case O_RUNASUSER: /* run bulk of code as this user */ 3909c2aa98e2SPeter Wemm for (p = val; *p != '\0'; p++) 3910c2aa98e2SPeter Wemm { 391140266059SGregory Neil Shapiro # if _FFR_DOTTED_USERNAMES 391240266059SGregory Neil Shapiro if (*p == '/' || *p == ':') 3913*5b0945b5SGregory Neil Shapiro # else 3914c2aa98e2SPeter Wemm if (*p == '.' || *p == '/' || *p == ':') 3915*5b0945b5SGregory Neil Shapiro # endif 3916c2aa98e2SPeter Wemm { 3917c2aa98e2SPeter Wemm *p++ = '\0'; 3918c2aa98e2SPeter Wemm break; 3919c2aa98e2SPeter Wemm } 3920c2aa98e2SPeter Wemm } 3921c2aa98e2SPeter Wemm if (isascii(*val) && isdigit(*val)) 3922c2aa98e2SPeter Wemm { 3923c2aa98e2SPeter Wemm if (can_setuid) 3924c2aa98e2SPeter Wemm RunAsUid = atoi(val); 3925c2aa98e2SPeter Wemm } 3926c2aa98e2SPeter Wemm else 3927c2aa98e2SPeter Wemm { 3928c2aa98e2SPeter Wemm register struct passwd *pw; 3929c2aa98e2SPeter Wemm 3930c2aa98e2SPeter Wemm pw = sm_getpwnam(val); 3931c2aa98e2SPeter Wemm if (pw == NULL) 3932193538b7SGregory Neil Shapiro { 3933c2aa98e2SPeter Wemm syserr("readcf: option RunAsUser: unknown user %s", val); 3934193538b7SGregory Neil Shapiro break; 3935193538b7SGregory Neil Shapiro } 3936c2aa98e2SPeter Wemm else if (can_setuid) 3937c2aa98e2SPeter Wemm { 3938c2aa98e2SPeter Wemm if (*p == '\0') 3939c2aa98e2SPeter Wemm RunAsUserName = newstr(val); 3940c2aa98e2SPeter Wemm RunAsUid = pw->pw_uid; 3941c2aa98e2SPeter Wemm RunAsGid = pw->pw_gid; 3942c2aa98e2SPeter Wemm } 394340266059SGregory Neil Shapiro else if (EffGid == pw->pw_gid) 394440266059SGregory Neil Shapiro RunAsGid = pw->pw_gid; 394540266059SGregory Neil Shapiro else if (UseMSP && *p == '\0') 394640266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3947da7d7b9cSGregory Neil Shapiro "WARNING: RunAsUser for MSP ignored, check group ids (egid=%ld, want=%ld)\n", 3948da7d7b9cSGregory Neil Shapiro (long) EffGid, 3949da7d7b9cSGregory Neil Shapiro (long) pw->pw_gid); 3950c2aa98e2SPeter Wemm } 3951c2aa98e2SPeter Wemm # ifdef UID_MAX 3952c2aa98e2SPeter Wemm if (RunAsUid > UID_MAX) 3953c2aa98e2SPeter Wemm { 3954c2aa98e2SPeter Wemm syserr("readcf: option RunAsUser: uid value (%ld) > UID_MAX (%ld); ignored", 3955193538b7SGregory Neil Shapiro (long) RunAsUid, (long) UID_MAX); 3956193538b7SGregory Neil Shapiro break; 3957c2aa98e2SPeter Wemm } 395806f25ae9SGregory Neil Shapiro # endif /* UID_MAX */ 3959c2aa98e2SPeter Wemm if (*p != '\0') 3960c2aa98e2SPeter Wemm { 3961c2aa98e2SPeter Wemm if (isascii(*p) && isdigit(*p)) 3962c2aa98e2SPeter Wemm { 396340266059SGregory Neil Shapiro gid_t runasgid; 396440266059SGregory Neil Shapiro 396540266059SGregory Neil Shapiro runasgid = (gid_t) atoi(p); 396640266059SGregory Neil Shapiro if (can_setuid || EffGid == runasgid) 396740266059SGregory Neil Shapiro RunAsGid = runasgid; 396840266059SGregory Neil Shapiro else if (UseMSP) 396940266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, 397040266059SGregory Neil Shapiro SM_TIME_DEFAULT, 3971da7d7b9cSGregory Neil Shapiro "WARNING: RunAsUser for MSP ignored, check group ids (egid=%ld, want=%ld)\n", 3972da7d7b9cSGregory Neil Shapiro (long) EffGid, 3973da7d7b9cSGregory Neil Shapiro (long) runasgid); 3974c2aa98e2SPeter Wemm } 3975c2aa98e2SPeter Wemm else 3976c2aa98e2SPeter Wemm { 3977c2aa98e2SPeter Wemm register struct group *gr; 3978c2aa98e2SPeter Wemm 3979c2aa98e2SPeter Wemm gr = getgrnam(p); 3980c2aa98e2SPeter Wemm if (gr == NULL) 3981c2aa98e2SPeter Wemm syserr("readcf: option RunAsUser: unknown group %s", 3982c2aa98e2SPeter Wemm p); 398340266059SGregory Neil Shapiro else if (can_setuid || EffGid == gr->gr_gid) 3984c2aa98e2SPeter Wemm RunAsGid = gr->gr_gid; 398540266059SGregory Neil Shapiro else if (UseMSP) 398640266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, 398740266059SGregory Neil Shapiro SM_TIME_DEFAULT, 3988da7d7b9cSGregory Neil Shapiro "WARNING: RunAsUser for MSP ignored, check group ids (egid=%ld, want=%ld)\n", 3989da7d7b9cSGregory Neil Shapiro (long) EffGid, 3990da7d7b9cSGregory Neil Shapiro (long) gr->gr_gid); 3991c2aa98e2SPeter Wemm } 3992c2aa98e2SPeter Wemm } 3993c2aa98e2SPeter Wemm if (tTd(47, 5)) 399440266059SGregory Neil Shapiro sm_dprintf("readcf: RunAsUser = %d:%d\n", 399506f25ae9SGregory Neil Shapiro (int) RunAsUid, (int) RunAsGid); 3996c2aa98e2SPeter Wemm break; 3997c2aa98e2SPeter Wemm 3998c2aa98e2SPeter Wemm case O_DSN_RRT: 3999c2aa98e2SPeter Wemm RrtImpliesDsn = atobool(val); 4000c2aa98e2SPeter Wemm break; 4001c2aa98e2SPeter Wemm 4002c2aa98e2SPeter Wemm case O_PIDFILE: 400340266059SGregory Neil Shapiro PSTRSET(PidFile, val); 4004c2aa98e2SPeter Wemm break; 4005c2aa98e2SPeter Wemm 4006c2aa98e2SPeter Wemm case O_DONTBLAMESENDMAIL: 4007c2aa98e2SPeter Wemm p = val; 4008c2aa98e2SPeter Wemm for (;;) 4009c2aa98e2SPeter Wemm { 4010c2aa98e2SPeter Wemm register struct dbsval *dbs; 4011c2aa98e2SPeter Wemm extern struct dbsval DontBlameSendmailValues[]; 4012c2aa98e2SPeter Wemm 4013c2aa98e2SPeter Wemm while (isascii(*p) && (isspace(*p) || ispunct(*p))) 4014c2aa98e2SPeter Wemm p++; 4015c2aa98e2SPeter Wemm if (*p == '\0') 4016c2aa98e2SPeter Wemm break; 4017c2aa98e2SPeter Wemm val = p; 4018c2aa98e2SPeter Wemm while (isascii(*p) && isalnum(*p)) 4019c2aa98e2SPeter Wemm p++; 4020c2aa98e2SPeter Wemm if (*p != '\0') 4021c2aa98e2SPeter Wemm *p++ = '\0'; 4022c2aa98e2SPeter Wemm 4023c2aa98e2SPeter Wemm for (dbs = DontBlameSendmailValues; 4024c2aa98e2SPeter Wemm dbs->dbs_name != NULL; dbs++) 4025c2aa98e2SPeter Wemm { 402640266059SGregory Neil Shapiro if (sm_strcasecmp(val, dbs->dbs_name) == 0) 4027c2aa98e2SPeter Wemm break; 4028c2aa98e2SPeter Wemm } 4029c2aa98e2SPeter Wemm if (dbs->dbs_name == NULL) 4030c2aa98e2SPeter Wemm syserr("readcf: DontBlameSendmail option: %s unrecognized", val); 4031c2aa98e2SPeter Wemm else if (dbs->dbs_flag == DBS_SAFE) 403206f25ae9SGregory Neil Shapiro clrbitmap(DontBlameSendmail); 4033c2aa98e2SPeter Wemm else 403406f25ae9SGregory Neil Shapiro setbitn(dbs->dbs_flag, DontBlameSendmail); 4035c2aa98e2SPeter Wemm } 403640266059SGregory Neil Shapiro sticky = false; 4037c2aa98e2SPeter Wemm break; 4038c2aa98e2SPeter Wemm 4039c2aa98e2SPeter Wemm case O_DPI: 404040266059SGregory Neil Shapiro if (sm_strcasecmp(val, "loopback") == 0) 404140266059SGregory Neil Shapiro DontProbeInterfaces = DPI_SKIPLOOPBACK; 404240266059SGregory Neil Shapiro else if (atobool(val)) 404340266059SGregory Neil Shapiro DontProbeInterfaces = DPI_PROBENONE; 404440266059SGregory Neil Shapiro else 404540266059SGregory Neil Shapiro DontProbeInterfaces = DPI_PROBEALL; 4046c2aa98e2SPeter Wemm break; 4047c2aa98e2SPeter Wemm 4048c2aa98e2SPeter Wemm case O_MAXRCPT: 4049c2aa98e2SPeter Wemm MaxRcptPerMsg = atoi(val); 4050c2aa98e2SPeter Wemm break; 4051c2aa98e2SPeter Wemm 405240266059SGregory Neil Shapiro case O_RCPTTHROT: 405340266059SGregory Neil Shapiro BadRcptThrottle = atoi(val); 405440266059SGregory Neil Shapiro break; 405540266059SGregory Neil Shapiro 40569bd497b8SGregory Neil Shapiro #if _FFR_RCPTTHROTDELAY 40579bd497b8SGregory Neil Shapiro case O_RCPTTHROTDELAY: 40589bd497b8SGregory Neil Shapiro BadRcptThrottleDelay = atoi(val); 40599bd497b8SGregory Neil Shapiro break; 4060*5b0945b5SGregory Neil Shapiro #endif 40619bd497b8SGregory Neil Shapiro 4062c2aa98e2SPeter Wemm case O_DEADLETTER: 406340266059SGregory Neil Shapiro CANONIFY(val); 406440266059SGregory Neil Shapiro PSTRSET(DeadLetterDrop, val); 4065c2aa98e2SPeter Wemm break; 4066c2aa98e2SPeter Wemm 4067c2aa98e2SPeter Wemm #if _FFR_DONTLOCKFILESFORREAD_OPTION 4068c2aa98e2SPeter Wemm case O_DONTLOCK: 4069c2aa98e2SPeter Wemm DontLockReadFiles = atobool(val); 4070c2aa98e2SPeter Wemm break; 4071*5b0945b5SGregory Neil Shapiro #endif 4072c2aa98e2SPeter Wemm 4073c2aa98e2SPeter Wemm case O_MAXALIASRCSN: 4074c2aa98e2SPeter Wemm MaxAliasRecursion = atoi(val); 4075c2aa98e2SPeter Wemm break; 4076c2aa98e2SPeter Wemm 4077c2aa98e2SPeter Wemm case O_CNCTONLYTO: 4078c2aa98e2SPeter Wemm /* XXX should probably use gethostbyname */ 407906f25ae9SGregory Neil Shapiro #if NETINET || NETINET6 4080*5b0945b5SGregory Neil Shapiro i = 0; 4081*5b0945b5SGregory Neil Shapiro if ((subopt = strchr(val, '@')) != NULL) 4082*5b0945b5SGregory Neil Shapiro { 4083*5b0945b5SGregory Neil Shapiro *subopt = '\0'; 4084*5b0945b5SGregory Neil Shapiro i = (int) strtoul(val, NULL, 0); 4085*5b0945b5SGregory Neil Shapiro 4086*5b0945b5SGregory Neil Shapiro /* stricter checks? probably not useful. */ 4087*5b0945b5SGregory Neil Shapiro if (i > USHRT_MAX) 4088*5b0945b5SGregory Neil Shapiro { 4089*5b0945b5SGregory Neil Shapiro syserr("readcf: option ConnectOnlyTo: invalid port %s", 4090*5b0945b5SGregory Neil Shapiro val); 4091*5b0945b5SGregory Neil Shapiro break; 4092*5b0945b5SGregory Neil Shapiro } 4093*5b0945b5SGregory Neil Shapiro val = subopt + 1; 4094*5b0945b5SGregory Neil Shapiro } 409540266059SGregory Neil Shapiro ConnectOnlyTo.sa.sa_family = AF_UNSPEC; 409606f25ae9SGregory Neil Shapiro # if NETINET6 409740266059SGregory Neil Shapiro if (anynet_pton(AF_INET6, val, 40986f9c8e5bSGregory Neil Shapiro &ConnectOnlyTo.sin6.sin6_addr) == 1) 4099*5b0945b5SGregory Neil Shapiro { 410040266059SGregory Neil Shapiro ConnectOnlyTo.sa.sa_family = AF_INET6; 4101*5b0945b5SGregory Neil Shapiro if (i != 0) 4102*5b0945b5SGregory Neil Shapiro ConnectOnlyTo.sin6.sin6_port = htons(i); 4103*5b0945b5SGregory Neil Shapiro } 410406f25ae9SGregory Neil Shapiro else 410506f25ae9SGregory Neil Shapiro # endif /* NETINET6 */ 410640266059SGregory Neil Shapiro # if NETINET 410706f25ae9SGregory Neil Shapiro { 410806f25ae9SGregory Neil Shapiro ConnectOnlyTo.sin.sin_addr.s_addr = inet_addr(val); 410940266059SGregory Neil Shapiro if (ConnectOnlyTo.sin.sin_addr.s_addr != INADDR_NONE) 411040266059SGregory Neil Shapiro ConnectOnlyTo.sa.sa_family = AF_INET; 4111*5b0945b5SGregory Neil Shapiro if (i != 0) 4112*5b0945b5SGregory Neil Shapiro ConnectOnlyTo.sin.sin_port = htons(i); 411340266059SGregory Neil Shapiro } 411440266059SGregory Neil Shapiro 411540266059SGregory Neil Shapiro # endif /* NETINET */ 411640266059SGregory Neil Shapiro if (ConnectOnlyTo.sa.sa_family == AF_UNSPEC) 411740266059SGregory Neil Shapiro { 411840266059SGregory Neil Shapiro syserr("readcf: option ConnectOnlyTo: invalid IP address %s", 411940266059SGregory Neil Shapiro val); 412040266059SGregory Neil Shapiro break; 412106f25ae9SGregory Neil Shapiro } 412206f25ae9SGregory Neil Shapiro #endif /* NETINET || NETINET6 */ 4123c2aa98e2SPeter Wemm break; 4124c2aa98e2SPeter Wemm 4125065a643dSPeter Wemm case O_TRUSTUSER: 412640266059SGregory Neil Shapiro # if !HASFCHOWN && !defined(_FFR_DROP_TRUSTUSER_WARNING) 412740266059SGregory Neil Shapiro if (!UseMSP) 412840266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 412940266059SGregory Neil Shapiro "readcf: option TrustedUser may cause problems on systems\n which do not support fchown() if UseMSP is not set.\n"); 413040266059SGregory Neil Shapiro # endif /* !HASFCHOWN && !defined(_FFR_DROP_TRUSTUSER_WARNING) */ 4131c2aa98e2SPeter Wemm if (isascii(*val) && isdigit(*val)) 4132065a643dSPeter Wemm TrustedUid = atoi(val); 4133c2aa98e2SPeter Wemm else 4134c2aa98e2SPeter Wemm { 4135c2aa98e2SPeter Wemm register struct passwd *pw; 4136c2aa98e2SPeter Wemm 4137065a643dSPeter Wemm TrustedUid = 0; 4138c2aa98e2SPeter Wemm pw = sm_getpwnam(val); 4139c2aa98e2SPeter Wemm if (pw == NULL) 4140193538b7SGregory Neil Shapiro { 4141065a643dSPeter Wemm syserr("readcf: option TrustedUser: unknown user %s", val); 4142193538b7SGregory Neil Shapiro break; 4143193538b7SGregory Neil Shapiro } 4144c2aa98e2SPeter Wemm else 4145065a643dSPeter Wemm TrustedUid = pw->pw_uid; 4146c2aa98e2SPeter Wemm } 4147c2aa98e2SPeter Wemm 4148c2aa98e2SPeter Wemm # ifdef UID_MAX 4149065a643dSPeter Wemm if (TrustedUid > UID_MAX) 4150c2aa98e2SPeter Wemm { 4151065a643dSPeter Wemm syserr("readcf: option TrustedUser: uid value (%ld) > UID_MAX (%ld)", 4152193538b7SGregory Neil Shapiro (long) TrustedUid, (long) UID_MAX); 4153065a643dSPeter Wemm TrustedUid = 0; 4154c2aa98e2SPeter Wemm } 415506f25ae9SGregory Neil Shapiro # endif /* UID_MAX */ 4156c2aa98e2SPeter Wemm break; 4157c2aa98e2SPeter Wemm 4158065a643dSPeter Wemm case O_MAXMIMEHDRLEN: 4159065a643dSPeter Wemm p = strchr(val, '/'); 4160065a643dSPeter Wemm if (p != NULL) 4161065a643dSPeter Wemm *p++ = '\0'; 4162065a643dSPeter Wemm MaxMimeHeaderLength = atoi(val); 4163065a643dSPeter Wemm if (p != NULL && *p != '\0') 4164065a643dSPeter Wemm MaxMimeFieldLength = atoi(p); 4165065a643dSPeter Wemm else 4166065a643dSPeter Wemm MaxMimeFieldLength = MaxMimeHeaderLength / 2; 4167065a643dSPeter Wemm 4168a7ec597cSGregory Neil Shapiro if (MaxMimeHeaderLength <= 0) 4169065a643dSPeter Wemm MaxMimeHeaderLength = 0; 4170065a643dSPeter Wemm else if (MaxMimeHeaderLength < 128) 417140266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 417240266059SGregory Neil Shapiro "Warning: MaxMimeHeaderLength: header length limit set lower than 128\n"); 4173065a643dSPeter Wemm 4174a7ec597cSGregory Neil Shapiro if (MaxMimeFieldLength <= 0) 4175065a643dSPeter Wemm MaxMimeFieldLength = 0; 4176065a643dSPeter Wemm else if (MaxMimeFieldLength < 40) 417740266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 417840266059SGregory Neil Shapiro "Warning: MaxMimeHeaderLength: field length limit set lower than 40\n"); 4179d0cef73dSGregory Neil Shapiro 4180d0cef73dSGregory Neil Shapiro /* 4181d0cef73dSGregory Neil Shapiro ** Headers field values now include leading space, so let's 4182d0cef73dSGregory Neil Shapiro ** adjust the values to be "backward compatible". 4183d0cef73dSGregory Neil Shapiro */ 4184d0cef73dSGregory Neil Shapiro 4185d0cef73dSGregory Neil Shapiro if (MaxMimeHeaderLength > 0) 4186d0cef73dSGregory Neil Shapiro MaxMimeHeaderLength++; 4187d0cef73dSGregory Neil Shapiro if (MaxMimeFieldLength > 0) 4188d0cef73dSGregory Neil Shapiro MaxMimeFieldLength++; 4189065a643dSPeter Wemm break; 4190065a643dSPeter Wemm 4191065a643dSPeter Wemm case O_CONTROLSOCKET: 419240266059SGregory Neil Shapiro PSTRSET(ControlSocketName, val); 4193065a643dSPeter Wemm break; 4194065a643dSPeter Wemm 41952e43090eSPeter Wemm case O_MAXHDRSLEN: 41962e43090eSPeter Wemm MaxHeadersLength = atoi(val); 419725bab6e9SPeter Wemm 41982e43090eSPeter Wemm if (MaxHeadersLength > 0 && 41992e43090eSPeter Wemm MaxHeadersLength < (MAXHDRSLEN / 2)) 420040266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 420140266059SGregory Neil Shapiro "Warning: MaxHeadersLength: headers length limit set lower than %d\n", 420240266059SGregory Neil Shapiro (MAXHDRSLEN / 2)); 420325bab6e9SPeter Wemm break; 420406f25ae9SGregory Neil Shapiro 420506f25ae9SGregory Neil Shapiro case O_PROCTITLEPREFIX: 420640266059SGregory Neil Shapiro PSTRSET(ProcTitlePrefix, val); 420706f25ae9SGregory Neil Shapiro break; 420806f25ae9SGregory Neil Shapiro 420906f25ae9SGregory Neil Shapiro #if SASL 421006f25ae9SGregory Neil Shapiro case O_SASLINFO: 421106f25ae9SGregory Neil Shapiro # if _FFR_ALLOW_SASLINFO 421206f25ae9SGregory Neil Shapiro /* 421340266059SGregory Neil Shapiro ** Allow users to select their own authinfo file 421440266059SGregory Neil Shapiro ** under certain circumstances, otherwise just ignore 421540266059SGregory Neil Shapiro ** the option. If the option isn't ignored, several 421640266059SGregory Neil Shapiro ** commands don't work very well, e.g., mailq. 421706f25ae9SGregory Neil Shapiro ** However, this is not a "perfect" solution. 421806f25ae9SGregory Neil Shapiro ** If mail is queued, the authentication info 421906f25ae9SGregory Neil Shapiro ** will not be used in subsequent delivery attempts. 422006f25ae9SGregory Neil Shapiro ** If we really want to support this, then it has 422106f25ae9SGregory Neil Shapiro ** to be stored in the queue file. 422206f25ae9SGregory Neil Shapiro */ 422306f25ae9SGregory Neil Shapiro if (!bitset(SUBMIT_MSA, SubmitMode) && RealUid != 0 && 422406f25ae9SGregory Neil Shapiro RunAsUid != RealUid) 422506f25ae9SGregory Neil Shapiro break; 422606f25ae9SGregory Neil Shapiro # endif /* _FFR_ALLOW_SASLINFO */ 422740266059SGregory Neil Shapiro PSTRSET(SASLInfo, val); 422806f25ae9SGregory Neil Shapiro break; 422906f25ae9SGregory Neil Shapiro 423006f25ae9SGregory Neil Shapiro case O_SASLMECH: 423106f25ae9SGregory Neil Shapiro if (AuthMechanisms != NULL) 423240266059SGregory Neil Shapiro sm_free(AuthMechanisms); /* XXX */ 423306f25ae9SGregory Neil Shapiro if (*val != '\0') 423406f25ae9SGregory Neil Shapiro AuthMechanisms = newstr(val); 423506f25ae9SGregory Neil Shapiro else 423606f25ae9SGregory Neil Shapiro AuthMechanisms = NULL; 423706f25ae9SGregory Neil Shapiro break; 423806f25ae9SGregory Neil Shapiro 4239e92d3f3fSGregory Neil Shapiro case O_SASLREALM: 4240e92d3f3fSGregory Neil Shapiro if (AuthRealm != NULL) 4241e92d3f3fSGregory Neil Shapiro sm_free(AuthRealm); 4242e92d3f3fSGregory Neil Shapiro if (*val != '\0') 4243e92d3f3fSGregory Neil Shapiro AuthRealm = newstr(val); 4244e92d3f3fSGregory Neil Shapiro else 4245e92d3f3fSGregory Neil Shapiro AuthRealm = NULL; 4246e92d3f3fSGregory Neil Shapiro break; 4247e92d3f3fSGregory Neil Shapiro 424806f25ae9SGregory Neil Shapiro case O_SASLOPTS: 424906f25ae9SGregory Neil Shapiro while (val != NULL && *val != '\0') 425006f25ae9SGregory Neil Shapiro { 425106f25ae9SGregory Neil Shapiro switch (*val) 425206f25ae9SGregory Neil Shapiro { 425306f25ae9SGregory Neil Shapiro case 'A': 425406f25ae9SGregory Neil Shapiro SASLOpts |= SASL_AUTH_AUTH; 425506f25ae9SGregory Neil Shapiro break; 425613bd1963SGregory Neil Shapiro 425706f25ae9SGregory Neil Shapiro case 'a': 425806f25ae9SGregory Neil Shapiro SASLOpts |= SASL_SEC_NOACTIVE; 425906f25ae9SGregory Neil Shapiro break; 426013bd1963SGregory Neil Shapiro 426106f25ae9SGregory Neil Shapiro case 'c': 426206f25ae9SGregory Neil Shapiro SASLOpts |= SASL_SEC_PASS_CREDENTIALS; 426306f25ae9SGregory Neil Shapiro break; 426413bd1963SGregory Neil Shapiro 426506f25ae9SGregory Neil Shapiro case 'd': 426606f25ae9SGregory Neil Shapiro SASLOpts |= SASL_SEC_NODICTIONARY; 426706f25ae9SGregory Neil Shapiro break; 426813bd1963SGregory Neil Shapiro 426906f25ae9SGregory Neil Shapiro case 'f': 427006f25ae9SGregory Neil Shapiro SASLOpts |= SASL_SEC_FORWARD_SECRECY; 427106f25ae9SGregory Neil Shapiro break; 427213bd1963SGregory Neil Shapiro 427394c01205SGregory Neil Shapiro # if SASL >= 20101 427494c01205SGregory Neil Shapiro case 'm': 427594c01205SGregory Neil Shapiro SASLOpts |= SASL_SEC_MUTUAL_AUTH; 427694c01205SGregory Neil Shapiro break; 427794c01205SGregory Neil Shapiro # endif /* SASL >= 20101 */ 427813bd1963SGregory Neil Shapiro 427906f25ae9SGregory Neil Shapiro case 'p': 428006f25ae9SGregory Neil Shapiro SASLOpts |= SASL_SEC_NOPLAINTEXT; 428106f25ae9SGregory Neil Shapiro break; 428213bd1963SGregory Neil Shapiro 428306f25ae9SGregory Neil Shapiro case 'y': 428406f25ae9SGregory Neil Shapiro SASLOpts |= SASL_SEC_NOANONYMOUS; 428506f25ae9SGregory Neil Shapiro break; 428613bd1963SGregory Neil Shapiro 428740266059SGregory Neil Shapiro case ' ': /* ignore */ 428840266059SGregory Neil Shapiro case '\t': /* ignore */ 428940266059SGregory Neil Shapiro case ',': /* ignore */ 429040266059SGregory Neil Shapiro break; 429113bd1963SGregory Neil Shapiro 429206f25ae9SGregory Neil Shapiro default: 429340266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 429440266059SGregory Neil Shapiro "Warning: Option: %s unknown parameter '%c'\n", 429540266059SGregory Neil Shapiro OPTNAME, 429640266059SGregory Neil Shapiro (isascii(*val) && 429740266059SGregory Neil Shapiro isprint(*val)) 429840266059SGregory Neil Shapiro ? *val : '?'); 429940266059SGregory Neil Shapiro break; 430040266059SGregory Neil Shapiro } 430140266059SGregory Neil Shapiro ++val; 430240266059SGregory Neil Shapiro val = strpbrk(val, ", \t"); 430340266059SGregory Neil Shapiro if (val != NULL) 430440266059SGregory Neil Shapiro ++val; 430540266059SGregory Neil Shapiro } 430640266059SGregory Neil Shapiro break; 430713bd1963SGregory Neil Shapiro 430840266059SGregory Neil Shapiro case O_SASLBITS: 430940266059SGregory Neil Shapiro MaxSLBits = atoi(val); 431040266059SGregory Neil Shapiro break; 431140266059SGregory Neil Shapiro 431240266059SGregory Neil Shapiro #else /* SASL */ 431340266059SGregory Neil Shapiro case O_SASLINFO: 431440266059SGregory Neil Shapiro case O_SASLMECH: 4315e92d3f3fSGregory Neil Shapiro case O_SASLREALM: 431640266059SGregory Neil Shapiro case O_SASLOPTS: 431740266059SGregory Neil Shapiro case O_SASLBITS: 431840266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 431940266059SGregory Neil Shapiro "Warning: Option: %s requires SASL support (-DSASL)\n", 432040266059SGregory Neil Shapiro OPTNAME); 432140266059SGregory Neil Shapiro break; 432240266059SGregory Neil Shapiro #endif /* SASL */ 432340266059SGregory Neil Shapiro 432440266059SGregory Neil Shapiro #if STARTTLS 4325*5b0945b5SGregory Neil Shapiro case O_TLSFB2CLEAR: 4326*5b0945b5SGregory Neil Shapiro TLSFallbacktoClear = atobool(val); 4327*5b0945b5SGregory Neil Shapiro break; 432840266059SGregory Neil Shapiro case O_SRVCERTFILE: 432913bd1963SGregory Neil Shapiro SET_STRING_EXP(SrvCertFile); 433040266059SGregory Neil Shapiro case O_SRVKEYFILE: 433113bd1963SGregory Neil Shapiro SET_STRING_EXP(SrvKeyFile); 433240266059SGregory Neil Shapiro case O_CLTCERTFILE: 433313bd1963SGregory Neil Shapiro SET_STRING_EXP(CltCertFile); 433440266059SGregory Neil Shapiro case O_CLTKEYFILE: 433513bd1963SGregory Neil Shapiro SET_STRING_EXP(CltKeyFile); 433640266059SGregory Neil Shapiro case O_CACERTFILE: 433713bd1963SGregory Neil Shapiro SET_STRING_EXP(CACertFile); 433840266059SGregory Neil Shapiro case O_CACERTPATH: 433913bd1963SGregory Neil Shapiro SET_STRING_EXP(CACertPath); 4340*5b0945b5SGregory Neil Shapiro #if _FFR_CLIENTCA 4341*5b0945b5SGregory Neil Shapiro case O_CLTCACERTFILE: 4342*5b0945b5SGregory Neil Shapiro SET_STRING_EXP(CltCACertFile); 4343*5b0945b5SGregory Neil Shapiro case O_CLTCACERTPATH: 4344*5b0945b5SGregory Neil Shapiro SET_STRING_EXP(CltCACertPath); 4345*5b0945b5SGregory Neil Shapiro #endif 434640266059SGregory Neil Shapiro case O_DHPARAMS: 434740266059SGregory Neil Shapiro SET_STRING_EXP(DHParams); 434840266059SGregory Neil Shapiro case O_CIPHERLIST: 434940266059SGregory Neil Shapiro SET_STRING_EXP(CipherList); 4350da7d7b9cSGregory Neil Shapiro case O_DIG_ALG: 4351da7d7b9cSGregory Neil Shapiro SET_STRING_EXP(CertFingerprintAlgorithm); 4352*5b0945b5SGregory Neil Shapiro case O_SSLENGINEPATH: 4353*5b0945b5SGregory Neil Shapiro SET_STRING_EXP(SSLEnginePath); 4354*5b0945b5SGregory Neil Shapiro case O_SSLENGINE: 4355*5b0945b5SGregory Neil Shapiro newval = sm_pstrdup_x(val); 4356*5b0945b5SGregory Neil Shapiro if (SSLEngine != NULL) 4357*5b0945b5SGregory Neil Shapiro sm_free(SSLEngine); 4358*5b0945b5SGregory Neil Shapiro SSLEngine = newval; 4359*5b0945b5SGregory Neil Shapiro 4360*5b0945b5SGregory Neil Shapiro /* 4361*5b0945b5SGregory Neil Shapiro ** Which engines need to be initialized before fork()? 4362*5b0945b5SGregory Neil Shapiro ** XXX hack, should be an option? 4363*5b0945b5SGregory Neil Shapiro */ 4364*5b0945b5SGregory Neil Shapiro 4365*5b0945b5SGregory Neil Shapiro if (strcmp(SSLEngine, "chil") == 0) 4366*5b0945b5SGregory Neil Shapiro SSLEngineprefork = true; 4367*5b0945b5SGregory Neil Shapiro break; 43689bd497b8SGregory Neil Shapiro case O_SRV_SSL_OPTIONS: 43699bd497b8SGregory Neil Shapiro pssloptions = &Srv_SSL_Options; 43709bd497b8SGregory Neil Shapiro case O_CLT_SSL_OPTIONS: 43719bd497b8SGregory Neil Shapiro if (pssloptions == NULL) 43729bd497b8SGregory Neil Shapiro pssloptions = &Clt_SSL_Options; 4373da7d7b9cSGregory Neil Shapiro (void) readssloptions(o->o_name, val, pssloptions, '\0'); 4374da7d7b9cSGregory Neil Shapiro if (tTd(37, 8)) 4375da7d7b9cSGregory Neil Shapiro sm_dprintf("ssloptions=%#lx\n", *pssloptions); 43769bd497b8SGregory Neil Shapiro 43779bd497b8SGregory Neil Shapiro pssloptions = NULL; 43789bd497b8SGregory Neil Shapiro break; 43799bd497b8SGregory Neil Shapiro 4380e92d3f3fSGregory Neil Shapiro case O_CRLFILE: 4381e92d3f3fSGregory Neil Shapiro SET_STRING_EXP(CRLFile); 4382e92d3f3fSGregory Neil Shapiro break; 4383e92d3f3fSGregory Neil Shapiro 4384e92d3f3fSGregory Neil Shapiro case O_CRLPATH: 4385e92d3f3fSGregory Neil Shapiro SET_STRING_EXP(CRLPath); 4386e92d3f3fSGregory Neil Shapiro break; 438740266059SGregory Neil Shapiro 438840266059SGregory Neil Shapiro /* 438940266059SGregory Neil Shapiro ** XXX How about options per daemon/client instead of globally? 439040266059SGregory Neil Shapiro ** This doesn't work well for some options, e.g., no server cert, 439140266059SGregory Neil Shapiro ** but fine for others. 439240266059SGregory Neil Shapiro ** 439340266059SGregory Neil Shapiro ** XXX Some people may want different certs per server. 439440266059SGregory Neil Shapiro ** 439540266059SGregory Neil Shapiro ** See also srvfeatures() 439640266059SGregory Neil Shapiro */ 439740266059SGregory Neil Shapiro 439840266059SGregory Neil Shapiro case O_TLS_SRV_OPTS: 439940266059SGregory Neil Shapiro while (val != NULL && *val != '\0') 440040266059SGregory Neil Shapiro { 440140266059SGregory Neil Shapiro switch (*val) 440240266059SGregory Neil Shapiro { 440340266059SGregory Neil Shapiro case 'V': 440440266059SGregory Neil Shapiro TLS_Srv_Opts |= TLS_I_NO_VRFY; 440540266059SGregory Neil Shapiro break; 440640266059SGregory Neil Shapiro /* 440740266059SGregory Neil Shapiro ** Server without a cert? That works only if 440840266059SGregory Neil Shapiro ** AnonDH is enabled as cipher, which is not in the 440940266059SGregory Neil Shapiro ** default list. Hence the CipherList option must 441040266059SGregory Neil Shapiro ** be available. Moreover: which clients support this 441140266059SGregory Neil Shapiro ** besides sendmail with this setting? 441240266059SGregory Neil Shapiro */ 441340266059SGregory Neil Shapiro 441440266059SGregory Neil Shapiro case 'C': 441540266059SGregory Neil Shapiro TLS_Srv_Opts &= ~TLS_I_SRV_CERT; 441640266059SGregory Neil Shapiro break; 441740266059SGregory Neil Shapiro case ' ': /* ignore */ 441840266059SGregory Neil Shapiro case '\t': /* ignore */ 441940266059SGregory Neil Shapiro case ',': /* ignore */ 442040266059SGregory Neil Shapiro break; 442140266059SGregory Neil Shapiro default: 442240266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 442340266059SGregory Neil Shapiro "Warning: Option: %s unknown parameter '%c'\n", 442440266059SGregory Neil Shapiro OPTNAME, 442540266059SGregory Neil Shapiro (isascii(*val) && 442640266059SGregory Neil Shapiro isprint(*val)) 442740266059SGregory Neil Shapiro ? *val : '?'); 442806f25ae9SGregory Neil Shapiro break; 442906f25ae9SGregory Neil Shapiro } 443006f25ae9SGregory Neil Shapiro ++val; 443106f25ae9SGregory Neil Shapiro val = strpbrk(val, ", \t"); 443206f25ae9SGregory Neil Shapiro if (val != NULL) 443306f25ae9SGregory Neil Shapiro ++val; 443406f25ae9SGregory Neil Shapiro } 443506f25ae9SGregory Neil Shapiro break; 443606f25ae9SGregory Neil Shapiro 443706f25ae9SGregory Neil Shapiro case O_RANDFILE: 443840266059SGregory Neil Shapiro PSTRSET(RandFile, val); 443906f25ae9SGregory Neil Shapiro break; 444006f25ae9SGregory Neil Shapiro 444106f25ae9SGregory Neil Shapiro #else /* STARTTLS */ 444206f25ae9SGregory Neil Shapiro case O_SRVCERTFILE: 444306f25ae9SGregory Neil Shapiro case O_SRVKEYFILE: 444406f25ae9SGregory Neil Shapiro case O_CLTCERTFILE: 444506f25ae9SGregory Neil Shapiro case O_CLTKEYFILE: 444606f25ae9SGregory Neil Shapiro case O_CACERTFILE: 444706f25ae9SGregory Neil Shapiro case O_CACERTPATH: 4448*5b0945b5SGregory Neil Shapiro #if _FFR_CLIENTCA 4449*5b0945b5SGregory Neil Shapiro case O_CLTCACERTFILE: 4450*5b0945b5SGregory Neil Shapiro case O_CLTCACERTPATH: 4451*5b0945b5SGregory Neil Shapiro #endif 445206f25ae9SGregory Neil Shapiro case O_DHPARAMS: 4453da7d7b9cSGregory Neil Shapiro case O_SRV_SSL_OPTIONS: 4454da7d7b9cSGregory Neil Shapiro case O_CLT_SSL_OPTIONS: 445506f25ae9SGregory Neil Shapiro case O_CIPHERLIST: 4456*5b0945b5SGregory Neil Shapiro case O_DIG_ALG: 4457e92d3f3fSGregory Neil Shapiro case O_CRLFILE: 4458e92d3f3fSGregory Neil Shapiro case O_CRLPATH: 445906f25ae9SGregory Neil Shapiro case O_RANDFILE: 446040266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 446140266059SGregory Neil Shapiro "Warning: Option: %s requires TLS support\n", 446240266059SGregory Neil Shapiro OPTNAME); 446306f25ae9SGregory Neil Shapiro break; 446406f25ae9SGregory Neil Shapiro 446506f25ae9SGregory Neil Shapiro #endif /* STARTTLS */ 4466552d4955SGregory Neil Shapiro #if STARTTLS && _FFR_FIPSMODE 4467552d4955SGregory Neil Shapiro case O_FIPSMODE: 4468552d4955SGregory Neil Shapiro FipsMode = atobool(val); 4469552d4955SGregory Neil Shapiro break; 4470*5b0945b5SGregory Neil Shapiro #endif 447106f25ae9SGregory Neil Shapiro 447206f25ae9SGregory Neil Shapiro case O_CLIENTPORT: 447306f25ae9SGregory Neil Shapiro setclientoptions(val); 447406f25ae9SGregory Neil Shapiro break; 447506f25ae9SGregory Neil Shapiro 447606f25ae9SGregory Neil Shapiro case O_DF_BUFSIZE: 447706f25ae9SGregory Neil Shapiro DataFileBufferSize = atoi(val); 447806f25ae9SGregory Neil Shapiro break; 447906f25ae9SGregory Neil Shapiro 448006f25ae9SGregory Neil Shapiro case O_XF_BUFSIZE: 448106f25ae9SGregory Neil Shapiro XscriptFileBufferSize = atoi(val); 448206f25ae9SGregory Neil Shapiro break; 448306f25ae9SGregory Neil Shapiro 448406f25ae9SGregory Neil Shapiro case O_LDAPDEFAULTSPEC: 448540266059SGregory Neil Shapiro #if LDAPMAP 448606f25ae9SGregory Neil Shapiro ldapmap_set_defaults(val); 448706f25ae9SGregory Neil Shapiro #else /* LDAPMAP */ 448840266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 448940266059SGregory Neil Shapiro "Warning: Option: %s requires LDAP support (-DLDAPMAP)\n", 449040266059SGregory Neil Shapiro OPTNAME); 449106f25ae9SGregory Neil Shapiro #endif /* LDAPMAP */ 449206f25ae9SGregory Neil Shapiro break; 449306f25ae9SGregory Neil Shapiro 449406f25ae9SGregory Neil Shapiro case O_INPUTMILTER: 449540266059SGregory Neil Shapiro #if MILTER 449606f25ae9SGregory Neil Shapiro InputFilterList = newstr(val); 449740266059SGregory Neil Shapiro #else /* MILTER */ 449840266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 449940266059SGregory Neil Shapiro "Warning: Option: %s requires Milter support (-DMILTER)\n", 450040266059SGregory Neil Shapiro OPTNAME); 450140266059SGregory Neil Shapiro #endif /* MILTER */ 450206f25ae9SGregory Neil Shapiro break; 450306f25ae9SGregory Neil Shapiro 450406f25ae9SGregory Neil Shapiro case O_MILTER: 450540266059SGregory Neil Shapiro #if MILTER 450606f25ae9SGregory Neil Shapiro milter_set_option(subopt, val, sticky); 450740266059SGregory Neil Shapiro #else /* MILTER */ 450840266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 450940266059SGregory Neil Shapiro "Warning: Option: %s requires Milter support (-DMILTER)\n", 451040266059SGregory Neil Shapiro OPTNAME); 451140266059SGregory Neil Shapiro #endif /* MILTER */ 451206f25ae9SGregory Neil Shapiro break; 451306f25ae9SGregory Neil Shapiro 451406f25ae9SGregory Neil Shapiro case O_QUEUE_FILE_MODE: /* queue file mode */ 451506f25ae9SGregory Neil Shapiro QueueFileMode = atooct(val) & 0777; 451606f25ae9SGregory Neil Shapiro break; 451740266059SGregory Neil Shapiro 451840266059SGregory Neil Shapiro case O_DLVR_MIN: /* deliver by minimum time */ 451940266059SGregory Neil Shapiro DeliverByMin = convtime(val, 's'); 452040266059SGregory Neil Shapiro break; 452140266059SGregory Neil Shapiro 452240266059SGregory Neil Shapiro /* modifiers {daemon_flags} for direct submissions */ 452340266059SGregory Neil Shapiro case O_DIRECTSUBMODIFIERS: 452440266059SGregory Neil Shapiro { 452540266059SGregory Neil Shapiro BITMAP256 m; /* ignored */ 452640266059SGregory Neil Shapiro extern ENVELOPE BlankEnvelope; 452740266059SGregory Neil Shapiro 452840266059SGregory Neil Shapiro macdefine(&BlankEnvelope.e_macro, A_PERM, 452940266059SGregory Neil Shapiro macid("{daemon_flags}"), 453040266059SGregory Neil Shapiro getmodifiers(val, m)); 453140266059SGregory Neil Shapiro } 453240266059SGregory Neil Shapiro break; 453340266059SGregory Neil Shapiro 453440266059SGregory Neil Shapiro case O_FASTSPLIT: 453540266059SGregory Neil Shapiro FastSplit = atoi(val); 453640266059SGregory Neil Shapiro break; 453740266059SGregory Neil Shapiro 453840266059SGregory Neil Shapiro case O_MBDB: 453940266059SGregory Neil Shapiro Mbdb = newstr(val); 454040266059SGregory Neil Shapiro break; 454140266059SGregory Neil Shapiro 454240266059SGregory Neil Shapiro case O_MSQ: 454340266059SGregory Neil Shapiro UseMSP = atobool(val); 454440266059SGregory Neil Shapiro break; 454540266059SGregory Neil Shapiro 454640266059SGregory Neil Shapiro case O_SOFTBOUNCE: 454740266059SGregory Neil Shapiro SoftBounce = atobool(val); 454840266059SGregory Neil Shapiro break; 454925bab6e9SPeter Wemm 455013bd1963SGregory Neil Shapiro case O_REJECTLOGINTERVAL: /* time btwn log msgs while refusing */ 455113bd1963SGregory Neil Shapiro RejectLogInterval = convtime(val, 'h'); 455213bd1963SGregory Neil Shapiro break; 455313bd1963SGregory Neil Shapiro 455413bd1963SGregory Neil Shapiro case O_REQUIRES_DIR_FSYNC: 455513bd1963SGregory Neil Shapiro #if REQUIRES_DIR_FSYNC 455613bd1963SGregory Neil Shapiro RequiresDirfsync = atobool(val); 4557*5b0945b5SGregory Neil Shapiro #else 455813bd1963SGregory Neil Shapiro /* silently ignored... required for cf file option */ 4559*5b0945b5SGregory Neil Shapiro #endif 456013bd1963SGregory Neil Shapiro break; 4561e92d3f3fSGregory Neil Shapiro 4562e92d3f3fSGregory Neil Shapiro case O_CONNECTION_RATE_WINDOW_SIZE: 4563e92d3f3fSGregory Neil Shapiro ConnectionRateWindowSize = convtime(val, 's'); 4564e92d3f3fSGregory Neil Shapiro break; 4565e92d3f3fSGregory Neil Shapiro 4566e92d3f3fSGregory Neil Shapiro case O_FALLBACKSMARTHOST: /* fallback smart host */ 4567e92d3f3fSGregory Neil Shapiro if (val[0] != '\0') 4568e92d3f3fSGregory Neil Shapiro FallbackSmartHost = newstr(val); 4569e92d3f3fSGregory Neil Shapiro break; 4570e92d3f3fSGregory Neil Shapiro 4571e92d3f3fSGregory Neil Shapiro case O_HELONAME: 4572e92d3f3fSGregory Neil Shapiro HeloName = newstr(val); 4573e92d3f3fSGregory Neil Shapiro break; 4574d0cef73dSGregory Neil Shapiro 45754e4196cbSGregory Neil Shapiro #if _FFR_MEMSTAT 45764e4196cbSGregory Neil Shapiro case O_REFUSELOWMEM: 45774e4196cbSGregory Neil Shapiro RefuseLowMem = atoi(val); 45784e4196cbSGregory Neil Shapiro break; 45794e4196cbSGregory Neil Shapiro case O_QUEUELOWMEM: 45804e4196cbSGregory Neil Shapiro QueueLowMem = atoi(val); 45814e4196cbSGregory Neil Shapiro break; 45824e4196cbSGregory Neil Shapiro case O_MEMRESOURCE: 45834e4196cbSGregory Neil Shapiro MemoryResource = newstr(val); 45844e4196cbSGregory Neil Shapiro break; 45854e4196cbSGregory Neil Shapiro #endif /* _FFR_MEMSTAT */ 45864e4196cbSGregory Neil Shapiro 45874e4196cbSGregory Neil Shapiro case O_MAXNOOPCOMMANDS: 45884e4196cbSGregory Neil Shapiro MaxNOOPCommands = atoi(val); 45894e4196cbSGregory Neil Shapiro break; 45904e4196cbSGregory Neil Shapiro 45914e4196cbSGregory Neil Shapiro #if _FFR_MSG_ACCEPT 45924e4196cbSGregory Neil Shapiro case O_MSG_ACCEPT: 45934e4196cbSGregory Neil Shapiro MessageAccept = newstr(val); 45944e4196cbSGregory Neil Shapiro break; 4595*5b0945b5SGregory Neil Shapiro #endif 45964e4196cbSGregory Neil Shapiro 45974e4196cbSGregory Neil Shapiro #if _FFR_QUEUE_RUN_PARANOIA 45984e4196cbSGregory Neil Shapiro case O_CHK_Q_RUNNERS: 45994e4196cbSGregory Neil Shapiro CheckQueueRunners = atoi(val); 46004e4196cbSGregory Neil Shapiro break; 4601*5b0945b5SGregory Neil Shapiro #endif 460213bd1963SGregory Neil Shapiro 4603d0cef73dSGregory Neil Shapiro #if _FFR_EIGHT_BIT_ADDR_OK 4604d0cef73dSGregory Neil Shapiro case O_EIGHT_BIT_ADDR_OK: 4605d0cef73dSGregory Neil Shapiro EightBitAddrOK = atobool(val); 4606d0cef73dSGregory Neil Shapiro break; 4607*5b0945b5SGregory Neil Shapiro #endif 4608d0cef73dSGregory Neil Shapiro 4609ffb83623SGregory Neil Shapiro #if _FFR_ADDR_TYPE_MODES 4610ffb83623SGregory Neil Shapiro case O_ADDR_TYPE_MODES: 4611ffb83623SGregory Neil Shapiro AddrTypeModes = atobool(val); 4612ffb83623SGregory Neil Shapiro break; 4613*5b0945b5SGregory Neil Shapiro #endif 4614ffb83623SGregory Neil Shapiro 4615e3793f76SGregory Neil Shapiro #if _FFR_BADRCPT_SHUTDOWN 4616e3793f76SGregory Neil Shapiro case O_RCPTSHUTD: 4617e3793f76SGregory Neil Shapiro BadRcptShutdown = atoi(val); 4618e3793f76SGregory Neil Shapiro break; 4619e3793f76SGregory Neil Shapiro 4620e3793f76SGregory Neil Shapiro case O_RCPTSHUTDG: 4621e3793f76SGregory Neil Shapiro BadRcptShutdownGood = atoi(val); 4622e3793f76SGregory Neil Shapiro break; 4623e3793f76SGregory Neil Shapiro #endif /* _FFR_BADRCPT_SHUTDOWN */ 4624e3793f76SGregory Neil Shapiro 4625552d4955SGregory Neil Shapiro #if _FFR_REJECT_NUL_BYTE 4626552d4955SGregory Neil Shapiro case O_REJECTNUL: 4627552d4955SGregory Neil Shapiro RejectNUL = atobool(val); 4628552d4955SGregory Neil Shapiro break; 4629*5b0945b5SGregory Neil Shapiro #endif 4630552d4955SGregory Neil Shapiro 4631da7d7b9cSGregory Neil Shapiro #if _FFR_BOUNCE_QUEUE 4632da7d7b9cSGregory Neil Shapiro case O_BOUNCEQUEUE: 4633da7d7b9cSGregory Neil Shapiro bouncequeue = newstr(val); 4634da7d7b9cSGregory Neil Shapiro break; 4635*5b0945b5SGregory Neil Shapiro #endif 4636da7d7b9cSGregory Neil Shapiro 4637da7d7b9cSGregory Neil Shapiro #if _FFR_ADD_BCC 4638da7d7b9cSGregory Neil Shapiro case O_ADDBCC: 4639da7d7b9cSGregory Neil Shapiro AddBcc = atobool(val); 4640da7d7b9cSGregory Neil Shapiro break; 4641da7d7b9cSGregory Neil Shapiro #endif 4642da7d7b9cSGregory Neil Shapiro case O_USECOMPRESSEDIPV6ADDRESSES: 4643da7d7b9cSGregory Neil Shapiro UseCompressedIPv6Addresses = atobool(val); 4644da7d7b9cSGregory Neil Shapiro break; 4645da7d7b9cSGregory Neil Shapiro 4646*5b0945b5SGregory Neil Shapiro #if DNSSEC_TEST 4647*5b0945b5SGregory Neil Shapiro case O_NSPORTIP: 4648*5b0945b5SGregory Neil Shapiro nsportip(val); 4649*5b0945b5SGregory Neil Shapiro break; 4650*5b0945b5SGregory Neil Shapiro case O_NSSRCHLIST: 4651*5b0945b5SGregory Neil Shapiro NameSearchList = sm_strdup(val); 4652*5b0945b5SGregory Neil Shapiro break; 4653*5b0945b5SGregory Neil Shapiro #endif 4654*5b0945b5SGregory Neil Shapiro 4655*5b0945b5SGregory Neil Shapiro #if DANE 4656*5b0945b5SGregory Neil Shapiro case O_DANE: 4657*5b0945b5SGregory Neil Shapiro if (sm_strcasecmp(val, "always") == 0) 4658*5b0945b5SGregory Neil Shapiro Dane = DANE_ALWAYS; 4659*5b0945b5SGregory Neil Shapiro else 4660*5b0945b5SGregory Neil Shapiro Dane = atobool(val) ? DANE_SECURE : DANE_NEVER; 4661*5b0945b5SGregory Neil Shapiro break; 4662*5b0945b5SGregory Neil Shapiro #endif 4663*5b0945b5SGregory Neil Shapiro 4664*5b0945b5SGregory Neil Shapiro #if _FFR_BLANKENV_MACV 4665*5b0945b5SGregory Neil Shapiro case O_HACKS: 4666*5b0945b5SGregory Neil Shapiro Hacks = (int) strtol(val, NULL, 0); 4667*5b0945b5SGregory Neil Shapiro break; 4668*5b0945b5SGregory Neil Shapiro #endif 4669*5b0945b5SGregory Neil Shapiro 4670*5b0945b5SGregory Neil Shapiro #if _FFR_KEEPBCC 4671*5b0945b5SGregory Neil Shapiro case O_KEEPBCC: 4672*5b0945b5SGregory Neil Shapiro KeepBcc = atobool(val); 4673*5b0945b5SGregory Neil Shapiro break; 4674*5b0945b5SGregory Neil Shapiro #endif 4675*5b0945b5SGregory Neil Shapiro 4676*5b0945b5SGregory Neil Shapiro # if _FFR_TLS_ALTNAMES 4677*5b0945b5SGregory Neil Shapiro case O_CHECKALTNAMES: 4678*5b0945b5SGregory Neil Shapiro SetCertAltnames = atobool(val); 4679*5b0945b5SGregory Neil Shapiro break; 4680*5b0945b5SGregory Neil Shapiro # endif 4681*5b0945b5SGregory Neil Shapiro 4682c2aa98e2SPeter Wemm default: 4683c2aa98e2SPeter Wemm if (tTd(37, 1)) 4684c2aa98e2SPeter Wemm { 4685c2aa98e2SPeter Wemm if (isascii(opt) && isprint(opt)) 468640266059SGregory Neil Shapiro sm_dprintf("Warning: option %c unknown\n", opt); 4687c2aa98e2SPeter Wemm else 468840266059SGregory Neil Shapiro sm_dprintf("Warning: option 0x%x unknown\n", opt); 4689c2aa98e2SPeter Wemm } 4690c2aa98e2SPeter Wemm break; 4691c2aa98e2SPeter Wemm } 469206f25ae9SGregory Neil Shapiro 469306f25ae9SGregory Neil Shapiro /* 469406f25ae9SGregory Neil Shapiro ** Options with suboptions are responsible for taking care 469506f25ae9SGregory Neil Shapiro ** of sticky-ness (e.g., that a command line setting is kept 469606f25ae9SGregory Neil Shapiro ** when reading in the sendmail.cf file). This has to be done 469706f25ae9SGregory Neil Shapiro ** when the suboptions are parsed since each suboption must be 469806f25ae9SGregory Neil Shapiro ** sticky, not the root option. 469906f25ae9SGregory Neil Shapiro */ 470006f25ae9SGregory Neil Shapiro 470106f25ae9SGregory Neil Shapiro if (sticky && !bitset(OI_SUBOPT, o->o_flags)) 4702c2aa98e2SPeter Wemm setbitn(opt, StickyOpt); 4703c2aa98e2SPeter Wemm } 470440266059SGregory Neil Shapiro /* 4705c2aa98e2SPeter Wemm ** SETCLASS -- set a string into a class 4706c2aa98e2SPeter Wemm ** 4707c2aa98e2SPeter Wemm ** Parameters: 4708c2aa98e2SPeter Wemm ** class -- the class to put the string in. 4709c2aa98e2SPeter Wemm ** str -- the string to enter 4710c2aa98e2SPeter Wemm ** 4711c2aa98e2SPeter Wemm ** Returns: 4712c2aa98e2SPeter Wemm ** none. 4713c2aa98e2SPeter Wemm ** 4714c2aa98e2SPeter Wemm ** Side Effects: 4715c2aa98e2SPeter Wemm ** puts the word into the symbol table. 4716c2aa98e2SPeter Wemm */ 4717c2aa98e2SPeter Wemm 4718c2aa98e2SPeter Wemm void 4719c2aa98e2SPeter Wemm setclass(class, str) 4720c2aa98e2SPeter Wemm int class; 4721c2aa98e2SPeter Wemm char *str; 4722c2aa98e2SPeter Wemm { 4723c2aa98e2SPeter Wemm register STAB *s; 4724c2aa98e2SPeter Wemm 4725d0cef73dSGregory Neil Shapiro if ((str[0] & 0377) == MATCHCLASS) 472606f25ae9SGregory Neil Shapiro { 472706f25ae9SGregory Neil Shapiro int mid; 472806f25ae9SGregory Neil Shapiro 472906f25ae9SGregory Neil Shapiro str++; 473040266059SGregory Neil Shapiro mid = macid(str); 4731193538b7SGregory Neil Shapiro if (mid == 0) 473206f25ae9SGregory Neil Shapiro return; 473306f25ae9SGregory Neil Shapiro 4734c2aa98e2SPeter Wemm if (tTd(37, 8)) 473540266059SGregory Neil Shapiro sm_dprintf("setclass(%s, $=%s)\n", 473606f25ae9SGregory Neil Shapiro macname(class), macname(mid)); 473706f25ae9SGregory Neil Shapiro copy_class(mid, class); 473806f25ae9SGregory Neil Shapiro } 473906f25ae9SGregory Neil Shapiro else 474006f25ae9SGregory Neil Shapiro { 474106f25ae9SGregory Neil Shapiro if (tTd(37, 8)) 474240266059SGregory Neil Shapiro sm_dprintf("setclass(%s, %s)\n", macname(class), str); 474306f25ae9SGregory Neil Shapiro 4744c2aa98e2SPeter Wemm s = stab(str, ST_CLASS, ST_ENTER); 4745193538b7SGregory Neil Shapiro setbitn(bitidx(class), s->s_class); 4746c2aa98e2SPeter Wemm } 474706f25ae9SGregory Neil Shapiro } 474840266059SGregory Neil Shapiro /* 4749c2aa98e2SPeter Wemm ** MAKEMAPENTRY -- create a map entry 4750c2aa98e2SPeter Wemm ** 4751c2aa98e2SPeter Wemm ** Parameters: 4752c2aa98e2SPeter Wemm ** line -- the config file line 4753c2aa98e2SPeter Wemm ** 4754c2aa98e2SPeter Wemm ** Returns: 4755c2aa98e2SPeter Wemm ** A pointer to the map that has been created. 4756c2aa98e2SPeter Wemm ** NULL if there was a syntax error. 4757c2aa98e2SPeter Wemm ** 4758c2aa98e2SPeter Wemm ** Side Effects: 4759c2aa98e2SPeter Wemm ** Enters the map into the dictionary. 4760c2aa98e2SPeter Wemm */ 4761c2aa98e2SPeter Wemm 4762c2aa98e2SPeter Wemm MAP * 4763c2aa98e2SPeter Wemm makemapentry(line) 4764c2aa98e2SPeter Wemm char *line; 4765c2aa98e2SPeter Wemm { 4766c2aa98e2SPeter Wemm register char *p; 4767c2aa98e2SPeter Wemm char *mapname; 4768c2aa98e2SPeter Wemm char *classname; 4769c2aa98e2SPeter Wemm register STAB *s; 4770c2aa98e2SPeter Wemm STAB *class; 4771c2aa98e2SPeter Wemm 4772*5b0945b5SGregory Neil Shapiro for (p = line; SM_ISSPACE(*p); p++) 4773c2aa98e2SPeter Wemm continue; 4774c2aa98e2SPeter Wemm if (!(isascii(*p) && isalnum(*p))) 4775c2aa98e2SPeter Wemm { 4776c2aa98e2SPeter Wemm syserr("readcf: config K line: no map name"); 4777c2aa98e2SPeter Wemm return NULL; 4778c2aa98e2SPeter Wemm } 4779c2aa98e2SPeter Wemm 4780c2aa98e2SPeter Wemm mapname = p; 4781c2aa98e2SPeter Wemm while ((isascii(*++p) && isalnum(*p)) || *p == '_' || *p == '.') 4782c2aa98e2SPeter Wemm continue; 4783c2aa98e2SPeter Wemm if (*p != '\0') 4784c2aa98e2SPeter Wemm *p++ = '\0'; 4785*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p)) 4786c2aa98e2SPeter Wemm p++; 4787c2aa98e2SPeter Wemm if (!(isascii(*p) && isalnum(*p))) 4788c2aa98e2SPeter Wemm { 4789c2aa98e2SPeter Wemm syserr("readcf: config K line, map %s: no map class", mapname); 4790c2aa98e2SPeter Wemm return NULL; 4791c2aa98e2SPeter Wemm } 4792c2aa98e2SPeter Wemm classname = p; 4793c2aa98e2SPeter Wemm while (isascii(*++p) && isalnum(*p)) 4794c2aa98e2SPeter Wemm continue; 4795c2aa98e2SPeter Wemm if (*p != '\0') 4796c2aa98e2SPeter Wemm *p++ = '\0'; 4797*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p)) 4798c2aa98e2SPeter Wemm p++; 4799c2aa98e2SPeter Wemm 4800c2aa98e2SPeter Wemm /* look up the class */ 4801c2aa98e2SPeter Wemm class = stab(classname, ST_MAPCLASS, ST_FIND); 4802c2aa98e2SPeter Wemm if (class == NULL) 4803c2aa98e2SPeter Wemm { 480440266059SGregory Neil Shapiro syserr("readcf: map %s: class %s not available", mapname, 480540266059SGregory Neil Shapiro classname); 4806c2aa98e2SPeter Wemm return NULL; 4807c2aa98e2SPeter Wemm } 4808c2aa98e2SPeter Wemm 4809c2aa98e2SPeter Wemm /* enter the map */ 4810c2aa98e2SPeter Wemm s = stab(mapname, ST_MAP, ST_ENTER); 4811c2aa98e2SPeter Wemm s->s_map.map_class = &class->s_mapclass; 4812c2aa98e2SPeter Wemm s->s_map.map_mname = newstr(mapname); 4813c2aa98e2SPeter Wemm 4814c2aa98e2SPeter Wemm if (class->s_mapclass.map_parse(&s->s_map, p)) 4815c2aa98e2SPeter Wemm s->s_map.map_mflags |= MF_VALID; 4816c2aa98e2SPeter Wemm 4817c2aa98e2SPeter Wemm if (tTd(37, 5)) 4818c2aa98e2SPeter Wemm { 481940266059SGregory Neil Shapiro sm_dprintf("map %s, class %s, flags %lx, file %s,\n", 4820c2aa98e2SPeter Wemm s->s_map.map_mname, s->s_map.map_class->map_cname, 482140266059SGregory Neil Shapiro s->s_map.map_mflags, s->s_map.map_file); 482240266059SGregory Neil Shapiro sm_dprintf("\tapp %s, domain %s, rebuild %s\n", 482340266059SGregory Neil Shapiro s->s_map.map_app, s->s_map.map_domain, 482440266059SGregory Neil Shapiro s->s_map.map_rebuild); 4825c2aa98e2SPeter Wemm } 4826c2aa98e2SPeter Wemm return &s->s_map; 4827c2aa98e2SPeter Wemm } 482840266059SGregory Neil Shapiro /* 4829c2aa98e2SPeter Wemm ** STRTORWSET -- convert string to rewriting set number 4830c2aa98e2SPeter Wemm ** 4831c2aa98e2SPeter Wemm ** Parameters: 4832c2aa98e2SPeter Wemm ** p -- the pointer to the string to decode. 4833c2aa98e2SPeter Wemm ** endp -- if set, store the trailing delimiter here. 4834c2aa98e2SPeter Wemm ** stabmode -- ST_ENTER to create this entry, ST_FIND if 4835c2aa98e2SPeter Wemm ** it must already exist. 4836c2aa98e2SPeter Wemm ** 4837c2aa98e2SPeter Wemm ** Returns: 4838c2aa98e2SPeter Wemm ** The appropriate ruleset number. 4839c2aa98e2SPeter Wemm ** -1 if it is not valid (error already printed) 4840c2aa98e2SPeter Wemm */ 4841c2aa98e2SPeter Wemm 4842c2aa98e2SPeter Wemm int 4843c2aa98e2SPeter Wemm strtorwset(p, endp, stabmode) 4844c2aa98e2SPeter Wemm char *p; 4845c2aa98e2SPeter Wemm char **endp; 4846c2aa98e2SPeter Wemm int stabmode; 4847c2aa98e2SPeter Wemm { 4848c2aa98e2SPeter Wemm int ruleset; 4849c2aa98e2SPeter Wemm static int nextruleset = MAXRWSETS; 4850c2aa98e2SPeter Wemm 4851*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p)) 4852c2aa98e2SPeter Wemm p++; 4853c2aa98e2SPeter Wemm if (!isascii(*p)) 4854c2aa98e2SPeter Wemm { 4855c2aa98e2SPeter Wemm syserr("invalid ruleset name: \"%.20s\"", p); 4856c2aa98e2SPeter Wemm return -1; 4857c2aa98e2SPeter Wemm } 4858c2aa98e2SPeter Wemm if (isdigit(*p)) 4859c2aa98e2SPeter Wemm { 4860c2aa98e2SPeter Wemm ruleset = strtol(p, endp, 10); 4861c2aa98e2SPeter Wemm if (ruleset >= MAXRWSETS / 2 || ruleset < 0) 4862c2aa98e2SPeter Wemm { 4863c2aa98e2SPeter Wemm syserr("bad ruleset %d (%d max)", 4864c2aa98e2SPeter Wemm ruleset, MAXRWSETS / 2); 4865c2aa98e2SPeter Wemm ruleset = -1; 4866c2aa98e2SPeter Wemm } 4867c2aa98e2SPeter Wemm } 4868c2aa98e2SPeter Wemm else 4869c2aa98e2SPeter Wemm { 4870c2aa98e2SPeter Wemm STAB *s; 4871c2aa98e2SPeter Wemm char delim; 487206f25ae9SGregory Neil Shapiro char *q = NULL; 4873c2aa98e2SPeter Wemm 4874c2aa98e2SPeter Wemm q = p; 48759bd497b8SGregory Neil Shapiro while (*p != '\0' && isascii(*p) && (isalnum(*p) || *p == '_')) 4876c2aa98e2SPeter Wemm p++; 4877c2aa98e2SPeter Wemm if (q == p || !(isascii(*q) && isalpha(*q))) 4878c2aa98e2SPeter Wemm { 4879c2aa98e2SPeter Wemm /* no valid characters */ 4880c2aa98e2SPeter Wemm syserr("invalid ruleset name: \"%.20s\"", q); 4881c2aa98e2SPeter Wemm return -1; 4882c2aa98e2SPeter Wemm } 4883*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*p)) 4884c2aa98e2SPeter Wemm *p++ = '\0'; 4885c2aa98e2SPeter Wemm delim = *p; 4886c2aa98e2SPeter Wemm if (delim != '\0') 4887c2aa98e2SPeter Wemm *p = '\0'; 4888c2aa98e2SPeter Wemm s = stab(q, ST_RULESET, stabmode); 4889c2aa98e2SPeter Wemm if (delim != '\0') 4890c2aa98e2SPeter Wemm *p = delim; 4891c2aa98e2SPeter Wemm 4892c2aa98e2SPeter Wemm if (s == NULL) 4893c2aa98e2SPeter Wemm return -1; 4894c2aa98e2SPeter Wemm 4895c2aa98e2SPeter Wemm if (stabmode == ST_ENTER && delim == '=') 4896c2aa98e2SPeter Wemm { 4897c2aa98e2SPeter Wemm while (isascii(*++p) && isspace(*p)) 4898c2aa98e2SPeter Wemm continue; 4899c2aa98e2SPeter Wemm if (!(isascii(*p) && isdigit(*p))) 4900c2aa98e2SPeter Wemm { 4901c2aa98e2SPeter Wemm syserr("bad ruleset definition \"%s\" (number required after `=')", q); 4902c2aa98e2SPeter Wemm ruleset = -1; 4903c2aa98e2SPeter Wemm } 4904c2aa98e2SPeter Wemm else 4905c2aa98e2SPeter Wemm { 4906c2aa98e2SPeter Wemm ruleset = strtol(p, endp, 10); 4907c2aa98e2SPeter Wemm if (ruleset >= MAXRWSETS / 2 || ruleset < 0) 4908c2aa98e2SPeter Wemm { 4909c2aa98e2SPeter Wemm syserr("bad ruleset number %d in \"%s\" (%d max)", 4910c2aa98e2SPeter Wemm ruleset, q, MAXRWSETS / 2); 4911c2aa98e2SPeter Wemm ruleset = -1; 4912c2aa98e2SPeter Wemm } 4913c2aa98e2SPeter Wemm } 4914c2aa98e2SPeter Wemm } 4915c2aa98e2SPeter Wemm else 4916c2aa98e2SPeter Wemm { 4917c2aa98e2SPeter Wemm if (endp != NULL) 4918c2aa98e2SPeter Wemm *endp = p; 491906f25ae9SGregory Neil Shapiro if (s->s_ruleset >= 0) 4920c2aa98e2SPeter Wemm ruleset = s->s_ruleset; 4921c2aa98e2SPeter Wemm else if ((ruleset = --nextruleset) < MAXRWSETS / 2) 4922c2aa98e2SPeter Wemm { 4923c2aa98e2SPeter Wemm syserr("%s: too many named rulesets (%d max)", 4924c2aa98e2SPeter Wemm q, MAXRWSETS / 2); 4925c2aa98e2SPeter Wemm ruleset = -1; 4926c2aa98e2SPeter Wemm } 4927c2aa98e2SPeter Wemm } 492806f25ae9SGregory Neil Shapiro if (s->s_ruleset >= 0 && 492906f25ae9SGregory Neil Shapiro ruleset >= 0 && 493006f25ae9SGregory Neil Shapiro ruleset != s->s_ruleset) 4931c2aa98e2SPeter Wemm { 4932c2aa98e2SPeter Wemm syserr("%s: ruleset changed value (old %d, new %d)", 4933c2aa98e2SPeter Wemm q, s->s_ruleset, ruleset); 4934c2aa98e2SPeter Wemm ruleset = s->s_ruleset; 4935c2aa98e2SPeter Wemm } 493606f25ae9SGregory Neil Shapiro else if (ruleset >= 0) 4937c2aa98e2SPeter Wemm { 4938c2aa98e2SPeter Wemm s->s_ruleset = ruleset; 4939c2aa98e2SPeter Wemm } 4940193538b7SGregory Neil Shapiro if (stabmode == ST_ENTER && ruleset >= 0) 494106f25ae9SGregory Neil Shapiro { 494206f25ae9SGregory Neil Shapiro char *h = NULL; 494306f25ae9SGregory Neil Shapiro 494406f25ae9SGregory Neil Shapiro if (RuleSetNames[ruleset] != NULL) 494540266059SGregory Neil Shapiro sm_free(RuleSetNames[ruleset]); /* XXX */ 494606f25ae9SGregory Neil Shapiro if (delim != '\0' && (h = strchr(q, delim)) != NULL) 494706f25ae9SGregory Neil Shapiro *h = '\0'; 494806f25ae9SGregory Neil Shapiro RuleSetNames[ruleset] = newstr(q); 494906f25ae9SGregory Neil Shapiro if (delim == '/' && h != NULL) 495006f25ae9SGregory Neil Shapiro *h = delim; /* put back delim */ 495106f25ae9SGregory Neil Shapiro } 4952c2aa98e2SPeter Wemm } 4953c2aa98e2SPeter Wemm return ruleset; 4954c2aa98e2SPeter Wemm } 495540266059SGregory Neil Shapiro /* 495606f25ae9SGregory Neil Shapiro ** SETTIMEOUT -- set an individual timeout 495706f25ae9SGregory Neil Shapiro ** 495806f25ae9SGregory Neil Shapiro ** Parameters: 495906f25ae9SGregory Neil Shapiro ** name -- the name of the timeout. 496006f25ae9SGregory Neil Shapiro ** val -- the value of the timeout. 496106f25ae9SGregory Neil Shapiro ** sticky -- if set, don't let other setoptions override 496206f25ae9SGregory Neil Shapiro ** this value. 496306f25ae9SGregory Neil Shapiro ** 496406f25ae9SGregory Neil Shapiro ** Returns: 496506f25ae9SGregory Neil Shapiro ** none. 496606f25ae9SGregory Neil Shapiro */ 496706f25ae9SGregory Neil Shapiro 496806f25ae9SGregory Neil Shapiro /* set if Timeout sub-option is stuck */ 496906f25ae9SGregory Neil Shapiro static BITMAP256 StickyTimeoutOpt; 497006f25ae9SGregory Neil Shapiro 497106f25ae9SGregory Neil Shapiro static struct timeoutinfo 497206f25ae9SGregory Neil Shapiro { 497306f25ae9SGregory Neil Shapiro char *to_name; /* long name of timeout */ 497440266059SGregory Neil Shapiro unsigned char to_code; /* code for option */ 497506f25ae9SGregory Neil Shapiro } TimeOutTab[] = 497606f25ae9SGregory Neil Shapiro { 497706f25ae9SGregory Neil Shapiro #define TO_INITIAL 0x01 497806f25ae9SGregory Neil Shapiro { "initial", TO_INITIAL }, 497906f25ae9SGregory Neil Shapiro #define TO_MAIL 0x02 498006f25ae9SGregory Neil Shapiro { "mail", TO_MAIL }, 498106f25ae9SGregory Neil Shapiro #define TO_RCPT 0x03 498206f25ae9SGregory Neil Shapiro { "rcpt", TO_RCPT }, 498306f25ae9SGregory Neil Shapiro #define TO_DATAINIT 0x04 498406f25ae9SGregory Neil Shapiro { "datainit", TO_DATAINIT }, 498506f25ae9SGregory Neil Shapiro #define TO_DATABLOCK 0x05 498606f25ae9SGregory Neil Shapiro { "datablock", TO_DATABLOCK }, 498706f25ae9SGregory Neil Shapiro #define TO_DATAFINAL 0x06 498806f25ae9SGregory Neil Shapiro { "datafinal", TO_DATAFINAL }, 498906f25ae9SGregory Neil Shapiro #define TO_COMMAND 0x07 499006f25ae9SGregory Neil Shapiro { "command", TO_COMMAND }, 499106f25ae9SGregory Neil Shapiro #define TO_RSET 0x08 499206f25ae9SGregory Neil Shapiro { "rset", TO_RSET }, 499306f25ae9SGregory Neil Shapiro #define TO_HELO 0x09 499406f25ae9SGregory Neil Shapiro { "helo", TO_HELO }, 499506f25ae9SGregory Neil Shapiro #define TO_QUIT 0x0A 499606f25ae9SGregory Neil Shapiro { "quit", TO_QUIT }, 499706f25ae9SGregory Neil Shapiro #define TO_MISC 0x0B 499806f25ae9SGregory Neil Shapiro { "misc", TO_MISC }, 499906f25ae9SGregory Neil Shapiro #define TO_IDENT 0x0C 500006f25ae9SGregory Neil Shapiro { "ident", TO_IDENT }, 500106f25ae9SGregory Neil Shapiro #define TO_FILEOPEN 0x0D 500206f25ae9SGregory Neil Shapiro { "fileopen", TO_FILEOPEN }, 500306f25ae9SGregory Neil Shapiro #define TO_CONNECT 0x0E 500406f25ae9SGregory Neil Shapiro { "connect", TO_CONNECT }, 500506f25ae9SGregory Neil Shapiro #define TO_ICONNECT 0x0F 500606f25ae9SGregory Neil Shapiro { "iconnect", TO_ICONNECT }, 500706f25ae9SGregory Neil Shapiro #define TO_QUEUEWARN 0x10 500806f25ae9SGregory Neil Shapiro { "queuewarn", TO_QUEUEWARN }, 500906f25ae9SGregory Neil Shapiro { "queuewarn.*", TO_QUEUEWARN }, 501006f25ae9SGregory Neil Shapiro #define TO_QUEUEWARN_NORMAL 0x11 501106f25ae9SGregory Neil Shapiro { "queuewarn.normal", TO_QUEUEWARN_NORMAL }, 501206f25ae9SGregory Neil Shapiro #define TO_QUEUEWARN_URGENT 0x12 501306f25ae9SGregory Neil Shapiro { "queuewarn.urgent", TO_QUEUEWARN_URGENT }, 501406f25ae9SGregory Neil Shapiro #define TO_QUEUEWARN_NON_URGENT 0x13 501506f25ae9SGregory Neil Shapiro { "queuewarn.non-urgent", TO_QUEUEWARN_NON_URGENT }, 501606f25ae9SGregory Neil Shapiro #define TO_QUEUERETURN 0x14 501706f25ae9SGregory Neil Shapiro { "queuereturn", TO_QUEUERETURN }, 501806f25ae9SGregory Neil Shapiro { "queuereturn.*", TO_QUEUERETURN }, 501906f25ae9SGregory Neil Shapiro #define TO_QUEUERETURN_NORMAL 0x15 502006f25ae9SGregory Neil Shapiro { "queuereturn.normal", TO_QUEUERETURN_NORMAL }, 502106f25ae9SGregory Neil Shapiro #define TO_QUEUERETURN_URGENT 0x16 502206f25ae9SGregory Neil Shapiro { "queuereturn.urgent", TO_QUEUERETURN_URGENT }, 502306f25ae9SGregory Neil Shapiro #define TO_QUEUERETURN_NON_URGENT 0x17 502406f25ae9SGregory Neil Shapiro { "queuereturn.non-urgent", TO_QUEUERETURN_NON_URGENT }, 502506f25ae9SGregory Neil Shapiro #define TO_HOSTSTATUS 0x18 502606f25ae9SGregory Neil Shapiro { "hoststatus", TO_HOSTSTATUS }, 502706f25ae9SGregory Neil Shapiro #define TO_RESOLVER_RETRANS 0x19 502806f25ae9SGregory Neil Shapiro { "resolver.retrans", TO_RESOLVER_RETRANS }, 502906f25ae9SGregory Neil Shapiro #define TO_RESOLVER_RETRANS_NORMAL 0x1A 503006f25ae9SGregory Neil Shapiro { "resolver.retrans.normal", TO_RESOLVER_RETRANS_NORMAL }, 503106f25ae9SGregory Neil Shapiro #define TO_RESOLVER_RETRANS_FIRST 0x1B 503206f25ae9SGregory Neil Shapiro { "resolver.retrans.first", TO_RESOLVER_RETRANS_FIRST }, 503306f25ae9SGregory Neil Shapiro #define TO_RESOLVER_RETRY 0x1C 503406f25ae9SGregory Neil Shapiro { "resolver.retry", TO_RESOLVER_RETRY }, 503506f25ae9SGregory Neil Shapiro #define TO_RESOLVER_RETRY_NORMAL 0x1D 503606f25ae9SGregory Neil Shapiro { "resolver.retry.normal", TO_RESOLVER_RETRY_NORMAL }, 503706f25ae9SGregory Neil Shapiro #define TO_RESOLVER_RETRY_FIRST 0x1E 503806f25ae9SGregory Neil Shapiro { "resolver.retry.first", TO_RESOLVER_RETRY_FIRST }, 503906f25ae9SGregory Neil Shapiro #define TO_CONTROL 0x1F 504006f25ae9SGregory Neil Shapiro { "control", TO_CONTROL }, 504140266059SGregory Neil Shapiro #define TO_LHLO 0x20 504240266059SGregory Neil Shapiro { "lhlo", TO_LHLO }, 504340266059SGregory Neil Shapiro #define TO_AUTH 0x21 504440266059SGregory Neil Shapiro { "auth", TO_AUTH }, 504540266059SGregory Neil Shapiro #define TO_STARTTLS 0x22 504640266059SGregory Neil Shapiro { "starttls", TO_STARTTLS }, 504740266059SGregory Neil Shapiro #define TO_ACONNECT 0x23 504840266059SGregory Neil Shapiro { "aconnect", TO_ACONNECT }, 50495ef517c0SGregory Neil Shapiro #define TO_QUEUEWARN_DSN 0x24 50505ef517c0SGregory Neil Shapiro { "queuewarn.dsn", TO_QUEUEWARN_DSN }, 50515ef517c0SGregory Neil Shapiro #define TO_QUEUERETURN_DSN 0x25 50525ef517c0SGregory Neil Shapiro { "queuereturn.dsn", TO_QUEUERETURN_DSN }, 505306f25ae9SGregory Neil Shapiro { NULL, 0 }, 505406f25ae9SGregory Neil Shapiro }; 505506f25ae9SGregory Neil Shapiro 505606f25ae9SGregory Neil Shapiro 505706f25ae9SGregory Neil Shapiro static void 505806f25ae9SGregory Neil Shapiro settimeout(name, val, sticky) 505906f25ae9SGregory Neil Shapiro char *name; 506006f25ae9SGregory Neil Shapiro char *val; 506106f25ae9SGregory Neil Shapiro bool sticky; 506206f25ae9SGregory Neil Shapiro { 506306f25ae9SGregory Neil Shapiro register struct timeoutinfo *to; 506440266059SGregory Neil Shapiro int i, addopts; 506506f25ae9SGregory Neil Shapiro time_t toval; 506606f25ae9SGregory Neil Shapiro 506706f25ae9SGregory Neil Shapiro if (tTd(37, 2)) 506840266059SGregory Neil Shapiro sm_dprintf("settimeout(%s = %s)", name, val); 506906f25ae9SGregory Neil Shapiro 507006f25ae9SGregory Neil Shapiro for (to = TimeOutTab; to->to_name != NULL; to++) 507106f25ae9SGregory Neil Shapiro { 507240266059SGregory Neil Shapiro if (sm_strcasecmp(to->to_name, name) == 0) 507306f25ae9SGregory Neil Shapiro break; 507406f25ae9SGregory Neil Shapiro } 507506f25ae9SGregory Neil Shapiro 507606f25ae9SGregory Neil Shapiro if (to->to_name == NULL) 5077193538b7SGregory Neil Shapiro { 5078193538b7SGregory Neil Shapiro errno = 0; /* avoid bogus error text */ 507906f25ae9SGregory Neil Shapiro syserr("settimeout: invalid timeout %s", name); 5080193538b7SGregory Neil Shapiro return; 5081193538b7SGregory Neil Shapiro } 508206f25ae9SGregory Neil Shapiro 508306f25ae9SGregory Neil Shapiro /* 508406f25ae9SGregory Neil Shapiro ** See if this option is preset for us. 508506f25ae9SGregory Neil Shapiro */ 508606f25ae9SGregory Neil Shapiro 508706f25ae9SGregory Neil Shapiro if (!sticky && bitnset(to->to_code, StickyTimeoutOpt)) 508806f25ae9SGregory Neil Shapiro { 508906f25ae9SGregory Neil Shapiro if (tTd(37, 2)) 509040266059SGregory Neil Shapiro sm_dprintf(" (ignored)\n"); 509106f25ae9SGregory Neil Shapiro return; 509206f25ae9SGregory Neil Shapiro } 509306f25ae9SGregory Neil Shapiro 509406f25ae9SGregory Neil Shapiro if (tTd(37, 2)) 509540266059SGregory Neil Shapiro sm_dprintf("\n"); 509606f25ae9SGregory Neil Shapiro 509706f25ae9SGregory Neil Shapiro toval = convtime(val, 'm'); 509813058a91SGregory Neil Shapiro addopts = 0; 509906f25ae9SGregory Neil Shapiro 510006f25ae9SGregory Neil Shapiro switch (to->to_code) 510106f25ae9SGregory Neil Shapiro { 510206f25ae9SGregory Neil Shapiro case TO_INITIAL: 510306f25ae9SGregory Neil Shapiro TimeOuts.to_initial = toval; 510406f25ae9SGregory Neil Shapiro break; 510506f25ae9SGregory Neil Shapiro 510606f25ae9SGregory Neil Shapiro case TO_MAIL: 510706f25ae9SGregory Neil Shapiro TimeOuts.to_mail = toval; 510806f25ae9SGregory Neil Shapiro break; 510906f25ae9SGregory Neil Shapiro 511006f25ae9SGregory Neil Shapiro case TO_RCPT: 511106f25ae9SGregory Neil Shapiro TimeOuts.to_rcpt = toval; 511206f25ae9SGregory Neil Shapiro break; 511306f25ae9SGregory Neil Shapiro 511406f25ae9SGregory Neil Shapiro case TO_DATAINIT: 511506f25ae9SGregory Neil Shapiro TimeOuts.to_datainit = toval; 511606f25ae9SGregory Neil Shapiro break; 511706f25ae9SGregory Neil Shapiro 511806f25ae9SGregory Neil Shapiro case TO_DATABLOCK: 511906f25ae9SGregory Neil Shapiro TimeOuts.to_datablock = toval; 512006f25ae9SGregory Neil Shapiro break; 512106f25ae9SGregory Neil Shapiro 512206f25ae9SGregory Neil Shapiro case TO_DATAFINAL: 512306f25ae9SGregory Neil Shapiro TimeOuts.to_datafinal = toval; 512406f25ae9SGregory Neil Shapiro break; 512506f25ae9SGregory Neil Shapiro 512606f25ae9SGregory Neil Shapiro case TO_COMMAND: 512706f25ae9SGregory Neil Shapiro TimeOuts.to_nextcommand = toval; 512806f25ae9SGregory Neil Shapiro break; 512906f25ae9SGregory Neil Shapiro 513006f25ae9SGregory Neil Shapiro case TO_RSET: 513106f25ae9SGregory Neil Shapiro TimeOuts.to_rset = toval; 513206f25ae9SGregory Neil Shapiro break; 513306f25ae9SGregory Neil Shapiro 513406f25ae9SGregory Neil Shapiro case TO_HELO: 513506f25ae9SGregory Neil Shapiro TimeOuts.to_helo = toval; 513606f25ae9SGregory Neil Shapiro break; 513706f25ae9SGregory Neil Shapiro 513806f25ae9SGregory Neil Shapiro case TO_QUIT: 513906f25ae9SGregory Neil Shapiro TimeOuts.to_quit = toval; 514006f25ae9SGregory Neil Shapiro break; 514106f25ae9SGregory Neil Shapiro 514206f25ae9SGregory Neil Shapiro case TO_MISC: 514306f25ae9SGregory Neil Shapiro TimeOuts.to_miscshort = toval; 514406f25ae9SGregory Neil Shapiro break; 514506f25ae9SGregory Neil Shapiro 514606f25ae9SGregory Neil Shapiro case TO_IDENT: 514706f25ae9SGregory Neil Shapiro TimeOuts.to_ident = toval; 514806f25ae9SGregory Neil Shapiro break; 514906f25ae9SGregory Neil Shapiro 515006f25ae9SGregory Neil Shapiro case TO_FILEOPEN: 515106f25ae9SGregory Neil Shapiro TimeOuts.to_fileopen = toval; 515206f25ae9SGregory Neil Shapiro break; 515306f25ae9SGregory Neil Shapiro 515406f25ae9SGregory Neil Shapiro case TO_CONNECT: 515506f25ae9SGregory Neil Shapiro TimeOuts.to_connect = toval; 515606f25ae9SGregory Neil Shapiro break; 515706f25ae9SGregory Neil Shapiro 515806f25ae9SGregory Neil Shapiro case TO_ICONNECT: 515906f25ae9SGregory Neil Shapiro TimeOuts.to_iconnect = toval; 516006f25ae9SGregory Neil Shapiro break; 516106f25ae9SGregory Neil Shapiro 516240266059SGregory Neil Shapiro case TO_ACONNECT: 516340266059SGregory Neil Shapiro TimeOuts.to_aconnect = toval; 516440266059SGregory Neil Shapiro break; 516540266059SGregory Neil Shapiro 516606f25ae9SGregory Neil Shapiro case TO_QUEUEWARN: 516706f25ae9SGregory Neil Shapiro toval = convtime(val, 'h'); 516806f25ae9SGregory Neil Shapiro TimeOuts.to_q_warning[TOC_NORMAL] = toval; 516906f25ae9SGregory Neil Shapiro TimeOuts.to_q_warning[TOC_URGENT] = toval; 517006f25ae9SGregory Neil Shapiro TimeOuts.to_q_warning[TOC_NONURGENT] = toval; 51715ef517c0SGregory Neil Shapiro TimeOuts.to_q_warning[TOC_DSN] = toval; 517213058a91SGregory Neil Shapiro addopts = 2; 517306f25ae9SGregory Neil Shapiro break; 517406f25ae9SGregory Neil Shapiro 517506f25ae9SGregory Neil Shapiro case TO_QUEUEWARN_NORMAL: 517606f25ae9SGregory Neil Shapiro toval = convtime(val, 'h'); 517706f25ae9SGregory Neil Shapiro TimeOuts.to_q_warning[TOC_NORMAL] = toval; 517806f25ae9SGregory Neil Shapiro break; 517906f25ae9SGregory Neil Shapiro 518006f25ae9SGregory Neil Shapiro case TO_QUEUEWARN_URGENT: 518106f25ae9SGregory Neil Shapiro toval = convtime(val, 'h'); 518206f25ae9SGregory Neil Shapiro TimeOuts.to_q_warning[TOC_URGENT] = toval; 518306f25ae9SGregory Neil Shapiro break; 518406f25ae9SGregory Neil Shapiro 518506f25ae9SGregory Neil Shapiro case TO_QUEUEWARN_NON_URGENT: 518606f25ae9SGregory Neil Shapiro toval = convtime(val, 'h'); 518706f25ae9SGregory Neil Shapiro TimeOuts.to_q_warning[TOC_NONURGENT] = toval; 518806f25ae9SGregory Neil Shapiro break; 518906f25ae9SGregory Neil Shapiro 51905ef517c0SGregory Neil Shapiro case TO_QUEUEWARN_DSN: 51915ef517c0SGregory Neil Shapiro toval = convtime(val, 'h'); 51925ef517c0SGregory Neil Shapiro TimeOuts.to_q_warning[TOC_DSN] = toval; 51935ef517c0SGregory Neil Shapiro break; 51945ef517c0SGregory Neil Shapiro 519506f25ae9SGregory Neil Shapiro case TO_QUEUERETURN: 519606f25ae9SGregory Neil Shapiro toval = convtime(val, 'd'); 519706f25ae9SGregory Neil Shapiro TimeOuts.to_q_return[TOC_NORMAL] = toval; 519806f25ae9SGregory Neil Shapiro TimeOuts.to_q_return[TOC_URGENT] = toval; 519906f25ae9SGregory Neil Shapiro TimeOuts.to_q_return[TOC_NONURGENT] = toval; 52005ef517c0SGregory Neil Shapiro TimeOuts.to_q_return[TOC_DSN] = toval; 520113058a91SGregory Neil Shapiro addopts = 2; 520206f25ae9SGregory Neil Shapiro break; 520306f25ae9SGregory Neil Shapiro 520406f25ae9SGregory Neil Shapiro case TO_QUEUERETURN_NORMAL: 520506f25ae9SGregory Neil Shapiro toval = convtime(val, 'd'); 520606f25ae9SGregory Neil Shapiro TimeOuts.to_q_return[TOC_NORMAL] = toval; 520706f25ae9SGregory Neil Shapiro break; 520806f25ae9SGregory Neil Shapiro 520906f25ae9SGregory Neil Shapiro case TO_QUEUERETURN_URGENT: 521006f25ae9SGregory Neil Shapiro toval = convtime(val, 'd'); 521106f25ae9SGregory Neil Shapiro TimeOuts.to_q_return[TOC_URGENT] = toval; 521206f25ae9SGregory Neil Shapiro break; 521306f25ae9SGregory Neil Shapiro 521406f25ae9SGregory Neil Shapiro case TO_QUEUERETURN_NON_URGENT: 521506f25ae9SGregory Neil Shapiro toval = convtime(val, 'd'); 521606f25ae9SGregory Neil Shapiro TimeOuts.to_q_return[TOC_NONURGENT] = toval; 521706f25ae9SGregory Neil Shapiro break; 521806f25ae9SGregory Neil Shapiro 52195ef517c0SGregory Neil Shapiro case TO_QUEUERETURN_DSN: 52205ef517c0SGregory Neil Shapiro toval = convtime(val, 'd'); 52215ef517c0SGregory Neil Shapiro TimeOuts.to_q_return[TOC_DSN] = toval; 52225ef517c0SGregory Neil Shapiro break; 52235ef517c0SGregory Neil Shapiro 522406f25ae9SGregory Neil Shapiro case TO_HOSTSTATUS: 522506f25ae9SGregory Neil Shapiro MciInfoTimeout = toval; 522606f25ae9SGregory Neil Shapiro break; 522706f25ae9SGregory Neil Shapiro 522806f25ae9SGregory Neil Shapiro case TO_RESOLVER_RETRANS: 522906f25ae9SGregory Neil Shapiro toval = convtime(val, 's'); 523006f25ae9SGregory Neil Shapiro TimeOuts.res_retrans[RES_TO_DEFAULT] = toval; 523106f25ae9SGregory Neil Shapiro TimeOuts.res_retrans[RES_TO_FIRST] = toval; 523206f25ae9SGregory Neil Shapiro TimeOuts.res_retrans[RES_TO_NORMAL] = toval; 523313058a91SGregory Neil Shapiro addopts = 2; 523406f25ae9SGregory Neil Shapiro break; 523506f25ae9SGregory Neil Shapiro 523606f25ae9SGregory Neil Shapiro case TO_RESOLVER_RETRY: 523706f25ae9SGregory Neil Shapiro i = atoi(val); 523806f25ae9SGregory Neil Shapiro TimeOuts.res_retry[RES_TO_DEFAULT] = i; 523906f25ae9SGregory Neil Shapiro TimeOuts.res_retry[RES_TO_FIRST] = i; 524006f25ae9SGregory Neil Shapiro TimeOuts.res_retry[RES_TO_NORMAL] = i; 524113058a91SGregory Neil Shapiro addopts = 2; 524206f25ae9SGregory Neil Shapiro break; 524306f25ae9SGregory Neil Shapiro 524406f25ae9SGregory Neil Shapiro case TO_RESOLVER_RETRANS_NORMAL: 524506f25ae9SGregory Neil Shapiro TimeOuts.res_retrans[RES_TO_NORMAL] = convtime(val, 's'); 524606f25ae9SGregory Neil Shapiro break; 524706f25ae9SGregory Neil Shapiro 524806f25ae9SGregory Neil Shapiro case TO_RESOLVER_RETRY_NORMAL: 524906f25ae9SGregory Neil Shapiro TimeOuts.res_retry[RES_TO_NORMAL] = atoi(val); 525006f25ae9SGregory Neil Shapiro break; 525106f25ae9SGregory Neil Shapiro 525206f25ae9SGregory Neil Shapiro case TO_RESOLVER_RETRANS_FIRST: 525306f25ae9SGregory Neil Shapiro TimeOuts.res_retrans[RES_TO_FIRST] = convtime(val, 's'); 525406f25ae9SGregory Neil Shapiro break; 525506f25ae9SGregory Neil Shapiro 525606f25ae9SGregory Neil Shapiro case TO_RESOLVER_RETRY_FIRST: 525706f25ae9SGregory Neil Shapiro TimeOuts.res_retry[RES_TO_FIRST] = atoi(val); 525806f25ae9SGregory Neil Shapiro break; 525906f25ae9SGregory Neil Shapiro 526006f25ae9SGregory Neil Shapiro case TO_CONTROL: 526106f25ae9SGregory Neil Shapiro TimeOuts.to_control = toval; 526206f25ae9SGregory Neil Shapiro break; 526306f25ae9SGregory Neil Shapiro 526440266059SGregory Neil Shapiro case TO_LHLO: 526540266059SGregory Neil Shapiro TimeOuts.to_lhlo = toval; 526640266059SGregory Neil Shapiro break; 526740266059SGregory Neil Shapiro 526840266059SGregory Neil Shapiro #if SASL 526940266059SGregory Neil Shapiro case TO_AUTH: 527040266059SGregory Neil Shapiro TimeOuts.to_auth = toval; 527140266059SGregory Neil Shapiro break; 5272*5b0945b5SGregory Neil Shapiro #endif 527340266059SGregory Neil Shapiro 527440266059SGregory Neil Shapiro #if STARTTLS 527540266059SGregory Neil Shapiro case TO_STARTTLS: 527640266059SGregory Neil Shapiro TimeOuts.to_starttls = toval; 527740266059SGregory Neil Shapiro break; 5278*5b0945b5SGregory Neil Shapiro #endif 527940266059SGregory Neil Shapiro 528006f25ae9SGregory Neil Shapiro default: 528106f25ae9SGregory Neil Shapiro syserr("settimeout: invalid timeout %s", name); 528206f25ae9SGregory Neil Shapiro break; 528306f25ae9SGregory Neil Shapiro } 528406f25ae9SGregory Neil Shapiro 528506f25ae9SGregory Neil Shapiro if (sticky) 528613058a91SGregory Neil Shapiro { 528713058a91SGregory Neil Shapiro for (i = 0; i <= addopts; i++) 528813058a91SGregory Neil Shapiro setbitn(to->to_code + i, StickyTimeoutOpt); 528913058a91SGregory Neil Shapiro } 529006f25ae9SGregory Neil Shapiro } 529140266059SGregory Neil Shapiro /* 5292c2aa98e2SPeter Wemm ** INITTIMEOUTS -- parse and set timeout values 5293c2aa98e2SPeter Wemm ** 5294c2aa98e2SPeter Wemm ** Parameters: 5295c2aa98e2SPeter Wemm ** val -- a pointer to the values. If NULL, do initial 5296c2aa98e2SPeter Wemm ** settings. 529706f25ae9SGregory Neil Shapiro ** sticky -- if set, don't let other setoptions override 529806f25ae9SGregory Neil Shapiro ** this suboption value. 5299c2aa98e2SPeter Wemm ** 5300c2aa98e2SPeter Wemm ** Returns: 5301c2aa98e2SPeter Wemm ** none. 5302c2aa98e2SPeter Wemm ** 5303c2aa98e2SPeter Wemm ** Side Effects: 5304c2aa98e2SPeter Wemm ** Initializes the TimeOuts structure 5305c2aa98e2SPeter Wemm */ 5306c2aa98e2SPeter Wemm 5307c2aa98e2SPeter Wemm void 530806f25ae9SGregory Neil Shapiro inittimeouts(val, sticky) 5309c2aa98e2SPeter Wemm register char *val; 531006f25ae9SGregory Neil Shapiro bool sticky; 5311c2aa98e2SPeter Wemm { 5312c2aa98e2SPeter Wemm register char *p; 5313c2aa98e2SPeter Wemm 5314c2aa98e2SPeter Wemm if (tTd(37, 2)) 531540266059SGregory Neil Shapiro sm_dprintf("inittimeouts(%s)\n", val == NULL ? "<NULL>" : val); 5316c2aa98e2SPeter Wemm if (val == NULL) 5317c2aa98e2SPeter Wemm { 5318c2aa98e2SPeter Wemm TimeOuts.to_connect = (time_t) 0 SECONDS; 531940266059SGregory Neil Shapiro TimeOuts.to_aconnect = (time_t) 0 SECONDS; 5320605302a5SGregory Neil Shapiro TimeOuts.to_iconnect = (time_t) 0 SECONDS; 5321c2aa98e2SPeter Wemm TimeOuts.to_initial = (time_t) 5 MINUTES; 5322c2aa98e2SPeter Wemm TimeOuts.to_helo = (time_t) 5 MINUTES; 5323c2aa98e2SPeter Wemm TimeOuts.to_mail = (time_t) 10 MINUTES; 5324c2aa98e2SPeter Wemm TimeOuts.to_rcpt = (time_t) 1 HOUR; 5325c2aa98e2SPeter Wemm TimeOuts.to_datainit = (time_t) 5 MINUTES; 5326c2aa98e2SPeter Wemm TimeOuts.to_datablock = (time_t) 1 HOUR; 5327c2aa98e2SPeter Wemm TimeOuts.to_datafinal = (time_t) 1 HOUR; 5328c2aa98e2SPeter Wemm TimeOuts.to_rset = (time_t) 5 MINUTES; 5329c2aa98e2SPeter Wemm TimeOuts.to_quit = (time_t) 2 MINUTES; 5330c2aa98e2SPeter Wemm TimeOuts.to_nextcommand = (time_t) 1 HOUR; 5331c2aa98e2SPeter Wemm TimeOuts.to_miscshort = (time_t) 2 MINUTES; 5332c2aa98e2SPeter Wemm #if IDENTPROTO 533306f25ae9SGregory Neil Shapiro TimeOuts.to_ident = (time_t) 5 SECONDS; 5334*5b0945b5SGregory Neil Shapiro #else 5335c2aa98e2SPeter Wemm TimeOuts.to_ident = (time_t) 0 SECONDS; 5336*5b0945b5SGregory Neil Shapiro #endif 5337c2aa98e2SPeter Wemm TimeOuts.to_fileopen = (time_t) 60 SECONDS; 533806f25ae9SGregory Neil Shapiro TimeOuts.to_control = (time_t) 2 MINUTES; 533940266059SGregory Neil Shapiro TimeOuts.to_lhlo = (time_t) 2 MINUTES; 534040266059SGregory Neil Shapiro #if SASL 534140266059SGregory Neil Shapiro TimeOuts.to_auth = (time_t) 10 MINUTES; 5342*5b0945b5SGregory Neil Shapiro #endif 534340266059SGregory Neil Shapiro #if STARTTLS 534440266059SGregory Neil Shapiro TimeOuts.to_starttls = (time_t) 1 HOUR; 5345*5b0945b5SGregory Neil Shapiro #endif 5346c2aa98e2SPeter Wemm if (tTd(37, 5)) 5347c2aa98e2SPeter Wemm { 534840266059SGregory Neil Shapiro sm_dprintf("Timeouts:\n"); 534940266059SGregory Neil Shapiro sm_dprintf(" connect = %ld\n", 535040266059SGregory Neil Shapiro (long) TimeOuts.to_connect); 535140266059SGregory Neil Shapiro sm_dprintf(" aconnect = %ld\n", 535240266059SGregory Neil Shapiro (long) TimeOuts.to_aconnect); 535340266059SGregory Neil Shapiro sm_dprintf(" initial = %ld\n", 535440266059SGregory Neil Shapiro (long) TimeOuts.to_initial); 535540266059SGregory Neil Shapiro sm_dprintf(" helo = %ld\n", (long) TimeOuts.to_helo); 535640266059SGregory Neil Shapiro sm_dprintf(" mail = %ld\n", (long) TimeOuts.to_mail); 535740266059SGregory Neil Shapiro sm_dprintf(" rcpt = %ld\n", (long) TimeOuts.to_rcpt); 535840266059SGregory Neil Shapiro sm_dprintf(" datainit = %ld\n", 535940266059SGregory Neil Shapiro (long) TimeOuts.to_datainit); 536040266059SGregory Neil Shapiro sm_dprintf(" datablock = %ld\n", 536140266059SGregory Neil Shapiro (long) TimeOuts.to_datablock); 536240266059SGregory Neil Shapiro sm_dprintf(" datafinal = %ld\n", 536340266059SGregory Neil Shapiro (long) TimeOuts.to_datafinal); 536440266059SGregory Neil Shapiro sm_dprintf(" rset = %ld\n", (long) TimeOuts.to_rset); 536540266059SGregory Neil Shapiro sm_dprintf(" quit = %ld\n", (long) TimeOuts.to_quit); 536640266059SGregory Neil Shapiro sm_dprintf(" nextcommand = %ld\n", 536740266059SGregory Neil Shapiro (long) TimeOuts.to_nextcommand); 536840266059SGregory Neil Shapiro sm_dprintf(" miscshort = %ld\n", 536940266059SGregory Neil Shapiro (long) TimeOuts.to_miscshort); 537040266059SGregory Neil Shapiro sm_dprintf(" ident = %ld\n", (long) TimeOuts.to_ident); 537140266059SGregory Neil Shapiro sm_dprintf(" fileopen = %ld\n", 537240266059SGregory Neil Shapiro (long) TimeOuts.to_fileopen); 537340266059SGregory Neil Shapiro sm_dprintf(" lhlo = %ld\n", 537440266059SGregory Neil Shapiro (long) TimeOuts.to_lhlo); 537540266059SGregory Neil Shapiro sm_dprintf(" control = %ld\n", 537640266059SGregory Neil Shapiro (long) TimeOuts.to_control); 5377c2aa98e2SPeter Wemm } 5378c2aa98e2SPeter Wemm return; 5379c2aa98e2SPeter Wemm } 5380c2aa98e2SPeter Wemm 5381c2aa98e2SPeter Wemm for (;; val = p) 5382c2aa98e2SPeter Wemm { 5383*5b0945b5SGregory Neil Shapiro while (SM_ISSPACE(*val)) 5384c2aa98e2SPeter Wemm val++; 5385c2aa98e2SPeter Wemm if (*val == '\0') 5386c2aa98e2SPeter Wemm break; 5387c2aa98e2SPeter Wemm for (p = val; *p != '\0' && *p != ','; p++) 5388c2aa98e2SPeter Wemm continue; 5389c2aa98e2SPeter Wemm if (*p != '\0') 5390c2aa98e2SPeter Wemm *p++ = '\0'; 5391c2aa98e2SPeter Wemm 5392c2aa98e2SPeter Wemm if (isascii(*val) && isdigit(*val)) 5393c2aa98e2SPeter Wemm { 5394c2aa98e2SPeter Wemm /* old syntax -- set everything */ 5395c2aa98e2SPeter Wemm TimeOuts.to_mail = convtime(val, 'm'); 5396c2aa98e2SPeter Wemm TimeOuts.to_rcpt = TimeOuts.to_mail; 5397c2aa98e2SPeter Wemm TimeOuts.to_datainit = TimeOuts.to_mail; 5398c2aa98e2SPeter Wemm TimeOuts.to_datablock = TimeOuts.to_mail; 5399c2aa98e2SPeter Wemm TimeOuts.to_datafinal = TimeOuts.to_mail; 5400c2aa98e2SPeter Wemm TimeOuts.to_nextcommand = TimeOuts.to_mail; 540106f25ae9SGregory Neil Shapiro if (sticky) 540206f25ae9SGregory Neil Shapiro { 540306f25ae9SGregory Neil Shapiro setbitn(TO_MAIL, StickyTimeoutOpt); 540406f25ae9SGregory Neil Shapiro setbitn(TO_RCPT, StickyTimeoutOpt); 540506f25ae9SGregory Neil Shapiro setbitn(TO_DATAINIT, StickyTimeoutOpt); 540606f25ae9SGregory Neil Shapiro setbitn(TO_DATABLOCK, StickyTimeoutOpt); 540706f25ae9SGregory Neil Shapiro setbitn(TO_DATAFINAL, StickyTimeoutOpt); 540806f25ae9SGregory Neil Shapiro setbitn(TO_COMMAND, StickyTimeoutOpt); 540906f25ae9SGregory Neil Shapiro } 5410c2aa98e2SPeter Wemm continue; 5411c2aa98e2SPeter Wemm } 5412c2aa98e2SPeter Wemm else 5413c2aa98e2SPeter Wemm { 5414c2aa98e2SPeter Wemm register char *q = strchr(val, ':'); 5415c2aa98e2SPeter Wemm 5416c2aa98e2SPeter Wemm if (q == NULL && (q = strchr(val, '=')) == NULL) 5417c2aa98e2SPeter Wemm { 5418c2aa98e2SPeter Wemm /* syntax error */ 5419c2aa98e2SPeter Wemm continue; 5420c2aa98e2SPeter Wemm } 5421c2aa98e2SPeter Wemm *q++ = '\0'; 542206f25ae9SGregory Neil Shapiro settimeout(val, q, sticky); 5423c2aa98e2SPeter Wemm } 5424c2aa98e2SPeter Wemm } 5425c2aa98e2SPeter Wemm } 5426