17c478bd9Sstevel@tonic-gate /* 2*445f2479Sjbeck * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers. 37c478bd9Sstevel@tonic-gate * All rights reserved. 47c478bd9Sstevel@tonic-gate * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 57c478bd9Sstevel@tonic-gate * Copyright (c) 1988, 1993 67c478bd9Sstevel@tonic-gate * The Regents of the University of California. All rights reserved. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * By using this file, you agree to the terms and conditions set 97c478bd9Sstevel@tonic-gate * forth in the LICENSE file which can be found at the top level of 107c478bd9Sstevel@tonic-gate * the sendmail distribution. 117c478bd9Sstevel@tonic-gate * 127c478bd9Sstevel@tonic-gate */ 137c478bd9Sstevel@tonic-gate 147c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 157c478bd9Sstevel@tonic-gate 167c478bd9Sstevel@tonic-gate #include <sendmail.h> 177c478bd9Sstevel@tonic-gate 18*445f2479Sjbeck SM_RCSID("@(#)$Id: readcf.c,v 8.651 2006/03/02 19:17:09 ca Exp $") 197c478bd9Sstevel@tonic-gate 207c478bd9Sstevel@tonic-gate #if NETINET || NETINET6 217c478bd9Sstevel@tonic-gate # include <arpa/inet.h> 227c478bd9Sstevel@tonic-gate #endif /* NETINET || NETINET6 */ 237c478bd9Sstevel@tonic-gate 247c478bd9Sstevel@tonic-gate #define SECONDS 257c478bd9Sstevel@tonic-gate #define MINUTES * 60 267c478bd9Sstevel@tonic-gate #define HOUR * 3600 277c478bd9Sstevel@tonic-gate #define HOURS HOUR 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate static void fileclass __P((int, char *, char *, bool, bool, bool)); 307c478bd9Sstevel@tonic-gate static char **makeargv __P((char *)); 317c478bd9Sstevel@tonic-gate static void settimeout __P((char *, char *, bool)); 327c478bd9Sstevel@tonic-gate static void toomany __P((int, int)); 337c478bd9Sstevel@tonic-gate static char *extrquotstr __P((char *, char **, char *, bool *)); 347c478bd9Sstevel@tonic-gate static void parse_class_words __P((int, char *)); 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate /* 377c478bd9Sstevel@tonic-gate ** READCF -- read configuration file. 387c478bd9Sstevel@tonic-gate ** 397c478bd9Sstevel@tonic-gate ** This routine reads the configuration file and builds the internal 407c478bd9Sstevel@tonic-gate ** form. 417c478bd9Sstevel@tonic-gate ** 427c478bd9Sstevel@tonic-gate ** The file is formatted as a sequence of lines, each taken 437c478bd9Sstevel@tonic-gate ** atomically. The first character of each line describes how 447c478bd9Sstevel@tonic-gate ** the line is to be interpreted. The lines are: 457c478bd9Sstevel@tonic-gate ** Dxval Define macro x to have value val. 467c478bd9Sstevel@tonic-gate ** Cxword Put word into class x. 477c478bd9Sstevel@tonic-gate ** Fxfile [fmt] Read file for lines to put into 487c478bd9Sstevel@tonic-gate ** class x. Use scanf string 'fmt' 497c478bd9Sstevel@tonic-gate ** or "%s" if not present. Fmt should 507c478bd9Sstevel@tonic-gate ** only produce one string-valued result. 517c478bd9Sstevel@tonic-gate ** Hname: value Define header with field-name 'name' 527c478bd9Sstevel@tonic-gate ** and value as specified; this will be 537c478bd9Sstevel@tonic-gate ** macro expanded immediately before 547c478bd9Sstevel@tonic-gate ** use. 557c478bd9Sstevel@tonic-gate ** Sn Use rewriting set n. 567c478bd9Sstevel@tonic-gate ** Rlhs rhs Rewrite addresses that match lhs to 577c478bd9Sstevel@tonic-gate ** be rhs. 587c478bd9Sstevel@tonic-gate ** Mn arg=val... Define mailer. n is the internal name. 597c478bd9Sstevel@tonic-gate ** Args specify mailer parameters. 607c478bd9Sstevel@tonic-gate ** Oxvalue Set option x to value. 617c478bd9Sstevel@tonic-gate ** O option value Set option (long name) to value. 627c478bd9Sstevel@tonic-gate ** Pname=value Set precedence name to value. 637c478bd9Sstevel@tonic-gate ** Qn arg=val... Define queue groups. n is the internal name. 647c478bd9Sstevel@tonic-gate ** Args specify queue parameters. 657c478bd9Sstevel@tonic-gate ** Vversioncode[/vendorcode] 667c478bd9Sstevel@tonic-gate ** Version level/vendor name of 677c478bd9Sstevel@tonic-gate ** configuration syntax. 687c478bd9Sstevel@tonic-gate ** Kmapname mapclass arguments.... 697c478bd9Sstevel@tonic-gate ** Define keyed lookup of a given class. 707c478bd9Sstevel@tonic-gate ** Arguments are class dependent. 717c478bd9Sstevel@tonic-gate ** Eenvar=value Set the environment value to the given value. 727c478bd9Sstevel@tonic-gate ** 737c478bd9Sstevel@tonic-gate ** Parameters: 747c478bd9Sstevel@tonic-gate ** cfname -- configuration file name. 757c478bd9Sstevel@tonic-gate ** safe -- true if this is the system config file; 767c478bd9Sstevel@tonic-gate ** false otherwise. 777c478bd9Sstevel@tonic-gate ** e -- the main envelope. 787c478bd9Sstevel@tonic-gate ** 797c478bd9Sstevel@tonic-gate ** Returns: 807c478bd9Sstevel@tonic-gate ** none. 817c478bd9Sstevel@tonic-gate ** 827c478bd9Sstevel@tonic-gate ** Side Effects: 837c478bd9Sstevel@tonic-gate ** Builds several internal tables. 847c478bd9Sstevel@tonic-gate */ 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate void 877c478bd9Sstevel@tonic-gate readcf(cfname, safe, e) 887c478bd9Sstevel@tonic-gate char *cfname; 897c478bd9Sstevel@tonic-gate bool safe; 907c478bd9Sstevel@tonic-gate register ENVELOPE *e; 917c478bd9Sstevel@tonic-gate { 927c478bd9Sstevel@tonic-gate SM_FILE_T *cf; 937c478bd9Sstevel@tonic-gate int ruleset = -1; 947c478bd9Sstevel@tonic-gate char *q; 957c478bd9Sstevel@tonic-gate struct rewrite *rwp = NULL; 967c478bd9Sstevel@tonic-gate char *bp; 977c478bd9Sstevel@tonic-gate auto char *ep; 987c478bd9Sstevel@tonic-gate int nfuzzy; 997c478bd9Sstevel@tonic-gate char *file; 1007c478bd9Sstevel@tonic-gate bool optional; 1017c478bd9Sstevel@tonic-gate bool ok; 1027c478bd9Sstevel@tonic-gate bool ismap; 1037c478bd9Sstevel@tonic-gate int mid; 1047c478bd9Sstevel@tonic-gate register char *p; 1057c478bd9Sstevel@tonic-gate long sff = SFF_OPENASROOT; 1067c478bd9Sstevel@tonic-gate struct stat statb; 1077c478bd9Sstevel@tonic-gate char buf[MAXLINE]; 1087c478bd9Sstevel@tonic-gate char exbuf[MAXLINE]; 1097c478bd9Sstevel@tonic-gate char pvpbuf[MAXLINE + MAXATOM]; 1107c478bd9Sstevel@tonic-gate static char *null_list[1] = { NULL }; 1117c478bd9Sstevel@tonic-gate extern unsigned char TokTypeNoC[]; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate FileName = cfname; 1147c478bd9Sstevel@tonic-gate LineNumber = 0; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate if (DontLockReadFiles) 1177c478bd9Sstevel@tonic-gate sff |= SFF_NOLOCK; 1187c478bd9Sstevel@tonic-gate cf = safefopen(cfname, O_RDONLY, 0444, sff); 1197c478bd9Sstevel@tonic-gate if (cf == NULL) 1207c478bd9Sstevel@tonic-gate { 1217c478bd9Sstevel@tonic-gate syserr("cannot open"); 1227c478bd9Sstevel@tonic-gate finis(false, true, EX_OSFILE); 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate if (fstat(sm_io_getinfo(cf, SM_IO_WHAT_FD, NULL), &statb) < 0) 1267c478bd9Sstevel@tonic-gate { 1277c478bd9Sstevel@tonic-gate syserr("cannot fstat"); 1287c478bd9Sstevel@tonic-gate finis(false, true, EX_OSFILE); 1297c478bd9Sstevel@tonic-gate } 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate if (!S_ISREG(statb.st_mode)) 1327c478bd9Sstevel@tonic-gate { 1337c478bd9Sstevel@tonic-gate syserr("not a plain file"); 1347c478bd9Sstevel@tonic-gate finis(false, true, EX_OSFILE); 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate if (OpMode != MD_TEST && bitset(S_IWGRP|S_IWOTH, statb.st_mode)) 1387c478bd9Sstevel@tonic-gate { 1397c478bd9Sstevel@tonic-gate if (OpMode == MD_DAEMON || OpMode == MD_INITALIAS) 1407c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 1417c478bd9Sstevel@tonic-gate "%s: WARNING: dangerous write permissions\n", 1427c478bd9Sstevel@tonic-gate FileName); 1437c478bd9Sstevel@tonic-gate if (LogLevel > 0) 1447c478bd9Sstevel@tonic-gate sm_syslog(LOG_CRIT, NOQID, 1457c478bd9Sstevel@tonic-gate "%s: WARNING: dangerous write permissions", 1467c478bd9Sstevel@tonic-gate FileName); 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate #if XLA 1507c478bd9Sstevel@tonic-gate xla_zero(); 1517c478bd9Sstevel@tonic-gate #endif /* XLA */ 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate while ((bp = fgetfolded(buf, sizeof buf, cf)) != NULL) 1547c478bd9Sstevel@tonic-gate { 1557c478bd9Sstevel@tonic-gate if (bp[0] == '#') 1567c478bd9Sstevel@tonic-gate { 1577c478bd9Sstevel@tonic-gate if (bp != buf) 1587c478bd9Sstevel@tonic-gate sm_free(bp); /* XXX */ 1597c478bd9Sstevel@tonic-gate continue; 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate /* do macro expansion mappings */ 1637c478bd9Sstevel@tonic-gate translate_dollars(bp); 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate /* interpret this line */ 1667c478bd9Sstevel@tonic-gate errno = 0; 1677c478bd9Sstevel@tonic-gate switch (bp[0]) 1687c478bd9Sstevel@tonic-gate { 1697c478bd9Sstevel@tonic-gate case '\0': 1707c478bd9Sstevel@tonic-gate case '#': /* comment */ 1717c478bd9Sstevel@tonic-gate break; 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate case 'R': /* rewriting rule */ 1747c478bd9Sstevel@tonic-gate if (ruleset < 0) 1757c478bd9Sstevel@tonic-gate { 1767c478bd9Sstevel@tonic-gate syserr("missing valid ruleset for \"%s\"", bp); 1777c478bd9Sstevel@tonic-gate break; 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate for (p = &bp[1]; *p != '\0' && *p != '\t'; p++) 1807c478bd9Sstevel@tonic-gate continue; 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate if (*p == '\0') 1837c478bd9Sstevel@tonic-gate { 1847c478bd9Sstevel@tonic-gate syserr("invalid rewrite line \"%s\" (tab expected)", bp); 1857c478bd9Sstevel@tonic-gate break; 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate /* allocate space for the rule header */ 1897c478bd9Sstevel@tonic-gate if (rwp == NULL) 1907c478bd9Sstevel@tonic-gate { 1917c478bd9Sstevel@tonic-gate RewriteRules[ruleset] = rwp = 1927c478bd9Sstevel@tonic-gate (struct rewrite *) xalloc(sizeof *rwp); 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate else 1957c478bd9Sstevel@tonic-gate { 1967c478bd9Sstevel@tonic-gate rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp); 1977c478bd9Sstevel@tonic-gate rwp = rwp->r_next; 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate rwp->r_next = NULL; 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate /* expand and save the LHS */ 2027c478bd9Sstevel@tonic-gate *p = '\0'; 2037c478bd9Sstevel@tonic-gate expand(&bp[1], exbuf, sizeof exbuf, e); 2047c478bd9Sstevel@tonic-gate rwp->r_lhs = prescan(exbuf, '\t', pvpbuf, 2057c478bd9Sstevel@tonic-gate sizeof pvpbuf, NULL, 2067c478bd9Sstevel@tonic-gate ConfigLevel >= 9 ? TokTypeNoC : NULL, 2077c478bd9Sstevel@tonic-gate true); 2087c478bd9Sstevel@tonic-gate nfuzzy = 0; 2097c478bd9Sstevel@tonic-gate if (rwp->r_lhs != NULL) 2107c478bd9Sstevel@tonic-gate { 2117c478bd9Sstevel@tonic-gate register char **ap; 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate rwp->r_lhs = copyplist(rwp->r_lhs, true, NULL); 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate /* count the number of fuzzy matches in LHS */ 2167c478bd9Sstevel@tonic-gate for (ap = rwp->r_lhs; *ap != NULL; ap++) 2177c478bd9Sstevel@tonic-gate { 2187c478bd9Sstevel@tonic-gate char *botch; 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate botch = NULL; 2217c478bd9Sstevel@tonic-gate switch (**ap & 0377) 2227c478bd9Sstevel@tonic-gate { 2237c478bd9Sstevel@tonic-gate case MATCHZANY: 2247c478bd9Sstevel@tonic-gate case MATCHANY: 2257c478bd9Sstevel@tonic-gate case MATCHONE: 2267c478bd9Sstevel@tonic-gate case MATCHCLASS: 2277c478bd9Sstevel@tonic-gate case MATCHNCLASS: 2287c478bd9Sstevel@tonic-gate nfuzzy++; 2297c478bd9Sstevel@tonic-gate break; 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate case MATCHREPL: 2327c478bd9Sstevel@tonic-gate botch = "$0-$9"; 2337c478bd9Sstevel@tonic-gate break; 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate case CANONUSER: 2367c478bd9Sstevel@tonic-gate botch = "$:"; 2377c478bd9Sstevel@tonic-gate break; 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate case CALLSUBR: 2407c478bd9Sstevel@tonic-gate botch = "$>"; 2417c478bd9Sstevel@tonic-gate break; 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate case CONDIF: 2447c478bd9Sstevel@tonic-gate botch = "$?"; 2457c478bd9Sstevel@tonic-gate break; 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate case CONDFI: 2487c478bd9Sstevel@tonic-gate botch = "$."; 2497c478bd9Sstevel@tonic-gate break; 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate case HOSTBEGIN: 2527c478bd9Sstevel@tonic-gate botch = "$["; 2537c478bd9Sstevel@tonic-gate break; 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate case HOSTEND: 2567c478bd9Sstevel@tonic-gate botch = "$]"; 2577c478bd9Sstevel@tonic-gate break; 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate case LOOKUPBEGIN: 2607c478bd9Sstevel@tonic-gate botch = "$("; 2617c478bd9Sstevel@tonic-gate break; 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate case LOOKUPEND: 2647c478bd9Sstevel@tonic-gate botch = "$)"; 2657c478bd9Sstevel@tonic-gate break; 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate if (botch != NULL) 2687c478bd9Sstevel@tonic-gate syserr("Inappropriate use of %s on LHS", 2697c478bd9Sstevel@tonic-gate botch); 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate rwp->r_line = LineNumber; 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate else 2747c478bd9Sstevel@tonic-gate { 2757c478bd9Sstevel@tonic-gate syserr("R line: null LHS"); 2767c478bd9Sstevel@tonic-gate rwp->r_lhs = null_list; 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate if (nfuzzy > MAXMATCH) 2797c478bd9Sstevel@tonic-gate { 2807c478bd9Sstevel@tonic-gate syserr("R line: too many wildcards"); 2817c478bd9Sstevel@tonic-gate rwp->r_lhs = null_list; 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate /* expand and save the RHS */ 2857c478bd9Sstevel@tonic-gate while (*++p == '\t') 2867c478bd9Sstevel@tonic-gate continue; 2877c478bd9Sstevel@tonic-gate q = p; 2887c478bd9Sstevel@tonic-gate while (*p != '\0' && *p != '\t') 2897c478bd9Sstevel@tonic-gate p++; 2907c478bd9Sstevel@tonic-gate *p = '\0'; 2917c478bd9Sstevel@tonic-gate expand(q, exbuf, sizeof exbuf, e); 2927c478bd9Sstevel@tonic-gate rwp->r_rhs = prescan(exbuf, '\t', pvpbuf, 2937c478bd9Sstevel@tonic-gate sizeof pvpbuf, NULL, 2947c478bd9Sstevel@tonic-gate ConfigLevel >= 9 ? TokTypeNoC : NULL, 2957c478bd9Sstevel@tonic-gate true); 2967c478bd9Sstevel@tonic-gate if (rwp->r_rhs != NULL) 2977c478bd9Sstevel@tonic-gate { 2987c478bd9Sstevel@tonic-gate register char **ap; 2997c478bd9Sstevel@tonic-gate int args, endtoken; 3007c478bd9Sstevel@tonic-gate #if _FFR_EXTRA_MAP_CHECK 3017c478bd9Sstevel@tonic-gate int nexttoken; 3027c478bd9Sstevel@tonic-gate #endif /* _FFR_EXTRA_MAP_CHECK */ 3037c478bd9Sstevel@tonic-gate bool inmap; 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate rwp->r_rhs = copyplist(rwp->r_rhs, true, NULL); 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate /* check no out-of-bounds replacements */ 3087c478bd9Sstevel@tonic-gate nfuzzy += '0'; 3097c478bd9Sstevel@tonic-gate inmap = false; 3107c478bd9Sstevel@tonic-gate args = 0; 3117c478bd9Sstevel@tonic-gate endtoken = 0; 3127c478bd9Sstevel@tonic-gate for (ap = rwp->r_rhs; *ap != NULL; ap++) 3137c478bd9Sstevel@tonic-gate { 3147c478bd9Sstevel@tonic-gate char *botch; 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate botch = NULL; 3177c478bd9Sstevel@tonic-gate switch (**ap & 0377) 3187c478bd9Sstevel@tonic-gate { 3197c478bd9Sstevel@tonic-gate case MATCHREPL: 3207c478bd9Sstevel@tonic-gate if ((*ap)[1] <= '0' || (*ap)[1] > nfuzzy) 3217c478bd9Sstevel@tonic-gate { 3227c478bd9Sstevel@tonic-gate syserr("replacement $%c out of bounds", 3237c478bd9Sstevel@tonic-gate (*ap)[1]); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate break; 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate case MATCHZANY: 3287c478bd9Sstevel@tonic-gate botch = "$*"; 3297c478bd9Sstevel@tonic-gate break; 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate case MATCHANY: 3327c478bd9Sstevel@tonic-gate botch = "$+"; 3337c478bd9Sstevel@tonic-gate break; 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate case MATCHONE: 3367c478bd9Sstevel@tonic-gate botch = "$-"; 3377c478bd9Sstevel@tonic-gate break; 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate case MATCHCLASS: 3407c478bd9Sstevel@tonic-gate botch = "$="; 3417c478bd9Sstevel@tonic-gate break; 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate case MATCHNCLASS: 3447c478bd9Sstevel@tonic-gate botch = "$~"; 3457c478bd9Sstevel@tonic-gate break; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate case CANONHOST: 3487c478bd9Sstevel@tonic-gate if (!inmap) 3497c478bd9Sstevel@tonic-gate break; 3507c478bd9Sstevel@tonic-gate if (++args >= MAX_MAP_ARGS) 3517c478bd9Sstevel@tonic-gate syserr("too many arguments for map lookup"); 3527c478bd9Sstevel@tonic-gate break; 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate case HOSTBEGIN: 3557c478bd9Sstevel@tonic-gate endtoken = HOSTEND; 3567c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 3577c478bd9Sstevel@tonic-gate case LOOKUPBEGIN: 3587c478bd9Sstevel@tonic-gate /* see above... */ 3597c478bd9Sstevel@tonic-gate if ((**ap & 0377) == LOOKUPBEGIN) 3607c478bd9Sstevel@tonic-gate endtoken = LOOKUPEND; 3617c478bd9Sstevel@tonic-gate if (inmap) 3627c478bd9Sstevel@tonic-gate syserr("cannot nest map lookups"); 3637c478bd9Sstevel@tonic-gate inmap = true; 3647c478bd9Sstevel@tonic-gate args = 0; 3657c478bd9Sstevel@tonic-gate #if _FFR_EXTRA_MAP_CHECK 3667c478bd9Sstevel@tonic-gate if (*(ap + 1) == NULL) 3677c478bd9Sstevel@tonic-gate { 3687c478bd9Sstevel@tonic-gate syserr("syntax error in map lookup"); 3697c478bd9Sstevel@tonic-gate break; 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate nexttoken = **(ap + 1) & 0377; 3727c478bd9Sstevel@tonic-gate if (nexttoken == CANONHOST || 3737c478bd9Sstevel@tonic-gate nexttoken == CANONUSER || 3747c478bd9Sstevel@tonic-gate nexttoken == endtoken) 3757c478bd9Sstevel@tonic-gate { 3767c478bd9Sstevel@tonic-gate syserr("missing map name for lookup"); 3777c478bd9Sstevel@tonic-gate break; 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate if (*(ap + 2) == NULL) 3807c478bd9Sstevel@tonic-gate { 3817c478bd9Sstevel@tonic-gate syserr("syntax error in map lookup"); 3827c478bd9Sstevel@tonic-gate break; 3837c478bd9Sstevel@tonic-gate } 3847c478bd9Sstevel@tonic-gate if ((**ap & 0377) == HOSTBEGIN) 3857c478bd9Sstevel@tonic-gate break; 3867c478bd9Sstevel@tonic-gate nexttoken = **(ap + 2) & 0377; 3877c478bd9Sstevel@tonic-gate if (nexttoken == CANONHOST || 3887c478bd9Sstevel@tonic-gate nexttoken == CANONUSER || 3897c478bd9Sstevel@tonic-gate nexttoken == endtoken) 3907c478bd9Sstevel@tonic-gate { 3917c478bd9Sstevel@tonic-gate syserr("missing key name for lookup"); 3927c478bd9Sstevel@tonic-gate break; 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate #endif /* _FFR_EXTRA_MAP_CHECK */ 3957c478bd9Sstevel@tonic-gate break; 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate case HOSTEND: 3987c478bd9Sstevel@tonic-gate case LOOKUPEND: 3997c478bd9Sstevel@tonic-gate if ((**ap & 0377) != endtoken) 4007c478bd9Sstevel@tonic-gate break; 4017c478bd9Sstevel@tonic-gate inmap = false; 4027c478bd9Sstevel@tonic-gate endtoken = 0; 4037c478bd9Sstevel@tonic-gate break; 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate #if 0 4077c478bd9Sstevel@tonic-gate /* 4087c478bd9Sstevel@tonic-gate ** This doesn't work yet as there are maps defined *after* the cf 4097c478bd9Sstevel@tonic-gate ** is read such as host, user, and alias. So for now, it's removed. 4107c478bd9Sstevel@tonic-gate ** When it comes back, the RELEASE_NOTES entry will be: 4117c478bd9Sstevel@tonic-gate ** Emit warnings for unknown maps when reading the .cf file. Based on 4127c478bd9Sstevel@tonic-gate ** patch from Robert Harker of Harker Systems. 4137c478bd9Sstevel@tonic-gate */ 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate case LOOKUPBEGIN: 4167c478bd9Sstevel@tonic-gate /* 4177c478bd9Sstevel@tonic-gate ** Got a database lookup, 4187c478bd9Sstevel@tonic-gate ** check if map is defined. 4197c478bd9Sstevel@tonic-gate */ 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate ep = *(ap + 1); 4227c478bd9Sstevel@tonic-gate if ((*ep & 0377) != MACRODEXPAND && 4237c478bd9Sstevel@tonic-gate stab(ep, ST_MAP, 4247c478bd9Sstevel@tonic-gate ST_FIND) == NULL) 4257c478bd9Sstevel@tonic-gate { 4267c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, 4277c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 4287c478bd9Sstevel@tonic-gate "Warning: %s: line %d: map %s not found\n", 4297c478bd9Sstevel@tonic-gate FileName, 4307c478bd9Sstevel@tonic-gate LineNumber, 4317c478bd9Sstevel@tonic-gate ep); 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate break; 4347c478bd9Sstevel@tonic-gate #endif /* 0 */ 4357c478bd9Sstevel@tonic-gate } 4367c478bd9Sstevel@tonic-gate if (botch != NULL) 4377c478bd9Sstevel@tonic-gate syserr("Inappropriate use of %s on RHS", 4387c478bd9Sstevel@tonic-gate botch); 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate if (inmap) 4417c478bd9Sstevel@tonic-gate syserr("missing map closing token"); 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate else 4447c478bd9Sstevel@tonic-gate { 4457c478bd9Sstevel@tonic-gate syserr("R line: null RHS"); 4467c478bd9Sstevel@tonic-gate rwp->r_rhs = null_list; 4477c478bd9Sstevel@tonic-gate } 4487c478bd9Sstevel@tonic-gate break; 4497c478bd9Sstevel@tonic-gate 4507c478bd9Sstevel@tonic-gate case 'S': /* select rewriting set */ 4517c478bd9Sstevel@tonic-gate expand(&bp[1], exbuf, sizeof exbuf, e); 4527c478bd9Sstevel@tonic-gate ruleset = strtorwset(exbuf, NULL, ST_ENTER); 4537c478bd9Sstevel@tonic-gate if (ruleset < 0) 4547c478bd9Sstevel@tonic-gate break; 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate rwp = RewriteRules[ruleset]; 4577c478bd9Sstevel@tonic-gate if (rwp != NULL) 4587c478bd9Sstevel@tonic-gate { 4597c478bd9Sstevel@tonic-gate if (OpMode == MD_TEST) 4607c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, 4617c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 4627c478bd9Sstevel@tonic-gate "WARNING: Ruleset %s has multiple definitions\n", 4637c478bd9Sstevel@tonic-gate &bp[1]); 4647c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 4657c478bd9Sstevel@tonic-gate sm_dprintf("WARNING: Ruleset %s has multiple definitions\n", 4667c478bd9Sstevel@tonic-gate &bp[1]); 4677c478bd9Sstevel@tonic-gate while (rwp->r_next != NULL) 4687c478bd9Sstevel@tonic-gate rwp = rwp->r_next; 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate break; 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate case 'D': /* macro definition */ 4737c478bd9Sstevel@tonic-gate mid = macid_parse(&bp[1], &ep); 4747c478bd9Sstevel@tonic-gate if (mid == 0) 4757c478bd9Sstevel@tonic-gate break; 4767c478bd9Sstevel@tonic-gate p = munchstring(ep, NULL, '\0'); 4777c478bd9Sstevel@tonic-gate macdefine(&e->e_macro, A_TEMP, mid, p); 4787c478bd9Sstevel@tonic-gate break; 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate case 'H': /* required header line */ 4817c478bd9Sstevel@tonic-gate (void) chompheader(&bp[1], CHHDR_DEF, NULL, e); 4827c478bd9Sstevel@tonic-gate break; 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate case 'C': /* word class */ 4857c478bd9Sstevel@tonic-gate case 'T': /* trusted user (set class `t') */ 4867c478bd9Sstevel@tonic-gate if (bp[0] == 'C') 4877c478bd9Sstevel@tonic-gate { 4887c478bd9Sstevel@tonic-gate mid = macid_parse(&bp[1], &ep); 4897c478bd9Sstevel@tonic-gate if (mid == 0) 4907c478bd9Sstevel@tonic-gate break; 4917c478bd9Sstevel@tonic-gate expand(ep, exbuf, sizeof exbuf, e); 4927c478bd9Sstevel@tonic-gate p = exbuf; 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate else 4957c478bd9Sstevel@tonic-gate { 4967c478bd9Sstevel@tonic-gate mid = 't'; 4977c478bd9Sstevel@tonic-gate p = &bp[1]; 4987c478bd9Sstevel@tonic-gate } 4997c478bd9Sstevel@tonic-gate while (*p != '\0') 5007c478bd9Sstevel@tonic-gate { 5017c478bd9Sstevel@tonic-gate register char *wd; 5027c478bd9Sstevel@tonic-gate char delim; 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate while (*p != '\0' && isascii(*p) && isspace(*p)) 5057c478bd9Sstevel@tonic-gate p++; 5067c478bd9Sstevel@tonic-gate wd = p; 5077c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 5087c478bd9Sstevel@tonic-gate p++; 5097c478bd9Sstevel@tonic-gate delim = *p; 5107c478bd9Sstevel@tonic-gate *p = '\0'; 5117c478bd9Sstevel@tonic-gate if (wd[0] != '\0') 5127c478bd9Sstevel@tonic-gate setclass(mid, wd); 5137c478bd9Sstevel@tonic-gate *p = delim; 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate break; 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate case 'F': /* word class from file */ 5187c478bd9Sstevel@tonic-gate mid = macid_parse(&bp[1], &ep); 5197c478bd9Sstevel@tonic-gate if (mid == 0) 5207c478bd9Sstevel@tonic-gate break; 5217c478bd9Sstevel@tonic-gate for (p = ep; isascii(*p) && isspace(*p); ) 5227c478bd9Sstevel@tonic-gate p++; 5237c478bd9Sstevel@tonic-gate if (p[0] == '-' && p[1] == 'o') 5247c478bd9Sstevel@tonic-gate { 5257c478bd9Sstevel@tonic-gate optional = true; 5267c478bd9Sstevel@tonic-gate while (*p != '\0' && 5277c478bd9Sstevel@tonic-gate !(isascii(*p) && isspace(*p))) 5287c478bd9Sstevel@tonic-gate p++; 5297c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 5307c478bd9Sstevel@tonic-gate p++; 5317c478bd9Sstevel@tonic-gate file = p; 5327c478bd9Sstevel@tonic-gate } 5337c478bd9Sstevel@tonic-gate else 5347c478bd9Sstevel@tonic-gate optional = false; 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate /* check if [key]@map:spec */ 5377c478bd9Sstevel@tonic-gate ismap = false; 5387c478bd9Sstevel@tonic-gate if (!SM_IS_DIR_DELIM(*p) && 5397c478bd9Sstevel@tonic-gate *p != '|' && 5407c478bd9Sstevel@tonic-gate (q = strchr(p, '@')) != NULL) 5417c478bd9Sstevel@tonic-gate { 5427c478bd9Sstevel@tonic-gate q++; 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate /* look for @LDAP or @map: in string */ 5457c478bd9Sstevel@tonic-gate if (strcmp(q, "LDAP") == 0 || 5467c478bd9Sstevel@tonic-gate (*q != ':' && 5477c478bd9Sstevel@tonic-gate strchr(q, ':') != NULL)) 5487c478bd9Sstevel@tonic-gate ismap = true; 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate if (ismap) 5527c478bd9Sstevel@tonic-gate { 5537c478bd9Sstevel@tonic-gate /* use entire spec */ 5547c478bd9Sstevel@tonic-gate file = p; 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate else 5577c478bd9Sstevel@tonic-gate { 5587c478bd9Sstevel@tonic-gate file = extrquotstr(p, &q, " ", &ok); 5597c478bd9Sstevel@tonic-gate if (!ok) 5607c478bd9Sstevel@tonic-gate { 5617c478bd9Sstevel@tonic-gate syserr("illegal filename '%s'", p); 5627c478bd9Sstevel@tonic-gate break; 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate } 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate if (*file == '|' || ismap) 5677c478bd9Sstevel@tonic-gate p = "%s"; 5687c478bd9Sstevel@tonic-gate else 5697c478bd9Sstevel@tonic-gate { 5707c478bd9Sstevel@tonic-gate p = q; 5717c478bd9Sstevel@tonic-gate if (*p == '\0') 5727c478bd9Sstevel@tonic-gate p = "%s"; 5737c478bd9Sstevel@tonic-gate else 5747c478bd9Sstevel@tonic-gate { 5757c478bd9Sstevel@tonic-gate *p = '\0'; 5767c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 5777c478bd9Sstevel@tonic-gate continue; 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate } 5807c478bd9Sstevel@tonic-gate fileclass(mid, file, p, ismap, safe, optional); 5817c478bd9Sstevel@tonic-gate break; 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate #if XLA 5847c478bd9Sstevel@tonic-gate case 'L': /* extended load average description */ 5857c478bd9Sstevel@tonic-gate xla_init(&bp[1]); 5867c478bd9Sstevel@tonic-gate break; 5877c478bd9Sstevel@tonic-gate #endif /* XLA */ 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(SUN_LOOKUP_MACRO) 5907c478bd9Sstevel@tonic-gate case 'L': /* lookup macro */ 5917c478bd9Sstevel@tonic-gate case 'G': /* lookup class */ 5927c478bd9Sstevel@tonic-gate /* reserved for Sun -- NIS+ database lookup */ 5937c478bd9Sstevel@tonic-gate if (VendorCode != VENDOR_SUN) 5947c478bd9Sstevel@tonic-gate goto badline; 5957c478bd9Sstevel@tonic-gate sun_lg_config_line(bp, e); 5967c478bd9Sstevel@tonic-gate break; 5977c478bd9Sstevel@tonic-gate #endif /* defined(SUN_EXTENSIONS) && defined(SUN_LOOKUP_MACRO) */ 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate case 'M': /* define mailer */ 6007c478bd9Sstevel@tonic-gate makemailer(&bp[1]); 6017c478bd9Sstevel@tonic-gate break; 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate case 'O': /* set option */ 6047c478bd9Sstevel@tonic-gate setoption(bp[1], &bp[2], safe, false, e); 6057c478bd9Sstevel@tonic-gate break; 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate case 'P': /* set precedence */ 6087c478bd9Sstevel@tonic-gate if (NumPriorities >= MAXPRIORITIES) 6097c478bd9Sstevel@tonic-gate { 6107c478bd9Sstevel@tonic-gate toomany('P', MAXPRIORITIES); 6117c478bd9Sstevel@tonic-gate break; 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate for (p = &bp[1]; *p != '\0' && *p != '='; p++) 6147c478bd9Sstevel@tonic-gate continue; 6157c478bd9Sstevel@tonic-gate if (*p == '\0') 6167c478bd9Sstevel@tonic-gate goto badline; 6177c478bd9Sstevel@tonic-gate *p = '\0'; 6187c478bd9Sstevel@tonic-gate Priorities[NumPriorities].pri_name = newstr(&bp[1]); 6197c478bd9Sstevel@tonic-gate Priorities[NumPriorities].pri_val = atoi(++p); 6207c478bd9Sstevel@tonic-gate NumPriorities++; 6217c478bd9Sstevel@tonic-gate break; 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate case 'Q': /* define queue */ 6247c478bd9Sstevel@tonic-gate makequeue(&bp[1], true); 6257c478bd9Sstevel@tonic-gate break; 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate case 'V': /* configuration syntax version */ 6287c478bd9Sstevel@tonic-gate for (p = &bp[1]; isascii(*p) && isspace(*p); p++) 6297c478bd9Sstevel@tonic-gate continue; 6307c478bd9Sstevel@tonic-gate if (!isascii(*p) || !isdigit(*p)) 6317c478bd9Sstevel@tonic-gate { 6327c478bd9Sstevel@tonic-gate syserr("invalid argument to V line: \"%.20s\"", 6337c478bd9Sstevel@tonic-gate &bp[1]); 6347c478bd9Sstevel@tonic-gate break; 6357c478bd9Sstevel@tonic-gate } 6367c478bd9Sstevel@tonic-gate ConfigLevel = strtol(p, &ep, 10); 6377c478bd9Sstevel@tonic-gate 6387c478bd9Sstevel@tonic-gate /* 6397c478bd9Sstevel@tonic-gate ** Do heuristic tweaking for back compatibility. 6407c478bd9Sstevel@tonic-gate */ 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate if (ConfigLevel >= 5) 6437c478bd9Sstevel@tonic-gate { 6447c478bd9Sstevel@tonic-gate /* level 5 configs have short name in $w */ 6457c478bd9Sstevel@tonic-gate p = macvalue('w', e); 6467c478bd9Sstevel@tonic-gate if (p != NULL && (p = strchr(p, '.')) != NULL) 6477c478bd9Sstevel@tonic-gate { 6487c478bd9Sstevel@tonic-gate *p = '\0'; 6497c478bd9Sstevel@tonic-gate macdefine(&e->e_macro, A_TEMP, 'w', 6507c478bd9Sstevel@tonic-gate macvalue('w', e)); 6517c478bd9Sstevel@tonic-gate } 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate if (ConfigLevel >= 6) 6547c478bd9Sstevel@tonic-gate { 6557c478bd9Sstevel@tonic-gate ColonOkInAddr = false; 6567c478bd9Sstevel@tonic-gate } 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate /* 6597c478bd9Sstevel@tonic-gate ** Look for vendor code. 6607c478bd9Sstevel@tonic-gate */ 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate if (*ep++ == '/') 6637c478bd9Sstevel@tonic-gate { 6647c478bd9Sstevel@tonic-gate /* extract vendor code */ 6657c478bd9Sstevel@tonic-gate for (p = ep; isascii(*p) && isalpha(*p); ) 6667c478bd9Sstevel@tonic-gate p++; 6677c478bd9Sstevel@tonic-gate *p = '\0'; 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate if (!setvendor(ep)) 6707c478bd9Sstevel@tonic-gate syserr("invalid V line vendor code: \"%s\"", 6717c478bd9Sstevel@tonic-gate ep); 6727c478bd9Sstevel@tonic-gate } 6737c478bd9Sstevel@tonic-gate break; 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate case 'K': 6767c478bd9Sstevel@tonic-gate expand(&bp[1], exbuf, sizeof exbuf, e); 6777c478bd9Sstevel@tonic-gate (void) makemapentry(exbuf); 6787c478bd9Sstevel@tonic-gate break; 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate case 'E': 6817c478bd9Sstevel@tonic-gate p = strchr(bp, '='); 6827c478bd9Sstevel@tonic-gate if (p != NULL) 6837c478bd9Sstevel@tonic-gate *p++ = '\0'; 684*445f2479Sjbeck sm_setuserenv(&bp[1], p); 6857c478bd9Sstevel@tonic-gate break; 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate case 'X': /* mail filter */ 6887c478bd9Sstevel@tonic-gate #if MILTER 6897c478bd9Sstevel@tonic-gate milter_setup(&bp[1]); 6907c478bd9Sstevel@tonic-gate #else /* MILTER */ 6917c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 6927c478bd9Sstevel@tonic-gate "Warning: Filter usage ('X') requires Milter support (-DMILTER)\n"); 6937c478bd9Sstevel@tonic-gate #endif /* MILTER */ 6947c478bd9Sstevel@tonic-gate break; 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate default: 6977c478bd9Sstevel@tonic-gate badline: 6987c478bd9Sstevel@tonic-gate syserr("unknown configuration line \"%s\"", bp); 6997c478bd9Sstevel@tonic-gate } 7007c478bd9Sstevel@tonic-gate if (bp != buf) 7017c478bd9Sstevel@tonic-gate sm_free(bp); /* XXX */ 7027c478bd9Sstevel@tonic-gate } 7037c478bd9Sstevel@tonic-gate if (sm_io_error(cf)) 7047c478bd9Sstevel@tonic-gate { 7057c478bd9Sstevel@tonic-gate syserr("I/O read error"); 7067c478bd9Sstevel@tonic-gate finis(false, true, EX_OSFILE); 7077c478bd9Sstevel@tonic-gate } 7087c478bd9Sstevel@tonic-gate (void) sm_io_close(cf, SM_TIME_DEFAULT); 7097c478bd9Sstevel@tonic-gate FileName = NULL; 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate /* initialize host maps from local service tables */ 7127c478bd9Sstevel@tonic-gate inithostmaps(); 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate /* initialize daemon (if not defined yet) */ 7157c478bd9Sstevel@tonic-gate initdaemon(); 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate /* determine if we need to do special name-server frotz */ 7187c478bd9Sstevel@tonic-gate { 7197c478bd9Sstevel@tonic-gate int nmaps; 7207c478bd9Sstevel@tonic-gate char *maptype[MAXMAPSTACK]; 7217c478bd9Sstevel@tonic-gate short mapreturn[MAXMAPACTIONS]; 7227c478bd9Sstevel@tonic-gate 7237c478bd9Sstevel@tonic-gate nmaps = switch_map_find("hosts", maptype, mapreturn); 7247c478bd9Sstevel@tonic-gate UseNameServer = false; 7257c478bd9Sstevel@tonic-gate if (nmaps > 0 && nmaps <= MAXMAPSTACK) 7267c478bd9Sstevel@tonic-gate { 7277c478bd9Sstevel@tonic-gate register int mapno; 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate for (mapno = 0; mapno < nmaps && !UseNameServer; 7307c478bd9Sstevel@tonic-gate mapno++) 7317c478bd9Sstevel@tonic-gate { 7327c478bd9Sstevel@tonic-gate if (strcmp(maptype[mapno], "dns") == 0) 7337c478bd9Sstevel@tonic-gate UseNameServer = true; 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate } 7367c478bd9Sstevel@tonic-gate } 7377c478bd9Sstevel@tonic-gate } 7387c478bd9Sstevel@tonic-gate /* 7397c478bd9Sstevel@tonic-gate ** TRANSLATE_DOLLARS -- convert $x into internal form 7407c478bd9Sstevel@tonic-gate ** 7417c478bd9Sstevel@tonic-gate ** Actually does all appropriate pre-processing of a config line 7427c478bd9Sstevel@tonic-gate ** to turn it into internal form. 7437c478bd9Sstevel@tonic-gate ** 7447c478bd9Sstevel@tonic-gate ** Parameters: 7457c478bd9Sstevel@tonic-gate ** bp -- the buffer to translate. 7467c478bd9Sstevel@tonic-gate ** 7477c478bd9Sstevel@tonic-gate ** Returns: 7487c478bd9Sstevel@tonic-gate ** None. The buffer is translated in place. Since the 7497c478bd9Sstevel@tonic-gate ** translations always make the buffer shorter, this is 7507c478bd9Sstevel@tonic-gate ** safe without a size parameter. 7517c478bd9Sstevel@tonic-gate */ 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate void 7547c478bd9Sstevel@tonic-gate translate_dollars(bp) 7557c478bd9Sstevel@tonic-gate char *bp; 7567c478bd9Sstevel@tonic-gate { 7577c478bd9Sstevel@tonic-gate register char *p; 7587c478bd9Sstevel@tonic-gate auto char *ep; 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate for (p = bp; *p != '\0'; p++) 7617c478bd9Sstevel@tonic-gate { 7627c478bd9Sstevel@tonic-gate if (*p == '#' && p > bp && ConfigLevel >= 3) 7637c478bd9Sstevel@tonic-gate { 7647c478bd9Sstevel@tonic-gate register char *e; 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate switch (*--p & 0377) 7677c478bd9Sstevel@tonic-gate { 7687c478bd9Sstevel@tonic-gate case MACROEXPAND: 7697c478bd9Sstevel@tonic-gate /* it's from $# -- let it go through */ 7707c478bd9Sstevel@tonic-gate p++; 7717c478bd9Sstevel@tonic-gate break; 7727c478bd9Sstevel@tonic-gate 7737c478bd9Sstevel@tonic-gate case '\\': 7747c478bd9Sstevel@tonic-gate /* it's backslash escaped */ 7757c478bd9Sstevel@tonic-gate (void) sm_strlcpy(p, p + 1, strlen(p)); 7767c478bd9Sstevel@tonic-gate break; 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate default: 7797c478bd9Sstevel@tonic-gate /* delete leading white space */ 7807c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p) && 7817c478bd9Sstevel@tonic-gate *p != '\n' && p > bp) 7827c478bd9Sstevel@tonic-gate p--; 7837c478bd9Sstevel@tonic-gate if ((e = strchr(++p, '\n')) != NULL) 7847c478bd9Sstevel@tonic-gate (void) sm_strlcpy(p, e, strlen(p)); 7857c478bd9Sstevel@tonic-gate else 7867c478bd9Sstevel@tonic-gate *p-- = '\0'; 7877c478bd9Sstevel@tonic-gate break; 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate continue; 7907c478bd9Sstevel@tonic-gate } 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate if (*p != '$' || p[1] == '\0') 7937c478bd9Sstevel@tonic-gate continue; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate if (p[1] == '$') 7967c478bd9Sstevel@tonic-gate { 7977c478bd9Sstevel@tonic-gate /* actual dollar sign.... */ 7987c478bd9Sstevel@tonic-gate (void) sm_strlcpy(p, p + 1, strlen(p)); 7997c478bd9Sstevel@tonic-gate continue; 8007c478bd9Sstevel@tonic-gate } 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate /* convert to macro expansion character */ 8037c478bd9Sstevel@tonic-gate *p++ = MACROEXPAND; 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate /* special handling for $=, $~, $&, and $? */ 8067c478bd9Sstevel@tonic-gate if (*p == '=' || *p == '~' || *p == '&' || *p == '?') 8077c478bd9Sstevel@tonic-gate p++; 8087c478bd9Sstevel@tonic-gate 8097c478bd9Sstevel@tonic-gate /* convert macro name to code */ 8107c478bd9Sstevel@tonic-gate *p = macid_parse(p, &ep); 8117c478bd9Sstevel@tonic-gate if (ep != p + 1) 8127c478bd9Sstevel@tonic-gate (void) sm_strlcpy(p + 1, ep, strlen(p + 1)); 8137c478bd9Sstevel@tonic-gate } 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate /* strip trailing white space from the line */ 8167c478bd9Sstevel@tonic-gate while (--p > bp && isascii(*p) && isspace(*p)) 8177c478bd9Sstevel@tonic-gate *p = '\0'; 8187c478bd9Sstevel@tonic-gate } 8197c478bd9Sstevel@tonic-gate /* 8207c478bd9Sstevel@tonic-gate ** TOOMANY -- signal too many of some option 8217c478bd9Sstevel@tonic-gate ** 8227c478bd9Sstevel@tonic-gate ** Parameters: 8237c478bd9Sstevel@tonic-gate ** id -- the id of the error line 8247c478bd9Sstevel@tonic-gate ** maxcnt -- the maximum possible values 8257c478bd9Sstevel@tonic-gate ** 8267c478bd9Sstevel@tonic-gate ** Returns: 8277c478bd9Sstevel@tonic-gate ** none. 8287c478bd9Sstevel@tonic-gate ** 8297c478bd9Sstevel@tonic-gate ** Side Effects: 8307c478bd9Sstevel@tonic-gate ** gives a syserr. 8317c478bd9Sstevel@tonic-gate */ 8327c478bd9Sstevel@tonic-gate 8337c478bd9Sstevel@tonic-gate static void 8347c478bd9Sstevel@tonic-gate toomany(id, maxcnt) 8357c478bd9Sstevel@tonic-gate int id; 8367c478bd9Sstevel@tonic-gate int maxcnt; 8377c478bd9Sstevel@tonic-gate { 8387c478bd9Sstevel@tonic-gate syserr("too many %c lines, %d max", id, maxcnt); 8397c478bd9Sstevel@tonic-gate } 8407c478bd9Sstevel@tonic-gate /* 8417c478bd9Sstevel@tonic-gate ** FILECLASS -- read members of a class from a file 8427c478bd9Sstevel@tonic-gate ** 8437c478bd9Sstevel@tonic-gate ** Parameters: 8447c478bd9Sstevel@tonic-gate ** class -- class to define. 8457c478bd9Sstevel@tonic-gate ** filename -- name of file to read. 8467c478bd9Sstevel@tonic-gate ** fmt -- scanf string to use for match. 8477c478bd9Sstevel@tonic-gate ** ismap -- if set, this is a map lookup. 8487c478bd9Sstevel@tonic-gate ** safe -- if set, this is a safe read. 8497c478bd9Sstevel@tonic-gate ** optional -- if set, it is not an error for the file to 8507c478bd9Sstevel@tonic-gate ** not exist. 8517c478bd9Sstevel@tonic-gate ** 8527c478bd9Sstevel@tonic-gate ** Returns: 8537c478bd9Sstevel@tonic-gate ** none 8547c478bd9Sstevel@tonic-gate ** 8557c478bd9Sstevel@tonic-gate ** Side Effects: 8567c478bd9Sstevel@tonic-gate ** puts all lines in filename that match a scanf into 8577c478bd9Sstevel@tonic-gate ** the named class. 8587c478bd9Sstevel@tonic-gate */ 8597c478bd9Sstevel@tonic-gate 8607c478bd9Sstevel@tonic-gate /* 8617c478bd9Sstevel@tonic-gate ** Break up the match into words and add to class. 8627c478bd9Sstevel@tonic-gate */ 8637c478bd9Sstevel@tonic-gate 8647c478bd9Sstevel@tonic-gate static void 8657c478bd9Sstevel@tonic-gate parse_class_words(class, line) 8667c478bd9Sstevel@tonic-gate int class; 8677c478bd9Sstevel@tonic-gate char *line; 8687c478bd9Sstevel@tonic-gate { 8697c478bd9Sstevel@tonic-gate while (line != NULL && *line != '\0') 8707c478bd9Sstevel@tonic-gate { 8717c478bd9Sstevel@tonic-gate register char *q; 8727c478bd9Sstevel@tonic-gate 8737c478bd9Sstevel@tonic-gate /* strip leading spaces */ 8747c478bd9Sstevel@tonic-gate while (isascii(*line) && isspace(*line)) 8757c478bd9Sstevel@tonic-gate line++; 8767c478bd9Sstevel@tonic-gate if (*line == '\0') 8777c478bd9Sstevel@tonic-gate break; 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate /* find the end of the word */ 8807c478bd9Sstevel@tonic-gate q = line; 8817c478bd9Sstevel@tonic-gate while (*line != '\0' && !(isascii(*line) && isspace(*line))) 8827c478bd9Sstevel@tonic-gate line++; 8837c478bd9Sstevel@tonic-gate if (*line != '\0') 8847c478bd9Sstevel@tonic-gate *line++ = '\0'; 8857c478bd9Sstevel@tonic-gate 8867c478bd9Sstevel@tonic-gate /* enter the word in the symbol table */ 8877c478bd9Sstevel@tonic-gate setclass(class, q); 8887c478bd9Sstevel@tonic-gate } 8897c478bd9Sstevel@tonic-gate } 8907c478bd9Sstevel@tonic-gate 8917c478bd9Sstevel@tonic-gate static void 8927c478bd9Sstevel@tonic-gate fileclass(class, filename, fmt, ismap, safe, optional) 8937c478bd9Sstevel@tonic-gate int class; 8947c478bd9Sstevel@tonic-gate char *filename; 8957c478bd9Sstevel@tonic-gate char *fmt; 8967c478bd9Sstevel@tonic-gate bool ismap; 8977c478bd9Sstevel@tonic-gate bool safe; 8987c478bd9Sstevel@tonic-gate bool optional; 8997c478bd9Sstevel@tonic-gate { 9007c478bd9Sstevel@tonic-gate SM_FILE_T *f; 9017c478bd9Sstevel@tonic-gate long sff; 9027c478bd9Sstevel@tonic-gate pid_t pid; 9037c478bd9Sstevel@tonic-gate register char *p; 9047c478bd9Sstevel@tonic-gate char buf[MAXLINE]; 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 9077c478bd9Sstevel@tonic-gate sm_dprintf("fileclass(%s, fmt=%s)\n", filename, fmt); 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate if (*filename == '\0') 9107c478bd9Sstevel@tonic-gate { 9117c478bd9Sstevel@tonic-gate syserr("fileclass: missing file name"); 9127c478bd9Sstevel@tonic-gate return; 9137c478bd9Sstevel@tonic-gate } 9147c478bd9Sstevel@tonic-gate else if (ismap) 9157c478bd9Sstevel@tonic-gate { 9167c478bd9Sstevel@tonic-gate int status = 0; 9177c478bd9Sstevel@tonic-gate char *key; 9187c478bd9Sstevel@tonic-gate char *mn; 9197c478bd9Sstevel@tonic-gate char *cl, *spec; 9207c478bd9Sstevel@tonic-gate STAB *mapclass; 9217c478bd9Sstevel@tonic-gate MAP map; 9227c478bd9Sstevel@tonic-gate 9237c478bd9Sstevel@tonic-gate mn = newstr(macname(class)); 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate key = filename; 9267c478bd9Sstevel@tonic-gate 9277c478bd9Sstevel@tonic-gate /* skip past key */ 9287c478bd9Sstevel@tonic-gate if ((p = strchr(filename, '@')) == NULL) 9297c478bd9Sstevel@tonic-gate { 9307c478bd9Sstevel@tonic-gate /* should not happen */ 9317c478bd9Sstevel@tonic-gate syserr("fileclass: bogus map specification"); 9327c478bd9Sstevel@tonic-gate sm_free(mn); 9337c478bd9Sstevel@tonic-gate return; 9347c478bd9Sstevel@tonic-gate } 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate /* skip past '@' */ 9377c478bd9Sstevel@tonic-gate *p++ = '\0'; 9387c478bd9Sstevel@tonic-gate cl = p; 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate #if LDAPMAP 9417c478bd9Sstevel@tonic-gate if (strcmp(cl, "LDAP") == 0) 9427c478bd9Sstevel@tonic-gate { 9437c478bd9Sstevel@tonic-gate int n; 9447c478bd9Sstevel@tonic-gate char *lc; 9457c478bd9Sstevel@tonic-gate char jbuf[MAXHOSTNAMELEN]; 9467c478bd9Sstevel@tonic-gate char lcbuf[MAXLINE]; 9477c478bd9Sstevel@tonic-gate 9487c478bd9Sstevel@tonic-gate /* Get $j */ 9497c478bd9Sstevel@tonic-gate expand("\201j", jbuf, sizeof jbuf, &BlankEnvelope); 9507c478bd9Sstevel@tonic-gate if (jbuf[0] == '\0') 9517c478bd9Sstevel@tonic-gate { 9527c478bd9Sstevel@tonic-gate (void) sm_strlcpy(jbuf, "localhost", 9537c478bd9Sstevel@tonic-gate sizeof jbuf); 9547c478bd9Sstevel@tonic-gate } 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate /* impose the default schema */ 9577c478bd9Sstevel@tonic-gate lc = macvalue(macid("{sendmailMTACluster}"), CurEnv); 9587c478bd9Sstevel@tonic-gate if (lc == NULL) 9597c478bd9Sstevel@tonic-gate lc = ""; 9607c478bd9Sstevel@tonic-gate else 9617c478bd9Sstevel@tonic-gate { 9627c478bd9Sstevel@tonic-gate expand(lc, lcbuf, sizeof lcbuf, CurEnv); 9637c478bd9Sstevel@tonic-gate lc = lcbuf; 9647c478bd9Sstevel@tonic-gate } 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate cl = "ldap"; 9677c478bd9Sstevel@tonic-gate n = sm_snprintf(buf, sizeof buf, 9687c478bd9Sstevel@tonic-gate "-k (&(objectClass=sendmailMTAClass)(sendmailMTAClassName=%s)(|(sendmailMTACluster=%s)(sendmailMTAHost=%s))) -v sendmailMTAClassValue,sendmailMTAClassSearch:FILTER:sendmailMTAClass,sendmailMTAClassURL:URL:sendmailMTAClass", 9697c478bd9Sstevel@tonic-gate mn, lc, jbuf); 9707c478bd9Sstevel@tonic-gate if (n >= sizeof buf) 9717c478bd9Sstevel@tonic-gate { 9727c478bd9Sstevel@tonic-gate syserr("fileclass: F{%s}: Default LDAP string too long", 9737c478bd9Sstevel@tonic-gate mn); 9747c478bd9Sstevel@tonic-gate sm_free(mn); 9757c478bd9Sstevel@tonic-gate return; 9767c478bd9Sstevel@tonic-gate } 9777c478bd9Sstevel@tonic-gate spec = buf; 9787c478bd9Sstevel@tonic-gate } 9797c478bd9Sstevel@tonic-gate else 9807c478bd9Sstevel@tonic-gate #endif /* LDAPMAP */ 9817c478bd9Sstevel@tonic-gate { 9827c478bd9Sstevel@tonic-gate if ((spec = strchr(cl, ':')) == NULL) 9837c478bd9Sstevel@tonic-gate { 9847c478bd9Sstevel@tonic-gate syserr("fileclass: F{%s}: missing map class", 9857c478bd9Sstevel@tonic-gate mn); 9867c478bd9Sstevel@tonic-gate sm_free(mn); 9877c478bd9Sstevel@tonic-gate return; 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate *spec++ ='\0'; 9907c478bd9Sstevel@tonic-gate } 9917c478bd9Sstevel@tonic-gate 9927c478bd9Sstevel@tonic-gate /* set up map structure */ 9937c478bd9Sstevel@tonic-gate mapclass = stab(cl, ST_MAPCLASS, ST_FIND); 9947c478bd9Sstevel@tonic-gate if (mapclass == NULL) 9957c478bd9Sstevel@tonic-gate { 9967c478bd9Sstevel@tonic-gate syserr("fileclass: F{%s}: class %s not available", 9977c478bd9Sstevel@tonic-gate mn, cl); 9987c478bd9Sstevel@tonic-gate sm_free(mn); 9997c478bd9Sstevel@tonic-gate return; 10007c478bd9Sstevel@tonic-gate } 10017c478bd9Sstevel@tonic-gate memset(&map, '\0', sizeof map); 10027c478bd9Sstevel@tonic-gate map.map_class = &mapclass->s_mapclass; 10037c478bd9Sstevel@tonic-gate map.map_mname = mn; 10047c478bd9Sstevel@tonic-gate map.map_mflags |= MF_FILECLASS; 10057c478bd9Sstevel@tonic-gate 10067c478bd9Sstevel@tonic-gate if (tTd(37, 5)) 10077c478bd9Sstevel@tonic-gate sm_dprintf("fileclass: F{%s}: map class %s, key %s, spec %s\n", 10087c478bd9Sstevel@tonic-gate mn, cl, key, spec); 10097c478bd9Sstevel@tonic-gate 10107c478bd9Sstevel@tonic-gate 10117c478bd9Sstevel@tonic-gate /* parse map spec */ 10127c478bd9Sstevel@tonic-gate if (!map.map_class->map_parse(&map, spec)) 10137c478bd9Sstevel@tonic-gate { 10147c478bd9Sstevel@tonic-gate /* map_parse() showed the error already */ 10157c478bd9Sstevel@tonic-gate sm_free(mn); 10167c478bd9Sstevel@tonic-gate return; 10177c478bd9Sstevel@tonic-gate } 10187c478bd9Sstevel@tonic-gate map.map_mflags |= MF_VALID; 10197c478bd9Sstevel@tonic-gate 10207c478bd9Sstevel@tonic-gate /* open map */ 10217c478bd9Sstevel@tonic-gate if (map.map_class->map_open(&map, O_RDONLY)) 10227c478bd9Sstevel@tonic-gate { 10237c478bd9Sstevel@tonic-gate map.map_mflags |= MF_OPEN; 10247c478bd9Sstevel@tonic-gate map.map_pid = getpid(); 10257c478bd9Sstevel@tonic-gate } 10267c478bd9Sstevel@tonic-gate else 10277c478bd9Sstevel@tonic-gate { 10287c478bd9Sstevel@tonic-gate if (!optional && 10297c478bd9Sstevel@tonic-gate !bitset(MF_OPTIONAL, map.map_mflags)) 10307c478bd9Sstevel@tonic-gate syserr("fileclass: F{%s}: map open failed", 10317c478bd9Sstevel@tonic-gate mn); 10327c478bd9Sstevel@tonic-gate sm_free(mn); 10337c478bd9Sstevel@tonic-gate return; 10347c478bd9Sstevel@tonic-gate } 10357c478bd9Sstevel@tonic-gate 10367c478bd9Sstevel@tonic-gate /* lookup */ 10377c478bd9Sstevel@tonic-gate p = (*map.map_class->map_lookup)(&map, key, NULL, &status); 10387c478bd9Sstevel@tonic-gate if (status != EX_OK && status != EX_NOTFOUND) 10397c478bd9Sstevel@tonic-gate { 10407c478bd9Sstevel@tonic-gate if (!optional) 10417c478bd9Sstevel@tonic-gate syserr("fileclass: F{%s}: map lookup failed", 10427c478bd9Sstevel@tonic-gate mn); 10437c478bd9Sstevel@tonic-gate p = NULL; 10447c478bd9Sstevel@tonic-gate } 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate /* use the results */ 10477c478bd9Sstevel@tonic-gate if (p != NULL) 10487c478bd9Sstevel@tonic-gate parse_class_words(class, p); 10497c478bd9Sstevel@tonic-gate 10507c478bd9Sstevel@tonic-gate /* close map */ 10517c478bd9Sstevel@tonic-gate map.map_mflags |= MF_CLOSING; 10527c478bd9Sstevel@tonic-gate map.map_class->map_close(&map); 10537c478bd9Sstevel@tonic-gate map.map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING); 10547c478bd9Sstevel@tonic-gate sm_free(mn); 10557c478bd9Sstevel@tonic-gate return; 10567c478bd9Sstevel@tonic-gate } 10577c478bd9Sstevel@tonic-gate else if (filename[0] == '|') 10587c478bd9Sstevel@tonic-gate { 10597c478bd9Sstevel@tonic-gate auto int fd; 10607c478bd9Sstevel@tonic-gate int i; 10617c478bd9Sstevel@tonic-gate char *argv[MAXPV + 1]; 10627c478bd9Sstevel@tonic-gate 10637c478bd9Sstevel@tonic-gate i = 0; 10647c478bd9Sstevel@tonic-gate for (p = strtok(&filename[1], " \t"); 10657c478bd9Sstevel@tonic-gate p != NULL && i < MAXPV; 10667c478bd9Sstevel@tonic-gate p = strtok(NULL, " \t")) 10677c478bd9Sstevel@tonic-gate argv[i++] = p; 10687c478bd9Sstevel@tonic-gate argv[i] = NULL; 10697c478bd9Sstevel@tonic-gate pid = prog_open(argv, &fd, CurEnv); 10707c478bd9Sstevel@tonic-gate if (pid < 0) 10717c478bd9Sstevel@tonic-gate f = NULL; 10727c478bd9Sstevel@tonic-gate else 10737c478bd9Sstevel@tonic-gate f = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 10747c478bd9Sstevel@tonic-gate (void *) &fd, SM_IO_RDONLY, NULL); 10757c478bd9Sstevel@tonic-gate } 10767c478bd9Sstevel@tonic-gate else 10777c478bd9Sstevel@tonic-gate { 10787c478bd9Sstevel@tonic-gate pid = -1; 10797c478bd9Sstevel@tonic-gate sff = SFF_REGONLY; 10807c478bd9Sstevel@tonic-gate if (!bitnset(DBS_CLASSFILEINUNSAFEDIRPATH, DontBlameSendmail)) 10817c478bd9Sstevel@tonic-gate sff |= SFF_SAFEDIRPATH; 10827c478bd9Sstevel@tonic-gate if (!bitnset(DBS_LINKEDCLASSFILEINWRITABLEDIR, 10837c478bd9Sstevel@tonic-gate DontBlameSendmail)) 10847c478bd9Sstevel@tonic-gate sff |= SFF_NOWLINK; 10857c478bd9Sstevel@tonic-gate if (safe) 10867c478bd9Sstevel@tonic-gate sff |= SFF_OPENASROOT; 10877c478bd9Sstevel@tonic-gate else if (RealUid == 0) 10887c478bd9Sstevel@tonic-gate sff |= SFF_ROOTOK; 10897c478bd9Sstevel@tonic-gate if (DontLockReadFiles) 10907c478bd9Sstevel@tonic-gate sff |= SFF_NOLOCK; 10917c478bd9Sstevel@tonic-gate f = safefopen(filename, O_RDONLY, 0, sff); 10927c478bd9Sstevel@tonic-gate } 10937c478bd9Sstevel@tonic-gate if (f == NULL) 10947c478bd9Sstevel@tonic-gate { 10957c478bd9Sstevel@tonic-gate if (!optional) 10967c478bd9Sstevel@tonic-gate syserr("fileclass: cannot open '%s'", filename); 10977c478bd9Sstevel@tonic-gate return; 10987c478bd9Sstevel@tonic-gate } 10997c478bd9Sstevel@tonic-gate 11007c478bd9Sstevel@tonic-gate while (sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof buf) != NULL) 11017c478bd9Sstevel@tonic-gate { 11027c478bd9Sstevel@tonic-gate #if SCANF 11037c478bd9Sstevel@tonic-gate char wordbuf[MAXLINE + 1]; 11047c478bd9Sstevel@tonic-gate #endif /* SCANF */ 11057c478bd9Sstevel@tonic-gate 11067c478bd9Sstevel@tonic-gate if (buf[0] == '#') 11077c478bd9Sstevel@tonic-gate continue; 11087c478bd9Sstevel@tonic-gate #if SCANF 11097c478bd9Sstevel@tonic-gate if (sm_io_sscanf(buf, fmt, wordbuf) != 1) 11107c478bd9Sstevel@tonic-gate continue; 11117c478bd9Sstevel@tonic-gate p = wordbuf; 11127c478bd9Sstevel@tonic-gate #else /* SCANF */ 11137c478bd9Sstevel@tonic-gate p = buf; 11147c478bd9Sstevel@tonic-gate #endif /* SCANF */ 11157c478bd9Sstevel@tonic-gate 11167c478bd9Sstevel@tonic-gate parse_class_words(class, p); 11177c478bd9Sstevel@tonic-gate 11187c478bd9Sstevel@tonic-gate /* 11197c478bd9Sstevel@tonic-gate ** If anything else is added here, 11207c478bd9Sstevel@tonic-gate ** check if the '@' map case above 11217c478bd9Sstevel@tonic-gate ** needs the code as well. 11227c478bd9Sstevel@tonic-gate */ 11237c478bd9Sstevel@tonic-gate } 11247c478bd9Sstevel@tonic-gate 11257c478bd9Sstevel@tonic-gate (void) sm_io_close(f, SM_TIME_DEFAULT); 11267c478bd9Sstevel@tonic-gate if (pid > 0) 11277c478bd9Sstevel@tonic-gate (void) waitfor(pid); 11287c478bd9Sstevel@tonic-gate } 11297c478bd9Sstevel@tonic-gate /* 11307c478bd9Sstevel@tonic-gate ** MAKEMAILER -- define a new mailer. 11317c478bd9Sstevel@tonic-gate ** 11327c478bd9Sstevel@tonic-gate ** Parameters: 11337c478bd9Sstevel@tonic-gate ** line -- description of mailer. This is in labeled 11347c478bd9Sstevel@tonic-gate ** fields. The fields are: 11357c478bd9Sstevel@tonic-gate ** A -- the argv for this mailer 11367c478bd9Sstevel@tonic-gate ** C -- the character set for MIME conversions 11377c478bd9Sstevel@tonic-gate ** D -- the directory to run in 11387c478bd9Sstevel@tonic-gate ** E -- the eol string 11397c478bd9Sstevel@tonic-gate ** F -- the flags associated with the mailer 11407c478bd9Sstevel@tonic-gate ** L -- the maximum line length 11417c478bd9Sstevel@tonic-gate ** M -- the maximum message size 11427c478bd9Sstevel@tonic-gate ** N -- the niceness at which to run 11437c478bd9Sstevel@tonic-gate ** P -- the path to the mailer 11447c478bd9Sstevel@tonic-gate ** Q -- the queue group for the mailer 11457c478bd9Sstevel@tonic-gate ** R -- the recipient rewriting set 11467c478bd9Sstevel@tonic-gate ** S -- the sender rewriting set 11477c478bd9Sstevel@tonic-gate ** T -- the mailer type (for DSNs) 11487c478bd9Sstevel@tonic-gate ** U -- the uid to run as 11497c478bd9Sstevel@tonic-gate ** W -- the time to wait at the end 11507c478bd9Sstevel@tonic-gate ** m -- maximum messages per connection 11517c478bd9Sstevel@tonic-gate ** r -- maximum number of recipients per message 11527c478bd9Sstevel@tonic-gate ** / -- new root directory 11537c478bd9Sstevel@tonic-gate ** The first word is the canonical name of the mailer. 11547c478bd9Sstevel@tonic-gate ** 11557c478bd9Sstevel@tonic-gate ** Returns: 11567c478bd9Sstevel@tonic-gate ** none. 11577c478bd9Sstevel@tonic-gate ** 11587c478bd9Sstevel@tonic-gate ** Side Effects: 11597c478bd9Sstevel@tonic-gate ** enters the mailer into the mailer table. 11607c478bd9Sstevel@tonic-gate */ 11617c478bd9Sstevel@tonic-gate 11627c478bd9Sstevel@tonic-gate void 11637c478bd9Sstevel@tonic-gate makemailer(line) 11647c478bd9Sstevel@tonic-gate char *line; 11657c478bd9Sstevel@tonic-gate { 11667c478bd9Sstevel@tonic-gate register char *p; 11677c478bd9Sstevel@tonic-gate register struct mailer *m; 11687c478bd9Sstevel@tonic-gate register STAB *s; 11697c478bd9Sstevel@tonic-gate int i; 11707c478bd9Sstevel@tonic-gate char fcode; 11717c478bd9Sstevel@tonic-gate auto char *endp; 11727c478bd9Sstevel@tonic-gate static int nextmailer = 0; /* "free" index into Mailer struct */ 11737c478bd9Sstevel@tonic-gate 11747c478bd9Sstevel@tonic-gate /* allocate a mailer and set up defaults */ 11757c478bd9Sstevel@tonic-gate m = (struct mailer *) xalloc(sizeof *m); 11767c478bd9Sstevel@tonic-gate memset((char *) m, '\0', sizeof *m); 11777c478bd9Sstevel@tonic-gate errno = 0; /* avoid bogus error text */ 11787c478bd9Sstevel@tonic-gate 11797c478bd9Sstevel@tonic-gate /* collect the mailer name */ 11807c478bd9Sstevel@tonic-gate for (p = line; 11817c478bd9Sstevel@tonic-gate *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p)); 11827c478bd9Sstevel@tonic-gate p++) 11837c478bd9Sstevel@tonic-gate continue; 11847c478bd9Sstevel@tonic-gate if (*p != '\0') 11857c478bd9Sstevel@tonic-gate *p++ = '\0'; 11867c478bd9Sstevel@tonic-gate if (line[0] == '\0') 11877c478bd9Sstevel@tonic-gate { 11887c478bd9Sstevel@tonic-gate syserr("name required for mailer"); 11897c478bd9Sstevel@tonic-gate return; 11907c478bd9Sstevel@tonic-gate } 11917c478bd9Sstevel@tonic-gate m->m_name = newstr(line); 11927c478bd9Sstevel@tonic-gate m->m_qgrp = NOQGRP; 11937c478bd9Sstevel@tonic-gate m->m_uid = NO_UID; 11947c478bd9Sstevel@tonic-gate m->m_gid = NO_GID; 11957c478bd9Sstevel@tonic-gate 11967c478bd9Sstevel@tonic-gate /* now scan through and assign info from the fields */ 11977c478bd9Sstevel@tonic-gate while (*p != '\0') 11987c478bd9Sstevel@tonic-gate { 11997c478bd9Sstevel@tonic-gate auto char *delimptr; 12007c478bd9Sstevel@tonic-gate 12017c478bd9Sstevel@tonic-gate while (*p != '\0' && 12027c478bd9Sstevel@tonic-gate (*p == ',' || (isascii(*p) && isspace(*p)))) 12037c478bd9Sstevel@tonic-gate p++; 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate /* p now points to field code */ 12067c478bd9Sstevel@tonic-gate fcode = *p; 12077c478bd9Sstevel@tonic-gate while (*p != '\0' && *p != '=' && *p != ',') 12087c478bd9Sstevel@tonic-gate p++; 12097c478bd9Sstevel@tonic-gate if (*p++ != '=') 12107c478bd9Sstevel@tonic-gate { 12117c478bd9Sstevel@tonic-gate syserr("mailer %s: `=' expected", m->m_name); 12127c478bd9Sstevel@tonic-gate return; 12137c478bd9Sstevel@tonic-gate } 12147c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 12157c478bd9Sstevel@tonic-gate p++; 12167c478bd9Sstevel@tonic-gate 12177c478bd9Sstevel@tonic-gate /* p now points to the field body */ 12187c478bd9Sstevel@tonic-gate p = munchstring(p, &delimptr, ','); 12197c478bd9Sstevel@tonic-gate 12207c478bd9Sstevel@tonic-gate /* install the field into the mailer struct */ 12217c478bd9Sstevel@tonic-gate switch (fcode) 12227c478bd9Sstevel@tonic-gate { 12237c478bd9Sstevel@tonic-gate case 'P': /* pathname */ 12247c478bd9Sstevel@tonic-gate if (*p != '\0') /* error is issued below */ 12257c478bd9Sstevel@tonic-gate m->m_mailer = newstr(p); 12267c478bd9Sstevel@tonic-gate break; 12277c478bd9Sstevel@tonic-gate 12287c478bd9Sstevel@tonic-gate case 'F': /* flags */ 12297c478bd9Sstevel@tonic-gate for (; *p != '\0'; p++) 12307c478bd9Sstevel@tonic-gate { 12317c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isspace(*p))) 12327c478bd9Sstevel@tonic-gate { 12337c478bd9Sstevel@tonic-gate #if _FFR_DEPRECATE_MAILER_FLAG_I 12347c478bd9Sstevel@tonic-gate if (*p == M_INTERNAL) 12357c478bd9Sstevel@tonic-gate sm_syslog(LOG_WARNING, NOQID, 12367c478bd9Sstevel@tonic-gate "WARNING: mailer=%s, flag=%c deprecated", 12377c478bd9Sstevel@tonic-gate m->m_name, *p); 12387c478bd9Sstevel@tonic-gate #endif /* _FFR_DEPRECATE_MAILER_FLAG_I */ 12397c478bd9Sstevel@tonic-gate setbitn(bitidx(*p), m->m_flags); 12407c478bd9Sstevel@tonic-gate } 12417c478bd9Sstevel@tonic-gate } 12427c478bd9Sstevel@tonic-gate break; 12437c478bd9Sstevel@tonic-gate 12447c478bd9Sstevel@tonic-gate case 'S': /* sender rewriting ruleset */ 12457c478bd9Sstevel@tonic-gate case 'R': /* recipient rewriting ruleset */ 12467c478bd9Sstevel@tonic-gate i = strtorwset(p, &endp, ST_ENTER); 12477c478bd9Sstevel@tonic-gate if (i < 0) 12487c478bd9Sstevel@tonic-gate return; 12497c478bd9Sstevel@tonic-gate if (fcode == 'S') 12507c478bd9Sstevel@tonic-gate m->m_sh_rwset = m->m_se_rwset = i; 12517c478bd9Sstevel@tonic-gate else 12527c478bd9Sstevel@tonic-gate m->m_rh_rwset = m->m_re_rwset = i; 12537c478bd9Sstevel@tonic-gate 12547c478bd9Sstevel@tonic-gate p = endp; 12557c478bd9Sstevel@tonic-gate if (*p++ == '/') 12567c478bd9Sstevel@tonic-gate { 12577c478bd9Sstevel@tonic-gate i = strtorwset(p, NULL, ST_ENTER); 12587c478bd9Sstevel@tonic-gate if (i < 0) 12597c478bd9Sstevel@tonic-gate return; 12607c478bd9Sstevel@tonic-gate if (fcode == 'S') 12617c478bd9Sstevel@tonic-gate m->m_sh_rwset = i; 12627c478bd9Sstevel@tonic-gate else 12637c478bd9Sstevel@tonic-gate m->m_rh_rwset = i; 12647c478bd9Sstevel@tonic-gate } 12657c478bd9Sstevel@tonic-gate break; 12667c478bd9Sstevel@tonic-gate 12677c478bd9Sstevel@tonic-gate case 'E': /* end of line string */ 12687c478bd9Sstevel@tonic-gate if (*p == '\0') 12697c478bd9Sstevel@tonic-gate syserr("mailer %s: null end-of-line string", 12707c478bd9Sstevel@tonic-gate m->m_name); 12717c478bd9Sstevel@tonic-gate else 12727c478bd9Sstevel@tonic-gate m->m_eol = newstr(p); 12737c478bd9Sstevel@tonic-gate break; 12747c478bd9Sstevel@tonic-gate 12757c478bd9Sstevel@tonic-gate case 'A': /* argument vector */ 12767c478bd9Sstevel@tonic-gate if (*p != '\0') /* error is issued below */ 12777c478bd9Sstevel@tonic-gate m->m_argv = makeargv(p); 12787c478bd9Sstevel@tonic-gate break; 12797c478bd9Sstevel@tonic-gate 12807c478bd9Sstevel@tonic-gate case 'M': /* maximum message size */ 12817c478bd9Sstevel@tonic-gate m->m_maxsize = atol(p); 12827c478bd9Sstevel@tonic-gate break; 12837c478bd9Sstevel@tonic-gate 12847c478bd9Sstevel@tonic-gate case 'm': /* maximum messages per connection */ 12857c478bd9Sstevel@tonic-gate m->m_maxdeliveries = atoi(p); 12867c478bd9Sstevel@tonic-gate break; 12877c478bd9Sstevel@tonic-gate 12887c478bd9Sstevel@tonic-gate case 'r': /* max recipient per envelope */ 12897c478bd9Sstevel@tonic-gate m->m_maxrcpt = atoi(p); 12907c478bd9Sstevel@tonic-gate break; 12917c478bd9Sstevel@tonic-gate 12927c478bd9Sstevel@tonic-gate case 'L': /* maximum line length */ 12937c478bd9Sstevel@tonic-gate m->m_linelimit = atoi(p); 12947c478bd9Sstevel@tonic-gate if (m->m_linelimit < 0) 12957c478bd9Sstevel@tonic-gate m->m_linelimit = 0; 12967c478bd9Sstevel@tonic-gate break; 12977c478bd9Sstevel@tonic-gate 12987c478bd9Sstevel@tonic-gate case 'N': /* run niceness */ 12997c478bd9Sstevel@tonic-gate m->m_nice = atoi(p); 13007c478bd9Sstevel@tonic-gate break; 13017c478bd9Sstevel@tonic-gate 13027c478bd9Sstevel@tonic-gate case 'D': /* working directory */ 13037c478bd9Sstevel@tonic-gate if (*p == '\0') 13047c478bd9Sstevel@tonic-gate syserr("mailer %s: null working directory", 13057c478bd9Sstevel@tonic-gate m->m_name); 13067c478bd9Sstevel@tonic-gate else 13077c478bd9Sstevel@tonic-gate m->m_execdir = newstr(p); 13087c478bd9Sstevel@tonic-gate break; 13097c478bd9Sstevel@tonic-gate 13107c478bd9Sstevel@tonic-gate case 'C': /* default charset */ 13117c478bd9Sstevel@tonic-gate if (*p == '\0') 13127c478bd9Sstevel@tonic-gate syserr("mailer %s: null charset", m->m_name); 13137c478bd9Sstevel@tonic-gate else 13147c478bd9Sstevel@tonic-gate m->m_defcharset = newstr(p); 13157c478bd9Sstevel@tonic-gate break; 13167c478bd9Sstevel@tonic-gate 13177c478bd9Sstevel@tonic-gate case 'Q': /* queue for this mailer */ 13187c478bd9Sstevel@tonic-gate if (*p == '\0') 13197c478bd9Sstevel@tonic-gate { 13207c478bd9Sstevel@tonic-gate syserr("mailer %s: null queue", m->m_name); 13217c478bd9Sstevel@tonic-gate break; 13227c478bd9Sstevel@tonic-gate } 13237c478bd9Sstevel@tonic-gate s = stab(p, ST_QUEUE, ST_FIND); 13247c478bd9Sstevel@tonic-gate if (s == NULL) 13257c478bd9Sstevel@tonic-gate syserr("mailer %s: unknown queue %s", 13267c478bd9Sstevel@tonic-gate m->m_name, p); 13277c478bd9Sstevel@tonic-gate else 13287c478bd9Sstevel@tonic-gate m->m_qgrp = s->s_quegrp->qg_index; 13297c478bd9Sstevel@tonic-gate break; 13307c478bd9Sstevel@tonic-gate 13317c478bd9Sstevel@tonic-gate case 'T': /* MTA-Name/Address/Diagnostic types */ 13327c478bd9Sstevel@tonic-gate /* extract MTA name type; default to "dns" */ 13337c478bd9Sstevel@tonic-gate m->m_mtatype = newstr(p); 13347c478bd9Sstevel@tonic-gate p = strchr(m->m_mtatype, '/'); 13357c478bd9Sstevel@tonic-gate if (p != NULL) 13367c478bd9Sstevel@tonic-gate { 13377c478bd9Sstevel@tonic-gate *p++ = '\0'; 13387c478bd9Sstevel@tonic-gate if (*p == '\0') 13397c478bd9Sstevel@tonic-gate p = NULL; 13407c478bd9Sstevel@tonic-gate } 13417c478bd9Sstevel@tonic-gate if (*m->m_mtatype == '\0') 13427c478bd9Sstevel@tonic-gate m->m_mtatype = "dns"; 13437c478bd9Sstevel@tonic-gate 13447c478bd9Sstevel@tonic-gate /* extract address type; default to "rfc822" */ 13457c478bd9Sstevel@tonic-gate m->m_addrtype = p; 13467c478bd9Sstevel@tonic-gate if (p != NULL) 13477c478bd9Sstevel@tonic-gate p = strchr(p, '/'); 13487c478bd9Sstevel@tonic-gate if (p != NULL) 13497c478bd9Sstevel@tonic-gate { 13507c478bd9Sstevel@tonic-gate *p++ = '\0'; 13517c478bd9Sstevel@tonic-gate if (*p == '\0') 13527c478bd9Sstevel@tonic-gate p = NULL; 13537c478bd9Sstevel@tonic-gate } 13547c478bd9Sstevel@tonic-gate if (m->m_addrtype == NULL || *m->m_addrtype == '\0') 13557c478bd9Sstevel@tonic-gate m->m_addrtype = "rfc822"; 13567c478bd9Sstevel@tonic-gate 13577c478bd9Sstevel@tonic-gate /* extract diagnostic type; default to "smtp" */ 13587c478bd9Sstevel@tonic-gate m->m_diagtype = p; 13597c478bd9Sstevel@tonic-gate if (m->m_diagtype == NULL || *m->m_diagtype == '\0') 13607c478bd9Sstevel@tonic-gate m->m_diagtype = "smtp"; 13617c478bd9Sstevel@tonic-gate break; 13627c478bd9Sstevel@tonic-gate 13637c478bd9Sstevel@tonic-gate case 'U': /* user id */ 13647c478bd9Sstevel@tonic-gate if (isascii(*p) && !isdigit(*p)) 13657c478bd9Sstevel@tonic-gate { 13667c478bd9Sstevel@tonic-gate char *q = p; 13677c478bd9Sstevel@tonic-gate struct passwd *pw; 13687c478bd9Sstevel@tonic-gate 13697c478bd9Sstevel@tonic-gate while (*p != '\0' && isascii(*p) && 13707c478bd9Sstevel@tonic-gate (isalnum(*p) || strchr("-_", *p) != NULL)) 13717c478bd9Sstevel@tonic-gate p++; 13727c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 13737c478bd9Sstevel@tonic-gate *p++ = '\0'; 13747c478bd9Sstevel@tonic-gate if (*p != '\0') 13757c478bd9Sstevel@tonic-gate *p++ = '\0'; 13767c478bd9Sstevel@tonic-gate if (*q == '\0') 13777c478bd9Sstevel@tonic-gate { 13787c478bd9Sstevel@tonic-gate syserr("mailer %s: null user name", 13797c478bd9Sstevel@tonic-gate m->m_name); 13807c478bd9Sstevel@tonic-gate break; 13817c478bd9Sstevel@tonic-gate } 13827c478bd9Sstevel@tonic-gate pw = sm_getpwnam(q); 13837c478bd9Sstevel@tonic-gate if (pw == NULL) 13847c478bd9Sstevel@tonic-gate { 13857c478bd9Sstevel@tonic-gate syserr("readcf: mailer U= flag: unknown user %s", q); 13867c478bd9Sstevel@tonic-gate break; 13877c478bd9Sstevel@tonic-gate } 13887c478bd9Sstevel@tonic-gate else 13897c478bd9Sstevel@tonic-gate { 13907c478bd9Sstevel@tonic-gate m->m_uid = pw->pw_uid; 13917c478bd9Sstevel@tonic-gate m->m_gid = pw->pw_gid; 13927c478bd9Sstevel@tonic-gate } 13937c478bd9Sstevel@tonic-gate } 13947c478bd9Sstevel@tonic-gate else 13957c478bd9Sstevel@tonic-gate { 13967c478bd9Sstevel@tonic-gate auto char *q; 13977c478bd9Sstevel@tonic-gate 13987c478bd9Sstevel@tonic-gate m->m_uid = strtol(p, &q, 0); 13997c478bd9Sstevel@tonic-gate p = q; 14007c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 14017c478bd9Sstevel@tonic-gate p++; 14027c478bd9Sstevel@tonic-gate if (*p != '\0') 14037c478bd9Sstevel@tonic-gate p++; 14047c478bd9Sstevel@tonic-gate } 14057c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 14067c478bd9Sstevel@tonic-gate p++; 14077c478bd9Sstevel@tonic-gate if (*p == '\0') 14087c478bd9Sstevel@tonic-gate break; 14097c478bd9Sstevel@tonic-gate if (isascii(*p) && !isdigit(*p)) 14107c478bd9Sstevel@tonic-gate { 14117c478bd9Sstevel@tonic-gate char *q = p; 14127c478bd9Sstevel@tonic-gate struct group *gr; 14137c478bd9Sstevel@tonic-gate 14147c478bd9Sstevel@tonic-gate while (isascii(*p) && isalnum(*p)) 14157c478bd9Sstevel@tonic-gate p++; 14167c478bd9Sstevel@tonic-gate *p++ = '\0'; 14177c478bd9Sstevel@tonic-gate if (*q == '\0') 14187c478bd9Sstevel@tonic-gate { 14197c478bd9Sstevel@tonic-gate syserr("mailer %s: null group name", 14207c478bd9Sstevel@tonic-gate m->m_name); 14217c478bd9Sstevel@tonic-gate break; 14227c478bd9Sstevel@tonic-gate } 14237c478bd9Sstevel@tonic-gate gr = getgrnam(q); 14247c478bd9Sstevel@tonic-gate if (gr == NULL) 14257c478bd9Sstevel@tonic-gate { 14267c478bd9Sstevel@tonic-gate syserr("readcf: mailer U= flag: unknown group %s", q); 14277c478bd9Sstevel@tonic-gate break; 14287c478bd9Sstevel@tonic-gate } 14297c478bd9Sstevel@tonic-gate else 14307c478bd9Sstevel@tonic-gate m->m_gid = gr->gr_gid; 14317c478bd9Sstevel@tonic-gate } 14327c478bd9Sstevel@tonic-gate else 14337c478bd9Sstevel@tonic-gate { 14347c478bd9Sstevel@tonic-gate m->m_gid = strtol(p, NULL, 0); 14357c478bd9Sstevel@tonic-gate } 14367c478bd9Sstevel@tonic-gate break; 14377c478bd9Sstevel@tonic-gate 14387c478bd9Sstevel@tonic-gate case 'W': /* wait timeout */ 14397c478bd9Sstevel@tonic-gate m->m_wait = convtime(p, 's'); 14407c478bd9Sstevel@tonic-gate break; 14417c478bd9Sstevel@tonic-gate 14427c478bd9Sstevel@tonic-gate case '/': /* new root directory */ 14437c478bd9Sstevel@tonic-gate if (*p == '\0') 14447c478bd9Sstevel@tonic-gate syserr("mailer %s: null root directory", 14457c478bd9Sstevel@tonic-gate m->m_name); 14467c478bd9Sstevel@tonic-gate else 14477c478bd9Sstevel@tonic-gate m->m_rootdir = newstr(p); 14487c478bd9Sstevel@tonic-gate break; 14497c478bd9Sstevel@tonic-gate 14507c478bd9Sstevel@tonic-gate default: 14517c478bd9Sstevel@tonic-gate syserr("M%s: unknown mailer equate %c=", 14527c478bd9Sstevel@tonic-gate m->m_name, fcode); 14537c478bd9Sstevel@tonic-gate break; 14547c478bd9Sstevel@tonic-gate } 14557c478bd9Sstevel@tonic-gate 14567c478bd9Sstevel@tonic-gate p = delimptr; 14577c478bd9Sstevel@tonic-gate } 14587c478bd9Sstevel@tonic-gate 14597c478bd9Sstevel@tonic-gate #if !HASRRESVPORT 14607c478bd9Sstevel@tonic-gate if (bitnset(M_SECURE_PORT, m->m_flags)) 14617c478bd9Sstevel@tonic-gate { 14627c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 14637c478bd9Sstevel@tonic-gate "M%s: Warning: F=%c set on system that doesn't support rresvport()\n", 14647c478bd9Sstevel@tonic-gate m->m_name, M_SECURE_PORT); 14657c478bd9Sstevel@tonic-gate } 14667c478bd9Sstevel@tonic-gate #endif /* !HASRRESVPORT */ 14677c478bd9Sstevel@tonic-gate 14687c478bd9Sstevel@tonic-gate #if !HASNICE 14697c478bd9Sstevel@tonic-gate if (m->m_nice != 0) 14707c478bd9Sstevel@tonic-gate { 14717c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 14727c478bd9Sstevel@tonic-gate "M%s: Warning: N= set on system that doesn't support nice()\n", 14737c478bd9Sstevel@tonic-gate m->m_name); 14747c478bd9Sstevel@tonic-gate } 14757c478bd9Sstevel@tonic-gate #endif /* !HASNICE */ 14767c478bd9Sstevel@tonic-gate 14777c478bd9Sstevel@tonic-gate /* do some rationality checking */ 14787c478bd9Sstevel@tonic-gate if (m->m_argv == NULL) 14797c478bd9Sstevel@tonic-gate { 14807c478bd9Sstevel@tonic-gate syserr("M%s: A= argument required", m->m_name); 14817c478bd9Sstevel@tonic-gate return; 14827c478bd9Sstevel@tonic-gate } 14837c478bd9Sstevel@tonic-gate if (m->m_mailer == NULL) 14847c478bd9Sstevel@tonic-gate { 14857c478bd9Sstevel@tonic-gate syserr("M%s: P= argument required", m->m_name); 14867c478bd9Sstevel@tonic-gate return; 14877c478bd9Sstevel@tonic-gate } 14887c478bd9Sstevel@tonic-gate 14897c478bd9Sstevel@tonic-gate if (nextmailer >= MAXMAILERS) 14907c478bd9Sstevel@tonic-gate { 14917c478bd9Sstevel@tonic-gate syserr("too many mailers defined (%d max)", MAXMAILERS); 14927c478bd9Sstevel@tonic-gate return; 14937c478bd9Sstevel@tonic-gate } 14947c478bd9Sstevel@tonic-gate 14957c478bd9Sstevel@tonic-gate if (m->m_maxrcpt <= 0) 14967c478bd9Sstevel@tonic-gate m->m_maxrcpt = DEFAULT_MAX_RCPT; 14977c478bd9Sstevel@tonic-gate 14987c478bd9Sstevel@tonic-gate /* do some heuristic cleanup for back compatibility */ 14997c478bd9Sstevel@tonic-gate if (bitnset(M_LIMITS, m->m_flags)) 15007c478bd9Sstevel@tonic-gate { 15017c478bd9Sstevel@tonic-gate if (m->m_linelimit == 0) 15027c478bd9Sstevel@tonic-gate m->m_linelimit = SMTPLINELIM; 15037c478bd9Sstevel@tonic-gate if (ConfigLevel < 2) 15047c478bd9Sstevel@tonic-gate setbitn(M_7BITS, m->m_flags); 15057c478bd9Sstevel@tonic-gate } 15067c478bd9Sstevel@tonic-gate 15077c478bd9Sstevel@tonic-gate if (strcmp(m->m_mailer, "[TCP]") == 0) 15087c478bd9Sstevel@tonic-gate { 15097c478bd9Sstevel@tonic-gate syserr("M%s: P=[TCP] must be replaced by P=[IPC]", m->m_name); 15107c478bd9Sstevel@tonic-gate return; 15117c478bd9Sstevel@tonic-gate } 15127c478bd9Sstevel@tonic-gate 15137c478bd9Sstevel@tonic-gate if (strcmp(m->m_mailer, "[IPC]") == 0) 15147c478bd9Sstevel@tonic-gate { 15157c478bd9Sstevel@tonic-gate /* Use the second argument for host or path to socket */ 15167c478bd9Sstevel@tonic-gate if (m->m_argv[0] == NULL || m->m_argv[1] == NULL || 15177c478bd9Sstevel@tonic-gate m->m_argv[1][0] == '\0') 15187c478bd9Sstevel@tonic-gate { 15197c478bd9Sstevel@tonic-gate syserr("M%s: too few parameters for %s mailer", 15207c478bd9Sstevel@tonic-gate m->m_name, m->m_mailer); 15217c478bd9Sstevel@tonic-gate return; 15227c478bd9Sstevel@tonic-gate } 15237c478bd9Sstevel@tonic-gate if (strcmp(m->m_argv[0], "TCP") != 0 15247c478bd9Sstevel@tonic-gate #if NETUNIX 15257c478bd9Sstevel@tonic-gate && strcmp(m->m_argv[0], "FILE") != 0 15267c478bd9Sstevel@tonic-gate #endif /* NETUNIX */ 15277c478bd9Sstevel@tonic-gate ) 15287c478bd9Sstevel@tonic-gate { 15297c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 15307c478bd9Sstevel@tonic-gate "M%s: Warning: first argument in %s mailer must be %s\n", 15317c478bd9Sstevel@tonic-gate m->m_name, m->m_mailer, 15327c478bd9Sstevel@tonic-gate #if NETUNIX 15337c478bd9Sstevel@tonic-gate "TCP or FILE" 15347c478bd9Sstevel@tonic-gate #else /* NETUNIX */ 15357c478bd9Sstevel@tonic-gate "TCP" 15367c478bd9Sstevel@tonic-gate #endif /* NETUNIX */ 15377c478bd9Sstevel@tonic-gate ); 15387c478bd9Sstevel@tonic-gate } 15397c478bd9Sstevel@tonic-gate if (m->m_mtatype == NULL) 15407c478bd9Sstevel@tonic-gate m->m_mtatype = "dns"; 15417c478bd9Sstevel@tonic-gate if (m->m_addrtype == NULL) 15427c478bd9Sstevel@tonic-gate m->m_addrtype = "rfc822"; 15437c478bd9Sstevel@tonic-gate if (m->m_diagtype == NULL) 15447c478bd9Sstevel@tonic-gate { 15457c478bd9Sstevel@tonic-gate if (m->m_argv[0] != NULL && 15467c478bd9Sstevel@tonic-gate strcmp(m->m_argv[0], "FILE") == 0) 15477c478bd9Sstevel@tonic-gate m->m_diagtype = "x-unix"; 15487c478bd9Sstevel@tonic-gate else 15497c478bd9Sstevel@tonic-gate m->m_diagtype = "smtp"; 15507c478bd9Sstevel@tonic-gate } 15517c478bd9Sstevel@tonic-gate } 15527c478bd9Sstevel@tonic-gate else if (strcmp(m->m_mailer, "[FILE]") == 0) 15537c478bd9Sstevel@tonic-gate { 15547c478bd9Sstevel@tonic-gate /* Use the second argument for filename */ 15557c478bd9Sstevel@tonic-gate if (m->m_argv[0] == NULL || m->m_argv[1] == NULL || 15567c478bd9Sstevel@tonic-gate m->m_argv[2] != NULL) 15577c478bd9Sstevel@tonic-gate { 15587c478bd9Sstevel@tonic-gate syserr("M%s: too %s parameters for [FILE] mailer", 15597c478bd9Sstevel@tonic-gate m->m_name, 15607c478bd9Sstevel@tonic-gate (m->m_argv[0] == NULL || 15617c478bd9Sstevel@tonic-gate m->m_argv[1] == NULL) ? "few" : "many"); 15627c478bd9Sstevel@tonic-gate return; 15637c478bd9Sstevel@tonic-gate } 15647c478bd9Sstevel@tonic-gate else if (strcmp(m->m_argv[0], "FILE") != 0) 15657c478bd9Sstevel@tonic-gate { 15667c478bd9Sstevel@tonic-gate syserr("M%s: first argument in [FILE] mailer must be FILE", 15677c478bd9Sstevel@tonic-gate m->m_name); 15687c478bd9Sstevel@tonic-gate return; 15697c478bd9Sstevel@tonic-gate } 15707c478bd9Sstevel@tonic-gate } 15717c478bd9Sstevel@tonic-gate 15727c478bd9Sstevel@tonic-gate if (m->m_eol == NULL) 15737c478bd9Sstevel@tonic-gate { 15747c478bd9Sstevel@tonic-gate char **pp; 15757c478bd9Sstevel@tonic-gate 15767c478bd9Sstevel@tonic-gate /* default for SMTP is \r\n; use \n for local delivery */ 15777c478bd9Sstevel@tonic-gate for (pp = m->m_argv; *pp != NULL; pp++) 15787c478bd9Sstevel@tonic-gate { 15797c478bd9Sstevel@tonic-gate for (p = *pp; *p != '\0'; ) 15807c478bd9Sstevel@tonic-gate { 15817c478bd9Sstevel@tonic-gate if ((*p++ & 0377) == MACROEXPAND && *p == 'u') 15827c478bd9Sstevel@tonic-gate break; 15837c478bd9Sstevel@tonic-gate } 15847c478bd9Sstevel@tonic-gate if (*p != '\0') 15857c478bd9Sstevel@tonic-gate break; 15867c478bd9Sstevel@tonic-gate } 15877c478bd9Sstevel@tonic-gate if (*pp == NULL) 15887c478bd9Sstevel@tonic-gate m->m_eol = "\r\n"; 15897c478bd9Sstevel@tonic-gate else 15907c478bd9Sstevel@tonic-gate m->m_eol = "\n"; 15917c478bd9Sstevel@tonic-gate } 15927c478bd9Sstevel@tonic-gate 15937c478bd9Sstevel@tonic-gate /* enter the mailer into the symbol table */ 15947c478bd9Sstevel@tonic-gate s = stab(m->m_name, ST_MAILER, ST_ENTER); 15957c478bd9Sstevel@tonic-gate if (s->s_mailer != NULL) 15967c478bd9Sstevel@tonic-gate { 15977c478bd9Sstevel@tonic-gate i = s->s_mailer->m_mno; 15987c478bd9Sstevel@tonic-gate sm_free(s->s_mailer); /* XXX */ 15997c478bd9Sstevel@tonic-gate } 16007c478bd9Sstevel@tonic-gate else 16017c478bd9Sstevel@tonic-gate { 16027c478bd9Sstevel@tonic-gate i = nextmailer++; 16037c478bd9Sstevel@tonic-gate } 16047c478bd9Sstevel@tonic-gate Mailer[i] = s->s_mailer = m; 16057c478bd9Sstevel@tonic-gate m->m_mno = i; 16067c478bd9Sstevel@tonic-gate } 16077c478bd9Sstevel@tonic-gate /* 16087c478bd9Sstevel@tonic-gate ** MUNCHSTRING -- translate a string into internal form. 16097c478bd9Sstevel@tonic-gate ** 16107c478bd9Sstevel@tonic-gate ** Parameters: 16117c478bd9Sstevel@tonic-gate ** p -- the string to munch. 16127c478bd9Sstevel@tonic-gate ** delimptr -- if non-NULL, set to the pointer of the 16137c478bd9Sstevel@tonic-gate ** field delimiter character. 16147c478bd9Sstevel@tonic-gate ** delim -- the delimiter for the field. 16157c478bd9Sstevel@tonic-gate ** 16167c478bd9Sstevel@tonic-gate ** Returns: 16177c478bd9Sstevel@tonic-gate ** the munched string. 16187c478bd9Sstevel@tonic-gate ** 16197c478bd9Sstevel@tonic-gate ** Side Effects: 16207c478bd9Sstevel@tonic-gate ** the munched string is a local static buffer. 16217c478bd9Sstevel@tonic-gate ** it must be copied before the function is called again. 16227c478bd9Sstevel@tonic-gate */ 16237c478bd9Sstevel@tonic-gate 16247c478bd9Sstevel@tonic-gate char * 16257c478bd9Sstevel@tonic-gate munchstring(p, delimptr, delim) 16267c478bd9Sstevel@tonic-gate register char *p; 16277c478bd9Sstevel@tonic-gate char **delimptr; 16287c478bd9Sstevel@tonic-gate int delim; 16297c478bd9Sstevel@tonic-gate { 16307c478bd9Sstevel@tonic-gate register char *q; 16317c478bd9Sstevel@tonic-gate bool backslash = false; 16327c478bd9Sstevel@tonic-gate bool quotemode = false; 16337c478bd9Sstevel@tonic-gate static char buf[MAXLINE]; 16347c478bd9Sstevel@tonic-gate 16357c478bd9Sstevel@tonic-gate for (q = buf; *p != '\0' && q < &buf[sizeof buf - 1]; p++) 16367c478bd9Sstevel@tonic-gate { 16377c478bd9Sstevel@tonic-gate if (backslash) 16387c478bd9Sstevel@tonic-gate { 16397c478bd9Sstevel@tonic-gate /* everything is roughly literal */ 16407c478bd9Sstevel@tonic-gate backslash = false; 16417c478bd9Sstevel@tonic-gate switch (*p) 16427c478bd9Sstevel@tonic-gate { 16437c478bd9Sstevel@tonic-gate case 'r': /* carriage return */ 16447c478bd9Sstevel@tonic-gate *q++ = '\r'; 16457c478bd9Sstevel@tonic-gate continue; 16467c478bd9Sstevel@tonic-gate 16477c478bd9Sstevel@tonic-gate case 'n': /* newline */ 16487c478bd9Sstevel@tonic-gate *q++ = '\n'; 16497c478bd9Sstevel@tonic-gate continue; 16507c478bd9Sstevel@tonic-gate 16517c478bd9Sstevel@tonic-gate case 'f': /* form feed */ 16527c478bd9Sstevel@tonic-gate *q++ = '\f'; 16537c478bd9Sstevel@tonic-gate continue; 16547c478bd9Sstevel@tonic-gate 16557c478bd9Sstevel@tonic-gate case 'b': /* backspace */ 16567c478bd9Sstevel@tonic-gate *q++ = '\b'; 16577c478bd9Sstevel@tonic-gate continue; 16587c478bd9Sstevel@tonic-gate } 16597c478bd9Sstevel@tonic-gate *q++ = *p; 16607c478bd9Sstevel@tonic-gate } 16617c478bd9Sstevel@tonic-gate else 16627c478bd9Sstevel@tonic-gate { 16637c478bd9Sstevel@tonic-gate if (*p == '\\') 16647c478bd9Sstevel@tonic-gate backslash = true; 16657c478bd9Sstevel@tonic-gate else if (*p == '"') 16667c478bd9Sstevel@tonic-gate quotemode = !quotemode; 16677c478bd9Sstevel@tonic-gate else if (quotemode || *p != delim) 16687c478bd9Sstevel@tonic-gate *q++ = *p; 16697c478bd9Sstevel@tonic-gate else 16707c478bd9Sstevel@tonic-gate break; 16717c478bd9Sstevel@tonic-gate } 16727c478bd9Sstevel@tonic-gate } 16737c478bd9Sstevel@tonic-gate 16747c478bd9Sstevel@tonic-gate if (delimptr != NULL) 16757c478bd9Sstevel@tonic-gate *delimptr = p; 16767c478bd9Sstevel@tonic-gate *q++ = '\0'; 16777c478bd9Sstevel@tonic-gate return buf; 16787c478bd9Sstevel@tonic-gate } 16797c478bd9Sstevel@tonic-gate /* 16807c478bd9Sstevel@tonic-gate ** EXTRQUOTSTR -- extract a (quoted) string. 16817c478bd9Sstevel@tonic-gate ** 16827c478bd9Sstevel@tonic-gate ** This routine deals with quoted (") strings and escaped 16837c478bd9Sstevel@tonic-gate ** spaces (\\ ). 16847c478bd9Sstevel@tonic-gate ** 16857c478bd9Sstevel@tonic-gate ** Parameters: 16867c478bd9Sstevel@tonic-gate ** p -- source string. 16877c478bd9Sstevel@tonic-gate ** delimptr -- if non-NULL, set to the pointer of the 16887c478bd9Sstevel@tonic-gate ** field delimiter character. 16897c478bd9Sstevel@tonic-gate ** delimbuf -- delimiters for the field. 16907c478bd9Sstevel@tonic-gate ** st -- if non-NULL, store the return value (whether the 16917c478bd9Sstevel@tonic-gate ** string was correctly quoted) here. 16927c478bd9Sstevel@tonic-gate ** 16937c478bd9Sstevel@tonic-gate ** Returns: 16947c478bd9Sstevel@tonic-gate ** the extracted string. 16957c478bd9Sstevel@tonic-gate ** 16967c478bd9Sstevel@tonic-gate ** Side Effects: 16977c478bd9Sstevel@tonic-gate ** the returned string is a local static buffer. 16987c478bd9Sstevel@tonic-gate ** it must be copied before the function is called again. 16997c478bd9Sstevel@tonic-gate */ 17007c478bd9Sstevel@tonic-gate 17017c478bd9Sstevel@tonic-gate static char * 17027c478bd9Sstevel@tonic-gate extrquotstr(p, delimptr, delimbuf, st) 17037c478bd9Sstevel@tonic-gate register char *p; 17047c478bd9Sstevel@tonic-gate char **delimptr; 17057c478bd9Sstevel@tonic-gate char *delimbuf; 17067c478bd9Sstevel@tonic-gate bool *st; 17077c478bd9Sstevel@tonic-gate { 17087c478bd9Sstevel@tonic-gate register char *q; 17097c478bd9Sstevel@tonic-gate bool backslash = false; 17107c478bd9Sstevel@tonic-gate bool quotemode = false; 17117c478bd9Sstevel@tonic-gate static char buf[MAXLINE]; 17127c478bd9Sstevel@tonic-gate 17137c478bd9Sstevel@tonic-gate for (q = buf; *p != '\0' && q < &buf[sizeof buf - 1]; p++) 17147c478bd9Sstevel@tonic-gate { 17157c478bd9Sstevel@tonic-gate if (backslash) 17167c478bd9Sstevel@tonic-gate { 17177c478bd9Sstevel@tonic-gate backslash = false; 17187c478bd9Sstevel@tonic-gate if (*p != ' ') 17197c478bd9Sstevel@tonic-gate *q++ = '\\'; 17207c478bd9Sstevel@tonic-gate } 17217c478bd9Sstevel@tonic-gate if (*p == '\\') 17227c478bd9Sstevel@tonic-gate backslash = true; 17237c478bd9Sstevel@tonic-gate else if (*p == '"') 17247c478bd9Sstevel@tonic-gate quotemode = !quotemode; 17257c478bd9Sstevel@tonic-gate else if (quotemode || 17267c478bd9Sstevel@tonic-gate strchr(delimbuf, (int) *p) == NULL) 17277c478bd9Sstevel@tonic-gate *q++ = *p; 17287c478bd9Sstevel@tonic-gate else 17297c478bd9Sstevel@tonic-gate break; 17307c478bd9Sstevel@tonic-gate } 17317c478bd9Sstevel@tonic-gate 17327c478bd9Sstevel@tonic-gate if (delimptr != NULL) 17337c478bd9Sstevel@tonic-gate *delimptr = p; 17347c478bd9Sstevel@tonic-gate *q++ = '\0'; 17357c478bd9Sstevel@tonic-gate if (st != NULL) 17367c478bd9Sstevel@tonic-gate *st = !(quotemode || backslash); 17377c478bd9Sstevel@tonic-gate return buf; 17387c478bd9Sstevel@tonic-gate } 17397c478bd9Sstevel@tonic-gate /* 17407c478bd9Sstevel@tonic-gate ** MAKEARGV -- break up a string into words 17417c478bd9Sstevel@tonic-gate ** 17427c478bd9Sstevel@tonic-gate ** Parameters: 17437c478bd9Sstevel@tonic-gate ** p -- the string to break up. 17447c478bd9Sstevel@tonic-gate ** 17457c478bd9Sstevel@tonic-gate ** Returns: 17467c478bd9Sstevel@tonic-gate ** a char **argv (dynamically allocated) 17477c478bd9Sstevel@tonic-gate ** 17487c478bd9Sstevel@tonic-gate ** Side Effects: 17497c478bd9Sstevel@tonic-gate ** munges p. 17507c478bd9Sstevel@tonic-gate */ 17517c478bd9Sstevel@tonic-gate 17527c478bd9Sstevel@tonic-gate static char ** 17537c478bd9Sstevel@tonic-gate makeargv(p) 17547c478bd9Sstevel@tonic-gate register char *p; 17557c478bd9Sstevel@tonic-gate { 17567c478bd9Sstevel@tonic-gate char *q; 17577c478bd9Sstevel@tonic-gate int i; 17587c478bd9Sstevel@tonic-gate char **avp; 17597c478bd9Sstevel@tonic-gate char *argv[MAXPV + 1]; 17607c478bd9Sstevel@tonic-gate 17617c478bd9Sstevel@tonic-gate /* take apart the words */ 17627c478bd9Sstevel@tonic-gate i = 0; 17637c478bd9Sstevel@tonic-gate while (*p != '\0' && i < MAXPV) 17647c478bd9Sstevel@tonic-gate { 17657c478bd9Sstevel@tonic-gate q = p; 17667c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 17677c478bd9Sstevel@tonic-gate p++; 17687c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 17697c478bd9Sstevel@tonic-gate *p++ = '\0'; 17707c478bd9Sstevel@tonic-gate argv[i++] = newstr(q); 17717c478bd9Sstevel@tonic-gate } 17727c478bd9Sstevel@tonic-gate argv[i++] = NULL; 17737c478bd9Sstevel@tonic-gate 17747c478bd9Sstevel@tonic-gate /* now make a copy of the argv */ 17757c478bd9Sstevel@tonic-gate avp = (char **) xalloc(sizeof *avp * i); 17767c478bd9Sstevel@tonic-gate memmove((char *) avp, (char *) argv, sizeof *avp * i); 17777c478bd9Sstevel@tonic-gate 17787c478bd9Sstevel@tonic-gate return avp; 17797c478bd9Sstevel@tonic-gate } 17807c478bd9Sstevel@tonic-gate /* 17817c478bd9Sstevel@tonic-gate ** PRINTRULES -- print rewrite rules (for debugging) 17827c478bd9Sstevel@tonic-gate ** 17837c478bd9Sstevel@tonic-gate ** Parameters: 17847c478bd9Sstevel@tonic-gate ** none. 17857c478bd9Sstevel@tonic-gate ** 17867c478bd9Sstevel@tonic-gate ** Returns: 17877c478bd9Sstevel@tonic-gate ** none. 17887c478bd9Sstevel@tonic-gate ** 17897c478bd9Sstevel@tonic-gate ** Side Effects: 17907c478bd9Sstevel@tonic-gate ** prints rewrite rules. 17917c478bd9Sstevel@tonic-gate */ 17927c478bd9Sstevel@tonic-gate 17937c478bd9Sstevel@tonic-gate void 17947c478bd9Sstevel@tonic-gate printrules() 17957c478bd9Sstevel@tonic-gate { 17967c478bd9Sstevel@tonic-gate register struct rewrite *rwp; 17977c478bd9Sstevel@tonic-gate register int ruleset; 17987c478bd9Sstevel@tonic-gate 17997c478bd9Sstevel@tonic-gate for (ruleset = 0; ruleset < 10; ruleset++) 18007c478bd9Sstevel@tonic-gate { 18017c478bd9Sstevel@tonic-gate if (RewriteRules[ruleset] == NULL) 18027c478bd9Sstevel@tonic-gate continue; 18037c478bd9Sstevel@tonic-gate sm_dprintf("\n----Rule Set %d:", ruleset); 18047c478bd9Sstevel@tonic-gate 18057c478bd9Sstevel@tonic-gate for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next) 18067c478bd9Sstevel@tonic-gate { 18077c478bd9Sstevel@tonic-gate sm_dprintf("\nLHS:"); 18087c478bd9Sstevel@tonic-gate printav(sm_debug_file(), rwp->r_lhs); 18097c478bd9Sstevel@tonic-gate sm_dprintf("RHS:"); 18107c478bd9Sstevel@tonic-gate printav(sm_debug_file(), rwp->r_rhs); 18117c478bd9Sstevel@tonic-gate } 18127c478bd9Sstevel@tonic-gate } 18137c478bd9Sstevel@tonic-gate } 18147c478bd9Sstevel@tonic-gate /* 18157c478bd9Sstevel@tonic-gate ** PRINTMAILER -- print mailer structure (for debugging) 18167c478bd9Sstevel@tonic-gate ** 18177c478bd9Sstevel@tonic-gate ** Parameters: 18187c478bd9Sstevel@tonic-gate ** fp -- output file 18197c478bd9Sstevel@tonic-gate ** m -- the mailer to print 18207c478bd9Sstevel@tonic-gate ** 18217c478bd9Sstevel@tonic-gate ** Returns: 18227c478bd9Sstevel@tonic-gate ** none. 18237c478bd9Sstevel@tonic-gate */ 18247c478bd9Sstevel@tonic-gate 18257c478bd9Sstevel@tonic-gate void 18267c478bd9Sstevel@tonic-gate printmailer(fp, m) 18277c478bd9Sstevel@tonic-gate SM_FILE_T *fp; 18287c478bd9Sstevel@tonic-gate register MAILER *m; 18297c478bd9Sstevel@tonic-gate { 18307c478bd9Sstevel@tonic-gate int j; 18317c478bd9Sstevel@tonic-gate 18327c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, 18337c478bd9Sstevel@tonic-gate "mailer %d (%s): P=%s S=", m->m_mno, m->m_name, 18347c478bd9Sstevel@tonic-gate m->m_mailer); 18357c478bd9Sstevel@tonic-gate if (RuleSetNames[m->m_se_rwset] == NULL) 18367c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d/", 18377c478bd9Sstevel@tonic-gate m->m_se_rwset); 18387c478bd9Sstevel@tonic-gate else 18397c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s/", 18407c478bd9Sstevel@tonic-gate RuleSetNames[m->m_se_rwset]); 18417c478bd9Sstevel@tonic-gate if (RuleSetNames[m->m_sh_rwset] == NULL) 18427c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d R=", 18437c478bd9Sstevel@tonic-gate m->m_sh_rwset); 18447c478bd9Sstevel@tonic-gate else 18457c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s R=", 18467c478bd9Sstevel@tonic-gate RuleSetNames[m->m_sh_rwset]); 18477c478bd9Sstevel@tonic-gate if (RuleSetNames[m->m_re_rwset] == NULL) 18487c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d/", 18497c478bd9Sstevel@tonic-gate m->m_re_rwset); 18507c478bd9Sstevel@tonic-gate else 18517c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s/", 18527c478bd9Sstevel@tonic-gate RuleSetNames[m->m_re_rwset]); 18537c478bd9Sstevel@tonic-gate if (RuleSetNames[m->m_rh_rwset] == NULL) 18547c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d ", 18557c478bd9Sstevel@tonic-gate m->m_rh_rwset); 18567c478bd9Sstevel@tonic-gate else 18577c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s ", 18587c478bd9Sstevel@tonic-gate RuleSetNames[m->m_rh_rwset]); 18597c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "M=%ld U=%d:%d F=", 18607c478bd9Sstevel@tonic-gate m->m_maxsize, (int) m->m_uid, (int) m->m_gid); 18617c478bd9Sstevel@tonic-gate for (j = '\0'; j <= '\177'; j++) 18627c478bd9Sstevel@tonic-gate if (bitnset(j, m->m_flags)) 18637c478bd9Sstevel@tonic-gate (void) sm_io_putc(fp, SM_TIME_DEFAULT, j); 18647c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " L=%d E=", 18657c478bd9Sstevel@tonic-gate m->m_linelimit); 18667c478bd9Sstevel@tonic-gate xputs(fp, m->m_eol); 18677c478bd9Sstevel@tonic-gate if (m->m_defcharset != NULL) 18687c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " C=%s", 18697c478bd9Sstevel@tonic-gate m->m_defcharset); 18707c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " T=%s/%s/%s", 18717c478bd9Sstevel@tonic-gate m->m_mtatype == NULL 18727c478bd9Sstevel@tonic-gate ? "<undefined>" : m->m_mtatype, 18737c478bd9Sstevel@tonic-gate m->m_addrtype == NULL 18747c478bd9Sstevel@tonic-gate ? "<undefined>" : m->m_addrtype, 18757c478bd9Sstevel@tonic-gate m->m_diagtype == NULL 18767c478bd9Sstevel@tonic-gate ? "<undefined>" : m->m_diagtype); 18777c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " r=%d", m->m_maxrcpt); 18787c478bd9Sstevel@tonic-gate if (m->m_argv != NULL) 18797c478bd9Sstevel@tonic-gate { 18807c478bd9Sstevel@tonic-gate char **a = m->m_argv; 18817c478bd9Sstevel@tonic-gate 18827c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " A="); 18837c478bd9Sstevel@tonic-gate while (*a != NULL) 18847c478bd9Sstevel@tonic-gate { 18857c478bd9Sstevel@tonic-gate if (a != m->m_argv) 18867c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, 18877c478bd9Sstevel@tonic-gate " "); 18887c478bd9Sstevel@tonic-gate xputs(fp, *a++); 18897c478bd9Sstevel@tonic-gate } 18907c478bd9Sstevel@tonic-gate } 18917c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\n"); 18927c478bd9Sstevel@tonic-gate } 18937c478bd9Sstevel@tonic-gate /* 18947c478bd9Sstevel@tonic-gate ** SETOPTION -- set global processing option 18957c478bd9Sstevel@tonic-gate ** 18967c478bd9Sstevel@tonic-gate ** Parameters: 18977c478bd9Sstevel@tonic-gate ** opt -- option name. 18987c478bd9Sstevel@tonic-gate ** val -- option value (as a text string). 18997c478bd9Sstevel@tonic-gate ** safe -- set if this came from a configuration file. 19007c478bd9Sstevel@tonic-gate ** Some options (if set from the command line) will 19017c478bd9Sstevel@tonic-gate ** reset the user id to avoid security problems. 19027c478bd9Sstevel@tonic-gate ** sticky -- if set, don't let other setoptions override 19037c478bd9Sstevel@tonic-gate ** this value. 19047c478bd9Sstevel@tonic-gate ** e -- the main envelope. 19057c478bd9Sstevel@tonic-gate ** 19067c478bd9Sstevel@tonic-gate ** Returns: 19077c478bd9Sstevel@tonic-gate ** none. 19087c478bd9Sstevel@tonic-gate ** 19097c478bd9Sstevel@tonic-gate ** Side Effects: 19107c478bd9Sstevel@tonic-gate ** Sets options as implied by the arguments. 19117c478bd9Sstevel@tonic-gate */ 19127c478bd9Sstevel@tonic-gate 19137c478bd9Sstevel@tonic-gate static BITMAP256 StickyOpt; /* set if option is stuck */ 19147c478bd9Sstevel@tonic-gate 19157c478bd9Sstevel@tonic-gate #if NAMED_BIND 19167c478bd9Sstevel@tonic-gate 19177c478bd9Sstevel@tonic-gate static struct resolverflags 19187c478bd9Sstevel@tonic-gate { 19197c478bd9Sstevel@tonic-gate char *rf_name; /* name of the flag */ 19207c478bd9Sstevel@tonic-gate long rf_bits; /* bits to set/clear */ 19217c478bd9Sstevel@tonic-gate } ResolverFlags[] = 19227c478bd9Sstevel@tonic-gate { 19237c478bd9Sstevel@tonic-gate { "debug", RES_DEBUG }, 19247c478bd9Sstevel@tonic-gate { "aaonly", RES_AAONLY }, 19257c478bd9Sstevel@tonic-gate { "usevc", RES_USEVC }, 19267c478bd9Sstevel@tonic-gate { "primary", RES_PRIMARY }, 19277c478bd9Sstevel@tonic-gate { "igntc", RES_IGNTC }, 19287c478bd9Sstevel@tonic-gate { "recurse", RES_RECURSE }, 19297c478bd9Sstevel@tonic-gate { "defnames", RES_DEFNAMES }, 19307c478bd9Sstevel@tonic-gate { "stayopen", RES_STAYOPEN }, 19317c478bd9Sstevel@tonic-gate { "dnsrch", RES_DNSRCH }, 19327c478bd9Sstevel@tonic-gate # ifdef RES_USE_INET6 19337c478bd9Sstevel@tonic-gate { "use_inet6", RES_USE_INET6 }, 19347c478bd9Sstevel@tonic-gate # endif /* RES_USE_INET6 */ 19357c478bd9Sstevel@tonic-gate { "true", 0 }, /* avoid error on old syntax */ 19367c478bd9Sstevel@tonic-gate { NULL, 0 } 19377c478bd9Sstevel@tonic-gate }; 19387c478bd9Sstevel@tonic-gate 19397c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */ 19407c478bd9Sstevel@tonic-gate 19417c478bd9Sstevel@tonic-gate #define OI_NONE 0 /* no special treatment */ 19427c478bd9Sstevel@tonic-gate #define OI_SAFE 0x0001 /* safe for random people to use */ 19437c478bd9Sstevel@tonic-gate #define OI_SUBOPT 0x0002 /* option has suboptions */ 19447c478bd9Sstevel@tonic-gate 19457c478bd9Sstevel@tonic-gate static struct optioninfo 19467c478bd9Sstevel@tonic-gate { 19477c478bd9Sstevel@tonic-gate char *o_name; /* long name of option */ 19487c478bd9Sstevel@tonic-gate unsigned char o_code; /* short name of option */ 19497c478bd9Sstevel@tonic-gate unsigned short o_flags; /* option flags */ 19507c478bd9Sstevel@tonic-gate } OptionTab[] = 19517c478bd9Sstevel@tonic-gate { 19527c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(REMOTE_MODE) 19537c478bd9Sstevel@tonic-gate { "RemoteMode", '>', OI_NONE }, 19547c478bd9Sstevel@tonic-gate #endif /* defined(SUN_EXTENSIONS) && defined(REMOTE_MODE) */ 19557c478bd9Sstevel@tonic-gate { "SevenBitInput", '7', OI_SAFE }, 19567c478bd9Sstevel@tonic-gate { "EightBitMode", '8', OI_SAFE }, 19577c478bd9Sstevel@tonic-gate { "AliasFile", 'A', OI_NONE }, 19587c478bd9Sstevel@tonic-gate { "AliasWait", 'a', OI_NONE }, 19597c478bd9Sstevel@tonic-gate { "BlankSub", 'B', OI_NONE }, 19607c478bd9Sstevel@tonic-gate { "MinFreeBlocks", 'b', OI_SAFE }, 19617c478bd9Sstevel@tonic-gate { "CheckpointInterval", 'C', OI_SAFE }, 19627c478bd9Sstevel@tonic-gate { "HoldExpensive", 'c', OI_NONE }, 19637c478bd9Sstevel@tonic-gate { "DeliveryMode", 'd', OI_SAFE }, 19647c478bd9Sstevel@tonic-gate { "ErrorHeader", 'E', OI_NONE }, 19657c478bd9Sstevel@tonic-gate { "ErrorMode", 'e', OI_SAFE }, 19667c478bd9Sstevel@tonic-gate { "TempFileMode", 'F', OI_NONE }, 19677c478bd9Sstevel@tonic-gate { "SaveFromLine", 'f', OI_NONE }, 19687c478bd9Sstevel@tonic-gate { "MatchGECOS", 'G', OI_NONE }, 19697c478bd9Sstevel@tonic-gate 19707c478bd9Sstevel@tonic-gate /* no long name, just here to avoid problems in setoption */ 19717c478bd9Sstevel@tonic-gate { "", 'g', OI_NONE }, 19727c478bd9Sstevel@tonic-gate { "HelpFile", 'H', OI_NONE }, 19737c478bd9Sstevel@tonic-gate { "MaxHopCount", 'h', OI_NONE }, 19747c478bd9Sstevel@tonic-gate { "ResolverOptions", 'I', OI_NONE }, 19757c478bd9Sstevel@tonic-gate { "IgnoreDots", 'i', OI_SAFE }, 19767c478bd9Sstevel@tonic-gate { "ForwardPath", 'J', OI_NONE }, 19777c478bd9Sstevel@tonic-gate { "SendMimeErrors", 'j', OI_SAFE }, 19787c478bd9Sstevel@tonic-gate { "ConnectionCacheSize", 'k', OI_NONE }, 19797c478bd9Sstevel@tonic-gate { "ConnectionCacheTimeout", 'K', OI_NONE }, 19807c478bd9Sstevel@tonic-gate { "UseErrorsTo", 'l', OI_NONE }, 19817c478bd9Sstevel@tonic-gate { "LogLevel", 'L', OI_SAFE }, 19827c478bd9Sstevel@tonic-gate { "MeToo", 'm', OI_SAFE }, 19837c478bd9Sstevel@tonic-gate 19847c478bd9Sstevel@tonic-gate /* no long name, just here to avoid problems in setoption */ 19857c478bd9Sstevel@tonic-gate { "", 'M', OI_NONE }, 19867c478bd9Sstevel@tonic-gate { "CheckAliases", 'n', OI_NONE }, 19877c478bd9Sstevel@tonic-gate { "OldStyleHeaders", 'o', OI_SAFE }, 19887c478bd9Sstevel@tonic-gate { "DaemonPortOptions", 'O', OI_NONE }, 19897c478bd9Sstevel@tonic-gate { "PrivacyOptions", 'p', OI_SAFE }, 19907c478bd9Sstevel@tonic-gate { "PostmasterCopy", 'P', OI_NONE }, 19917c478bd9Sstevel@tonic-gate { "QueueFactor", 'q', OI_NONE }, 19927c478bd9Sstevel@tonic-gate { "QueueDirectory", 'Q', OI_NONE }, 19937c478bd9Sstevel@tonic-gate { "DontPruneRoutes", 'R', OI_NONE }, 19947c478bd9Sstevel@tonic-gate { "Timeout", 'r', OI_SUBOPT }, 19957c478bd9Sstevel@tonic-gate { "StatusFile", 'S', OI_NONE }, 19967c478bd9Sstevel@tonic-gate { "SuperSafe", 's', OI_SAFE }, 19977c478bd9Sstevel@tonic-gate { "QueueTimeout", 'T', OI_NONE }, 19987c478bd9Sstevel@tonic-gate { "TimeZoneSpec", 't', OI_NONE }, 19997c478bd9Sstevel@tonic-gate { "UserDatabaseSpec", 'U', OI_NONE }, 20007c478bd9Sstevel@tonic-gate { "DefaultUser", 'u', OI_NONE }, 20017c478bd9Sstevel@tonic-gate { "FallbackMXhost", 'V', OI_NONE }, 20027c478bd9Sstevel@tonic-gate { "Verbose", 'v', OI_SAFE }, 20037c478bd9Sstevel@tonic-gate { "TryNullMXList", 'w', OI_NONE }, 20047c478bd9Sstevel@tonic-gate { "QueueLA", 'x', OI_NONE }, 20057c478bd9Sstevel@tonic-gate { "RefuseLA", 'X', OI_NONE }, 20067c478bd9Sstevel@tonic-gate { "RecipientFactor", 'y', OI_NONE }, 20077c478bd9Sstevel@tonic-gate { "ForkEachJob", 'Y', OI_NONE }, 20087c478bd9Sstevel@tonic-gate { "ClassFactor", 'z', OI_NONE }, 20097c478bd9Sstevel@tonic-gate { "RetryFactor", 'Z', OI_NONE }, 20107c478bd9Sstevel@tonic-gate #define O_QUEUESORTORD 0x81 20117c478bd9Sstevel@tonic-gate { "QueueSortOrder", O_QUEUESORTORD, OI_SAFE }, 20127c478bd9Sstevel@tonic-gate #define O_HOSTSFILE 0x82 20137c478bd9Sstevel@tonic-gate { "HostsFile", O_HOSTSFILE, OI_NONE }, 20147c478bd9Sstevel@tonic-gate #define O_MQA 0x83 20157c478bd9Sstevel@tonic-gate { "MinQueueAge", O_MQA, OI_SAFE }, 20167c478bd9Sstevel@tonic-gate #define O_DEFCHARSET 0x85 20177c478bd9Sstevel@tonic-gate { "DefaultCharSet", O_DEFCHARSET, OI_SAFE }, 20187c478bd9Sstevel@tonic-gate #define O_SSFILE 0x86 20197c478bd9Sstevel@tonic-gate { "ServiceSwitchFile", O_SSFILE, OI_NONE }, 20207c478bd9Sstevel@tonic-gate #define O_DIALDELAY 0x87 20217c478bd9Sstevel@tonic-gate { "DialDelay", O_DIALDELAY, OI_SAFE }, 20227c478bd9Sstevel@tonic-gate #define O_NORCPTACTION 0x88 20237c478bd9Sstevel@tonic-gate { "NoRecipientAction", O_NORCPTACTION, OI_SAFE }, 20247c478bd9Sstevel@tonic-gate #define O_SAFEFILEENV 0x89 20257c478bd9Sstevel@tonic-gate { "SafeFileEnvironment", O_SAFEFILEENV, OI_NONE }, 20267c478bd9Sstevel@tonic-gate #define O_MAXMSGSIZE 0x8a 20277c478bd9Sstevel@tonic-gate { "MaxMessageSize", O_MAXMSGSIZE, OI_NONE }, 20287c478bd9Sstevel@tonic-gate #define O_COLONOKINADDR 0x8b 20297c478bd9Sstevel@tonic-gate { "ColonOkInAddr", O_COLONOKINADDR, OI_SAFE }, 20307c478bd9Sstevel@tonic-gate #define O_MAXQUEUERUN 0x8c 20317c478bd9Sstevel@tonic-gate { "MaxQueueRunSize", O_MAXQUEUERUN, OI_SAFE }, 20327c478bd9Sstevel@tonic-gate #define O_MAXCHILDREN 0x8d 20337c478bd9Sstevel@tonic-gate { "MaxDaemonChildren", O_MAXCHILDREN, OI_NONE }, 20347c478bd9Sstevel@tonic-gate #define O_KEEPCNAMES 0x8e 20357c478bd9Sstevel@tonic-gate { "DontExpandCnames", O_KEEPCNAMES, OI_NONE }, 20367c478bd9Sstevel@tonic-gate #define O_MUSTQUOTE 0x8f 20377c478bd9Sstevel@tonic-gate { "MustQuoteChars", O_MUSTQUOTE, OI_NONE }, 20387c478bd9Sstevel@tonic-gate #define O_SMTPGREETING 0x90 20397c478bd9Sstevel@tonic-gate { "SmtpGreetingMessage", O_SMTPGREETING, OI_NONE }, 20407c478bd9Sstevel@tonic-gate #define O_UNIXFROM 0x91 20417c478bd9Sstevel@tonic-gate { "UnixFromLine", O_UNIXFROM, OI_NONE }, 20427c478bd9Sstevel@tonic-gate #define O_OPCHARS 0x92 20437c478bd9Sstevel@tonic-gate { "OperatorChars", O_OPCHARS, OI_NONE }, 20447c478bd9Sstevel@tonic-gate #define O_DONTINITGRPS 0x93 20457c478bd9Sstevel@tonic-gate { "DontInitGroups", O_DONTINITGRPS, OI_NONE }, 20467c478bd9Sstevel@tonic-gate #define O_SLFH 0x94 20477c478bd9Sstevel@tonic-gate { "SingleLineFromHeader", O_SLFH, OI_SAFE }, 20487c478bd9Sstevel@tonic-gate #define O_ABH 0x95 20497c478bd9Sstevel@tonic-gate { "AllowBogusHELO", O_ABH, OI_SAFE }, 20507c478bd9Sstevel@tonic-gate #define O_CONNTHROT 0x97 20517c478bd9Sstevel@tonic-gate { "ConnectionRateThrottle", O_CONNTHROT, OI_NONE }, 20527c478bd9Sstevel@tonic-gate #define O_UGW 0x99 20537c478bd9Sstevel@tonic-gate { "UnsafeGroupWrites", O_UGW, OI_NONE }, 20547c478bd9Sstevel@tonic-gate #define O_DBLBOUNCE 0x9a 20557c478bd9Sstevel@tonic-gate { "DoubleBounceAddress", O_DBLBOUNCE, OI_NONE }, 20567c478bd9Sstevel@tonic-gate #define O_HSDIR 0x9b 20577c478bd9Sstevel@tonic-gate { "HostStatusDirectory", O_HSDIR, OI_NONE }, 20587c478bd9Sstevel@tonic-gate #define O_SINGTHREAD 0x9c 20597c478bd9Sstevel@tonic-gate { "SingleThreadDelivery", O_SINGTHREAD, OI_NONE }, 20607c478bd9Sstevel@tonic-gate #define O_RUNASUSER 0x9d 20617c478bd9Sstevel@tonic-gate { "RunAsUser", O_RUNASUSER, OI_NONE }, 20627c478bd9Sstevel@tonic-gate #define O_DSN_RRT 0x9e 20637c478bd9Sstevel@tonic-gate { "RrtImpliesDsn", O_DSN_RRT, OI_NONE }, 20647c478bd9Sstevel@tonic-gate #define O_PIDFILE 0x9f 20657c478bd9Sstevel@tonic-gate { "PidFile", O_PIDFILE, OI_NONE }, 20667c478bd9Sstevel@tonic-gate #define O_DONTBLAMESENDMAIL 0xa0 20677c478bd9Sstevel@tonic-gate { "DontBlameSendmail", O_DONTBLAMESENDMAIL, OI_NONE }, 20687c478bd9Sstevel@tonic-gate #define O_DPI 0xa1 20697c478bd9Sstevel@tonic-gate { "DontProbeInterfaces", O_DPI, OI_NONE }, 20707c478bd9Sstevel@tonic-gate #define O_MAXRCPT 0xa2 20717c478bd9Sstevel@tonic-gate { "MaxRecipientsPerMessage", O_MAXRCPT, OI_SAFE }, 20727c478bd9Sstevel@tonic-gate #define O_DEADLETTER 0xa3 20737c478bd9Sstevel@tonic-gate { "DeadLetterDrop", O_DEADLETTER, OI_NONE }, 20747c478bd9Sstevel@tonic-gate #if _FFR_DONTLOCKFILESFORREAD_OPTION 20757c478bd9Sstevel@tonic-gate # define O_DONTLOCK 0xa4 20767c478bd9Sstevel@tonic-gate { "DontLockFilesForRead", O_DONTLOCK, OI_NONE }, 20777c478bd9Sstevel@tonic-gate #endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */ 20787c478bd9Sstevel@tonic-gate #define O_MAXALIASRCSN 0xa5 20797c478bd9Sstevel@tonic-gate { "MaxAliasRecursion", O_MAXALIASRCSN, OI_NONE }, 20807c478bd9Sstevel@tonic-gate #define O_CNCTONLYTO 0xa6 20817c478bd9Sstevel@tonic-gate { "ConnectOnlyTo", O_CNCTONLYTO, OI_NONE }, 20827c478bd9Sstevel@tonic-gate #define O_TRUSTUSER 0xa7 20837c478bd9Sstevel@tonic-gate { "TrustedUser", O_TRUSTUSER, OI_NONE }, 20847c478bd9Sstevel@tonic-gate #define O_MAXMIMEHDRLEN 0xa8 20857c478bd9Sstevel@tonic-gate { "MaxMimeHeaderLength", O_MAXMIMEHDRLEN, OI_NONE }, 20867c478bd9Sstevel@tonic-gate #define O_CONTROLSOCKET 0xa9 20877c478bd9Sstevel@tonic-gate { "ControlSocketName", O_CONTROLSOCKET, OI_NONE }, 20887c478bd9Sstevel@tonic-gate #define O_MAXHDRSLEN 0xaa 20897c478bd9Sstevel@tonic-gate { "MaxHeadersLength", O_MAXHDRSLEN, OI_NONE }, 20907c478bd9Sstevel@tonic-gate #if _FFR_MAX_FORWARD_ENTRIES 20917c478bd9Sstevel@tonic-gate # define O_MAXFORWARD 0xab 20927c478bd9Sstevel@tonic-gate { "MaxForwardEntries", O_MAXFORWARD, OI_NONE }, 20937c478bd9Sstevel@tonic-gate #endif /* _FFR_MAX_FORWARD_ENTRIES */ 20947c478bd9Sstevel@tonic-gate #define O_PROCTITLEPREFIX 0xac 20957c478bd9Sstevel@tonic-gate { "ProcessTitlePrefix", O_PROCTITLEPREFIX, OI_NONE }, 20967c478bd9Sstevel@tonic-gate #define O_SASLINFO 0xad 20977c478bd9Sstevel@tonic-gate #if _FFR_ALLOW_SASLINFO 20987c478bd9Sstevel@tonic-gate { "DefaultAuthInfo", O_SASLINFO, OI_SAFE }, 20997c478bd9Sstevel@tonic-gate #else /* _FFR_ALLOW_SASLINFO */ 21007c478bd9Sstevel@tonic-gate { "DefaultAuthInfo", O_SASLINFO, OI_NONE }, 21017c478bd9Sstevel@tonic-gate #endif /* _FFR_ALLOW_SASLINFO */ 21027c478bd9Sstevel@tonic-gate #define O_SASLMECH 0xae 21037c478bd9Sstevel@tonic-gate { "AuthMechanisms", O_SASLMECH, OI_NONE }, 21047c478bd9Sstevel@tonic-gate #define O_CLIENTPORT 0xaf 21057c478bd9Sstevel@tonic-gate { "ClientPortOptions", O_CLIENTPORT, OI_NONE }, 21067c478bd9Sstevel@tonic-gate #define O_DF_BUFSIZE 0xb0 21077c478bd9Sstevel@tonic-gate { "DataFileBufferSize", O_DF_BUFSIZE, OI_NONE }, 21087c478bd9Sstevel@tonic-gate #define O_XF_BUFSIZE 0xb1 21097c478bd9Sstevel@tonic-gate { "XscriptFileBufferSize", O_XF_BUFSIZE, OI_NONE }, 21107c478bd9Sstevel@tonic-gate #define O_LDAPDEFAULTSPEC 0xb2 21117c478bd9Sstevel@tonic-gate { "LDAPDefaultSpec", O_LDAPDEFAULTSPEC, OI_NONE }, 21127c478bd9Sstevel@tonic-gate #define O_SRVCERTFILE 0xb4 21137c478bd9Sstevel@tonic-gate { "ServerCertFile", O_SRVCERTFILE, OI_NONE }, 21147c478bd9Sstevel@tonic-gate #define O_SRVKEYFILE 0xb5 21157c478bd9Sstevel@tonic-gate { "ServerKeyFile", O_SRVKEYFILE, OI_NONE }, 21167c478bd9Sstevel@tonic-gate #define O_CLTCERTFILE 0xb6 21177c478bd9Sstevel@tonic-gate { "ClientCertFile", O_CLTCERTFILE, OI_NONE }, 21187c478bd9Sstevel@tonic-gate #define O_CLTKEYFILE 0xb7 21197c478bd9Sstevel@tonic-gate { "ClientKeyFile", O_CLTKEYFILE, OI_NONE }, 21207c478bd9Sstevel@tonic-gate #define O_CACERTFILE 0xb8 21217c478bd9Sstevel@tonic-gate { "CACertFile", O_CACERTFILE, OI_NONE }, 21227c478bd9Sstevel@tonic-gate #define O_CACERTPATH 0xb9 21237c478bd9Sstevel@tonic-gate { "CACertPath", O_CACERTPATH, OI_NONE }, 21247c478bd9Sstevel@tonic-gate #define O_DHPARAMS 0xba 21257c478bd9Sstevel@tonic-gate { "DHParameters", O_DHPARAMS, OI_NONE }, 21267c478bd9Sstevel@tonic-gate #define O_INPUTMILTER 0xbb 21277c478bd9Sstevel@tonic-gate { "InputMailFilters", O_INPUTMILTER, OI_NONE }, 21287c478bd9Sstevel@tonic-gate #define O_MILTER 0xbc 21297c478bd9Sstevel@tonic-gate { "Milter", O_MILTER, OI_SUBOPT }, 21307c478bd9Sstevel@tonic-gate #define O_SASLOPTS 0xbd 21317c478bd9Sstevel@tonic-gate { "AuthOptions", O_SASLOPTS, OI_NONE }, 21327c478bd9Sstevel@tonic-gate #define O_QUEUE_FILE_MODE 0xbe 21337c478bd9Sstevel@tonic-gate { "QueueFileMode", O_QUEUE_FILE_MODE, OI_NONE }, 21347c478bd9Sstevel@tonic-gate #if _FFR_TLS_1 21357c478bd9Sstevel@tonic-gate # define O_DHPARAMS5 0xbf 21367c478bd9Sstevel@tonic-gate { "DHParameters512", O_DHPARAMS5, OI_NONE }, 21377c478bd9Sstevel@tonic-gate # define O_CIPHERLIST 0xc0 21387c478bd9Sstevel@tonic-gate { "CipherList", O_CIPHERLIST, OI_NONE }, 21397c478bd9Sstevel@tonic-gate #endif /* _FFR_TLS_1 */ 21407c478bd9Sstevel@tonic-gate #define O_RANDFILE 0xc1 21417c478bd9Sstevel@tonic-gate { "RandFile", O_RANDFILE, OI_NONE }, 21427c478bd9Sstevel@tonic-gate #define O_TLS_SRV_OPTS 0xc2 21437c478bd9Sstevel@tonic-gate { "TLSSrvOptions", O_TLS_SRV_OPTS, OI_NONE }, 21447c478bd9Sstevel@tonic-gate #define O_RCPTTHROT 0xc3 21457c478bd9Sstevel@tonic-gate { "BadRcptThrottle", O_RCPTTHROT, OI_SAFE }, 21467c478bd9Sstevel@tonic-gate #define O_DLVR_MIN 0xc4 21477c478bd9Sstevel@tonic-gate { "DeliverByMin", O_DLVR_MIN, OI_NONE }, 21487c478bd9Sstevel@tonic-gate #define O_MAXQUEUECHILDREN 0xc5 21497c478bd9Sstevel@tonic-gate { "MaxQueueChildren", O_MAXQUEUECHILDREN, OI_NONE }, 21507c478bd9Sstevel@tonic-gate #define O_MAXRUNNERSPERQUEUE 0xc6 21517c478bd9Sstevel@tonic-gate { "MaxRunnersPerQueue", O_MAXRUNNERSPERQUEUE, OI_NONE }, 21527c478bd9Sstevel@tonic-gate #define O_DIRECTSUBMODIFIERS 0xc7 21537c478bd9Sstevel@tonic-gate { "DirectSubmissionModifiers", O_DIRECTSUBMODIFIERS, OI_NONE }, 21547c478bd9Sstevel@tonic-gate #define O_NICEQUEUERUN 0xc8 21557c478bd9Sstevel@tonic-gate { "NiceQueueRun", O_NICEQUEUERUN, OI_NONE }, 21567c478bd9Sstevel@tonic-gate #define O_SHMKEY 0xc9 21577c478bd9Sstevel@tonic-gate { "SharedMemoryKey", O_SHMKEY, OI_NONE }, 21587c478bd9Sstevel@tonic-gate #define O_SASLBITS 0xca 21597c478bd9Sstevel@tonic-gate { "AuthMaxBits", O_SASLBITS, OI_NONE }, 21607c478bd9Sstevel@tonic-gate #define O_MBDB 0xcb 21617c478bd9Sstevel@tonic-gate { "MailboxDatabase", O_MBDB, OI_NONE }, 21627c478bd9Sstevel@tonic-gate #define O_MSQ 0xcc 21637c478bd9Sstevel@tonic-gate { "UseMSP", O_MSQ, OI_NONE }, 21647c478bd9Sstevel@tonic-gate #define O_DELAY_LA 0xcd 21657c478bd9Sstevel@tonic-gate { "DelayLA", O_DELAY_LA, OI_NONE }, 21667c478bd9Sstevel@tonic-gate #define O_FASTSPLIT 0xce 21677c478bd9Sstevel@tonic-gate { "FastSplit", O_FASTSPLIT, OI_NONE }, 21687c478bd9Sstevel@tonic-gate #if _FFR_SOFT_BOUNCE 21697c478bd9Sstevel@tonic-gate # define O_SOFTBOUNCE 0xcf 21707c478bd9Sstevel@tonic-gate { "SoftBounce", O_SOFTBOUNCE, OI_NONE }, 21717c478bd9Sstevel@tonic-gate #endif /* _FFR_SOFT_BOUNCE */ 21727c478bd9Sstevel@tonic-gate #if _FFR_SELECT_SHM 21737c478bd9Sstevel@tonic-gate # define O_SHMKEYFILE 0xd0 21747c478bd9Sstevel@tonic-gate { "SharedMemoryKeyFile", O_SHMKEYFILE, OI_NONE }, 21757c478bd9Sstevel@tonic-gate #endif /* _FFR_SELECT_SHM */ 21767c478bd9Sstevel@tonic-gate #define O_REJECTLOGINTERVAL 0xd1 21777c478bd9Sstevel@tonic-gate { "RejectLogInterval", O_REJECTLOGINTERVAL, OI_NONE }, 21787c478bd9Sstevel@tonic-gate #define O_REQUIRES_DIR_FSYNC 0xd2 21797c478bd9Sstevel@tonic-gate { "RequiresDirfsync", O_REQUIRES_DIR_FSYNC, OI_NONE }, 21807c478bd9Sstevel@tonic-gate #define O_CONNECTION_RATE_WINDOW_SIZE 0xd3 21817c478bd9Sstevel@tonic-gate { "ConnectionRateWindowSize", O_CONNECTION_RATE_WINDOW_SIZE, OI_NONE }, 21827c478bd9Sstevel@tonic-gate #define O_CRLFILE 0xd4 21837c478bd9Sstevel@tonic-gate { "CRLFile", O_CRLFILE, OI_NONE }, 21847c478bd9Sstevel@tonic-gate #define O_FALLBACKSMARTHOST 0xd5 21857c478bd9Sstevel@tonic-gate { "FallbackSmartHost", O_FALLBACKSMARTHOST, OI_NONE }, 21867c478bd9Sstevel@tonic-gate #define O_SASLREALM 0xd6 21877c478bd9Sstevel@tonic-gate { "AuthRealm", O_SASLREALM, OI_NONE }, 21887c478bd9Sstevel@tonic-gate #if _FFR_CRLPATH 21897c478bd9Sstevel@tonic-gate # define O_CRLPATH 0xd7 21907c478bd9Sstevel@tonic-gate { "CRLPath", O_CRLPATH, OI_NONE }, 21917c478bd9Sstevel@tonic-gate #endif /* _FFR_CRLPATH */ 21927c478bd9Sstevel@tonic-gate #if _FFR_HELONAME 21937c478bd9Sstevel@tonic-gate # define O_HELONAME 0xd8 21947c478bd9Sstevel@tonic-gate { "HeloName", O_HELONAME, OI_NONE }, 21957c478bd9Sstevel@tonic-gate #endif /* _FFR_HELONAME */ 2196*445f2479Sjbeck #if _FFR_MEMSTAT 2197*445f2479Sjbeck # define O_REFUSELOWMEM 0xd9 2198*445f2479Sjbeck { "RefuseLowMem", O_REFUSELOWMEM, OI_NONE }, 2199*445f2479Sjbeck # define O_QUEUELOWMEM 0xda 2200*445f2479Sjbeck { "QueueLowMem", O_QUEUELOWMEM, OI_NONE }, 2201*445f2479Sjbeck # define O_MEMRESOURCE 0xdb 2202*445f2479Sjbeck { "MemoryResource", O_MEMRESOURCE, OI_NONE }, 2203*445f2479Sjbeck #endif /* _FFR_MEMSTAT */ 2204*445f2479Sjbeck #if _FFR_MAXNOOPCOMMANDS 2205*445f2479Sjbeck # define O_MAXNOOPCOMMANDS 0xdc 2206*445f2479Sjbeck { "MaxNOOPCommands", O_MAXNOOPCOMMANDS, OI_NONE }, 2207*445f2479Sjbeck #endif /* _FFR_MAXNOOPCOMMANDS */ 2208*445f2479Sjbeck #if _FFR_MSG_ACCEPT 2209*445f2479Sjbeck # define O_MSG_ACCEPT 0xdd 2210*445f2479Sjbeck { "MessageAccept", O_MSG_ACCEPT, OI_NONE }, 2211*445f2479Sjbeck #endif /* _FFR_MSG_ACCEPT */ 2212*445f2479Sjbeck #if _FFR_QUEUE_RUN_PARANOIA 2213*445f2479Sjbeck # define O_CHK_Q_RUNNERS 0xde 2214*445f2479Sjbeck { "CheckQueueRunners", O_CHK_Q_RUNNERS, OI_NONE }, 2215*445f2479Sjbeck #endif /* _FFR_QUEUE_RUN_PARANOIA */ 22167c478bd9Sstevel@tonic-gate 22177c478bd9Sstevel@tonic-gate { NULL, '\0', OI_NONE } 22187c478bd9Sstevel@tonic-gate }; 22197c478bd9Sstevel@tonic-gate 22207c478bd9Sstevel@tonic-gate # define CANONIFY(val) 22217c478bd9Sstevel@tonic-gate 22227c478bd9Sstevel@tonic-gate # define SET_OPT_DEFAULT(opt, val) opt = val 22237c478bd9Sstevel@tonic-gate 22247c478bd9Sstevel@tonic-gate /* set a string option by expanding the value and assigning it */ 22257c478bd9Sstevel@tonic-gate /* WARNING this belongs ONLY into a case statement! */ 22267c478bd9Sstevel@tonic-gate #define SET_STRING_EXP(str) \ 22277c478bd9Sstevel@tonic-gate expand(val, exbuf, sizeof exbuf, e); \ 22287c478bd9Sstevel@tonic-gate newval = sm_pstrdup_x(exbuf); \ 22297c478bd9Sstevel@tonic-gate if (str != NULL) \ 22307c478bd9Sstevel@tonic-gate sm_free(str); \ 22317c478bd9Sstevel@tonic-gate CANONIFY(newval); \ 22327c478bd9Sstevel@tonic-gate str = newval; \ 22337c478bd9Sstevel@tonic-gate break 22347c478bd9Sstevel@tonic-gate 22357c478bd9Sstevel@tonic-gate #define OPTNAME o->o_name == NULL ? "<unknown>" : o->o_name 22367c478bd9Sstevel@tonic-gate 22377c478bd9Sstevel@tonic-gate void 22387c478bd9Sstevel@tonic-gate setoption(opt, val, safe, sticky, e) 22397c478bd9Sstevel@tonic-gate int opt; 22407c478bd9Sstevel@tonic-gate char *val; 22417c478bd9Sstevel@tonic-gate bool safe; 22427c478bd9Sstevel@tonic-gate bool sticky; 22437c478bd9Sstevel@tonic-gate register ENVELOPE *e; 22447c478bd9Sstevel@tonic-gate { 22457c478bd9Sstevel@tonic-gate register char *p; 22467c478bd9Sstevel@tonic-gate register struct optioninfo *o; 22477c478bd9Sstevel@tonic-gate char *subopt; 22487c478bd9Sstevel@tonic-gate int mid; 22497c478bd9Sstevel@tonic-gate bool can_setuid = RunAsUid == 0; 22507c478bd9Sstevel@tonic-gate auto char *ep; 22517c478bd9Sstevel@tonic-gate char buf[50]; 22527c478bd9Sstevel@tonic-gate extern bool Warn_Q_option; 22537c478bd9Sstevel@tonic-gate #if _FFR_ALLOW_SASLINFO 22547c478bd9Sstevel@tonic-gate extern unsigned int SubmitMode; 22557c478bd9Sstevel@tonic-gate #endif /* _FFR_ALLOW_SASLINFO */ 225649218d4fSjbeck #if STARTTLS || (_FFR_SELECT_SHM && SM_CONF_SHM) 22577c478bd9Sstevel@tonic-gate char *newval; 22587c478bd9Sstevel@tonic-gate char exbuf[MAXLINE]; 225949218d4fSjbeck #endif /* STARTTLS || (_FFR_SELECT_SHM && SM_CONF_SHM) */ 22607c478bd9Sstevel@tonic-gate 22617c478bd9Sstevel@tonic-gate errno = 0; 22627c478bd9Sstevel@tonic-gate if (opt == ' ') 22637c478bd9Sstevel@tonic-gate { 22647c478bd9Sstevel@tonic-gate /* full word options */ 22657c478bd9Sstevel@tonic-gate struct optioninfo *sel; 22667c478bd9Sstevel@tonic-gate 22677c478bd9Sstevel@tonic-gate p = strchr(val, '='); 22687c478bd9Sstevel@tonic-gate if (p == NULL) 22697c478bd9Sstevel@tonic-gate p = &val[strlen(val)]; 22707c478bd9Sstevel@tonic-gate while (*--p == ' ') 22717c478bd9Sstevel@tonic-gate continue; 22727c478bd9Sstevel@tonic-gate while (*++p == ' ') 22737c478bd9Sstevel@tonic-gate *p = '\0'; 22747c478bd9Sstevel@tonic-gate if (p == val) 22757c478bd9Sstevel@tonic-gate { 22767c478bd9Sstevel@tonic-gate syserr("readcf: null option name"); 22777c478bd9Sstevel@tonic-gate return; 22787c478bd9Sstevel@tonic-gate } 22797c478bd9Sstevel@tonic-gate if (*p == '=') 22807c478bd9Sstevel@tonic-gate *p++ = '\0'; 22817c478bd9Sstevel@tonic-gate while (*p == ' ') 22827c478bd9Sstevel@tonic-gate p++; 22837c478bd9Sstevel@tonic-gate subopt = strchr(val, '.'); 22847c478bd9Sstevel@tonic-gate if (subopt != NULL) 22857c478bd9Sstevel@tonic-gate *subopt++ = '\0'; 22867c478bd9Sstevel@tonic-gate sel = NULL; 22877c478bd9Sstevel@tonic-gate for (o = OptionTab; o->o_name != NULL; o++) 22887c478bd9Sstevel@tonic-gate { 22897c478bd9Sstevel@tonic-gate if (sm_strncasecmp(o->o_name, val, strlen(val)) != 0) 22907c478bd9Sstevel@tonic-gate continue; 22917c478bd9Sstevel@tonic-gate if (strlen(o->o_name) == strlen(val)) 22927c478bd9Sstevel@tonic-gate { 22937c478bd9Sstevel@tonic-gate /* completely specified -- this must be it */ 22947c478bd9Sstevel@tonic-gate sel = NULL; 22957c478bd9Sstevel@tonic-gate break; 22967c478bd9Sstevel@tonic-gate } 22977c478bd9Sstevel@tonic-gate if (sel != NULL) 22987c478bd9Sstevel@tonic-gate break; 22997c478bd9Sstevel@tonic-gate sel = o; 23007c478bd9Sstevel@tonic-gate } 23017c478bd9Sstevel@tonic-gate if (sel != NULL && o->o_name == NULL) 23027c478bd9Sstevel@tonic-gate o = sel; 23037c478bd9Sstevel@tonic-gate else if (o->o_name == NULL) 23047c478bd9Sstevel@tonic-gate { 23057c478bd9Sstevel@tonic-gate syserr("readcf: unknown option name %s", val); 23067c478bd9Sstevel@tonic-gate return; 23077c478bd9Sstevel@tonic-gate } 23087c478bd9Sstevel@tonic-gate else if (sel != NULL) 23097c478bd9Sstevel@tonic-gate { 23107c478bd9Sstevel@tonic-gate syserr("readcf: ambiguous option name %s (matches %s and %s)", 23117c478bd9Sstevel@tonic-gate val, sel->o_name, o->o_name); 23127c478bd9Sstevel@tonic-gate return; 23137c478bd9Sstevel@tonic-gate } 23147c478bd9Sstevel@tonic-gate if (strlen(val) != strlen(o->o_name)) 23157c478bd9Sstevel@tonic-gate { 23167c478bd9Sstevel@tonic-gate int oldVerbose = Verbose; 23177c478bd9Sstevel@tonic-gate 23187c478bd9Sstevel@tonic-gate Verbose = 1; 23197c478bd9Sstevel@tonic-gate message("Option %s used as abbreviation for %s", 23207c478bd9Sstevel@tonic-gate val, o->o_name); 23217c478bd9Sstevel@tonic-gate Verbose = oldVerbose; 23227c478bd9Sstevel@tonic-gate } 23237c478bd9Sstevel@tonic-gate opt = o->o_code; 23247c478bd9Sstevel@tonic-gate val = p; 23257c478bd9Sstevel@tonic-gate } 23267c478bd9Sstevel@tonic-gate else 23277c478bd9Sstevel@tonic-gate { 23287c478bd9Sstevel@tonic-gate for (o = OptionTab; o->o_name != NULL; o++) 23297c478bd9Sstevel@tonic-gate { 23307c478bd9Sstevel@tonic-gate if (o->o_code == opt) 23317c478bd9Sstevel@tonic-gate break; 23327c478bd9Sstevel@tonic-gate } 23337c478bd9Sstevel@tonic-gate if (o->o_name == NULL) 23347c478bd9Sstevel@tonic-gate { 23357c478bd9Sstevel@tonic-gate syserr("readcf: unknown option name 0x%x", opt & 0xff); 23367c478bd9Sstevel@tonic-gate return; 23377c478bd9Sstevel@tonic-gate } 23387c478bd9Sstevel@tonic-gate subopt = NULL; 23397c478bd9Sstevel@tonic-gate } 23407c478bd9Sstevel@tonic-gate 23417c478bd9Sstevel@tonic-gate if (subopt != NULL && !bitset(OI_SUBOPT, o->o_flags)) 23427c478bd9Sstevel@tonic-gate { 23437c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 23447c478bd9Sstevel@tonic-gate sm_dprintf("setoption: %s does not support suboptions, ignoring .%s\n", 23457c478bd9Sstevel@tonic-gate OPTNAME, subopt); 23467c478bd9Sstevel@tonic-gate subopt = NULL; 23477c478bd9Sstevel@tonic-gate } 23487c478bd9Sstevel@tonic-gate 23497c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 23507c478bd9Sstevel@tonic-gate { 23517c478bd9Sstevel@tonic-gate sm_dprintf(isascii(opt) && isprint(opt) ? 23527c478bd9Sstevel@tonic-gate "setoption %s (%c)%s%s=" : 23537c478bd9Sstevel@tonic-gate "setoption %s (0x%x)%s%s=", 23547c478bd9Sstevel@tonic-gate OPTNAME, opt, subopt == NULL ? "" : ".", 23557c478bd9Sstevel@tonic-gate subopt == NULL ? "" : subopt); 23567c478bd9Sstevel@tonic-gate xputs(sm_debug_file(), val); 23577c478bd9Sstevel@tonic-gate } 23587c478bd9Sstevel@tonic-gate 23597c478bd9Sstevel@tonic-gate /* 23607c478bd9Sstevel@tonic-gate ** See if this option is preset for us. 23617c478bd9Sstevel@tonic-gate */ 23627c478bd9Sstevel@tonic-gate 23637c478bd9Sstevel@tonic-gate if (!sticky && bitnset(opt, StickyOpt)) 23647c478bd9Sstevel@tonic-gate { 23657c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 23667c478bd9Sstevel@tonic-gate sm_dprintf(" (ignored)\n"); 23677c478bd9Sstevel@tonic-gate return; 23687c478bd9Sstevel@tonic-gate } 23697c478bd9Sstevel@tonic-gate 23707c478bd9Sstevel@tonic-gate /* 23717c478bd9Sstevel@tonic-gate ** Check to see if this option can be specified by this user. 23727c478bd9Sstevel@tonic-gate */ 23737c478bd9Sstevel@tonic-gate 23747c478bd9Sstevel@tonic-gate if (!safe && RealUid == 0) 23757c478bd9Sstevel@tonic-gate safe = true; 23767c478bd9Sstevel@tonic-gate if (!safe && !bitset(OI_SAFE, o->o_flags)) 23777c478bd9Sstevel@tonic-gate { 23787c478bd9Sstevel@tonic-gate if (opt != 'M' || (val[0] != 'r' && val[0] != 's')) 23797c478bd9Sstevel@tonic-gate { 23807c478bd9Sstevel@tonic-gate int dp; 23817c478bd9Sstevel@tonic-gate 23827c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 23837c478bd9Sstevel@tonic-gate sm_dprintf(" (unsafe)"); 23847c478bd9Sstevel@tonic-gate dp = drop_privileges(true); 23857c478bd9Sstevel@tonic-gate setstat(dp); 23867c478bd9Sstevel@tonic-gate } 23877c478bd9Sstevel@tonic-gate } 23887c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 23897c478bd9Sstevel@tonic-gate sm_dprintf("\n"); 23907c478bd9Sstevel@tonic-gate 23917c478bd9Sstevel@tonic-gate switch (opt & 0xff) 23927c478bd9Sstevel@tonic-gate { 23937c478bd9Sstevel@tonic-gate case '7': /* force seven-bit input */ 23947c478bd9Sstevel@tonic-gate SevenBitInput = atobool(val); 23957c478bd9Sstevel@tonic-gate break; 23967c478bd9Sstevel@tonic-gate 23977c478bd9Sstevel@tonic-gate case '8': /* handling of 8-bit input */ 23987c478bd9Sstevel@tonic-gate #if MIME8TO7 23997c478bd9Sstevel@tonic-gate switch (*val) 24007c478bd9Sstevel@tonic-gate { 24017c478bd9Sstevel@tonic-gate case 'p': /* pass 8 bit, convert MIME */ 24027c478bd9Sstevel@tonic-gate MimeMode = MM_CVTMIME|MM_PASS8BIT; 24037c478bd9Sstevel@tonic-gate break; 24047c478bd9Sstevel@tonic-gate 24057c478bd9Sstevel@tonic-gate case 'm': /* convert 8-bit, convert MIME */ 24067c478bd9Sstevel@tonic-gate MimeMode = MM_CVTMIME|MM_MIME8BIT; 24077c478bd9Sstevel@tonic-gate break; 24087c478bd9Sstevel@tonic-gate 24097c478bd9Sstevel@tonic-gate case 's': /* strict adherence */ 24107c478bd9Sstevel@tonic-gate MimeMode = MM_CVTMIME; 24117c478bd9Sstevel@tonic-gate break; 24127c478bd9Sstevel@tonic-gate 24137c478bd9Sstevel@tonic-gate # if 0 24147c478bd9Sstevel@tonic-gate case 'r': /* reject 8-bit, don't convert MIME */ 24157c478bd9Sstevel@tonic-gate MimeMode = 0; 24167c478bd9Sstevel@tonic-gate break; 24177c478bd9Sstevel@tonic-gate 24187c478bd9Sstevel@tonic-gate case 'j': /* "just send 8" */ 24197c478bd9Sstevel@tonic-gate MimeMode = MM_PASS8BIT; 24207c478bd9Sstevel@tonic-gate break; 24217c478bd9Sstevel@tonic-gate 24227c478bd9Sstevel@tonic-gate case 'a': /* encode 8 bit if available */ 24237c478bd9Sstevel@tonic-gate MimeMode = MM_MIME8BIT|MM_PASS8BIT|MM_CVTMIME; 24247c478bd9Sstevel@tonic-gate break; 24257c478bd9Sstevel@tonic-gate 24267c478bd9Sstevel@tonic-gate case 'c': /* convert 8 bit to MIME, never 7 bit */ 24277c478bd9Sstevel@tonic-gate MimeMode = MM_MIME8BIT; 24287c478bd9Sstevel@tonic-gate break; 24297c478bd9Sstevel@tonic-gate # endif /* 0 */ 24307c478bd9Sstevel@tonic-gate 24317c478bd9Sstevel@tonic-gate default: 24327c478bd9Sstevel@tonic-gate syserr("Unknown 8-bit mode %c", *val); 24337c478bd9Sstevel@tonic-gate finis(false, true, EX_USAGE); 24347c478bd9Sstevel@tonic-gate } 24357c478bd9Sstevel@tonic-gate #else /* MIME8TO7 */ 24367c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 24377c478bd9Sstevel@tonic-gate "Warning: Option: %s requires MIME8TO7 support\n", 24387c478bd9Sstevel@tonic-gate OPTNAME); 24397c478bd9Sstevel@tonic-gate #endif /* MIME8TO7 */ 24407c478bd9Sstevel@tonic-gate break; 24417c478bd9Sstevel@tonic-gate 24427c478bd9Sstevel@tonic-gate case 'A': /* set default alias file */ 24437c478bd9Sstevel@tonic-gate if (val[0] == '\0') 24447c478bd9Sstevel@tonic-gate { 24457c478bd9Sstevel@tonic-gate char *al; 24467c478bd9Sstevel@tonic-gate 24477c478bd9Sstevel@tonic-gate SET_OPT_DEFAULT(al, "aliases"); 24487c478bd9Sstevel@tonic-gate setalias(al); 24497c478bd9Sstevel@tonic-gate } 24507c478bd9Sstevel@tonic-gate else 24517c478bd9Sstevel@tonic-gate setalias(val); 24527c478bd9Sstevel@tonic-gate break; 24537c478bd9Sstevel@tonic-gate 24547c478bd9Sstevel@tonic-gate case 'a': /* look N minutes for "@:@" in alias file */ 24557c478bd9Sstevel@tonic-gate if (val[0] == '\0') 24567c478bd9Sstevel@tonic-gate SafeAlias = 5 MINUTES; 24577c478bd9Sstevel@tonic-gate else 24587c478bd9Sstevel@tonic-gate SafeAlias = convtime(val, 'm'); 24597c478bd9Sstevel@tonic-gate break; 24607c478bd9Sstevel@tonic-gate 24617c478bd9Sstevel@tonic-gate case 'B': /* substitution for blank character */ 24627c478bd9Sstevel@tonic-gate SpaceSub = val[0]; 24637c478bd9Sstevel@tonic-gate if (SpaceSub == '\0') 24647c478bd9Sstevel@tonic-gate SpaceSub = ' '; 24657c478bd9Sstevel@tonic-gate break; 24667c478bd9Sstevel@tonic-gate 24677c478bd9Sstevel@tonic-gate case 'b': /* min blocks free on queue fs/max msg size */ 24687c478bd9Sstevel@tonic-gate p = strchr(val, '/'); 24697c478bd9Sstevel@tonic-gate if (p != NULL) 24707c478bd9Sstevel@tonic-gate { 24717c478bd9Sstevel@tonic-gate *p++ = '\0'; 24727c478bd9Sstevel@tonic-gate MaxMessageSize = atol(p); 24737c478bd9Sstevel@tonic-gate } 24747c478bd9Sstevel@tonic-gate MinBlocksFree = atol(val); 24757c478bd9Sstevel@tonic-gate break; 24767c478bd9Sstevel@tonic-gate 24777c478bd9Sstevel@tonic-gate case 'c': /* don't connect to "expensive" mailers */ 24787c478bd9Sstevel@tonic-gate NoConnect = atobool(val); 24797c478bd9Sstevel@tonic-gate break; 24807c478bd9Sstevel@tonic-gate 24817c478bd9Sstevel@tonic-gate case 'C': /* checkpoint every N addresses */ 24827c478bd9Sstevel@tonic-gate if (safe || CheckpointInterval > atoi(val)) 24837c478bd9Sstevel@tonic-gate CheckpointInterval = atoi(val); 24847c478bd9Sstevel@tonic-gate break; 24857c478bd9Sstevel@tonic-gate 24867c478bd9Sstevel@tonic-gate case 'd': /* delivery mode */ 24877c478bd9Sstevel@tonic-gate switch (*val) 24887c478bd9Sstevel@tonic-gate { 24897c478bd9Sstevel@tonic-gate case '\0': 24907c478bd9Sstevel@tonic-gate set_delivery_mode(SM_DELIVER, e); 24917c478bd9Sstevel@tonic-gate break; 24927c478bd9Sstevel@tonic-gate 24937c478bd9Sstevel@tonic-gate case SM_QUEUE: /* queue only */ 24947c478bd9Sstevel@tonic-gate case SM_DEFER: /* queue only and defer map lookups */ 24957c478bd9Sstevel@tonic-gate case SM_DELIVER: /* do everything */ 24967c478bd9Sstevel@tonic-gate case SM_FORK: /* fork after verification */ 2497*445f2479Sjbeck #if _FFR_DM_ONE 2498*445f2479Sjbeck /* deliver first TA in background, then queue */ 2499*445f2479Sjbeck case SM_DM_ONE: 2500*445f2479Sjbeck #endif /* _FFR_DM_ONE */ 25017c478bd9Sstevel@tonic-gate set_delivery_mode(*val, e); 25027c478bd9Sstevel@tonic-gate break; 25037c478bd9Sstevel@tonic-gate 25047c478bd9Sstevel@tonic-gate default: 25057c478bd9Sstevel@tonic-gate syserr("Unknown delivery mode %c", *val); 25067c478bd9Sstevel@tonic-gate finis(false, true, EX_USAGE); 25077c478bd9Sstevel@tonic-gate } 25087c478bd9Sstevel@tonic-gate break; 25097c478bd9Sstevel@tonic-gate 25107c478bd9Sstevel@tonic-gate case 'E': /* error message header/header file */ 25117c478bd9Sstevel@tonic-gate if (*val != '\0') 25127c478bd9Sstevel@tonic-gate ErrMsgFile = newstr(val); 25137c478bd9Sstevel@tonic-gate break; 25147c478bd9Sstevel@tonic-gate 25157c478bd9Sstevel@tonic-gate case 'e': /* set error processing mode */ 25167c478bd9Sstevel@tonic-gate switch (*val) 25177c478bd9Sstevel@tonic-gate { 25187c478bd9Sstevel@tonic-gate case EM_QUIET: /* be silent about it */ 25197c478bd9Sstevel@tonic-gate case EM_MAIL: /* mail back */ 25207c478bd9Sstevel@tonic-gate case EM_BERKNET: /* do berknet error processing */ 25217c478bd9Sstevel@tonic-gate case EM_WRITE: /* write back (or mail) */ 25227c478bd9Sstevel@tonic-gate case EM_PRINT: /* print errors normally (default) */ 25237c478bd9Sstevel@tonic-gate e->e_errormode = *val; 25247c478bd9Sstevel@tonic-gate break; 25257c478bd9Sstevel@tonic-gate } 25267c478bd9Sstevel@tonic-gate break; 25277c478bd9Sstevel@tonic-gate 25287c478bd9Sstevel@tonic-gate case 'F': /* file mode */ 25297c478bd9Sstevel@tonic-gate FileMode = atooct(val) & 0777; 25307c478bd9Sstevel@tonic-gate break; 25317c478bd9Sstevel@tonic-gate 25327c478bd9Sstevel@tonic-gate case 'f': /* save Unix-style From lines on front */ 25337c478bd9Sstevel@tonic-gate SaveFrom = atobool(val); 25347c478bd9Sstevel@tonic-gate break; 25357c478bd9Sstevel@tonic-gate 25367c478bd9Sstevel@tonic-gate case 'G': /* match recipients against GECOS field */ 25377c478bd9Sstevel@tonic-gate MatchGecos = atobool(val); 25387c478bd9Sstevel@tonic-gate break; 25397c478bd9Sstevel@tonic-gate 25407c478bd9Sstevel@tonic-gate case 'g': /* default gid */ 25417c478bd9Sstevel@tonic-gate g_opt: 25427c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 25437c478bd9Sstevel@tonic-gate DefGid = atoi(val); 25447c478bd9Sstevel@tonic-gate else 25457c478bd9Sstevel@tonic-gate { 25467c478bd9Sstevel@tonic-gate register struct group *gr; 25477c478bd9Sstevel@tonic-gate 25487c478bd9Sstevel@tonic-gate DefGid = -1; 25497c478bd9Sstevel@tonic-gate gr = getgrnam(val); 25507c478bd9Sstevel@tonic-gate if (gr == NULL) 25517c478bd9Sstevel@tonic-gate syserr("readcf: option %c: unknown group %s", 25527c478bd9Sstevel@tonic-gate opt, val); 25537c478bd9Sstevel@tonic-gate else 25547c478bd9Sstevel@tonic-gate DefGid = gr->gr_gid; 25557c478bd9Sstevel@tonic-gate } 25567c478bd9Sstevel@tonic-gate break; 25577c478bd9Sstevel@tonic-gate 25587c478bd9Sstevel@tonic-gate case 'H': /* help file */ 25597c478bd9Sstevel@tonic-gate if (val[0] == '\0') 25607c478bd9Sstevel@tonic-gate { 25617c478bd9Sstevel@tonic-gate SET_OPT_DEFAULT(HelpFile, "helpfile"); 25627c478bd9Sstevel@tonic-gate } 25637c478bd9Sstevel@tonic-gate else 25647c478bd9Sstevel@tonic-gate { 25657c478bd9Sstevel@tonic-gate CANONIFY(val); 25667c478bd9Sstevel@tonic-gate HelpFile = newstr(val); 25677c478bd9Sstevel@tonic-gate } 25687c478bd9Sstevel@tonic-gate break; 25697c478bd9Sstevel@tonic-gate 25707c478bd9Sstevel@tonic-gate case 'h': /* maximum hop count */ 25717c478bd9Sstevel@tonic-gate MaxHopCount = atoi(val); 25727c478bd9Sstevel@tonic-gate break; 25737c478bd9Sstevel@tonic-gate 25747c478bd9Sstevel@tonic-gate case 'I': /* use internet domain name server */ 25757c478bd9Sstevel@tonic-gate #if NAMED_BIND 25767c478bd9Sstevel@tonic-gate for (p = val; *p != 0; ) 25777c478bd9Sstevel@tonic-gate { 25787c478bd9Sstevel@tonic-gate bool clearmode; 25797c478bd9Sstevel@tonic-gate char *q; 25807c478bd9Sstevel@tonic-gate struct resolverflags *rfp; 25817c478bd9Sstevel@tonic-gate 25827c478bd9Sstevel@tonic-gate while (*p == ' ') 25837c478bd9Sstevel@tonic-gate p++; 25847c478bd9Sstevel@tonic-gate if (*p == '\0') 25857c478bd9Sstevel@tonic-gate break; 25867c478bd9Sstevel@tonic-gate clearmode = false; 25877c478bd9Sstevel@tonic-gate if (*p == '-') 25887c478bd9Sstevel@tonic-gate clearmode = true; 25897c478bd9Sstevel@tonic-gate else if (*p != '+') 25907c478bd9Sstevel@tonic-gate p--; 25917c478bd9Sstevel@tonic-gate p++; 25927c478bd9Sstevel@tonic-gate q = p; 25937c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 25947c478bd9Sstevel@tonic-gate p++; 25957c478bd9Sstevel@tonic-gate if (*p != '\0') 25967c478bd9Sstevel@tonic-gate *p++ = '\0'; 25977c478bd9Sstevel@tonic-gate if (sm_strcasecmp(q, "HasWildcardMX") == 0) 25987c478bd9Sstevel@tonic-gate { 25997c478bd9Sstevel@tonic-gate HasWildcardMX = !clearmode; 26007c478bd9Sstevel@tonic-gate continue; 26017c478bd9Sstevel@tonic-gate } 26027c478bd9Sstevel@tonic-gate if (sm_strcasecmp(q, "WorkAroundBrokenAAAA") == 0) 26037c478bd9Sstevel@tonic-gate { 26047c478bd9Sstevel@tonic-gate WorkAroundBrokenAAAA = !clearmode; 26057c478bd9Sstevel@tonic-gate continue; 26067c478bd9Sstevel@tonic-gate } 26077c478bd9Sstevel@tonic-gate for (rfp = ResolverFlags; rfp->rf_name != NULL; rfp++) 26087c478bd9Sstevel@tonic-gate { 26097c478bd9Sstevel@tonic-gate if (sm_strcasecmp(q, rfp->rf_name) == 0) 26107c478bd9Sstevel@tonic-gate break; 26117c478bd9Sstevel@tonic-gate } 26127c478bd9Sstevel@tonic-gate if (rfp->rf_name == NULL) 26137c478bd9Sstevel@tonic-gate syserr("readcf: I option value %s unrecognized", q); 26147c478bd9Sstevel@tonic-gate else if (clearmode) 26157c478bd9Sstevel@tonic-gate _res.options &= ~rfp->rf_bits; 26167c478bd9Sstevel@tonic-gate else 26177c478bd9Sstevel@tonic-gate _res.options |= rfp->rf_bits; 26187c478bd9Sstevel@tonic-gate } 26197c478bd9Sstevel@tonic-gate if (tTd(8, 2)) 26207c478bd9Sstevel@tonic-gate sm_dprintf("_res.options = %x, HasWildcardMX = %d\n", 26217c478bd9Sstevel@tonic-gate (unsigned int) _res.options, HasWildcardMX); 26227c478bd9Sstevel@tonic-gate #else /* NAMED_BIND */ 26237c478bd9Sstevel@tonic-gate usrerr("name server (I option) specified but BIND not compiled in"); 26247c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */ 26257c478bd9Sstevel@tonic-gate break; 26267c478bd9Sstevel@tonic-gate 26277c478bd9Sstevel@tonic-gate case 'i': /* ignore dot lines in message */ 26287c478bd9Sstevel@tonic-gate IgnrDot = atobool(val); 26297c478bd9Sstevel@tonic-gate break; 26307c478bd9Sstevel@tonic-gate 26317c478bd9Sstevel@tonic-gate case 'j': /* send errors in MIME (RFC 1341) format */ 26327c478bd9Sstevel@tonic-gate SendMIMEErrors = atobool(val); 26337c478bd9Sstevel@tonic-gate break; 26347c478bd9Sstevel@tonic-gate 26357c478bd9Sstevel@tonic-gate case 'J': /* .forward search path */ 26367c478bd9Sstevel@tonic-gate CANONIFY(val); 26377c478bd9Sstevel@tonic-gate ForwardPath = newstr(val); 26387c478bd9Sstevel@tonic-gate break; 26397c478bd9Sstevel@tonic-gate 26407c478bd9Sstevel@tonic-gate case 'k': /* connection cache size */ 26417c478bd9Sstevel@tonic-gate MaxMciCache = atoi(val); 26427c478bd9Sstevel@tonic-gate if (MaxMciCache < 0) 26437c478bd9Sstevel@tonic-gate MaxMciCache = 0; 26447c478bd9Sstevel@tonic-gate break; 26457c478bd9Sstevel@tonic-gate 26467c478bd9Sstevel@tonic-gate case 'K': /* connection cache timeout */ 26477c478bd9Sstevel@tonic-gate MciCacheTimeout = convtime(val, 'm'); 26487c478bd9Sstevel@tonic-gate break; 26497c478bd9Sstevel@tonic-gate 26507c478bd9Sstevel@tonic-gate case 'l': /* use Errors-To: header */ 26517c478bd9Sstevel@tonic-gate UseErrorsTo = atobool(val); 26527c478bd9Sstevel@tonic-gate break; 26537c478bd9Sstevel@tonic-gate 26547c478bd9Sstevel@tonic-gate case 'L': /* log level */ 26557c478bd9Sstevel@tonic-gate if (safe || LogLevel < atoi(val)) 26567c478bd9Sstevel@tonic-gate LogLevel = atoi(val); 26577c478bd9Sstevel@tonic-gate break; 26587c478bd9Sstevel@tonic-gate 26597c478bd9Sstevel@tonic-gate case 'M': /* define macro */ 26607c478bd9Sstevel@tonic-gate sticky = false; 26617c478bd9Sstevel@tonic-gate mid = macid_parse(val, &ep); 26627c478bd9Sstevel@tonic-gate if (mid == 0) 26637c478bd9Sstevel@tonic-gate break; 26647c478bd9Sstevel@tonic-gate p = newstr(ep); 26657c478bd9Sstevel@tonic-gate if (!safe) 26667c478bd9Sstevel@tonic-gate cleanstrcpy(p, p, strlen(p) + 1); 26677c478bd9Sstevel@tonic-gate macdefine(&CurEnv->e_macro, A_TEMP, mid, p); 26687c478bd9Sstevel@tonic-gate break; 26697c478bd9Sstevel@tonic-gate 26707c478bd9Sstevel@tonic-gate case 'm': /* send to me too */ 26717c478bd9Sstevel@tonic-gate MeToo = atobool(val); 26727c478bd9Sstevel@tonic-gate break; 26737c478bd9Sstevel@tonic-gate 26747c478bd9Sstevel@tonic-gate case 'n': /* validate RHS in newaliases */ 26757c478bd9Sstevel@tonic-gate CheckAliases = atobool(val); 26767c478bd9Sstevel@tonic-gate break; 26777c478bd9Sstevel@tonic-gate 26787c478bd9Sstevel@tonic-gate /* 'N' available -- was "net name" */ 26797c478bd9Sstevel@tonic-gate 26807c478bd9Sstevel@tonic-gate case 'O': /* daemon options */ 26817c478bd9Sstevel@tonic-gate if (!setdaemonoptions(val)) 26827c478bd9Sstevel@tonic-gate syserr("too many daemons defined (%d max)", MAXDAEMONS); 26837c478bd9Sstevel@tonic-gate break; 26847c478bd9Sstevel@tonic-gate 26857c478bd9Sstevel@tonic-gate case 'o': /* assume old style headers */ 26867c478bd9Sstevel@tonic-gate if (atobool(val)) 26877c478bd9Sstevel@tonic-gate CurEnv->e_flags |= EF_OLDSTYLE; 26887c478bd9Sstevel@tonic-gate else 26897c478bd9Sstevel@tonic-gate CurEnv->e_flags &= ~EF_OLDSTYLE; 26907c478bd9Sstevel@tonic-gate break; 26917c478bd9Sstevel@tonic-gate 26927c478bd9Sstevel@tonic-gate case 'p': /* select privacy level */ 26937c478bd9Sstevel@tonic-gate p = val; 26947c478bd9Sstevel@tonic-gate for (;;) 26957c478bd9Sstevel@tonic-gate { 26967c478bd9Sstevel@tonic-gate register struct prival *pv; 26977c478bd9Sstevel@tonic-gate extern struct prival PrivacyValues[]; 26987c478bd9Sstevel@tonic-gate 26997c478bd9Sstevel@tonic-gate while (isascii(*p) && (isspace(*p) || ispunct(*p))) 27007c478bd9Sstevel@tonic-gate p++; 27017c478bd9Sstevel@tonic-gate if (*p == '\0') 27027c478bd9Sstevel@tonic-gate break; 27037c478bd9Sstevel@tonic-gate val = p; 27047c478bd9Sstevel@tonic-gate while (isascii(*p) && isalnum(*p)) 27057c478bd9Sstevel@tonic-gate p++; 27067c478bd9Sstevel@tonic-gate if (*p != '\0') 27077c478bd9Sstevel@tonic-gate *p++ = '\0'; 27087c478bd9Sstevel@tonic-gate 27097c478bd9Sstevel@tonic-gate for (pv = PrivacyValues; pv->pv_name != NULL; pv++) 27107c478bd9Sstevel@tonic-gate { 27117c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, pv->pv_name) == 0) 27127c478bd9Sstevel@tonic-gate break; 27137c478bd9Sstevel@tonic-gate } 27147c478bd9Sstevel@tonic-gate if (pv->pv_name == NULL) 27157c478bd9Sstevel@tonic-gate syserr("readcf: Op line: %s unrecognized", val); 27167c478bd9Sstevel@tonic-gate else 27177c478bd9Sstevel@tonic-gate PrivacyFlags |= pv->pv_flag; 27187c478bd9Sstevel@tonic-gate } 27197c478bd9Sstevel@tonic-gate sticky = false; 27207c478bd9Sstevel@tonic-gate break; 27217c478bd9Sstevel@tonic-gate 27227c478bd9Sstevel@tonic-gate case 'P': /* postmaster copy address for returned mail */ 27237c478bd9Sstevel@tonic-gate PostMasterCopy = newstr(val); 27247c478bd9Sstevel@tonic-gate break; 27257c478bd9Sstevel@tonic-gate 27267c478bd9Sstevel@tonic-gate case 'q': /* slope of queue only function */ 27277c478bd9Sstevel@tonic-gate QueueFactor = atoi(val); 27287c478bd9Sstevel@tonic-gate break; 27297c478bd9Sstevel@tonic-gate 27307c478bd9Sstevel@tonic-gate case 'Q': /* queue directory */ 27317c478bd9Sstevel@tonic-gate if (val[0] == '\0') 27327c478bd9Sstevel@tonic-gate { 27337c478bd9Sstevel@tonic-gate QueueDir = "mqueue"; 27347c478bd9Sstevel@tonic-gate } 27357c478bd9Sstevel@tonic-gate else 27367c478bd9Sstevel@tonic-gate { 27377c478bd9Sstevel@tonic-gate QueueDir = newstr(val); 27387c478bd9Sstevel@tonic-gate } 27397c478bd9Sstevel@tonic-gate if (RealUid != 0 && !safe) 27407c478bd9Sstevel@tonic-gate Warn_Q_option = true; 27417c478bd9Sstevel@tonic-gate break; 27427c478bd9Sstevel@tonic-gate 27437c478bd9Sstevel@tonic-gate case 'R': /* don't prune routes */ 27447c478bd9Sstevel@tonic-gate DontPruneRoutes = atobool(val); 27457c478bd9Sstevel@tonic-gate break; 27467c478bd9Sstevel@tonic-gate 27477c478bd9Sstevel@tonic-gate case 'r': /* read timeout */ 27487c478bd9Sstevel@tonic-gate if (subopt == NULL) 27497c478bd9Sstevel@tonic-gate inittimeouts(val, sticky); 27507c478bd9Sstevel@tonic-gate else 27517c478bd9Sstevel@tonic-gate settimeout(subopt, val, sticky); 27527c478bd9Sstevel@tonic-gate break; 27537c478bd9Sstevel@tonic-gate 27547c478bd9Sstevel@tonic-gate case 'S': /* status file */ 27557c478bd9Sstevel@tonic-gate if (val[0] == '\0') 27567c478bd9Sstevel@tonic-gate { 27577c478bd9Sstevel@tonic-gate SET_OPT_DEFAULT(StatFile, "statistics"); 27587c478bd9Sstevel@tonic-gate } 27597c478bd9Sstevel@tonic-gate else 27607c478bd9Sstevel@tonic-gate { 27617c478bd9Sstevel@tonic-gate CANONIFY(val); 27627c478bd9Sstevel@tonic-gate StatFile = newstr(val); 27637c478bd9Sstevel@tonic-gate } 27647c478bd9Sstevel@tonic-gate break; 27657c478bd9Sstevel@tonic-gate 27667c478bd9Sstevel@tonic-gate case 's': /* be super safe, even if expensive */ 27677c478bd9Sstevel@tonic-gate if (tolower(*val) == 'i') 27687c478bd9Sstevel@tonic-gate SuperSafe = SAFE_INTERACTIVE; 27697c478bd9Sstevel@tonic-gate else if (tolower(*val) == 'p') 27707c478bd9Sstevel@tonic-gate #if MILTER 27717c478bd9Sstevel@tonic-gate SuperSafe = SAFE_REALLY_POSTMILTER; 27727c478bd9Sstevel@tonic-gate #else /* MILTER */ 27737c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 27747c478bd9Sstevel@tonic-gate "Warning: SuperSafe=PostMilter requires Milter support (-DMILTER)\n"); 27757c478bd9Sstevel@tonic-gate #endif /* MILTER */ 27767c478bd9Sstevel@tonic-gate else 27777c478bd9Sstevel@tonic-gate SuperSafe = atobool(val) ? SAFE_REALLY : SAFE_NO; 27787c478bd9Sstevel@tonic-gate break; 27797c478bd9Sstevel@tonic-gate 27807c478bd9Sstevel@tonic-gate case 'T': /* queue timeout */ 27817c478bd9Sstevel@tonic-gate p = strchr(val, '/'); 27827c478bd9Sstevel@tonic-gate if (p != NULL) 27837c478bd9Sstevel@tonic-gate { 27847c478bd9Sstevel@tonic-gate *p++ = '\0'; 27857c478bd9Sstevel@tonic-gate settimeout("queuewarn", p, sticky); 27867c478bd9Sstevel@tonic-gate } 27877c478bd9Sstevel@tonic-gate settimeout("queuereturn", val, sticky); 27887c478bd9Sstevel@tonic-gate break; 27897c478bd9Sstevel@tonic-gate 27907c478bd9Sstevel@tonic-gate case 't': /* time zone name */ 27917c478bd9Sstevel@tonic-gate TimeZoneSpec = newstr(val); 27927c478bd9Sstevel@tonic-gate break; 27937c478bd9Sstevel@tonic-gate 27947c478bd9Sstevel@tonic-gate case 'U': /* location of user database */ 27957c478bd9Sstevel@tonic-gate UdbSpec = newstr(val); 27967c478bd9Sstevel@tonic-gate break; 27977c478bd9Sstevel@tonic-gate 27987c478bd9Sstevel@tonic-gate case 'u': /* set default uid */ 27997c478bd9Sstevel@tonic-gate for (p = val; *p != '\0'; p++) 28007c478bd9Sstevel@tonic-gate { 28017c478bd9Sstevel@tonic-gate # if _FFR_DOTTED_USERNAMES 28027c478bd9Sstevel@tonic-gate if (*p == '/' || *p == ':') 28037c478bd9Sstevel@tonic-gate # else /* _FFR_DOTTED_USERNAMES */ 28047c478bd9Sstevel@tonic-gate if (*p == '.' || *p == '/' || *p == ':') 28057c478bd9Sstevel@tonic-gate # endif /* _FFR_DOTTED_USERNAMES */ 28067c478bd9Sstevel@tonic-gate { 28077c478bd9Sstevel@tonic-gate *p++ = '\0'; 28087c478bd9Sstevel@tonic-gate break; 28097c478bd9Sstevel@tonic-gate } 28107c478bd9Sstevel@tonic-gate } 28117c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 28127c478bd9Sstevel@tonic-gate { 28137c478bd9Sstevel@tonic-gate DefUid = atoi(val); 28147c478bd9Sstevel@tonic-gate setdefuser(); 28157c478bd9Sstevel@tonic-gate } 28167c478bd9Sstevel@tonic-gate else 28177c478bd9Sstevel@tonic-gate { 28187c478bd9Sstevel@tonic-gate register struct passwd *pw; 28197c478bd9Sstevel@tonic-gate 28207c478bd9Sstevel@tonic-gate DefUid = -1; 28217c478bd9Sstevel@tonic-gate pw = sm_getpwnam(val); 28227c478bd9Sstevel@tonic-gate if (pw == NULL) 28237c478bd9Sstevel@tonic-gate { 28247c478bd9Sstevel@tonic-gate syserr("readcf: option u: unknown user %s", val); 28257c478bd9Sstevel@tonic-gate break; 28267c478bd9Sstevel@tonic-gate } 28277c478bd9Sstevel@tonic-gate else 28287c478bd9Sstevel@tonic-gate { 28297c478bd9Sstevel@tonic-gate DefUid = pw->pw_uid; 28307c478bd9Sstevel@tonic-gate DefGid = pw->pw_gid; 28317c478bd9Sstevel@tonic-gate DefUser = newstr(pw->pw_name); 28327c478bd9Sstevel@tonic-gate } 28337c478bd9Sstevel@tonic-gate } 28347c478bd9Sstevel@tonic-gate 28357c478bd9Sstevel@tonic-gate # ifdef UID_MAX 28367c478bd9Sstevel@tonic-gate if (DefUid > UID_MAX) 28377c478bd9Sstevel@tonic-gate { 28387c478bd9Sstevel@tonic-gate syserr("readcf: option u: uid value (%ld) > UID_MAX (%ld); ignored", 28397c478bd9Sstevel@tonic-gate (long)DefUid, (long)UID_MAX); 28407c478bd9Sstevel@tonic-gate break; 28417c478bd9Sstevel@tonic-gate } 28427c478bd9Sstevel@tonic-gate # endif /* UID_MAX */ 28437c478bd9Sstevel@tonic-gate 28447c478bd9Sstevel@tonic-gate /* handle the group if it is there */ 28457c478bd9Sstevel@tonic-gate if (*p == '\0') 28467c478bd9Sstevel@tonic-gate break; 28477c478bd9Sstevel@tonic-gate val = p; 28487c478bd9Sstevel@tonic-gate goto g_opt; 28497c478bd9Sstevel@tonic-gate 28507c478bd9Sstevel@tonic-gate case 'V': /* fallback MX host */ 28517c478bd9Sstevel@tonic-gate if (val[0] != '\0') 28527c478bd9Sstevel@tonic-gate FallbackMX = newstr(val); 28537c478bd9Sstevel@tonic-gate break; 28547c478bd9Sstevel@tonic-gate 28557c478bd9Sstevel@tonic-gate case 'v': /* run in verbose mode */ 28567c478bd9Sstevel@tonic-gate Verbose = atobool(val) ? 1 : 0; 28577c478bd9Sstevel@tonic-gate break; 28587c478bd9Sstevel@tonic-gate 28597c478bd9Sstevel@tonic-gate case 'w': /* if we are best MX, try host directly */ 28607c478bd9Sstevel@tonic-gate TryNullMXList = atobool(val); 28617c478bd9Sstevel@tonic-gate break; 28627c478bd9Sstevel@tonic-gate 28637c478bd9Sstevel@tonic-gate /* 'W' available -- was wizard password */ 28647c478bd9Sstevel@tonic-gate 28657c478bd9Sstevel@tonic-gate case 'x': /* load avg at which to auto-queue msgs */ 28667c478bd9Sstevel@tonic-gate QueueLA = atoi(val); 28677c478bd9Sstevel@tonic-gate break; 28687c478bd9Sstevel@tonic-gate 28697c478bd9Sstevel@tonic-gate case 'X': /* load avg at which to auto-reject connections */ 28707c478bd9Sstevel@tonic-gate RefuseLA = atoi(val); 28717c478bd9Sstevel@tonic-gate break; 28727c478bd9Sstevel@tonic-gate 28737c478bd9Sstevel@tonic-gate case O_DELAY_LA: /* load avg at which to delay connections */ 28747c478bd9Sstevel@tonic-gate DelayLA = atoi(val); 28757c478bd9Sstevel@tonic-gate break; 28767c478bd9Sstevel@tonic-gate 28777c478bd9Sstevel@tonic-gate case 'y': /* work recipient factor */ 28787c478bd9Sstevel@tonic-gate WkRecipFact = atoi(val); 28797c478bd9Sstevel@tonic-gate break; 28807c478bd9Sstevel@tonic-gate 28817c478bd9Sstevel@tonic-gate case 'Y': /* fork jobs during queue runs */ 28827c478bd9Sstevel@tonic-gate ForkQueueRuns = atobool(val); 28837c478bd9Sstevel@tonic-gate break; 28847c478bd9Sstevel@tonic-gate 28857c478bd9Sstevel@tonic-gate case 'z': /* work message class factor */ 28867c478bd9Sstevel@tonic-gate WkClassFact = atoi(val); 28877c478bd9Sstevel@tonic-gate break; 28887c478bd9Sstevel@tonic-gate 28897c478bd9Sstevel@tonic-gate case 'Z': /* work time factor */ 28907c478bd9Sstevel@tonic-gate WkTimeFact = atoi(val); 28917c478bd9Sstevel@tonic-gate break; 28927c478bd9Sstevel@tonic-gate 28937c478bd9Sstevel@tonic-gate 28947c478bd9Sstevel@tonic-gate #if _FFR_QUEUE_GROUP_SORTORDER 28957c478bd9Sstevel@tonic-gate /* coordinate this with makequeue() */ 28967c478bd9Sstevel@tonic-gate #endif /* _FFR_QUEUE_GROUP_SORTORDER */ 28977c478bd9Sstevel@tonic-gate case O_QUEUESORTORD: /* queue sorting order */ 28987c478bd9Sstevel@tonic-gate switch (*val) 28997c478bd9Sstevel@tonic-gate { 29007c478bd9Sstevel@tonic-gate case 'f': /* File Name */ 29017c478bd9Sstevel@tonic-gate case 'F': 29027c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYFILENAME; 29037c478bd9Sstevel@tonic-gate break; 29047c478bd9Sstevel@tonic-gate 29057c478bd9Sstevel@tonic-gate case 'h': /* Host first */ 29067c478bd9Sstevel@tonic-gate case 'H': 29077c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYHOST; 29087c478bd9Sstevel@tonic-gate break; 29097c478bd9Sstevel@tonic-gate 29107c478bd9Sstevel@tonic-gate case 'm': /* Modification time */ 29117c478bd9Sstevel@tonic-gate case 'M': 29127c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYMODTIME; 29137c478bd9Sstevel@tonic-gate break; 29147c478bd9Sstevel@tonic-gate 29157c478bd9Sstevel@tonic-gate case 'p': /* Priority order */ 29167c478bd9Sstevel@tonic-gate case 'P': 29177c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYPRIORITY; 29187c478bd9Sstevel@tonic-gate break; 29197c478bd9Sstevel@tonic-gate 29207c478bd9Sstevel@tonic-gate case 't': /* Submission time */ 29217c478bd9Sstevel@tonic-gate case 'T': 29227c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYTIME; 29237c478bd9Sstevel@tonic-gate break; 29247c478bd9Sstevel@tonic-gate 29257c478bd9Sstevel@tonic-gate case 'r': /* Random */ 29267c478bd9Sstevel@tonic-gate case 'R': 29277c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_RANDOM; 29287c478bd9Sstevel@tonic-gate break; 29297c478bd9Sstevel@tonic-gate 29307c478bd9Sstevel@tonic-gate #if _FFR_RHS 29317c478bd9Sstevel@tonic-gate case 's': /* Shuffled host name */ 29327c478bd9Sstevel@tonic-gate case 'S': 29337c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYSHUFFLE; 29347c478bd9Sstevel@tonic-gate break; 29357c478bd9Sstevel@tonic-gate #endif /* _FFR_RHS */ 29367c478bd9Sstevel@tonic-gate 29377c478bd9Sstevel@tonic-gate case 'n': /* none */ 29387c478bd9Sstevel@tonic-gate case 'N': 29397c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_NONE; 29407c478bd9Sstevel@tonic-gate break; 29417c478bd9Sstevel@tonic-gate 29427c478bd9Sstevel@tonic-gate default: 29437c478bd9Sstevel@tonic-gate syserr("Invalid queue sort order \"%s\"", val); 29447c478bd9Sstevel@tonic-gate } 29457c478bd9Sstevel@tonic-gate break; 29467c478bd9Sstevel@tonic-gate 29477c478bd9Sstevel@tonic-gate case O_HOSTSFILE: /* pathname of /etc/hosts file */ 29487c478bd9Sstevel@tonic-gate CANONIFY(val); 29497c478bd9Sstevel@tonic-gate HostsFile = newstr(val); 29507c478bd9Sstevel@tonic-gate break; 29517c478bd9Sstevel@tonic-gate 29527c478bd9Sstevel@tonic-gate case O_MQA: /* minimum queue age between deliveries */ 29537c478bd9Sstevel@tonic-gate MinQueueAge = convtime(val, 'm'); 29547c478bd9Sstevel@tonic-gate break; 29557c478bd9Sstevel@tonic-gate 29567c478bd9Sstevel@tonic-gate case O_DEFCHARSET: /* default character set for mimefying */ 29577c478bd9Sstevel@tonic-gate DefaultCharSet = newstr(denlstring(val, true, true)); 29587c478bd9Sstevel@tonic-gate break; 29597c478bd9Sstevel@tonic-gate 29607c478bd9Sstevel@tonic-gate case O_SSFILE: /* service switch file */ 29617c478bd9Sstevel@tonic-gate CANONIFY(val); 29627c478bd9Sstevel@tonic-gate ServiceSwitchFile = newstr(val); 29637c478bd9Sstevel@tonic-gate break; 29647c478bd9Sstevel@tonic-gate 29657c478bd9Sstevel@tonic-gate case O_DIALDELAY: /* delay for dial-on-demand operation */ 29667c478bd9Sstevel@tonic-gate DialDelay = convtime(val, 's'); 29677c478bd9Sstevel@tonic-gate break; 29687c478bd9Sstevel@tonic-gate 29697c478bd9Sstevel@tonic-gate case O_NORCPTACTION: /* what to do if no recipient */ 29707c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, "none") == 0) 29717c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_NO_ACTION; 29727c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-to") == 0) 29737c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_TO; 29747c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-apparently-to") == 0) 29757c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_APPARENTLY_TO; 29767c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-bcc") == 0) 29777c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_BCC; 29787c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-to-undisclosed") == 0) 29797c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_TO_UNDISCLOSED; 29807c478bd9Sstevel@tonic-gate else 29817c478bd9Sstevel@tonic-gate syserr("Invalid NoRecipientAction: %s", val); 29827c478bd9Sstevel@tonic-gate break; 29837c478bd9Sstevel@tonic-gate 29847c478bd9Sstevel@tonic-gate case O_SAFEFILEENV: /* chroot() environ for writing to files */ 29857c478bd9Sstevel@tonic-gate if (*val == '\0') 29867c478bd9Sstevel@tonic-gate break; 29877c478bd9Sstevel@tonic-gate 29887c478bd9Sstevel@tonic-gate /* strip trailing slashes */ 29897c478bd9Sstevel@tonic-gate p = val + strlen(val) - 1; 29907c478bd9Sstevel@tonic-gate while (p >= val && *p == '/') 29917c478bd9Sstevel@tonic-gate *p-- = '\0'; 29927c478bd9Sstevel@tonic-gate 29937c478bd9Sstevel@tonic-gate if (*val == '\0') 29947c478bd9Sstevel@tonic-gate break; 29957c478bd9Sstevel@tonic-gate 29967c478bd9Sstevel@tonic-gate SafeFileEnv = newstr(val); 29977c478bd9Sstevel@tonic-gate break; 29987c478bd9Sstevel@tonic-gate 29997c478bd9Sstevel@tonic-gate case O_MAXMSGSIZE: /* maximum message size */ 30007c478bd9Sstevel@tonic-gate MaxMessageSize = atol(val); 30017c478bd9Sstevel@tonic-gate break; 30027c478bd9Sstevel@tonic-gate 30037c478bd9Sstevel@tonic-gate case O_COLONOKINADDR: /* old style handling of colon addresses */ 30047c478bd9Sstevel@tonic-gate ColonOkInAddr = atobool(val); 30057c478bd9Sstevel@tonic-gate break; 30067c478bd9Sstevel@tonic-gate 30077c478bd9Sstevel@tonic-gate case O_MAXQUEUERUN: /* max # of jobs in a single queue run */ 30087c478bd9Sstevel@tonic-gate MaxQueueRun = atoi(val); 30097c478bd9Sstevel@tonic-gate break; 30107c478bd9Sstevel@tonic-gate 30117c478bd9Sstevel@tonic-gate case O_MAXCHILDREN: /* max # of children of daemon */ 30127c478bd9Sstevel@tonic-gate MaxChildren = atoi(val); 30137c478bd9Sstevel@tonic-gate break; 30147c478bd9Sstevel@tonic-gate 30157c478bd9Sstevel@tonic-gate case O_MAXQUEUECHILDREN: /* max # of children of daemon */ 30167c478bd9Sstevel@tonic-gate MaxQueueChildren = atoi(val); 30177c478bd9Sstevel@tonic-gate break; 30187c478bd9Sstevel@tonic-gate 30197c478bd9Sstevel@tonic-gate case O_MAXRUNNERSPERQUEUE: /* max # runners in a queue group */ 30207c478bd9Sstevel@tonic-gate MaxRunnersPerQueue = atoi(val); 30217c478bd9Sstevel@tonic-gate break; 30227c478bd9Sstevel@tonic-gate 30237c478bd9Sstevel@tonic-gate case O_NICEQUEUERUN: /* nice queue runs */ 30247c478bd9Sstevel@tonic-gate #if !HASNICE 30257c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 30267c478bd9Sstevel@tonic-gate "Warning: NiceQueueRun set on system that doesn't support nice()\n"); 30277c478bd9Sstevel@tonic-gate #endif /* !HASNICE */ 30287c478bd9Sstevel@tonic-gate 30297c478bd9Sstevel@tonic-gate /* XXX do we want to check the range? > 0 ? */ 30307c478bd9Sstevel@tonic-gate NiceQueueRun = atoi(val); 30317c478bd9Sstevel@tonic-gate break; 30327c478bd9Sstevel@tonic-gate 30337c478bd9Sstevel@tonic-gate case O_SHMKEY: /* shared memory key */ 30347c478bd9Sstevel@tonic-gate #if SM_CONF_SHM 30357c478bd9Sstevel@tonic-gate ShmKey = atol(val); 30367c478bd9Sstevel@tonic-gate #else /* SM_CONF_SHM */ 30377c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 30387c478bd9Sstevel@tonic-gate "Warning: Option: %s requires shared memory support (-DSM_CONF_SHM)\n", 30397c478bd9Sstevel@tonic-gate OPTNAME); 30407c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SHM */ 30417c478bd9Sstevel@tonic-gate break; 30427c478bd9Sstevel@tonic-gate 30437c478bd9Sstevel@tonic-gate #if _FFR_SELECT_SHM 30447c478bd9Sstevel@tonic-gate case O_SHMKEYFILE: /* shared memory key file */ 30457c478bd9Sstevel@tonic-gate # if SM_CONF_SHM 30467c478bd9Sstevel@tonic-gate SET_STRING_EXP(ShmKeyFile); 30477c478bd9Sstevel@tonic-gate # else /* SM_CONF_SHM */ 30487c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 30497c478bd9Sstevel@tonic-gate "Warning: Option: %s requires shared memory support (-DSM_CONF_SHM)\n", 30507c478bd9Sstevel@tonic-gate OPTNAME); 30517c478bd9Sstevel@tonic-gate break; 30527c478bd9Sstevel@tonic-gate # endif /* SM_CONF_SHM */ 30537c478bd9Sstevel@tonic-gate #endif /* _FFR_SELECT_SHM */ 30547c478bd9Sstevel@tonic-gate 30557c478bd9Sstevel@tonic-gate #if _FFR_MAX_FORWARD_ENTRIES 30567c478bd9Sstevel@tonic-gate case O_MAXFORWARD: /* max # of forward entries */ 30577c478bd9Sstevel@tonic-gate MaxForwardEntries = atoi(val); 30587c478bd9Sstevel@tonic-gate break; 30597c478bd9Sstevel@tonic-gate #endif /* _FFR_MAX_FORWARD_ENTRIES */ 30607c478bd9Sstevel@tonic-gate 30617c478bd9Sstevel@tonic-gate case O_KEEPCNAMES: /* don't expand CNAME records */ 30627c478bd9Sstevel@tonic-gate DontExpandCnames = atobool(val); 30637c478bd9Sstevel@tonic-gate break; 30647c478bd9Sstevel@tonic-gate 30657c478bd9Sstevel@tonic-gate case O_MUSTQUOTE: /* must quote these characters in phrases */ 30667c478bd9Sstevel@tonic-gate (void) sm_strlcpy(buf, "@,;:\\()[]", sizeof buf); 30677c478bd9Sstevel@tonic-gate if (strlen(val) < sizeof buf - 10) 30687c478bd9Sstevel@tonic-gate (void) sm_strlcat(buf, val, sizeof buf); 30697c478bd9Sstevel@tonic-gate else 30707c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 30717c478bd9Sstevel@tonic-gate "Warning: MustQuoteChars too long, ignored.\n"); 30727c478bd9Sstevel@tonic-gate MustQuoteChars = newstr(buf); 30737c478bd9Sstevel@tonic-gate break; 30747c478bd9Sstevel@tonic-gate 30757c478bd9Sstevel@tonic-gate case O_SMTPGREETING: /* SMTP greeting message (old $e macro) */ 30767c478bd9Sstevel@tonic-gate SmtpGreeting = newstr(munchstring(val, NULL, '\0')); 30777c478bd9Sstevel@tonic-gate break; 30787c478bd9Sstevel@tonic-gate 30797c478bd9Sstevel@tonic-gate case O_UNIXFROM: /* UNIX From_ line (old $l macro) */ 30807c478bd9Sstevel@tonic-gate UnixFromLine = newstr(munchstring(val, NULL, '\0')); 30817c478bd9Sstevel@tonic-gate break; 30827c478bd9Sstevel@tonic-gate 30837c478bd9Sstevel@tonic-gate case O_OPCHARS: /* operator characters (old $o macro) */ 30847c478bd9Sstevel@tonic-gate if (OperatorChars != NULL) 30857c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 30867c478bd9Sstevel@tonic-gate "Warning: OperatorChars is being redefined.\n It should only be set before ruleset definitions.\n"); 30877c478bd9Sstevel@tonic-gate OperatorChars = newstr(munchstring(val, NULL, '\0')); 30887c478bd9Sstevel@tonic-gate break; 30897c478bd9Sstevel@tonic-gate 30907c478bd9Sstevel@tonic-gate case O_DONTINITGRPS: /* don't call initgroups(3) */ 30917c478bd9Sstevel@tonic-gate DontInitGroups = atobool(val); 30927c478bd9Sstevel@tonic-gate break; 30937c478bd9Sstevel@tonic-gate 30947c478bd9Sstevel@tonic-gate case O_SLFH: /* make sure from fits on one line */ 30957c478bd9Sstevel@tonic-gate SingleLineFromHeader = atobool(val); 30967c478bd9Sstevel@tonic-gate break; 30977c478bd9Sstevel@tonic-gate 30987c478bd9Sstevel@tonic-gate case O_ABH: /* allow HELO commands with syntax errors */ 30997c478bd9Sstevel@tonic-gate AllowBogusHELO = atobool(val); 31007c478bd9Sstevel@tonic-gate break; 31017c478bd9Sstevel@tonic-gate 31027c478bd9Sstevel@tonic-gate case O_CONNTHROT: /* connection rate throttle */ 31037c478bd9Sstevel@tonic-gate ConnRateThrottle = atoi(val); 31047c478bd9Sstevel@tonic-gate break; 31057c478bd9Sstevel@tonic-gate 31067c478bd9Sstevel@tonic-gate case O_UGW: /* group writable files are unsafe */ 31077c478bd9Sstevel@tonic-gate if (!atobool(val)) 31087c478bd9Sstevel@tonic-gate { 31097c478bd9Sstevel@tonic-gate setbitn(DBS_GROUPWRITABLEFORWARDFILESAFE, 31107c478bd9Sstevel@tonic-gate DontBlameSendmail); 31117c478bd9Sstevel@tonic-gate setbitn(DBS_GROUPWRITABLEINCLUDEFILESAFE, 31127c478bd9Sstevel@tonic-gate DontBlameSendmail); 31137c478bd9Sstevel@tonic-gate } 31147c478bd9Sstevel@tonic-gate break; 31157c478bd9Sstevel@tonic-gate 31167c478bd9Sstevel@tonic-gate case O_DBLBOUNCE: /* address to which to send double bounces */ 31177c478bd9Sstevel@tonic-gate DoubleBounceAddr = newstr(val); 31187c478bd9Sstevel@tonic-gate break; 31197c478bd9Sstevel@tonic-gate 31207c478bd9Sstevel@tonic-gate case O_HSDIR: /* persistent host status directory */ 31217c478bd9Sstevel@tonic-gate if (val[0] != '\0') 31227c478bd9Sstevel@tonic-gate { 31237c478bd9Sstevel@tonic-gate CANONIFY(val); 31247c478bd9Sstevel@tonic-gate HostStatDir = newstr(val); 31257c478bd9Sstevel@tonic-gate } 31267c478bd9Sstevel@tonic-gate break; 31277c478bd9Sstevel@tonic-gate 31287c478bd9Sstevel@tonic-gate case O_SINGTHREAD: /* single thread deliveries (requires hsdir) */ 31297c478bd9Sstevel@tonic-gate SingleThreadDelivery = atobool(val); 31307c478bd9Sstevel@tonic-gate break; 31317c478bd9Sstevel@tonic-gate 31327c478bd9Sstevel@tonic-gate case O_RUNASUSER: /* run bulk of code as this user */ 31337c478bd9Sstevel@tonic-gate for (p = val; *p != '\0'; p++) 31347c478bd9Sstevel@tonic-gate { 31357c478bd9Sstevel@tonic-gate # if _FFR_DOTTED_USERNAMES 31367c478bd9Sstevel@tonic-gate if (*p == '/' || *p == ':') 31377c478bd9Sstevel@tonic-gate # else /* _FFR_DOTTED_USERNAMES */ 31387c478bd9Sstevel@tonic-gate if (*p == '.' || *p == '/' || *p == ':') 31397c478bd9Sstevel@tonic-gate # endif /* _FFR_DOTTED_USERNAMES */ 31407c478bd9Sstevel@tonic-gate { 31417c478bd9Sstevel@tonic-gate *p++ = '\0'; 31427c478bd9Sstevel@tonic-gate break; 31437c478bd9Sstevel@tonic-gate } 31447c478bd9Sstevel@tonic-gate } 31457c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 31467c478bd9Sstevel@tonic-gate { 31477c478bd9Sstevel@tonic-gate if (can_setuid) 31487c478bd9Sstevel@tonic-gate RunAsUid = atoi(val); 31497c478bd9Sstevel@tonic-gate } 31507c478bd9Sstevel@tonic-gate else 31517c478bd9Sstevel@tonic-gate { 31527c478bd9Sstevel@tonic-gate register struct passwd *pw; 31537c478bd9Sstevel@tonic-gate 31547c478bd9Sstevel@tonic-gate pw = sm_getpwnam(val); 31557c478bd9Sstevel@tonic-gate if (pw == NULL) 31567c478bd9Sstevel@tonic-gate { 31577c478bd9Sstevel@tonic-gate syserr("readcf: option RunAsUser: unknown user %s", val); 31587c478bd9Sstevel@tonic-gate break; 31597c478bd9Sstevel@tonic-gate } 31607c478bd9Sstevel@tonic-gate else if (can_setuid) 31617c478bd9Sstevel@tonic-gate { 31627c478bd9Sstevel@tonic-gate if (*p == '\0') 31637c478bd9Sstevel@tonic-gate RunAsUserName = newstr(val); 31647c478bd9Sstevel@tonic-gate RunAsUid = pw->pw_uid; 31657c478bd9Sstevel@tonic-gate RunAsGid = pw->pw_gid; 31667c478bd9Sstevel@tonic-gate } 31677c478bd9Sstevel@tonic-gate else if (EffGid == pw->pw_gid) 31687c478bd9Sstevel@tonic-gate RunAsGid = pw->pw_gid; 31697c478bd9Sstevel@tonic-gate else if (UseMSP && *p == '\0') 31707c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 31717c478bd9Sstevel@tonic-gate "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n", 31727c478bd9Sstevel@tonic-gate (int) EffGid, 31737c478bd9Sstevel@tonic-gate (int) pw->pw_gid); 31747c478bd9Sstevel@tonic-gate } 31757c478bd9Sstevel@tonic-gate # ifdef UID_MAX 31767c478bd9Sstevel@tonic-gate if (RunAsUid > UID_MAX) 31777c478bd9Sstevel@tonic-gate { 31787c478bd9Sstevel@tonic-gate syserr("readcf: option RunAsUser: uid value (%ld) > UID_MAX (%ld); ignored", 31797c478bd9Sstevel@tonic-gate (long) RunAsUid, (long) UID_MAX); 31807c478bd9Sstevel@tonic-gate break; 31817c478bd9Sstevel@tonic-gate } 31827c478bd9Sstevel@tonic-gate # endif /* UID_MAX */ 31837c478bd9Sstevel@tonic-gate if (*p != '\0') 31847c478bd9Sstevel@tonic-gate { 31857c478bd9Sstevel@tonic-gate if (isascii(*p) && isdigit(*p)) 31867c478bd9Sstevel@tonic-gate { 31877c478bd9Sstevel@tonic-gate gid_t runasgid; 31887c478bd9Sstevel@tonic-gate 31897c478bd9Sstevel@tonic-gate runasgid = (gid_t) atoi(p); 31907c478bd9Sstevel@tonic-gate if (can_setuid || EffGid == runasgid) 31917c478bd9Sstevel@tonic-gate RunAsGid = runasgid; 31927c478bd9Sstevel@tonic-gate else if (UseMSP) 31937c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, 31947c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 31957c478bd9Sstevel@tonic-gate "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n", 31967c478bd9Sstevel@tonic-gate (int) EffGid, 31977c478bd9Sstevel@tonic-gate (int) runasgid); 31987c478bd9Sstevel@tonic-gate } 31997c478bd9Sstevel@tonic-gate else 32007c478bd9Sstevel@tonic-gate { 32017c478bd9Sstevel@tonic-gate register struct group *gr; 32027c478bd9Sstevel@tonic-gate 32037c478bd9Sstevel@tonic-gate gr = getgrnam(p); 32047c478bd9Sstevel@tonic-gate if (gr == NULL) 32057c478bd9Sstevel@tonic-gate syserr("readcf: option RunAsUser: unknown group %s", 32067c478bd9Sstevel@tonic-gate p); 32077c478bd9Sstevel@tonic-gate else if (can_setuid || EffGid == gr->gr_gid) 32087c478bd9Sstevel@tonic-gate RunAsGid = gr->gr_gid; 32097c478bd9Sstevel@tonic-gate else if (UseMSP) 32107c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, 32117c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 32127c478bd9Sstevel@tonic-gate "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n", 32137c478bd9Sstevel@tonic-gate (int) EffGid, 32147c478bd9Sstevel@tonic-gate (int) gr->gr_gid); 32157c478bd9Sstevel@tonic-gate } 32167c478bd9Sstevel@tonic-gate } 32177c478bd9Sstevel@tonic-gate if (tTd(47, 5)) 32187c478bd9Sstevel@tonic-gate sm_dprintf("readcf: RunAsUser = %d:%d\n", 32197c478bd9Sstevel@tonic-gate (int) RunAsUid, (int) RunAsGid); 32207c478bd9Sstevel@tonic-gate break; 32217c478bd9Sstevel@tonic-gate 32227c478bd9Sstevel@tonic-gate case O_DSN_RRT: 32237c478bd9Sstevel@tonic-gate RrtImpliesDsn = atobool(val); 32247c478bd9Sstevel@tonic-gate break; 32257c478bd9Sstevel@tonic-gate 32267c478bd9Sstevel@tonic-gate case O_PIDFILE: 32277c478bd9Sstevel@tonic-gate PSTRSET(PidFile, val); 32287c478bd9Sstevel@tonic-gate break; 32297c478bd9Sstevel@tonic-gate 32307c478bd9Sstevel@tonic-gate case O_DONTBLAMESENDMAIL: 32317c478bd9Sstevel@tonic-gate p = val; 32327c478bd9Sstevel@tonic-gate for (;;) 32337c478bd9Sstevel@tonic-gate { 32347c478bd9Sstevel@tonic-gate register struct dbsval *dbs; 32357c478bd9Sstevel@tonic-gate extern struct dbsval DontBlameSendmailValues[]; 32367c478bd9Sstevel@tonic-gate 32377c478bd9Sstevel@tonic-gate while (isascii(*p) && (isspace(*p) || ispunct(*p))) 32387c478bd9Sstevel@tonic-gate p++; 32397c478bd9Sstevel@tonic-gate if (*p == '\0') 32407c478bd9Sstevel@tonic-gate break; 32417c478bd9Sstevel@tonic-gate val = p; 32427c478bd9Sstevel@tonic-gate while (isascii(*p) && isalnum(*p)) 32437c478bd9Sstevel@tonic-gate p++; 32447c478bd9Sstevel@tonic-gate if (*p != '\0') 32457c478bd9Sstevel@tonic-gate *p++ = '\0'; 32467c478bd9Sstevel@tonic-gate 32477c478bd9Sstevel@tonic-gate for (dbs = DontBlameSendmailValues; 32487c478bd9Sstevel@tonic-gate dbs->dbs_name != NULL; dbs++) 32497c478bd9Sstevel@tonic-gate { 32507c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, dbs->dbs_name) == 0) 32517c478bd9Sstevel@tonic-gate break; 32527c478bd9Sstevel@tonic-gate } 32537c478bd9Sstevel@tonic-gate if (dbs->dbs_name == NULL) 32547c478bd9Sstevel@tonic-gate syserr("readcf: DontBlameSendmail option: %s unrecognized", val); 32557c478bd9Sstevel@tonic-gate else if (dbs->dbs_flag == DBS_SAFE) 32567c478bd9Sstevel@tonic-gate clrbitmap(DontBlameSendmail); 32577c478bd9Sstevel@tonic-gate else 32587c478bd9Sstevel@tonic-gate setbitn(dbs->dbs_flag, DontBlameSendmail); 32597c478bd9Sstevel@tonic-gate } 32607c478bd9Sstevel@tonic-gate sticky = false; 32617c478bd9Sstevel@tonic-gate break; 32627c478bd9Sstevel@tonic-gate 32637c478bd9Sstevel@tonic-gate case O_DPI: 32647c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, "loopback") == 0) 32657c478bd9Sstevel@tonic-gate DontProbeInterfaces = DPI_SKIPLOOPBACK; 32667c478bd9Sstevel@tonic-gate else if (atobool(val)) 32677c478bd9Sstevel@tonic-gate DontProbeInterfaces = DPI_PROBENONE; 32687c478bd9Sstevel@tonic-gate else 32697c478bd9Sstevel@tonic-gate DontProbeInterfaces = DPI_PROBEALL; 32707c478bd9Sstevel@tonic-gate break; 32717c478bd9Sstevel@tonic-gate 32727c478bd9Sstevel@tonic-gate case O_MAXRCPT: 32737c478bd9Sstevel@tonic-gate MaxRcptPerMsg = atoi(val); 32747c478bd9Sstevel@tonic-gate break; 32757c478bd9Sstevel@tonic-gate 32767c478bd9Sstevel@tonic-gate case O_RCPTTHROT: 32777c478bd9Sstevel@tonic-gate BadRcptThrottle = atoi(val); 32787c478bd9Sstevel@tonic-gate break; 32797c478bd9Sstevel@tonic-gate 32807c478bd9Sstevel@tonic-gate case O_DEADLETTER: 32817c478bd9Sstevel@tonic-gate CANONIFY(val); 32827c478bd9Sstevel@tonic-gate PSTRSET(DeadLetterDrop, val); 32837c478bd9Sstevel@tonic-gate break; 32847c478bd9Sstevel@tonic-gate 32857c478bd9Sstevel@tonic-gate #if _FFR_DONTLOCKFILESFORREAD_OPTION 32867c478bd9Sstevel@tonic-gate case O_DONTLOCK: 32877c478bd9Sstevel@tonic-gate DontLockReadFiles = atobool(val); 32887c478bd9Sstevel@tonic-gate break; 32897c478bd9Sstevel@tonic-gate #endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */ 32907c478bd9Sstevel@tonic-gate 32917c478bd9Sstevel@tonic-gate case O_MAXALIASRCSN: 32927c478bd9Sstevel@tonic-gate MaxAliasRecursion = atoi(val); 32937c478bd9Sstevel@tonic-gate break; 32947c478bd9Sstevel@tonic-gate 32957c478bd9Sstevel@tonic-gate case O_CNCTONLYTO: 32967c478bd9Sstevel@tonic-gate /* XXX should probably use gethostbyname */ 32977c478bd9Sstevel@tonic-gate #if NETINET || NETINET6 32987c478bd9Sstevel@tonic-gate ConnectOnlyTo.sa.sa_family = AF_UNSPEC; 32997c478bd9Sstevel@tonic-gate # if NETINET6 33007c478bd9Sstevel@tonic-gate if (anynet_pton(AF_INET6, val, 33017c478bd9Sstevel@tonic-gate &ConnectOnlyTo.sin6.sin6_addr) != 1) 33027c478bd9Sstevel@tonic-gate ConnectOnlyTo.sa.sa_family = AF_INET6; 33037c478bd9Sstevel@tonic-gate else 33047c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 33057c478bd9Sstevel@tonic-gate # if NETINET 33067c478bd9Sstevel@tonic-gate { 33077c478bd9Sstevel@tonic-gate ConnectOnlyTo.sin.sin_addr.s_addr = inet_addr(val); 33087c478bd9Sstevel@tonic-gate if (ConnectOnlyTo.sin.sin_addr.s_addr != INADDR_NONE) 33097c478bd9Sstevel@tonic-gate ConnectOnlyTo.sa.sa_family = AF_INET; 33107c478bd9Sstevel@tonic-gate } 33117c478bd9Sstevel@tonic-gate 33127c478bd9Sstevel@tonic-gate # endif /* NETINET */ 33137c478bd9Sstevel@tonic-gate if (ConnectOnlyTo.sa.sa_family == AF_UNSPEC) 33147c478bd9Sstevel@tonic-gate { 33157c478bd9Sstevel@tonic-gate syserr("readcf: option ConnectOnlyTo: invalid IP address %s", 33167c478bd9Sstevel@tonic-gate val); 33177c478bd9Sstevel@tonic-gate break; 33187c478bd9Sstevel@tonic-gate } 33197c478bd9Sstevel@tonic-gate #endif /* NETINET || NETINET6 */ 33207c478bd9Sstevel@tonic-gate break; 33217c478bd9Sstevel@tonic-gate 33227c478bd9Sstevel@tonic-gate case O_TRUSTUSER: 33237c478bd9Sstevel@tonic-gate # if !HASFCHOWN && !defined(_FFR_DROP_TRUSTUSER_WARNING) 33247c478bd9Sstevel@tonic-gate if (!UseMSP) 33257c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 33267c478bd9Sstevel@tonic-gate "readcf: option TrustedUser may cause problems on systems\n which do not support fchown() if UseMSP is not set.\n"); 33277c478bd9Sstevel@tonic-gate # endif /* !HASFCHOWN && !defined(_FFR_DROP_TRUSTUSER_WARNING) */ 33287c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 33297c478bd9Sstevel@tonic-gate TrustedUid = atoi(val); 33307c478bd9Sstevel@tonic-gate else 33317c478bd9Sstevel@tonic-gate { 33327c478bd9Sstevel@tonic-gate register struct passwd *pw; 33337c478bd9Sstevel@tonic-gate 33347c478bd9Sstevel@tonic-gate TrustedUid = 0; 33357c478bd9Sstevel@tonic-gate pw = sm_getpwnam(val); 33367c478bd9Sstevel@tonic-gate if (pw == NULL) 33377c478bd9Sstevel@tonic-gate { 33387c478bd9Sstevel@tonic-gate syserr("readcf: option TrustedUser: unknown user %s", val); 33397c478bd9Sstevel@tonic-gate break; 33407c478bd9Sstevel@tonic-gate } 33417c478bd9Sstevel@tonic-gate else 33427c478bd9Sstevel@tonic-gate TrustedUid = pw->pw_uid; 33437c478bd9Sstevel@tonic-gate } 33447c478bd9Sstevel@tonic-gate 33457c478bd9Sstevel@tonic-gate # ifdef UID_MAX 33467c478bd9Sstevel@tonic-gate if (TrustedUid > UID_MAX) 33477c478bd9Sstevel@tonic-gate { 33487c478bd9Sstevel@tonic-gate syserr("readcf: option TrustedUser: uid value (%ld) > UID_MAX (%ld)", 33497c478bd9Sstevel@tonic-gate (long) TrustedUid, (long) UID_MAX); 33507c478bd9Sstevel@tonic-gate TrustedUid = 0; 33517c478bd9Sstevel@tonic-gate } 33527c478bd9Sstevel@tonic-gate # endif /* UID_MAX */ 33537c478bd9Sstevel@tonic-gate break; 33547c478bd9Sstevel@tonic-gate 33557c478bd9Sstevel@tonic-gate case O_MAXMIMEHDRLEN: 33567c478bd9Sstevel@tonic-gate p = strchr(val, '/'); 33577c478bd9Sstevel@tonic-gate if (p != NULL) 33587c478bd9Sstevel@tonic-gate *p++ = '\0'; 33597c478bd9Sstevel@tonic-gate MaxMimeHeaderLength = atoi(val); 33607c478bd9Sstevel@tonic-gate if (p != NULL && *p != '\0') 33617c478bd9Sstevel@tonic-gate MaxMimeFieldLength = atoi(p); 33627c478bd9Sstevel@tonic-gate else 33637c478bd9Sstevel@tonic-gate MaxMimeFieldLength = MaxMimeHeaderLength / 2; 33647c478bd9Sstevel@tonic-gate 33657c478bd9Sstevel@tonic-gate if (MaxMimeHeaderLength <= 0) 33667c478bd9Sstevel@tonic-gate MaxMimeHeaderLength = 0; 33677c478bd9Sstevel@tonic-gate else if (MaxMimeHeaderLength < 128) 33687c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 33697c478bd9Sstevel@tonic-gate "Warning: MaxMimeHeaderLength: header length limit set lower than 128\n"); 33707c478bd9Sstevel@tonic-gate 33717c478bd9Sstevel@tonic-gate if (MaxMimeFieldLength <= 0) 33727c478bd9Sstevel@tonic-gate MaxMimeFieldLength = 0; 33737c478bd9Sstevel@tonic-gate else if (MaxMimeFieldLength < 40) 33747c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 33757c478bd9Sstevel@tonic-gate "Warning: MaxMimeHeaderLength: field length limit set lower than 40\n"); 33767c478bd9Sstevel@tonic-gate break; 33777c478bd9Sstevel@tonic-gate 33787c478bd9Sstevel@tonic-gate case O_CONTROLSOCKET: 33797c478bd9Sstevel@tonic-gate PSTRSET(ControlSocketName, val); 33807c478bd9Sstevel@tonic-gate break; 33817c478bd9Sstevel@tonic-gate 33827c478bd9Sstevel@tonic-gate case O_MAXHDRSLEN: 33837c478bd9Sstevel@tonic-gate MaxHeadersLength = atoi(val); 33847c478bd9Sstevel@tonic-gate 33857c478bd9Sstevel@tonic-gate if (MaxHeadersLength > 0 && 33867c478bd9Sstevel@tonic-gate MaxHeadersLength < (MAXHDRSLEN / 2)) 33877c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 33887c478bd9Sstevel@tonic-gate "Warning: MaxHeadersLength: headers length limit set lower than %d\n", 33897c478bd9Sstevel@tonic-gate (MAXHDRSLEN / 2)); 33907c478bd9Sstevel@tonic-gate break; 33917c478bd9Sstevel@tonic-gate 33927c478bd9Sstevel@tonic-gate case O_PROCTITLEPREFIX: 33937c478bd9Sstevel@tonic-gate PSTRSET(ProcTitlePrefix, val); 33947c478bd9Sstevel@tonic-gate break; 33957c478bd9Sstevel@tonic-gate 33967c478bd9Sstevel@tonic-gate #if SASL 33977c478bd9Sstevel@tonic-gate case O_SASLINFO: 33987c478bd9Sstevel@tonic-gate # if _FFR_ALLOW_SASLINFO 33997c478bd9Sstevel@tonic-gate /* 34007c478bd9Sstevel@tonic-gate ** Allow users to select their own authinfo file 34017c478bd9Sstevel@tonic-gate ** under certain circumstances, otherwise just ignore 34027c478bd9Sstevel@tonic-gate ** the option. If the option isn't ignored, several 34037c478bd9Sstevel@tonic-gate ** commands don't work very well, e.g., mailq. 34047c478bd9Sstevel@tonic-gate ** However, this is not a "perfect" solution. 34057c478bd9Sstevel@tonic-gate ** If mail is queued, the authentication info 34067c478bd9Sstevel@tonic-gate ** will not be used in subsequent delivery attempts. 34077c478bd9Sstevel@tonic-gate ** If we really want to support this, then it has 34087c478bd9Sstevel@tonic-gate ** to be stored in the queue file. 34097c478bd9Sstevel@tonic-gate */ 34107c478bd9Sstevel@tonic-gate if (!bitset(SUBMIT_MSA, SubmitMode) && RealUid != 0 && 34117c478bd9Sstevel@tonic-gate RunAsUid != RealUid) 34127c478bd9Sstevel@tonic-gate break; 34137c478bd9Sstevel@tonic-gate # endif /* _FFR_ALLOW_SASLINFO */ 34147c478bd9Sstevel@tonic-gate PSTRSET(SASLInfo, val); 34157c478bd9Sstevel@tonic-gate break; 34167c478bd9Sstevel@tonic-gate 34177c478bd9Sstevel@tonic-gate case O_SASLMECH: 34187c478bd9Sstevel@tonic-gate if (AuthMechanisms != NULL) 34197c478bd9Sstevel@tonic-gate sm_free(AuthMechanisms); /* XXX */ 34207c478bd9Sstevel@tonic-gate if (*val != '\0') 34217c478bd9Sstevel@tonic-gate AuthMechanisms = newstr(val); 34227c478bd9Sstevel@tonic-gate else 34237c478bd9Sstevel@tonic-gate AuthMechanisms = NULL; 34247c478bd9Sstevel@tonic-gate break; 34257c478bd9Sstevel@tonic-gate 34267c478bd9Sstevel@tonic-gate case O_SASLREALM: 34277c478bd9Sstevel@tonic-gate if (AuthRealm != NULL) 34287c478bd9Sstevel@tonic-gate sm_free(AuthRealm); 34297c478bd9Sstevel@tonic-gate if (*val != '\0') 34307c478bd9Sstevel@tonic-gate AuthRealm = newstr(val); 34317c478bd9Sstevel@tonic-gate else 34327c478bd9Sstevel@tonic-gate AuthRealm = NULL; 34337c478bd9Sstevel@tonic-gate break; 34347c478bd9Sstevel@tonic-gate 34357c478bd9Sstevel@tonic-gate case O_SASLOPTS: 34367c478bd9Sstevel@tonic-gate while (val != NULL && *val != '\0') 34377c478bd9Sstevel@tonic-gate { 34387c478bd9Sstevel@tonic-gate switch (*val) 34397c478bd9Sstevel@tonic-gate { 34407c478bd9Sstevel@tonic-gate case 'A': 34417c478bd9Sstevel@tonic-gate SASLOpts |= SASL_AUTH_AUTH; 34427c478bd9Sstevel@tonic-gate break; 34437c478bd9Sstevel@tonic-gate 34447c478bd9Sstevel@tonic-gate case 'a': 34457c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NOACTIVE; 34467c478bd9Sstevel@tonic-gate break; 34477c478bd9Sstevel@tonic-gate 34487c478bd9Sstevel@tonic-gate case 'c': 34497c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_PASS_CREDENTIALS; 34507c478bd9Sstevel@tonic-gate break; 34517c478bd9Sstevel@tonic-gate 34527c478bd9Sstevel@tonic-gate case 'd': 34537c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NODICTIONARY; 34547c478bd9Sstevel@tonic-gate break; 34557c478bd9Sstevel@tonic-gate 34567c478bd9Sstevel@tonic-gate case 'f': 34577c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_FORWARD_SECRECY; 34587c478bd9Sstevel@tonic-gate break; 34597c478bd9Sstevel@tonic-gate 34607c478bd9Sstevel@tonic-gate # if SASL >= 20101 34617c478bd9Sstevel@tonic-gate case 'm': 34627c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_MUTUAL_AUTH; 34637c478bd9Sstevel@tonic-gate break; 34647c478bd9Sstevel@tonic-gate # endif /* SASL >= 20101 */ 34657c478bd9Sstevel@tonic-gate 34667c478bd9Sstevel@tonic-gate case 'p': 34677c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NOPLAINTEXT; 34687c478bd9Sstevel@tonic-gate break; 34697c478bd9Sstevel@tonic-gate 34707c478bd9Sstevel@tonic-gate case 'y': 34717c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NOANONYMOUS; 34727c478bd9Sstevel@tonic-gate break; 34737c478bd9Sstevel@tonic-gate 34747c478bd9Sstevel@tonic-gate case ' ': /* ignore */ 34757c478bd9Sstevel@tonic-gate case '\t': /* ignore */ 34767c478bd9Sstevel@tonic-gate case ',': /* ignore */ 34777c478bd9Sstevel@tonic-gate break; 34787c478bd9Sstevel@tonic-gate 34797c478bd9Sstevel@tonic-gate default: 34807c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 34817c478bd9Sstevel@tonic-gate "Warning: Option: %s unknown parameter '%c'\n", 34827c478bd9Sstevel@tonic-gate OPTNAME, 34837c478bd9Sstevel@tonic-gate (isascii(*val) && 34847c478bd9Sstevel@tonic-gate isprint(*val)) 34857c478bd9Sstevel@tonic-gate ? *val : '?'); 34867c478bd9Sstevel@tonic-gate break; 34877c478bd9Sstevel@tonic-gate } 34887c478bd9Sstevel@tonic-gate ++val; 34897c478bd9Sstevel@tonic-gate val = strpbrk(val, ", \t"); 34907c478bd9Sstevel@tonic-gate if (val != NULL) 34917c478bd9Sstevel@tonic-gate ++val; 34927c478bd9Sstevel@tonic-gate } 34937c478bd9Sstevel@tonic-gate break; 34947c478bd9Sstevel@tonic-gate 34957c478bd9Sstevel@tonic-gate case O_SASLBITS: 34967c478bd9Sstevel@tonic-gate MaxSLBits = atoi(val); 34977c478bd9Sstevel@tonic-gate break; 34987c478bd9Sstevel@tonic-gate 34997c478bd9Sstevel@tonic-gate #else /* SASL */ 35007c478bd9Sstevel@tonic-gate case O_SASLINFO: 35017c478bd9Sstevel@tonic-gate case O_SASLMECH: 35027c478bd9Sstevel@tonic-gate case O_SASLREALM: 35037c478bd9Sstevel@tonic-gate case O_SASLOPTS: 35047c478bd9Sstevel@tonic-gate case O_SASLBITS: 35057c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 35067c478bd9Sstevel@tonic-gate "Warning: Option: %s requires SASL support (-DSASL)\n", 35077c478bd9Sstevel@tonic-gate OPTNAME); 35087c478bd9Sstevel@tonic-gate break; 35097c478bd9Sstevel@tonic-gate #endif /* SASL */ 35107c478bd9Sstevel@tonic-gate 35117c478bd9Sstevel@tonic-gate #if STARTTLS 35127c478bd9Sstevel@tonic-gate case O_SRVCERTFILE: 35137c478bd9Sstevel@tonic-gate SET_STRING_EXP(SrvCertFile); 35147c478bd9Sstevel@tonic-gate case O_SRVKEYFILE: 35157c478bd9Sstevel@tonic-gate SET_STRING_EXP(SrvKeyFile); 35167c478bd9Sstevel@tonic-gate case O_CLTCERTFILE: 35177c478bd9Sstevel@tonic-gate SET_STRING_EXP(CltCertFile); 35187c478bd9Sstevel@tonic-gate case O_CLTKEYFILE: 35197c478bd9Sstevel@tonic-gate SET_STRING_EXP(CltKeyFile); 35207c478bd9Sstevel@tonic-gate case O_CACERTFILE: 35217c478bd9Sstevel@tonic-gate SET_STRING_EXP(CACertFile); 35227c478bd9Sstevel@tonic-gate case O_CACERTPATH: 35237c478bd9Sstevel@tonic-gate SET_STRING_EXP(CACertPath); 35247c478bd9Sstevel@tonic-gate case O_DHPARAMS: 35257c478bd9Sstevel@tonic-gate SET_STRING_EXP(DHParams); 35267c478bd9Sstevel@tonic-gate # if _FFR_TLS_1 35277c478bd9Sstevel@tonic-gate case O_DHPARAMS5: 35287c478bd9Sstevel@tonic-gate SET_STRING_EXP(DHParams5); 35297c478bd9Sstevel@tonic-gate case O_CIPHERLIST: 35307c478bd9Sstevel@tonic-gate SET_STRING_EXP(CipherList); 35317c478bd9Sstevel@tonic-gate # endif /* _FFR_TLS_1 */ 35327c478bd9Sstevel@tonic-gate case O_CRLFILE: 35337c478bd9Sstevel@tonic-gate # if OPENSSL_VERSION_NUMBER > 0x00907000L 35347c478bd9Sstevel@tonic-gate SET_STRING_EXP(CRLFile); 35357c478bd9Sstevel@tonic-gate # else /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 35367c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 35377c478bd9Sstevel@tonic-gate "Warning: Option: %s requires at least OpenSSL 0.9.7\n", 35387c478bd9Sstevel@tonic-gate OPTNAME); 35397c478bd9Sstevel@tonic-gate break; 35407c478bd9Sstevel@tonic-gate # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 35417c478bd9Sstevel@tonic-gate 35427c478bd9Sstevel@tonic-gate # if _FFR_CRLPATH 35437c478bd9Sstevel@tonic-gate case O_CRLPATH: 35447c478bd9Sstevel@tonic-gate # if OPENSSL_VERSION_NUMBER > 0x00907000L 35457c478bd9Sstevel@tonic-gate SET_STRING_EXP(CRLPath); 35467c478bd9Sstevel@tonic-gate # else /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 35477c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 35487c478bd9Sstevel@tonic-gate "Warning: Option: %s requires at least OpenSSL 0.9.7\n", 35497c478bd9Sstevel@tonic-gate OPTNAME); 35507c478bd9Sstevel@tonic-gate break; 35517c478bd9Sstevel@tonic-gate # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 35527c478bd9Sstevel@tonic-gate # endif /* _FFR_CRLPATH */ 35537c478bd9Sstevel@tonic-gate 35547c478bd9Sstevel@tonic-gate /* 35557c478bd9Sstevel@tonic-gate ** XXX How about options per daemon/client instead of globally? 35567c478bd9Sstevel@tonic-gate ** This doesn't work well for some options, e.g., no server cert, 35577c478bd9Sstevel@tonic-gate ** but fine for others. 35587c478bd9Sstevel@tonic-gate ** 35597c478bd9Sstevel@tonic-gate ** XXX Some people may want different certs per server. 35607c478bd9Sstevel@tonic-gate ** 35617c478bd9Sstevel@tonic-gate ** See also srvfeatures() 35627c478bd9Sstevel@tonic-gate */ 35637c478bd9Sstevel@tonic-gate 35647c478bd9Sstevel@tonic-gate case O_TLS_SRV_OPTS: 35657c478bd9Sstevel@tonic-gate while (val != NULL && *val != '\0') 35667c478bd9Sstevel@tonic-gate { 35677c478bd9Sstevel@tonic-gate switch (*val) 35687c478bd9Sstevel@tonic-gate { 35697c478bd9Sstevel@tonic-gate case 'V': 35707c478bd9Sstevel@tonic-gate TLS_Srv_Opts |= TLS_I_NO_VRFY; 35717c478bd9Sstevel@tonic-gate break; 35727c478bd9Sstevel@tonic-gate # if _FFR_TLS_1 35737c478bd9Sstevel@tonic-gate /* 35747c478bd9Sstevel@tonic-gate ** Server without a cert? That works only if 35757c478bd9Sstevel@tonic-gate ** AnonDH is enabled as cipher, which is not in the 35767c478bd9Sstevel@tonic-gate ** default list. Hence the CipherList option must 35777c478bd9Sstevel@tonic-gate ** be available. Moreover: which clients support this 35787c478bd9Sstevel@tonic-gate ** besides sendmail with this setting? 35797c478bd9Sstevel@tonic-gate */ 35807c478bd9Sstevel@tonic-gate 35817c478bd9Sstevel@tonic-gate case 'C': 35827c478bd9Sstevel@tonic-gate TLS_Srv_Opts &= ~TLS_I_SRV_CERT; 35837c478bd9Sstevel@tonic-gate break; 35847c478bd9Sstevel@tonic-gate # endif /* _FFR_TLS_1 */ 35857c478bd9Sstevel@tonic-gate case ' ': /* ignore */ 35867c478bd9Sstevel@tonic-gate case '\t': /* ignore */ 35877c478bd9Sstevel@tonic-gate case ',': /* ignore */ 35887c478bd9Sstevel@tonic-gate break; 35897c478bd9Sstevel@tonic-gate default: 35907c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 35917c478bd9Sstevel@tonic-gate "Warning: Option: %s unknown parameter '%c'\n", 35927c478bd9Sstevel@tonic-gate OPTNAME, 35937c478bd9Sstevel@tonic-gate (isascii(*val) && 35947c478bd9Sstevel@tonic-gate isprint(*val)) 35957c478bd9Sstevel@tonic-gate ? *val : '?'); 35967c478bd9Sstevel@tonic-gate break; 35977c478bd9Sstevel@tonic-gate } 35987c478bd9Sstevel@tonic-gate ++val; 35997c478bd9Sstevel@tonic-gate val = strpbrk(val, ", \t"); 36007c478bd9Sstevel@tonic-gate if (val != NULL) 36017c478bd9Sstevel@tonic-gate ++val; 36027c478bd9Sstevel@tonic-gate } 36037c478bd9Sstevel@tonic-gate break; 36047c478bd9Sstevel@tonic-gate 36057c478bd9Sstevel@tonic-gate case O_RANDFILE: 36067c478bd9Sstevel@tonic-gate PSTRSET(RandFile, val); 36077c478bd9Sstevel@tonic-gate break; 36087c478bd9Sstevel@tonic-gate 36097c478bd9Sstevel@tonic-gate #else /* STARTTLS */ 36107c478bd9Sstevel@tonic-gate case O_SRVCERTFILE: 36117c478bd9Sstevel@tonic-gate case O_SRVKEYFILE: 36127c478bd9Sstevel@tonic-gate case O_CLTCERTFILE: 36137c478bd9Sstevel@tonic-gate case O_CLTKEYFILE: 36147c478bd9Sstevel@tonic-gate case O_CACERTFILE: 36157c478bd9Sstevel@tonic-gate case O_CACERTPATH: 36167c478bd9Sstevel@tonic-gate case O_DHPARAMS: 36177c478bd9Sstevel@tonic-gate # if _FFR_TLS_1 36187c478bd9Sstevel@tonic-gate case O_DHPARAMS5: 36197c478bd9Sstevel@tonic-gate case O_CIPHERLIST: 36207c478bd9Sstevel@tonic-gate # endif /* _FFR_TLS_1 */ 36217c478bd9Sstevel@tonic-gate case O_CRLFILE: 36227c478bd9Sstevel@tonic-gate # if _FFR_CRLPATH 36237c478bd9Sstevel@tonic-gate case O_CRLPATH: 36247c478bd9Sstevel@tonic-gate # endif /* _FFR_CRLPATH */ 36257c478bd9Sstevel@tonic-gate case O_RANDFILE: 36267c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 36277c478bd9Sstevel@tonic-gate "Warning: Option: %s requires TLS support\n", 36287c478bd9Sstevel@tonic-gate OPTNAME); 36297c478bd9Sstevel@tonic-gate break; 36307c478bd9Sstevel@tonic-gate 36317c478bd9Sstevel@tonic-gate #endif /* STARTTLS */ 36327c478bd9Sstevel@tonic-gate 36337c478bd9Sstevel@tonic-gate case O_CLIENTPORT: 36347c478bd9Sstevel@tonic-gate setclientoptions(val); 36357c478bd9Sstevel@tonic-gate break; 36367c478bd9Sstevel@tonic-gate 36377c478bd9Sstevel@tonic-gate case O_DF_BUFSIZE: 36387c478bd9Sstevel@tonic-gate DataFileBufferSize = atoi(val); 36397c478bd9Sstevel@tonic-gate break; 36407c478bd9Sstevel@tonic-gate 36417c478bd9Sstevel@tonic-gate case O_XF_BUFSIZE: 36427c478bd9Sstevel@tonic-gate XscriptFileBufferSize = atoi(val); 36437c478bd9Sstevel@tonic-gate break; 36447c478bd9Sstevel@tonic-gate 36457c478bd9Sstevel@tonic-gate case O_LDAPDEFAULTSPEC: 36467c478bd9Sstevel@tonic-gate #if LDAPMAP 36477c478bd9Sstevel@tonic-gate ldapmap_set_defaults(val); 36487c478bd9Sstevel@tonic-gate #else /* LDAPMAP */ 36497c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 36507c478bd9Sstevel@tonic-gate "Warning: Option: %s requires LDAP support (-DLDAPMAP)\n", 36517c478bd9Sstevel@tonic-gate OPTNAME); 36527c478bd9Sstevel@tonic-gate #endif /* LDAPMAP */ 36537c478bd9Sstevel@tonic-gate break; 36547c478bd9Sstevel@tonic-gate 36557c478bd9Sstevel@tonic-gate case O_INPUTMILTER: 36567c478bd9Sstevel@tonic-gate #if MILTER 36577c478bd9Sstevel@tonic-gate InputFilterList = newstr(val); 36587c478bd9Sstevel@tonic-gate #else /* MILTER */ 36597c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 36607c478bd9Sstevel@tonic-gate "Warning: Option: %s requires Milter support (-DMILTER)\n", 36617c478bd9Sstevel@tonic-gate OPTNAME); 36627c478bd9Sstevel@tonic-gate #endif /* MILTER */ 36637c478bd9Sstevel@tonic-gate break; 36647c478bd9Sstevel@tonic-gate 36657c478bd9Sstevel@tonic-gate case O_MILTER: 36667c478bd9Sstevel@tonic-gate #if MILTER 36677c478bd9Sstevel@tonic-gate milter_set_option(subopt, val, sticky); 36687c478bd9Sstevel@tonic-gate #else /* MILTER */ 36697c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 36707c478bd9Sstevel@tonic-gate "Warning: Option: %s requires Milter support (-DMILTER)\n", 36717c478bd9Sstevel@tonic-gate OPTNAME); 36727c478bd9Sstevel@tonic-gate #endif /* MILTER */ 36737c478bd9Sstevel@tonic-gate break; 36747c478bd9Sstevel@tonic-gate 36757c478bd9Sstevel@tonic-gate case O_QUEUE_FILE_MODE: /* queue file mode */ 36767c478bd9Sstevel@tonic-gate QueueFileMode = atooct(val) & 0777; 36777c478bd9Sstevel@tonic-gate break; 36787c478bd9Sstevel@tonic-gate 36797c478bd9Sstevel@tonic-gate case O_DLVR_MIN: /* deliver by minimum time */ 36807c478bd9Sstevel@tonic-gate DeliverByMin = convtime(val, 's'); 36817c478bd9Sstevel@tonic-gate break; 36827c478bd9Sstevel@tonic-gate 36837c478bd9Sstevel@tonic-gate /* modifiers {daemon_flags} for direct submissions */ 36847c478bd9Sstevel@tonic-gate case O_DIRECTSUBMODIFIERS: 36857c478bd9Sstevel@tonic-gate { 36867c478bd9Sstevel@tonic-gate BITMAP256 m; /* ignored */ 36877c478bd9Sstevel@tonic-gate extern ENVELOPE BlankEnvelope; 36887c478bd9Sstevel@tonic-gate 36897c478bd9Sstevel@tonic-gate macdefine(&BlankEnvelope.e_macro, A_PERM, 36907c478bd9Sstevel@tonic-gate macid("{daemon_flags}"), 36917c478bd9Sstevel@tonic-gate getmodifiers(val, m)); 36927c478bd9Sstevel@tonic-gate } 36937c478bd9Sstevel@tonic-gate break; 36947c478bd9Sstevel@tonic-gate 36957c478bd9Sstevel@tonic-gate case O_FASTSPLIT: 36967c478bd9Sstevel@tonic-gate FastSplit = atoi(val); 36977c478bd9Sstevel@tonic-gate break; 36987c478bd9Sstevel@tonic-gate 36997c478bd9Sstevel@tonic-gate case O_MBDB: 37007c478bd9Sstevel@tonic-gate Mbdb = newstr(val); 37017c478bd9Sstevel@tonic-gate break; 37027c478bd9Sstevel@tonic-gate 37037c478bd9Sstevel@tonic-gate case O_MSQ: 37047c478bd9Sstevel@tonic-gate UseMSP = atobool(val); 37057c478bd9Sstevel@tonic-gate break; 37067c478bd9Sstevel@tonic-gate 37077c478bd9Sstevel@tonic-gate #if _FFR_SOFT_BOUNCE 37087c478bd9Sstevel@tonic-gate case O_SOFTBOUNCE: 37097c478bd9Sstevel@tonic-gate SoftBounce = atobool(val); 37107c478bd9Sstevel@tonic-gate break; 37117c478bd9Sstevel@tonic-gate #endif /* _FFR_SOFT_BOUNCE */ 37127c478bd9Sstevel@tonic-gate 37137c478bd9Sstevel@tonic-gate case O_REJECTLOGINTERVAL: /* time btwn log msgs while refusing */ 37147c478bd9Sstevel@tonic-gate RejectLogInterval = convtime(val, 'h'); 37157c478bd9Sstevel@tonic-gate break; 37167c478bd9Sstevel@tonic-gate 37177c478bd9Sstevel@tonic-gate case O_REQUIRES_DIR_FSYNC: 37187c478bd9Sstevel@tonic-gate #if REQUIRES_DIR_FSYNC 37197c478bd9Sstevel@tonic-gate RequiresDirfsync = atobool(val); 37207c478bd9Sstevel@tonic-gate #else /* REQUIRES_DIR_FSYNC */ 37217c478bd9Sstevel@tonic-gate /* silently ignored... required for cf file option */ 37227c478bd9Sstevel@tonic-gate #endif /* REQUIRES_DIR_FSYNC */ 37237c478bd9Sstevel@tonic-gate break; 37247c478bd9Sstevel@tonic-gate 37257c478bd9Sstevel@tonic-gate case O_CONNECTION_RATE_WINDOW_SIZE: 37267c478bd9Sstevel@tonic-gate ConnectionRateWindowSize = convtime(val, 's'); 37277c478bd9Sstevel@tonic-gate break; 37287c478bd9Sstevel@tonic-gate 37297c478bd9Sstevel@tonic-gate case O_FALLBACKSMARTHOST: /* fallback smart host */ 37307c478bd9Sstevel@tonic-gate if (val[0] != '\0') 37317c478bd9Sstevel@tonic-gate FallbackSmartHost = newstr(val); 37327c478bd9Sstevel@tonic-gate break; 37337c478bd9Sstevel@tonic-gate 37347c478bd9Sstevel@tonic-gate #if _FFR_HELONAME 37357c478bd9Sstevel@tonic-gate case O_HELONAME: 3736*445f2479Sjbeck HeloName = newstr(val); 3737*445f2479Sjbeck break; 37387c478bd9Sstevel@tonic-gate #endif /* _FFR_HELONAME */ 3739*445f2479Sjbeck #if _FFR_MEMSTAT 3740*445f2479Sjbeck case O_REFUSELOWMEM: 3741*445f2479Sjbeck RefuseLowMem = atoi(val); 3742*445f2479Sjbeck break; 3743*445f2479Sjbeck case O_QUEUELOWMEM: 3744*445f2479Sjbeck QueueLowMem = atoi(val); 3745*445f2479Sjbeck break; 3746*445f2479Sjbeck case O_MEMRESOURCE: 3747*445f2479Sjbeck MemoryResource = newstr(val); 3748*445f2479Sjbeck break; 3749*445f2479Sjbeck #endif /* _FFR_MEMSTAT */ 3750*445f2479Sjbeck 3751*445f2479Sjbeck #if _FFR_MAXNOOPCOMMANDS 3752*445f2479Sjbeck case O_MAXNOOPCOMMANDS: 3753*445f2479Sjbeck MaxNOOPCommands = atoi(val); 3754*445f2479Sjbeck break; 3755*445f2479Sjbeck #endif /* _FFR_MAXNOOPCOMMANDS */ 3756*445f2479Sjbeck 3757*445f2479Sjbeck #if _FFR_MSG_ACCEPT 3758*445f2479Sjbeck case O_MSG_ACCEPT: 3759*445f2479Sjbeck MessageAccept = newstr(val); 3760*445f2479Sjbeck break; 3761*445f2479Sjbeck #endif /* _FFR_MSG_ACCEPT */ 3762*445f2479Sjbeck 3763*445f2479Sjbeck #if _FFR_QUEUE_RUN_PARANOIA 3764*445f2479Sjbeck case O_CHK_Q_RUNNERS: 3765*445f2479Sjbeck CheckQueueRunners = atoi(val); 3766*445f2479Sjbeck break; 3767*445f2479Sjbeck #endif /* _FFR_QUEUE_RUN_PARANOIA */ 37687c478bd9Sstevel@tonic-gate 37697c478bd9Sstevel@tonic-gate default: 37707c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 37717c478bd9Sstevel@tonic-gate { 37727c478bd9Sstevel@tonic-gate if (isascii(opt) && isprint(opt)) 37737c478bd9Sstevel@tonic-gate sm_dprintf("Warning: option %c unknown\n", opt); 37747c478bd9Sstevel@tonic-gate else 37757c478bd9Sstevel@tonic-gate sm_dprintf("Warning: option 0x%x unknown\n", opt); 37767c478bd9Sstevel@tonic-gate } 37777c478bd9Sstevel@tonic-gate break; 37787c478bd9Sstevel@tonic-gate } 37797c478bd9Sstevel@tonic-gate 37807c478bd9Sstevel@tonic-gate /* 37817c478bd9Sstevel@tonic-gate ** Options with suboptions are responsible for taking care 37827c478bd9Sstevel@tonic-gate ** of sticky-ness (e.g., that a command line setting is kept 37837c478bd9Sstevel@tonic-gate ** when reading in the sendmail.cf file). This has to be done 37847c478bd9Sstevel@tonic-gate ** when the suboptions are parsed since each suboption must be 37857c478bd9Sstevel@tonic-gate ** sticky, not the root option. 37867c478bd9Sstevel@tonic-gate */ 37877c478bd9Sstevel@tonic-gate 37887c478bd9Sstevel@tonic-gate if (sticky && !bitset(OI_SUBOPT, o->o_flags)) 37897c478bd9Sstevel@tonic-gate setbitn(opt, StickyOpt); 37907c478bd9Sstevel@tonic-gate } 37917c478bd9Sstevel@tonic-gate /* 37927c478bd9Sstevel@tonic-gate ** SETCLASS -- set a string into a class 37937c478bd9Sstevel@tonic-gate ** 37947c478bd9Sstevel@tonic-gate ** Parameters: 37957c478bd9Sstevel@tonic-gate ** class -- the class to put the string in. 37967c478bd9Sstevel@tonic-gate ** str -- the string to enter 37977c478bd9Sstevel@tonic-gate ** 37987c478bd9Sstevel@tonic-gate ** Returns: 37997c478bd9Sstevel@tonic-gate ** none. 38007c478bd9Sstevel@tonic-gate ** 38017c478bd9Sstevel@tonic-gate ** Side Effects: 38027c478bd9Sstevel@tonic-gate ** puts the word into the symbol table. 38037c478bd9Sstevel@tonic-gate */ 38047c478bd9Sstevel@tonic-gate 38057c478bd9Sstevel@tonic-gate void 38067c478bd9Sstevel@tonic-gate setclass(class, str) 38077c478bd9Sstevel@tonic-gate int class; 38087c478bd9Sstevel@tonic-gate char *str; 38097c478bd9Sstevel@tonic-gate { 38107c478bd9Sstevel@tonic-gate register STAB *s; 38117c478bd9Sstevel@tonic-gate 38127c478bd9Sstevel@tonic-gate if ((*str & 0377) == MATCHCLASS) 38137c478bd9Sstevel@tonic-gate { 38147c478bd9Sstevel@tonic-gate int mid; 38157c478bd9Sstevel@tonic-gate 38167c478bd9Sstevel@tonic-gate str++; 38177c478bd9Sstevel@tonic-gate mid = macid(str); 38187c478bd9Sstevel@tonic-gate if (mid == 0) 38197c478bd9Sstevel@tonic-gate return; 38207c478bd9Sstevel@tonic-gate 38217c478bd9Sstevel@tonic-gate if (tTd(37, 8)) 38227c478bd9Sstevel@tonic-gate sm_dprintf("setclass(%s, $=%s)\n", 38237c478bd9Sstevel@tonic-gate macname(class), macname(mid)); 38247c478bd9Sstevel@tonic-gate copy_class(mid, class); 38257c478bd9Sstevel@tonic-gate } 38267c478bd9Sstevel@tonic-gate else 38277c478bd9Sstevel@tonic-gate { 38287c478bd9Sstevel@tonic-gate if (tTd(37, 8)) 38297c478bd9Sstevel@tonic-gate sm_dprintf("setclass(%s, %s)\n", macname(class), str); 38307c478bd9Sstevel@tonic-gate 38317c478bd9Sstevel@tonic-gate s = stab(str, ST_CLASS, ST_ENTER); 38327c478bd9Sstevel@tonic-gate setbitn(bitidx(class), s->s_class); 38337c478bd9Sstevel@tonic-gate } 38347c478bd9Sstevel@tonic-gate } 38357c478bd9Sstevel@tonic-gate /* 38367c478bd9Sstevel@tonic-gate ** MAKEMAPENTRY -- create a map entry 38377c478bd9Sstevel@tonic-gate ** 38387c478bd9Sstevel@tonic-gate ** Parameters: 38397c478bd9Sstevel@tonic-gate ** line -- the config file line 38407c478bd9Sstevel@tonic-gate ** 38417c478bd9Sstevel@tonic-gate ** Returns: 38427c478bd9Sstevel@tonic-gate ** A pointer to the map that has been created. 38437c478bd9Sstevel@tonic-gate ** NULL if there was a syntax error. 38447c478bd9Sstevel@tonic-gate ** 38457c478bd9Sstevel@tonic-gate ** Side Effects: 38467c478bd9Sstevel@tonic-gate ** Enters the map into the dictionary. 38477c478bd9Sstevel@tonic-gate */ 38487c478bd9Sstevel@tonic-gate 38497c478bd9Sstevel@tonic-gate MAP * 38507c478bd9Sstevel@tonic-gate makemapentry(line) 38517c478bd9Sstevel@tonic-gate char *line; 38527c478bd9Sstevel@tonic-gate { 38537c478bd9Sstevel@tonic-gate register char *p; 38547c478bd9Sstevel@tonic-gate char *mapname; 38557c478bd9Sstevel@tonic-gate char *classname; 38567c478bd9Sstevel@tonic-gate register STAB *s; 38577c478bd9Sstevel@tonic-gate STAB *class; 38587c478bd9Sstevel@tonic-gate 38597c478bd9Sstevel@tonic-gate for (p = line; isascii(*p) && isspace(*p); p++) 38607c478bd9Sstevel@tonic-gate continue; 38617c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isalnum(*p))) 38627c478bd9Sstevel@tonic-gate { 38637c478bd9Sstevel@tonic-gate syserr("readcf: config K line: no map name"); 38647c478bd9Sstevel@tonic-gate return NULL; 38657c478bd9Sstevel@tonic-gate } 38667c478bd9Sstevel@tonic-gate 38677c478bd9Sstevel@tonic-gate mapname = p; 38687c478bd9Sstevel@tonic-gate while ((isascii(*++p) && isalnum(*p)) || *p == '_' || *p == '.') 38697c478bd9Sstevel@tonic-gate continue; 38707c478bd9Sstevel@tonic-gate if (*p != '\0') 38717c478bd9Sstevel@tonic-gate *p++ = '\0'; 38727c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 38737c478bd9Sstevel@tonic-gate p++; 38747c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isalnum(*p))) 38757c478bd9Sstevel@tonic-gate { 38767c478bd9Sstevel@tonic-gate syserr("readcf: config K line, map %s: no map class", mapname); 38777c478bd9Sstevel@tonic-gate return NULL; 38787c478bd9Sstevel@tonic-gate } 38797c478bd9Sstevel@tonic-gate classname = p; 38807c478bd9Sstevel@tonic-gate while (isascii(*++p) && isalnum(*p)) 38817c478bd9Sstevel@tonic-gate continue; 38827c478bd9Sstevel@tonic-gate if (*p != '\0') 38837c478bd9Sstevel@tonic-gate *p++ = '\0'; 38847c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 38857c478bd9Sstevel@tonic-gate p++; 38867c478bd9Sstevel@tonic-gate 38877c478bd9Sstevel@tonic-gate /* look up the class */ 38887c478bd9Sstevel@tonic-gate class = stab(classname, ST_MAPCLASS, ST_FIND); 38897c478bd9Sstevel@tonic-gate if (class == NULL) 38907c478bd9Sstevel@tonic-gate { 38917c478bd9Sstevel@tonic-gate syserr("readcf: map %s: class %s not available", mapname, 38927c478bd9Sstevel@tonic-gate classname); 38937c478bd9Sstevel@tonic-gate return NULL; 38947c478bd9Sstevel@tonic-gate } 38957c478bd9Sstevel@tonic-gate 38967c478bd9Sstevel@tonic-gate /* enter the map */ 38977c478bd9Sstevel@tonic-gate s = stab(mapname, ST_MAP, ST_ENTER); 38987c478bd9Sstevel@tonic-gate s->s_map.map_class = &class->s_mapclass; 38997c478bd9Sstevel@tonic-gate s->s_map.map_mname = newstr(mapname); 39007c478bd9Sstevel@tonic-gate 39017c478bd9Sstevel@tonic-gate if (class->s_mapclass.map_parse(&s->s_map, p)) 39027c478bd9Sstevel@tonic-gate s->s_map.map_mflags |= MF_VALID; 39037c478bd9Sstevel@tonic-gate 39047c478bd9Sstevel@tonic-gate if (tTd(37, 5)) 39057c478bd9Sstevel@tonic-gate { 39067c478bd9Sstevel@tonic-gate sm_dprintf("map %s, class %s, flags %lx, file %s,\n", 39077c478bd9Sstevel@tonic-gate s->s_map.map_mname, s->s_map.map_class->map_cname, 39087c478bd9Sstevel@tonic-gate s->s_map.map_mflags, s->s_map.map_file); 39097c478bd9Sstevel@tonic-gate sm_dprintf("\tapp %s, domain %s, rebuild %s\n", 39107c478bd9Sstevel@tonic-gate s->s_map.map_app, s->s_map.map_domain, 39117c478bd9Sstevel@tonic-gate s->s_map.map_rebuild); 39127c478bd9Sstevel@tonic-gate } 39137c478bd9Sstevel@tonic-gate return &s->s_map; 39147c478bd9Sstevel@tonic-gate } 39157c478bd9Sstevel@tonic-gate /* 39167c478bd9Sstevel@tonic-gate ** STRTORWSET -- convert string to rewriting set number 39177c478bd9Sstevel@tonic-gate ** 39187c478bd9Sstevel@tonic-gate ** Parameters: 39197c478bd9Sstevel@tonic-gate ** p -- the pointer to the string to decode. 39207c478bd9Sstevel@tonic-gate ** endp -- if set, store the trailing delimiter here. 39217c478bd9Sstevel@tonic-gate ** stabmode -- ST_ENTER to create this entry, ST_FIND if 39227c478bd9Sstevel@tonic-gate ** it must already exist. 39237c478bd9Sstevel@tonic-gate ** 39247c478bd9Sstevel@tonic-gate ** Returns: 39257c478bd9Sstevel@tonic-gate ** The appropriate ruleset number. 39267c478bd9Sstevel@tonic-gate ** -1 if it is not valid (error already printed) 39277c478bd9Sstevel@tonic-gate */ 39287c478bd9Sstevel@tonic-gate 39297c478bd9Sstevel@tonic-gate int 39307c478bd9Sstevel@tonic-gate strtorwset(p, endp, stabmode) 39317c478bd9Sstevel@tonic-gate char *p; 39327c478bd9Sstevel@tonic-gate char **endp; 39337c478bd9Sstevel@tonic-gate int stabmode; 39347c478bd9Sstevel@tonic-gate { 39357c478bd9Sstevel@tonic-gate int ruleset; 39367c478bd9Sstevel@tonic-gate static int nextruleset = MAXRWSETS; 39377c478bd9Sstevel@tonic-gate 39387c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 39397c478bd9Sstevel@tonic-gate p++; 39407c478bd9Sstevel@tonic-gate if (!isascii(*p)) 39417c478bd9Sstevel@tonic-gate { 39427c478bd9Sstevel@tonic-gate syserr("invalid ruleset name: \"%.20s\"", p); 39437c478bd9Sstevel@tonic-gate return -1; 39447c478bd9Sstevel@tonic-gate } 39457c478bd9Sstevel@tonic-gate if (isdigit(*p)) 39467c478bd9Sstevel@tonic-gate { 39477c478bd9Sstevel@tonic-gate ruleset = strtol(p, endp, 10); 39487c478bd9Sstevel@tonic-gate if (ruleset >= MAXRWSETS / 2 || ruleset < 0) 39497c478bd9Sstevel@tonic-gate { 39507c478bd9Sstevel@tonic-gate syserr("bad ruleset %d (%d max)", 39517c478bd9Sstevel@tonic-gate ruleset, MAXRWSETS / 2); 39527c478bd9Sstevel@tonic-gate ruleset = -1; 39537c478bd9Sstevel@tonic-gate } 39547c478bd9Sstevel@tonic-gate } 39557c478bd9Sstevel@tonic-gate else 39567c478bd9Sstevel@tonic-gate { 39577c478bd9Sstevel@tonic-gate STAB *s; 39587c478bd9Sstevel@tonic-gate char delim; 39597c478bd9Sstevel@tonic-gate char *q = NULL; 39607c478bd9Sstevel@tonic-gate 39617c478bd9Sstevel@tonic-gate q = p; 39627c478bd9Sstevel@tonic-gate while (*p != '\0' && isascii(*p) && 39637c478bd9Sstevel@tonic-gate (isalnum(*p) || *p == '_')) 39647c478bd9Sstevel@tonic-gate p++; 39657c478bd9Sstevel@tonic-gate if (q == p || !(isascii(*q) && isalpha(*q))) 39667c478bd9Sstevel@tonic-gate { 39677c478bd9Sstevel@tonic-gate /* no valid characters */ 39687c478bd9Sstevel@tonic-gate syserr("invalid ruleset name: \"%.20s\"", q); 39697c478bd9Sstevel@tonic-gate return -1; 39707c478bd9Sstevel@tonic-gate } 39717c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 39727c478bd9Sstevel@tonic-gate *p++ = '\0'; 39737c478bd9Sstevel@tonic-gate delim = *p; 39747c478bd9Sstevel@tonic-gate if (delim != '\0') 39757c478bd9Sstevel@tonic-gate *p = '\0'; 39767c478bd9Sstevel@tonic-gate s = stab(q, ST_RULESET, stabmode); 39777c478bd9Sstevel@tonic-gate if (delim != '\0') 39787c478bd9Sstevel@tonic-gate *p = delim; 39797c478bd9Sstevel@tonic-gate 39807c478bd9Sstevel@tonic-gate if (s == NULL) 39817c478bd9Sstevel@tonic-gate return -1; 39827c478bd9Sstevel@tonic-gate 39837c478bd9Sstevel@tonic-gate if (stabmode == ST_ENTER && delim == '=') 39847c478bd9Sstevel@tonic-gate { 39857c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 39867c478bd9Sstevel@tonic-gate continue; 39877c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isdigit(*p))) 39887c478bd9Sstevel@tonic-gate { 39897c478bd9Sstevel@tonic-gate syserr("bad ruleset definition \"%s\" (number required after `=')", q); 39907c478bd9Sstevel@tonic-gate ruleset = -1; 39917c478bd9Sstevel@tonic-gate } 39927c478bd9Sstevel@tonic-gate else 39937c478bd9Sstevel@tonic-gate { 39947c478bd9Sstevel@tonic-gate ruleset = strtol(p, endp, 10); 39957c478bd9Sstevel@tonic-gate if (ruleset >= MAXRWSETS / 2 || ruleset < 0) 39967c478bd9Sstevel@tonic-gate { 39977c478bd9Sstevel@tonic-gate syserr("bad ruleset number %d in \"%s\" (%d max)", 39987c478bd9Sstevel@tonic-gate ruleset, q, MAXRWSETS / 2); 39997c478bd9Sstevel@tonic-gate ruleset = -1; 40007c478bd9Sstevel@tonic-gate } 40017c478bd9Sstevel@tonic-gate } 40027c478bd9Sstevel@tonic-gate } 40037c478bd9Sstevel@tonic-gate else 40047c478bd9Sstevel@tonic-gate { 40057c478bd9Sstevel@tonic-gate if (endp != NULL) 40067c478bd9Sstevel@tonic-gate *endp = p; 40077c478bd9Sstevel@tonic-gate if (s->s_ruleset >= 0) 40087c478bd9Sstevel@tonic-gate ruleset = s->s_ruleset; 40097c478bd9Sstevel@tonic-gate else if ((ruleset = --nextruleset) < MAXRWSETS / 2) 40107c478bd9Sstevel@tonic-gate { 40117c478bd9Sstevel@tonic-gate syserr("%s: too many named rulesets (%d max)", 40127c478bd9Sstevel@tonic-gate q, MAXRWSETS / 2); 40137c478bd9Sstevel@tonic-gate ruleset = -1; 40147c478bd9Sstevel@tonic-gate } 40157c478bd9Sstevel@tonic-gate } 40167c478bd9Sstevel@tonic-gate if (s->s_ruleset >= 0 && 40177c478bd9Sstevel@tonic-gate ruleset >= 0 && 40187c478bd9Sstevel@tonic-gate ruleset != s->s_ruleset) 40197c478bd9Sstevel@tonic-gate { 40207c478bd9Sstevel@tonic-gate syserr("%s: ruleset changed value (old %d, new %d)", 40217c478bd9Sstevel@tonic-gate q, s->s_ruleset, ruleset); 40227c478bd9Sstevel@tonic-gate ruleset = s->s_ruleset; 40237c478bd9Sstevel@tonic-gate } 40247c478bd9Sstevel@tonic-gate else if (ruleset >= 0) 40257c478bd9Sstevel@tonic-gate { 40267c478bd9Sstevel@tonic-gate s->s_ruleset = ruleset; 40277c478bd9Sstevel@tonic-gate } 40287c478bd9Sstevel@tonic-gate if (stabmode == ST_ENTER && ruleset >= 0) 40297c478bd9Sstevel@tonic-gate { 40307c478bd9Sstevel@tonic-gate char *h = NULL; 40317c478bd9Sstevel@tonic-gate 40327c478bd9Sstevel@tonic-gate if (RuleSetNames[ruleset] != NULL) 40337c478bd9Sstevel@tonic-gate sm_free(RuleSetNames[ruleset]); /* XXX */ 40347c478bd9Sstevel@tonic-gate if (delim != '\0' && (h = strchr(q, delim)) != NULL) 40357c478bd9Sstevel@tonic-gate *h = '\0'; 40367c478bd9Sstevel@tonic-gate RuleSetNames[ruleset] = newstr(q); 40377c478bd9Sstevel@tonic-gate if (delim == '/' && h != NULL) 40387c478bd9Sstevel@tonic-gate *h = delim; /* put back delim */ 40397c478bd9Sstevel@tonic-gate } 40407c478bd9Sstevel@tonic-gate } 40417c478bd9Sstevel@tonic-gate return ruleset; 40427c478bd9Sstevel@tonic-gate } 40437c478bd9Sstevel@tonic-gate /* 40447c478bd9Sstevel@tonic-gate ** SETTIMEOUT -- set an individual timeout 40457c478bd9Sstevel@tonic-gate ** 40467c478bd9Sstevel@tonic-gate ** Parameters: 40477c478bd9Sstevel@tonic-gate ** name -- the name of the timeout. 40487c478bd9Sstevel@tonic-gate ** val -- the value of the timeout. 40497c478bd9Sstevel@tonic-gate ** sticky -- if set, don't let other setoptions override 40507c478bd9Sstevel@tonic-gate ** this value. 40517c478bd9Sstevel@tonic-gate ** 40527c478bd9Sstevel@tonic-gate ** Returns: 40537c478bd9Sstevel@tonic-gate ** none. 40547c478bd9Sstevel@tonic-gate */ 40557c478bd9Sstevel@tonic-gate 40567c478bd9Sstevel@tonic-gate /* set if Timeout sub-option is stuck */ 40577c478bd9Sstevel@tonic-gate static BITMAP256 StickyTimeoutOpt; 40587c478bd9Sstevel@tonic-gate 40597c478bd9Sstevel@tonic-gate static struct timeoutinfo 40607c478bd9Sstevel@tonic-gate { 40617c478bd9Sstevel@tonic-gate char *to_name; /* long name of timeout */ 40627c478bd9Sstevel@tonic-gate unsigned char to_code; /* code for option */ 40637c478bd9Sstevel@tonic-gate } TimeOutTab[] = 40647c478bd9Sstevel@tonic-gate { 40657c478bd9Sstevel@tonic-gate #define TO_INITIAL 0x01 40667c478bd9Sstevel@tonic-gate { "initial", TO_INITIAL }, 40677c478bd9Sstevel@tonic-gate #define TO_MAIL 0x02 40687c478bd9Sstevel@tonic-gate { "mail", TO_MAIL }, 40697c478bd9Sstevel@tonic-gate #define TO_RCPT 0x03 40707c478bd9Sstevel@tonic-gate { "rcpt", TO_RCPT }, 40717c478bd9Sstevel@tonic-gate #define TO_DATAINIT 0x04 40727c478bd9Sstevel@tonic-gate { "datainit", TO_DATAINIT }, 40737c478bd9Sstevel@tonic-gate #define TO_DATABLOCK 0x05 40747c478bd9Sstevel@tonic-gate { "datablock", TO_DATABLOCK }, 40757c478bd9Sstevel@tonic-gate #define TO_DATAFINAL 0x06 40767c478bd9Sstevel@tonic-gate { "datafinal", TO_DATAFINAL }, 40777c478bd9Sstevel@tonic-gate #define TO_COMMAND 0x07 40787c478bd9Sstevel@tonic-gate { "command", TO_COMMAND }, 40797c478bd9Sstevel@tonic-gate #define TO_RSET 0x08 40807c478bd9Sstevel@tonic-gate { "rset", TO_RSET }, 40817c478bd9Sstevel@tonic-gate #define TO_HELO 0x09 40827c478bd9Sstevel@tonic-gate { "helo", TO_HELO }, 40837c478bd9Sstevel@tonic-gate #define TO_QUIT 0x0A 40847c478bd9Sstevel@tonic-gate { "quit", TO_QUIT }, 40857c478bd9Sstevel@tonic-gate #define TO_MISC 0x0B 40867c478bd9Sstevel@tonic-gate { "misc", TO_MISC }, 40877c478bd9Sstevel@tonic-gate #define TO_IDENT 0x0C 40887c478bd9Sstevel@tonic-gate { "ident", TO_IDENT }, 40897c478bd9Sstevel@tonic-gate #define TO_FILEOPEN 0x0D 40907c478bd9Sstevel@tonic-gate { "fileopen", TO_FILEOPEN }, 40917c478bd9Sstevel@tonic-gate #define TO_CONNECT 0x0E 40927c478bd9Sstevel@tonic-gate { "connect", TO_CONNECT }, 40937c478bd9Sstevel@tonic-gate #define TO_ICONNECT 0x0F 40947c478bd9Sstevel@tonic-gate { "iconnect", TO_ICONNECT }, 40957c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN 0x10 40967c478bd9Sstevel@tonic-gate { "queuewarn", TO_QUEUEWARN }, 40977c478bd9Sstevel@tonic-gate { "queuewarn.*", TO_QUEUEWARN }, 40987c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_NORMAL 0x11 40997c478bd9Sstevel@tonic-gate { "queuewarn.normal", TO_QUEUEWARN_NORMAL }, 41007c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_URGENT 0x12 41017c478bd9Sstevel@tonic-gate { "queuewarn.urgent", TO_QUEUEWARN_URGENT }, 41027c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_NON_URGENT 0x13 41037c478bd9Sstevel@tonic-gate { "queuewarn.non-urgent", TO_QUEUEWARN_NON_URGENT }, 41047c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN 0x14 41057c478bd9Sstevel@tonic-gate { "queuereturn", TO_QUEUERETURN }, 41067c478bd9Sstevel@tonic-gate { "queuereturn.*", TO_QUEUERETURN }, 41077c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_NORMAL 0x15 41087c478bd9Sstevel@tonic-gate { "queuereturn.normal", TO_QUEUERETURN_NORMAL }, 41097c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_URGENT 0x16 41107c478bd9Sstevel@tonic-gate { "queuereturn.urgent", TO_QUEUERETURN_URGENT }, 41117c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_NON_URGENT 0x17 41127c478bd9Sstevel@tonic-gate { "queuereturn.non-urgent", TO_QUEUERETURN_NON_URGENT }, 41137c478bd9Sstevel@tonic-gate #define TO_HOSTSTATUS 0x18 41147c478bd9Sstevel@tonic-gate { "hoststatus", TO_HOSTSTATUS }, 41157c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRANS 0x19 41167c478bd9Sstevel@tonic-gate { "resolver.retrans", TO_RESOLVER_RETRANS }, 41177c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRANS_NORMAL 0x1A 41187c478bd9Sstevel@tonic-gate { "resolver.retrans.normal", TO_RESOLVER_RETRANS_NORMAL }, 41197c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRANS_FIRST 0x1B 41207c478bd9Sstevel@tonic-gate { "resolver.retrans.first", TO_RESOLVER_RETRANS_FIRST }, 41217c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRY 0x1C 41227c478bd9Sstevel@tonic-gate { "resolver.retry", TO_RESOLVER_RETRY }, 41237c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRY_NORMAL 0x1D 41247c478bd9Sstevel@tonic-gate { "resolver.retry.normal", TO_RESOLVER_RETRY_NORMAL }, 41257c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRY_FIRST 0x1E 41267c478bd9Sstevel@tonic-gate { "resolver.retry.first", TO_RESOLVER_RETRY_FIRST }, 41277c478bd9Sstevel@tonic-gate #define TO_CONTROL 0x1F 41287c478bd9Sstevel@tonic-gate { "control", TO_CONTROL }, 41297c478bd9Sstevel@tonic-gate #define TO_LHLO 0x20 41307c478bd9Sstevel@tonic-gate { "lhlo", TO_LHLO }, 41317c478bd9Sstevel@tonic-gate #define TO_AUTH 0x21 41327c478bd9Sstevel@tonic-gate { "auth", TO_AUTH }, 41337c478bd9Sstevel@tonic-gate #define TO_STARTTLS 0x22 41347c478bd9Sstevel@tonic-gate { "starttls", TO_STARTTLS }, 41357c478bd9Sstevel@tonic-gate #define TO_ACONNECT 0x23 41367c478bd9Sstevel@tonic-gate { "aconnect", TO_ACONNECT }, 41377c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_DSN 0x24 41387c478bd9Sstevel@tonic-gate { "queuewarn.dsn", TO_QUEUEWARN_DSN }, 41397c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_DSN 0x25 41407c478bd9Sstevel@tonic-gate { "queuereturn.dsn", TO_QUEUERETURN_DSN }, 41417c478bd9Sstevel@tonic-gate { NULL, 0 }, 41427c478bd9Sstevel@tonic-gate }; 41437c478bd9Sstevel@tonic-gate 41447c478bd9Sstevel@tonic-gate 41457c478bd9Sstevel@tonic-gate static void 41467c478bd9Sstevel@tonic-gate settimeout(name, val, sticky) 41477c478bd9Sstevel@tonic-gate char *name; 41487c478bd9Sstevel@tonic-gate char *val; 41497c478bd9Sstevel@tonic-gate bool sticky; 41507c478bd9Sstevel@tonic-gate { 41517c478bd9Sstevel@tonic-gate register struct timeoutinfo *to; 41527c478bd9Sstevel@tonic-gate int i, addopts; 41537c478bd9Sstevel@tonic-gate time_t toval; 41547c478bd9Sstevel@tonic-gate 41557c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 41567c478bd9Sstevel@tonic-gate sm_dprintf("settimeout(%s = %s)", name, val); 41577c478bd9Sstevel@tonic-gate 41587c478bd9Sstevel@tonic-gate for (to = TimeOutTab; to->to_name != NULL; to++) 41597c478bd9Sstevel@tonic-gate { 41607c478bd9Sstevel@tonic-gate if (sm_strcasecmp(to->to_name, name) == 0) 41617c478bd9Sstevel@tonic-gate break; 41627c478bd9Sstevel@tonic-gate } 41637c478bd9Sstevel@tonic-gate 41647c478bd9Sstevel@tonic-gate if (to->to_name == NULL) 41657c478bd9Sstevel@tonic-gate { 41667c478bd9Sstevel@tonic-gate errno = 0; /* avoid bogus error text */ 41677c478bd9Sstevel@tonic-gate syserr("settimeout: invalid timeout %s", name); 41687c478bd9Sstevel@tonic-gate return; 41697c478bd9Sstevel@tonic-gate } 41707c478bd9Sstevel@tonic-gate 41717c478bd9Sstevel@tonic-gate /* 41727c478bd9Sstevel@tonic-gate ** See if this option is preset for us. 41737c478bd9Sstevel@tonic-gate */ 41747c478bd9Sstevel@tonic-gate 41757c478bd9Sstevel@tonic-gate if (!sticky && bitnset(to->to_code, StickyTimeoutOpt)) 41767c478bd9Sstevel@tonic-gate { 41777c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 41787c478bd9Sstevel@tonic-gate sm_dprintf(" (ignored)\n"); 41797c478bd9Sstevel@tonic-gate return; 41807c478bd9Sstevel@tonic-gate } 41817c478bd9Sstevel@tonic-gate 41827c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 41837c478bd9Sstevel@tonic-gate sm_dprintf("\n"); 41847c478bd9Sstevel@tonic-gate 41857c478bd9Sstevel@tonic-gate toval = convtime(val, 'm'); 41867c478bd9Sstevel@tonic-gate addopts = 0; 41877c478bd9Sstevel@tonic-gate 41887c478bd9Sstevel@tonic-gate switch (to->to_code) 41897c478bd9Sstevel@tonic-gate { 41907c478bd9Sstevel@tonic-gate case TO_INITIAL: 41917c478bd9Sstevel@tonic-gate TimeOuts.to_initial = toval; 41927c478bd9Sstevel@tonic-gate break; 41937c478bd9Sstevel@tonic-gate 41947c478bd9Sstevel@tonic-gate case TO_MAIL: 41957c478bd9Sstevel@tonic-gate TimeOuts.to_mail = toval; 41967c478bd9Sstevel@tonic-gate break; 41977c478bd9Sstevel@tonic-gate 41987c478bd9Sstevel@tonic-gate case TO_RCPT: 41997c478bd9Sstevel@tonic-gate TimeOuts.to_rcpt = toval; 42007c478bd9Sstevel@tonic-gate break; 42017c478bd9Sstevel@tonic-gate 42027c478bd9Sstevel@tonic-gate case TO_DATAINIT: 42037c478bd9Sstevel@tonic-gate TimeOuts.to_datainit = toval; 42047c478bd9Sstevel@tonic-gate break; 42057c478bd9Sstevel@tonic-gate 42067c478bd9Sstevel@tonic-gate case TO_DATABLOCK: 42077c478bd9Sstevel@tonic-gate TimeOuts.to_datablock = toval; 42087c478bd9Sstevel@tonic-gate break; 42097c478bd9Sstevel@tonic-gate 42107c478bd9Sstevel@tonic-gate case TO_DATAFINAL: 42117c478bd9Sstevel@tonic-gate TimeOuts.to_datafinal = toval; 42127c478bd9Sstevel@tonic-gate break; 42137c478bd9Sstevel@tonic-gate 42147c478bd9Sstevel@tonic-gate case TO_COMMAND: 42157c478bd9Sstevel@tonic-gate TimeOuts.to_nextcommand = toval; 42167c478bd9Sstevel@tonic-gate break; 42177c478bd9Sstevel@tonic-gate 42187c478bd9Sstevel@tonic-gate case TO_RSET: 42197c478bd9Sstevel@tonic-gate TimeOuts.to_rset = toval; 42207c478bd9Sstevel@tonic-gate break; 42217c478bd9Sstevel@tonic-gate 42227c478bd9Sstevel@tonic-gate case TO_HELO: 42237c478bd9Sstevel@tonic-gate TimeOuts.to_helo = toval; 42247c478bd9Sstevel@tonic-gate break; 42257c478bd9Sstevel@tonic-gate 42267c478bd9Sstevel@tonic-gate case TO_QUIT: 42277c478bd9Sstevel@tonic-gate TimeOuts.to_quit = toval; 42287c478bd9Sstevel@tonic-gate break; 42297c478bd9Sstevel@tonic-gate 42307c478bd9Sstevel@tonic-gate case TO_MISC: 42317c478bd9Sstevel@tonic-gate TimeOuts.to_miscshort = toval; 42327c478bd9Sstevel@tonic-gate break; 42337c478bd9Sstevel@tonic-gate 42347c478bd9Sstevel@tonic-gate case TO_IDENT: 42357c478bd9Sstevel@tonic-gate TimeOuts.to_ident = toval; 42367c478bd9Sstevel@tonic-gate break; 42377c478bd9Sstevel@tonic-gate 42387c478bd9Sstevel@tonic-gate case TO_FILEOPEN: 42397c478bd9Sstevel@tonic-gate TimeOuts.to_fileopen = toval; 42407c478bd9Sstevel@tonic-gate break; 42417c478bd9Sstevel@tonic-gate 42427c478bd9Sstevel@tonic-gate case TO_CONNECT: 42437c478bd9Sstevel@tonic-gate TimeOuts.to_connect = toval; 42447c478bd9Sstevel@tonic-gate break; 42457c478bd9Sstevel@tonic-gate 42467c478bd9Sstevel@tonic-gate case TO_ICONNECT: 42477c478bd9Sstevel@tonic-gate TimeOuts.to_iconnect = toval; 42487c478bd9Sstevel@tonic-gate break; 42497c478bd9Sstevel@tonic-gate 42507c478bd9Sstevel@tonic-gate case TO_ACONNECT: 42517c478bd9Sstevel@tonic-gate TimeOuts.to_aconnect = toval; 42527c478bd9Sstevel@tonic-gate break; 42537c478bd9Sstevel@tonic-gate 42547c478bd9Sstevel@tonic-gate case TO_QUEUEWARN: 42557c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 42567c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NORMAL] = toval; 42577c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_URGENT] = toval; 42587c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NONURGENT] = toval; 42597c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_DSN] = toval; 42607c478bd9Sstevel@tonic-gate addopts = 2; 42617c478bd9Sstevel@tonic-gate break; 42627c478bd9Sstevel@tonic-gate 42637c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_NORMAL: 42647c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 42657c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NORMAL] = toval; 42667c478bd9Sstevel@tonic-gate break; 42677c478bd9Sstevel@tonic-gate 42687c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_URGENT: 42697c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 42707c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_URGENT] = toval; 42717c478bd9Sstevel@tonic-gate break; 42727c478bd9Sstevel@tonic-gate 42737c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_NON_URGENT: 42747c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 42757c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NONURGENT] = toval; 42767c478bd9Sstevel@tonic-gate break; 42777c478bd9Sstevel@tonic-gate 42787c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_DSN: 42797c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 42807c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_DSN] = toval; 42817c478bd9Sstevel@tonic-gate break; 42827c478bd9Sstevel@tonic-gate 42837c478bd9Sstevel@tonic-gate case TO_QUEUERETURN: 42847c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 42857c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NORMAL] = toval; 42867c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_URGENT] = toval; 42877c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NONURGENT] = toval; 42887c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_DSN] = toval; 42897c478bd9Sstevel@tonic-gate addopts = 2; 42907c478bd9Sstevel@tonic-gate break; 42917c478bd9Sstevel@tonic-gate 42927c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_NORMAL: 42937c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 42947c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NORMAL] = toval; 42957c478bd9Sstevel@tonic-gate break; 42967c478bd9Sstevel@tonic-gate 42977c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_URGENT: 42987c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 42997c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_URGENT] = toval; 43007c478bd9Sstevel@tonic-gate break; 43017c478bd9Sstevel@tonic-gate 43027c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_NON_URGENT: 43037c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 43047c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NONURGENT] = toval; 43057c478bd9Sstevel@tonic-gate break; 43067c478bd9Sstevel@tonic-gate 43077c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_DSN: 43087c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 43097c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_DSN] = toval; 43107c478bd9Sstevel@tonic-gate break; 43117c478bd9Sstevel@tonic-gate 43127c478bd9Sstevel@tonic-gate case TO_HOSTSTATUS: 43137c478bd9Sstevel@tonic-gate MciInfoTimeout = toval; 43147c478bd9Sstevel@tonic-gate break; 43157c478bd9Sstevel@tonic-gate 43167c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRANS: 43177c478bd9Sstevel@tonic-gate toval = convtime(val, 's'); 43187c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_DEFAULT] = toval; 43197c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_FIRST] = toval; 43207c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_NORMAL] = toval; 43217c478bd9Sstevel@tonic-gate addopts = 2; 43227c478bd9Sstevel@tonic-gate break; 43237c478bd9Sstevel@tonic-gate 43247c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRY: 43257c478bd9Sstevel@tonic-gate i = atoi(val); 43267c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_DEFAULT] = i; 43277c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_FIRST] = i; 43287c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_NORMAL] = i; 43297c478bd9Sstevel@tonic-gate addopts = 2; 43307c478bd9Sstevel@tonic-gate break; 43317c478bd9Sstevel@tonic-gate 43327c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRANS_NORMAL: 43337c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_NORMAL] = convtime(val, 's'); 43347c478bd9Sstevel@tonic-gate break; 43357c478bd9Sstevel@tonic-gate 43367c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRY_NORMAL: 43377c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_NORMAL] = atoi(val); 43387c478bd9Sstevel@tonic-gate break; 43397c478bd9Sstevel@tonic-gate 43407c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRANS_FIRST: 43417c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_FIRST] = convtime(val, 's'); 43427c478bd9Sstevel@tonic-gate break; 43437c478bd9Sstevel@tonic-gate 43447c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRY_FIRST: 43457c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_FIRST] = atoi(val); 43467c478bd9Sstevel@tonic-gate break; 43477c478bd9Sstevel@tonic-gate 43487c478bd9Sstevel@tonic-gate case TO_CONTROL: 43497c478bd9Sstevel@tonic-gate TimeOuts.to_control = toval; 43507c478bd9Sstevel@tonic-gate break; 43517c478bd9Sstevel@tonic-gate 43527c478bd9Sstevel@tonic-gate case TO_LHLO: 43537c478bd9Sstevel@tonic-gate TimeOuts.to_lhlo = toval; 43547c478bd9Sstevel@tonic-gate break; 43557c478bd9Sstevel@tonic-gate 43567c478bd9Sstevel@tonic-gate #if SASL 43577c478bd9Sstevel@tonic-gate case TO_AUTH: 43587c478bd9Sstevel@tonic-gate TimeOuts.to_auth = toval; 43597c478bd9Sstevel@tonic-gate break; 43607c478bd9Sstevel@tonic-gate #endif /* SASL */ 43617c478bd9Sstevel@tonic-gate 43627c478bd9Sstevel@tonic-gate #if STARTTLS 43637c478bd9Sstevel@tonic-gate case TO_STARTTLS: 43647c478bd9Sstevel@tonic-gate TimeOuts.to_starttls = toval; 43657c478bd9Sstevel@tonic-gate break; 43667c478bd9Sstevel@tonic-gate #endif /* STARTTLS */ 43677c478bd9Sstevel@tonic-gate 43687c478bd9Sstevel@tonic-gate default: 43697c478bd9Sstevel@tonic-gate syserr("settimeout: invalid timeout %s", name); 43707c478bd9Sstevel@tonic-gate break; 43717c478bd9Sstevel@tonic-gate } 43727c478bd9Sstevel@tonic-gate 43737c478bd9Sstevel@tonic-gate if (sticky) 43747c478bd9Sstevel@tonic-gate { 43757c478bd9Sstevel@tonic-gate for (i = 0; i <= addopts; i++) 43767c478bd9Sstevel@tonic-gate setbitn(to->to_code + i, StickyTimeoutOpt); 43777c478bd9Sstevel@tonic-gate } 43787c478bd9Sstevel@tonic-gate } 43797c478bd9Sstevel@tonic-gate /* 43807c478bd9Sstevel@tonic-gate ** INITTIMEOUTS -- parse and set timeout values 43817c478bd9Sstevel@tonic-gate ** 43827c478bd9Sstevel@tonic-gate ** Parameters: 43837c478bd9Sstevel@tonic-gate ** val -- a pointer to the values. If NULL, do initial 43847c478bd9Sstevel@tonic-gate ** settings. 43857c478bd9Sstevel@tonic-gate ** sticky -- if set, don't let other setoptions override 43867c478bd9Sstevel@tonic-gate ** this suboption value. 43877c478bd9Sstevel@tonic-gate ** 43887c478bd9Sstevel@tonic-gate ** Returns: 43897c478bd9Sstevel@tonic-gate ** none. 43907c478bd9Sstevel@tonic-gate ** 43917c478bd9Sstevel@tonic-gate ** Side Effects: 43927c478bd9Sstevel@tonic-gate ** Initializes the TimeOuts structure 43937c478bd9Sstevel@tonic-gate */ 43947c478bd9Sstevel@tonic-gate 43957c478bd9Sstevel@tonic-gate void 43967c478bd9Sstevel@tonic-gate inittimeouts(val, sticky) 43977c478bd9Sstevel@tonic-gate register char *val; 43987c478bd9Sstevel@tonic-gate bool sticky; 43997c478bd9Sstevel@tonic-gate { 44007c478bd9Sstevel@tonic-gate register char *p; 44017c478bd9Sstevel@tonic-gate 44027c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 44037c478bd9Sstevel@tonic-gate sm_dprintf("inittimeouts(%s)\n", val == NULL ? "<NULL>" : val); 44047c478bd9Sstevel@tonic-gate if (val == NULL) 44057c478bd9Sstevel@tonic-gate { 44067c478bd9Sstevel@tonic-gate TimeOuts.to_connect = (time_t) 0 SECONDS; 44077c478bd9Sstevel@tonic-gate TimeOuts.to_aconnect = (time_t) 0 SECONDS; 44087c478bd9Sstevel@tonic-gate TimeOuts.to_iconnect = (time_t) 0 SECONDS; 44097c478bd9Sstevel@tonic-gate TimeOuts.to_initial = (time_t) 5 MINUTES; 44107c478bd9Sstevel@tonic-gate TimeOuts.to_helo = (time_t) 5 MINUTES; 44117c478bd9Sstevel@tonic-gate TimeOuts.to_mail = (time_t) 10 MINUTES; 44127c478bd9Sstevel@tonic-gate TimeOuts.to_rcpt = (time_t) 1 HOUR; 44137c478bd9Sstevel@tonic-gate TimeOuts.to_datainit = (time_t) 5 MINUTES; 44147c478bd9Sstevel@tonic-gate TimeOuts.to_datablock = (time_t) 1 HOUR; 44157c478bd9Sstevel@tonic-gate TimeOuts.to_datafinal = (time_t) 1 HOUR; 44167c478bd9Sstevel@tonic-gate TimeOuts.to_rset = (time_t) 5 MINUTES; 44177c478bd9Sstevel@tonic-gate TimeOuts.to_quit = (time_t) 2 MINUTES; 44187c478bd9Sstevel@tonic-gate TimeOuts.to_nextcommand = (time_t) 1 HOUR; 44197c478bd9Sstevel@tonic-gate TimeOuts.to_miscshort = (time_t) 2 MINUTES; 44207c478bd9Sstevel@tonic-gate #if IDENTPROTO 44217c478bd9Sstevel@tonic-gate TimeOuts.to_ident = (time_t) 5 SECONDS; 44227c478bd9Sstevel@tonic-gate #else /* IDENTPROTO */ 44237c478bd9Sstevel@tonic-gate TimeOuts.to_ident = (time_t) 0 SECONDS; 44247c478bd9Sstevel@tonic-gate #endif /* IDENTPROTO */ 44257c478bd9Sstevel@tonic-gate TimeOuts.to_fileopen = (time_t) 60 SECONDS; 44267c478bd9Sstevel@tonic-gate TimeOuts.to_control = (time_t) 2 MINUTES; 44277c478bd9Sstevel@tonic-gate TimeOuts.to_lhlo = (time_t) 2 MINUTES; 44287c478bd9Sstevel@tonic-gate #if SASL 44297c478bd9Sstevel@tonic-gate TimeOuts.to_auth = (time_t) 10 MINUTES; 44307c478bd9Sstevel@tonic-gate #endif /* SASL */ 44317c478bd9Sstevel@tonic-gate #if STARTTLS 44327c478bd9Sstevel@tonic-gate TimeOuts.to_starttls = (time_t) 1 HOUR; 44337c478bd9Sstevel@tonic-gate #endif /* STARTTLS */ 44347c478bd9Sstevel@tonic-gate if (tTd(37, 5)) 44357c478bd9Sstevel@tonic-gate { 44367c478bd9Sstevel@tonic-gate sm_dprintf("Timeouts:\n"); 44377c478bd9Sstevel@tonic-gate sm_dprintf(" connect = %ld\n", 44387c478bd9Sstevel@tonic-gate (long) TimeOuts.to_connect); 44397c478bd9Sstevel@tonic-gate sm_dprintf(" aconnect = %ld\n", 44407c478bd9Sstevel@tonic-gate (long) TimeOuts.to_aconnect); 44417c478bd9Sstevel@tonic-gate sm_dprintf(" initial = %ld\n", 44427c478bd9Sstevel@tonic-gate (long) TimeOuts.to_initial); 44437c478bd9Sstevel@tonic-gate sm_dprintf(" helo = %ld\n", (long) TimeOuts.to_helo); 44447c478bd9Sstevel@tonic-gate sm_dprintf(" mail = %ld\n", (long) TimeOuts.to_mail); 44457c478bd9Sstevel@tonic-gate sm_dprintf(" rcpt = %ld\n", (long) TimeOuts.to_rcpt); 44467c478bd9Sstevel@tonic-gate sm_dprintf(" datainit = %ld\n", 44477c478bd9Sstevel@tonic-gate (long) TimeOuts.to_datainit); 44487c478bd9Sstevel@tonic-gate sm_dprintf(" datablock = %ld\n", 44497c478bd9Sstevel@tonic-gate (long) TimeOuts.to_datablock); 44507c478bd9Sstevel@tonic-gate sm_dprintf(" datafinal = %ld\n", 44517c478bd9Sstevel@tonic-gate (long) TimeOuts.to_datafinal); 44527c478bd9Sstevel@tonic-gate sm_dprintf(" rset = %ld\n", (long) TimeOuts.to_rset); 44537c478bd9Sstevel@tonic-gate sm_dprintf(" quit = %ld\n", (long) TimeOuts.to_quit); 44547c478bd9Sstevel@tonic-gate sm_dprintf(" nextcommand = %ld\n", 44557c478bd9Sstevel@tonic-gate (long) TimeOuts.to_nextcommand); 44567c478bd9Sstevel@tonic-gate sm_dprintf(" miscshort = %ld\n", 44577c478bd9Sstevel@tonic-gate (long) TimeOuts.to_miscshort); 44587c478bd9Sstevel@tonic-gate sm_dprintf(" ident = %ld\n", (long) TimeOuts.to_ident); 44597c478bd9Sstevel@tonic-gate sm_dprintf(" fileopen = %ld\n", 44607c478bd9Sstevel@tonic-gate (long) TimeOuts.to_fileopen); 44617c478bd9Sstevel@tonic-gate sm_dprintf(" lhlo = %ld\n", 44627c478bd9Sstevel@tonic-gate (long) TimeOuts.to_lhlo); 44637c478bd9Sstevel@tonic-gate sm_dprintf(" control = %ld\n", 44647c478bd9Sstevel@tonic-gate (long) TimeOuts.to_control); 44657c478bd9Sstevel@tonic-gate } 44667c478bd9Sstevel@tonic-gate return; 44677c478bd9Sstevel@tonic-gate } 44687c478bd9Sstevel@tonic-gate 44697c478bd9Sstevel@tonic-gate for (;; val = p) 44707c478bd9Sstevel@tonic-gate { 44717c478bd9Sstevel@tonic-gate while (isascii(*val) && isspace(*val)) 44727c478bd9Sstevel@tonic-gate val++; 44737c478bd9Sstevel@tonic-gate if (*val == '\0') 44747c478bd9Sstevel@tonic-gate break; 44757c478bd9Sstevel@tonic-gate for (p = val; *p != '\0' && *p != ','; p++) 44767c478bd9Sstevel@tonic-gate continue; 44777c478bd9Sstevel@tonic-gate if (*p != '\0') 44787c478bd9Sstevel@tonic-gate *p++ = '\0'; 44797c478bd9Sstevel@tonic-gate 44807c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 44817c478bd9Sstevel@tonic-gate { 44827c478bd9Sstevel@tonic-gate /* old syntax -- set everything */ 44837c478bd9Sstevel@tonic-gate TimeOuts.to_mail = convtime(val, 'm'); 44847c478bd9Sstevel@tonic-gate TimeOuts.to_rcpt = TimeOuts.to_mail; 44857c478bd9Sstevel@tonic-gate TimeOuts.to_datainit = TimeOuts.to_mail; 44867c478bd9Sstevel@tonic-gate TimeOuts.to_datablock = TimeOuts.to_mail; 44877c478bd9Sstevel@tonic-gate TimeOuts.to_datafinal = TimeOuts.to_mail; 44887c478bd9Sstevel@tonic-gate TimeOuts.to_nextcommand = TimeOuts.to_mail; 44897c478bd9Sstevel@tonic-gate if (sticky) 44907c478bd9Sstevel@tonic-gate { 44917c478bd9Sstevel@tonic-gate setbitn(TO_MAIL, StickyTimeoutOpt); 44927c478bd9Sstevel@tonic-gate setbitn(TO_RCPT, StickyTimeoutOpt); 44937c478bd9Sstevel@tonic-gate setbitn(TO_DATAINIT, StickyTimeoutOpt); 44947c478bd9Sstevel@tonic-gate setbitn(TO_DATABLOCK, StickyTimeoutOpt); 44957c478bd9Sstevel@tonic-gate setbitn(TO_DATAFINAL, StickyTimeoutOpt); 44967c478bd9Sstevel@tonic-gate setbitn(TO_COMMAND, StickyTimeoutOpt); 44977c478bd9Sstevel@tonic-gate } 44987c478bd9Sstevel@tonic-gate continue; 44997c478bd9Sstevel@tonic-gate } 45007c478bd9Sstevel@tonic-gate else 45017c478bd9Sstevel@tonic-gate { 45027c478bd9Sstevel@tonic-gate register char *q = strchr(val, ':'); 45037c478bd9Sstevel@tonic-gate 45047c478bd9Sstevel@tonic-gate if (q == NULL && (q = strchr(val, '=')) == NULL) 45057c478bd9Sstevel@tonic-gate { 45067c478bd9Sstevel@tonic-gate /* syntax error */ 45077c478bd9Sstevel@tonic-gate continue; 45087c478bd9Sstevel@tonic-gate } 45097c478bd9Sstevel@tonic-gate *q++ = '\0'; 45107c478bd9Sstevel@tonic-gate settimeout(val, q, sticky); 45117c478bd9Sstevel@tonic-gate } 45127c478bd9Sstevel@tonic-gate } 45137c478bd9Sstevel@tonic-gate } 4514