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