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> 17*058561cbSjbeck #include <sm/sendmail.h> 187c478bd9Sstevel@tonic-gate 19*058561cbSjbeck SM_RCSID("@(#)$Id: readcf.c,v 8.663 2006/10/05 20:58:59 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]; 109*058561cbSjbeck 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 155*058561cbSjbeck while (bufsize = sizeof(buf), 156*058561cbSjbeck (bp = fgetfolded(buf, &bufsize, cf)) != NULL) 1577c478bd9Sstevel@tonic-gate { 158*058561cbSjbeck char *nbp; 159*058561cbSjbeck 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 */ 168*058561cbSjbeck nbp = translate_dollars(bp, bp, &bufsize); 169*058561cbSjbeck if (nbp != bp && bp != buf) 170*058561cbSjbeck sm_free(bp); 171*058561cbSjbeck 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 = 200*058561cbSjbeck (struct rewrite *) xalloc(sizeof(*rwp)); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate else 2037c478bd9Sstevel@tonic-gate { 204*058561cbSjbeck 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'; 211*058561cbSjbeck expand(&bp[1], exbuf, sizeof(exbuf), e); 2127c478bd9Sstevel@tonic-gate rwp->r_lhs = prescan(exbuf, '\t', pvpbuf, 213*058561cbSjbeck sizeof(pvpbuf), NULL, 214*058561cbSjbeck 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; 229*058561cbSjbeck 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: 240*058561cbSjbeck 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'; 299*058561cbSjbeck expand(q, exbuf, sizeof(exbuf), e); 3007c478bd9Sstevel@tonic-gate rwp->r_rhs = prescan(exbuf, '\t', pvpbuf, 301*058561cbSjbeck sizeof(pvpbuf), NULL, 302*058561cbSjbeck 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; 325*058561cbSjbeck switch (ap[0][0] & 0377) 3267c478bd9Sstevel@tonic-gate { 3277c478bd9Sstevel@tonic-gate case MATCHREPL: 328*058561cbSjbeck if (ap[0][1] <= '0' || 329*058561cbSjbeck ap[0][1] > nfuzzy) 3307c478bd9Sstevel@tonic-gate { 3317c478bd9Sstevel@tonic-gate syserr("replacement $%c out of bounds", 332*058561cbSjbeck 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... */ 368*058561cbSjbeck 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 375*058561cbSjbeck if (ap[1] == NULL) 3767c478bd9Sstevel@tonic-gate { 3777c478bd9Sstevel@tonic-gate syserr("syntax error in map lookup"); 3787c478bd9Sstevel@tonic-gate break; 3797c478bd9Sstevel@tonic-gate } 380*058561cbSjbeck nexttoken = ap[1][0] & 0377; 3817c478bd9Sstevel@tonic-gate if (nexttoken == CANONHOST || 3827c478bd9Sstevel@tonic-gate nexttoken == CANONUSER || 383*058561cbSjbeck nexttoken == endtoken)) 3847c478bd9Sstevel@tonic-gate { 3857c478bd9Sstevel@tonic-gate syserr("missing map name for lookup"); 3867c478bd9Sstevel@tonic-gate break; 3877c478bd9Sstevel@tonic-gate } 388*058561cbSjbeck if (ap[2] == NULL) 3897c478bd9Sstevel@tonic-gate { 3907c478bd9Sstevel@tonic-gate syserr("syntax error in map lookup"); 3917c478bd9Sstevel@tonic-gate break; 3927c478bd9Sstevel@tonic-gate } 393*058561cbSjbeck if (ap[0][0] == HOSTBEGIN) 3947c478bd9Sstevel@tonic-gate break; 395*058561cbSjbeck 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: 408*058561cbSjbeck 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 430*058561cbSjbeck ep = ap[1]; 431*058561cbSjbeck if ((ep[0] & 0377) != MACRODEXPAND && 432*058561cbSjbeck 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 */ 459*058561cbSjbeck 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; 499*058561cbSjbeck 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': 684*058561cbSjbeck 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 } 746*058561cbSjbeck 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: 754*058561cbSjbeck ** ibp -- the buffer to translate. 755*058561cbSjbeck ** obp -- where to put the translation; may be the same as obp 756*058561cbSjbeck ** bsp -- a pointer to the size of obp; will be updated if 757*058561cbSjbeck ** the buffer needs to be replaced. 7587c478bd9Sstevel@tonic-gate ** 7597c478bd9Sstevel@tonic-gate ** Returns: 760*058561cbSjbeck ** The buffer pointer; may differ from obp if the expansion 761*058561cbSjbeck ** is larger then *bsp, in which case this will point to 762*058561cbSjbeck ** malloc()ed memory which must be free()d by the caller. 7637c478bd9Sstevel@tonic-gate */ 7647c478bd9Sstevel@tonic-gate 765*058561cbSjbeck char * 766*058561cbSjbeck translate_dollars(ibp, obp, bsp) 767*058561cbSjbeck char *ibp; 768*058561cbSjbeck char *obp; 769*058561cbSjbeck int *bsp; 7707c478bd9Sstevel@tonic-gate { 7717c478bd9Sstevel@tonic-gate register char *p; 7727c478bd9Sstevel@tonic-gate auto char *ep; 773*058561cbSjbeck char *bp; 774*058561cbSjbeck 775*058561cbSjbeck if (tTd(37, 53)) 776*058561cbSjbeck { 777*058561cbSjbeck sm_dprintf("translate_dollars("); 778*058561cbSjbeck xputs(sm_debug_file(), ibp); 779*058561cbSjbeck sm_dprintf(")\n"); 780*058561cbSjbeck } 781*058561cbSjbeck 782*058561cbSjbeck 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) 806*058561cbSjbeck { 8077c478bd9Sstevel@tonic-gate p--; 808*058561cbSjbeck } 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'; 844*058561cbSjbeck 845*058561cbSjbeck if (tTd(37, 53)) 846*058561cbSjbeck { 847*058561cbSjbeck sm_dprintf(" translate_dollars => "); 848*058561cbSjbeck xputs(sm_debug_file(), bp); 849*058561cbSjbeck sm_dprintf("\n"); 850*058561cbSjbeck } 851*058561cbSjbeck 852*058561cbSjbeck 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 */ 984*058561cbSjbeck expand("\201j", jbuf, sizeof(jbuf), &BlankEnvelope); 9857c478bd9Sstevel@tonic-gate if (jbuf[0] == '\0') 9867c478bd9Sstevel@tonic-gate { 9877c478bd9Sstevel@tonic-gate (void) sm_strlcpy(jbuf, "localhost", 988*058561cbSjbeck 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 { 997*058561cbSjbeck expand(lc, lcbuf, sizeof(lcbuf), CurEnv); 9987c478bd9Sstevel@tonic-gate lc = lcbuf; 9997c478bd9Sstevel@tonic-gate } 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate cl = "ldap"; 1002*058561cbSjbeck 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); 1005*058561cbSjbeck 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 } 1036*058561cbSjbeck 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 1135*058561cbSjbeck 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 */ 1210*058561cbSjbeck m = (struct mailer *) xalloc(sizeof(*m)); 1211*058561cbSjbeck 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 1670*058561cbSjbeck 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 1748*058561cbSjbeck 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 */ 1810*058561cbSjbeck avp = (char **) xalloc(sizeof(*avp) * i); 1811*058561cbSjbeck 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 */ 2243*058561cbSjbeck #if _FFR_EIGHT_BIT_ADDR_OK 2244*058561cbSjbeck # if !ALLOW_255 2245*058561cbSjbeck # ERROR FFR_EIGHT_BIT_ADDR_OK requires _ALLOW_255 2246*058561cbSjbeck # endif /* !ALLOW_255 */ 2247*058561cbSjbeck # define O_EIGHT_BIT_ADDR_OK 0xdf 2248*058561cbSjbeck { "EightBitAddrOK", O_EIGHT_BIT_ADDR_OK, OI_NONE }, 2249*058561cbSjbeck #endif /* _FFR_EIGHT_BIT_ADDR_OK */ 22507c478bd9Sstevel@tonic-gate 22517c478bd9Sstevel@tonic-gate { NULL, '\0', OI_NONE } 22527c478bd9Sstevel@tonic-gate }; 22537c478bd9Sstevel@tonic-gate 22547c478bd9Sstevel@tonic-gate # define CANONIFY(val) 22557c478bd9Sstevel@tonic-gate 22567c478bd9Sstevel@tonic-gate # define SET_OPT_DEFAULT(opt, val) opt = val 22577c478bd9Sstevel@tonic-gate 22587c478bd9Sstevel@tonic-gate /* set a string option by expanding the value and assigning it */ 22597c478bd9Sstevel@tonic-gate /* WARNING this belongs ONLY into a case statement! */ 22607c478bd9Sstevel@tonic-gate #define SET_STRING_EXP(str) \ 2261*058561cbSjbeck expand(val, exbuf, sizeof(exbuf), e); \ 22627c478bd9Sstevel@tonic-gate newval = sm_pstrdup_x(exbuf); \ 22637c478bd9Sstevel@tonic-gate if (str != NULL) \ 22647c478bd9Sstevel@tonic-gate sm_free(str); \ 22657c478bd9Sstevel@tonic-gate CANONIFY(newval); \ 22667c478bd9Sstevel@tonic-gate str = newval; \ 22677c478bd9Sstevel@tonic-gate break 22687c478bd9Sstevel@tonic-gate 22697c478bd9Sstevel@tonic-gate #define OPTNAME o->o_name == NULL ? "<unknown>" : o->o_name 22707c478bd9Sstevel@tonic-gate 22717c478bd9Sstevel@tonic-gate void 22727c478bd9Sstevel@tonic-gate setoption(opt, val, safe, sticky, e) 22737c478bd9Sstevel@tonic-gate int opt; 22747c478bd9Sstevel@tonic-gate char *val; 22757c478bd9Sstevel@tonic-gate bool safe; 22767c478bd9Sstevel@tonic-gate bool sticky; 22777c478bd9Sstevel@tonic-gate register ENVELOPE *e; 22787c478bd9Sstevel@tonic-gate { 22797c478bd9Sstevel@tonic-gate register char *p; 22807c478bd9Sstevel@tonic-gate register struct optioninfo *o; 22817c478bd9Sstevel@tonic-gate char *subopt; 22827c478bd9Sstevel@tonic-gate int mid; 22837c478bd9Sstevel@tonic-gate bool can_setuid = RunAsUid == 0; 22847c478bd9Sstevel@tonic-gate auto char *ep; 22857c478bd9Sstevel@tonic-gate char buf[50]; 22867c478bd9Sstevel@tonic-gate extern bool Warn_Q_option; 22877c478bd9Sstevel@tonic-gate #if _FFR_ALLOW_SASLINFO 22887c478bd9Sstevel@tonic-gate extern unsigned int SubmitMode; 22897c478bd9Sstevel@tonic-gate #endif /* _FFR_ALLOW_SASLINFO */ 2290*058561cbSjbeck #if STARTTLS || SM_CONF_SHM 22917c478bd9Sstevel@tonic-gate char *newval; 22927c478bd9Sstevel@tonic-gate char exbuf[MAXLINE]; 2293*058561cbSjbeck #endif /* STARTTLS || SM_CONF_SHM */ 22947c478bd9Sstevel@tonic-gate 22957c478bd9Sstevel@tonic-gate errno = 0; 22967c478bd9Sstevel@tonic-gate if (opt == ' ') 22977c478bd9Sstevel@tonic-gate { 22987c478bd9Sstevel@tonic-gate /* full word options */ 22997c478bd9Sstevel@tonic-gate struct optioninfo *sel; 23007c478bd9Sstevel@tonic-gate 23017c478bd9Sstevel@tonic-gate p = strchr(val, '='); 23027c478bd9Sstevel@tonic-gate if (p == NULL) 23037c478bd9Sstevel@tonic-gate p = &val[strlen(val)]; 23047c478bd9Sstevel@tonic-gate while (*--p == ' ') 23057c478bd9Sstevel@tonic-gate continue; 23067c478bd9Sstevel@tonic-gate while (*++p == ' ') 23077c478bd9Sstevel@tonic-gate *p = '\0'; 23087c478bd9Sstevel@tonic-gate if (p == val) 23097c478bd9Sstevel@tonic-gate { 23107c478bd9Sstevel@tonic-gate syserr("readcf: null option name"); 23117c478bd9Sstevel@tonic-gate return; 23127c478bd9Sstevel@tonic-gate } 23137c478bd9Sstevel@tonic-gate if (*p == '=') 23147c478bd9Sstevel@tonic-gate *p++ = '\0'; 23157c478bd9Sstevel@tonic-gate while (*p == ' ') 23167c478bd9Sstevel@tonic-gate p++; 23177c478bd9Sstevel@tonic-gate subopt = strchr(val, '.'); 23187c478bd9Sstevel@tonic-gate if (subopt != NULL) 23197c478bd9Sstevel@tonic-gate *subopt++ = '\0'; 23207c478bd9Sstevel@tonic-gate sel = NULL; 23217c478bd9Sstevel@tonic-gate for (o = OptionTab; o->o_name != NULL; o++) 23227c478bd9Sstevel@tonic-gate { 23237c478bd9Sstevel@tonic-gate if (sm_strncasecmp(o->o_name, val, strlen(val)) != 0) 23247c478bd9Sstevel@tonic-gate continue; 23257c478bd9Sstevel@tonic-gate if (strlen(o->o_name) == strlen(val)) 23267c478bd9Sstevel@tonic-gate { 23277c478bd9Sstevel@tonic-gate /* completely specified -- this must be it */ 23287c478bd9Sstevel@tonic-gate sel = NULL; 23297c478bd9Sstevel@tonic-gate break; 23307c478bd9Sstevel@tonic-gate } 23317c478bd9Sstevel@tonic-gate if (sel != NULL) 23327c478bd9Sstevel@tonic-gate break; 23337c478bd9Sstevel@tonic-gate sel = o; 23347c478bd9Sstevel@tonic-gate } 23357c478bd9Sstevel@tonic-gate if (sel != NULL && o->o_name == NULL) 23367c478bd9Sstevel@tonic-gate o = sel; 23377c478bd9Sstevel@tonic-gate else if (o->o_name == NULL) 23387c478bd9Sstevel@tonic-gate { 23397c478bd9Sstevel@tonic-gate syserr("readcf: unknown option name %s", val); 23407c478bd9Sstevel@tonic-gate return; 23417c478bd9Sstevel@tonic-gate } 23427c478bd9Sstevel@tonic-gate else if (sel != NULL) 23437c478bd9Sstevel@tonic-gate { 23447c478bd9Sstevel@tonic-gate syserr("readcf: ambiguous option name %s (matches %s and %s)", 23457c478bd9Sstevel@tonic-gate val, sel->o_name, o->o_name); 23467c478bd9Sstevel@tonic-gate return; 23477c478bd9Sstevel@tonic-gate } 23487c478bd9Sstevel@tonic-gate if (strlen(val) != strlen(o->o_name)) 23497c478bd9Sstevel@tonic-gate { 23507c478bd9Sstevel@tonic-gate int oldVerbose = Verbose; 23517c478bd9Sstevel@tonic-gate 23527c478bd9Sstevel@tonic-gate Verbose = 1; 23537c478bd9Sstevel@tonic-gate message("Option %s used as abbreviation for %s", 23547c478bd9Sstevel@tonic-gate val, o->o_name); 23557c478bd9Sstevel@tonic-gate Verbose = oldVerbose; 23567c478bd9Sstevel@tonic-gate } 23577c478bd9Sstevel@tonic-gate opt = o->o_code; 23587c478bd9Sstevel@tonic-gate val = p; 23597c478bd9Sstevel@tonic-gate } 23607c478bd9Sstevel@tonic-gate else 23617c478bd9Sstevel@tonic-gate { 23627c478bd9Sstevel@tonic-gate for (o = OptionTab; o->o_name != NULL; o++) 23637c478bd9Sstevel@tonic-gate { 23647c478bd9Sstevel@tonic-gate if (o->o_code == opt) 23657c478bd9Sstevel@tonic-gate break; 23667c478bd9Sstevel@tonic-gate } 23677c478bd9Sstevel@tonic-gate if (o->o_name == NULL) 23687c478bd9Sstevel@tonic-gate { 23697c478bd9Sstevel@tonic-gate syserr("readcf: unknown option name 0x%x", opt & 0xff); 23707c478bd9Sstevel@tonic-gate return; 23717c478bd9Sstevel@tonic-gate } 23727c478bd9Sstevel@tonic-gate subopt = NULL; 23737c478bd9Sstevel@tonic-gate } 23747c478bd9Sstevel@tonic-gate 23757c478bd9Sstevel@tonic-gate if (subopt != NULL && !bitset(OI_SUBOPT, o->o_flags)) 23767c478bd9Sstevel@tonic-gate { 23777c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 23787c478bd9Sstevel@tonic-gate sm_dprintf("setoption: %s does not support suboptions, ignoring .%s\n", 23797c478bd9Sstevel@tonic-gate OPTNAME, subopt); 23807c478bd9Sstevel@tonic-gate subopt = NULL; 23817c478bd9Sstevel@tonic-gate } 23827c478bd9Sstevel@tonic-gate 23837c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 23847c478bd9Sstevel@tonic-gate { 23857c478bd9Sstevel@tonic-gate sm_dprintf(isascii(opt) && isprint(opt) ? 23867c478bd9Sstevel@tonic-gate "setoption %s (%c)%s%s=" : 23877c478bd9Sstevel@tonic-gate "setoption %s (0x%x)%s%s=", 23887c478bd9Sstevel@tonic-gate OPTNAME, opt, subopt == NULL ? "" : ".", 23897c478bd9Sstevel@tonic-gate subopt == NULL ? "" : subopt); 23907c478bd9Sstevel@tonic-gate xputs(sm_debug_file(), val); 23917c478bd9Sstevel@tonic-gate } 23927c478bd9Sstevel@tonic-gate 23937c478bd9Sstevel@tonic-gate /* 23947c478bd9Sstevel@tonic-gate ** See if this option is preset for us. 23957c478bd9Sstevel@tonic-gate */ 23967c478bd9Sstevel@tonic-gate 23977c478bd9Sstevel@tonic-gate if (!sticky && bitnset(opt, StickyOpt)) 23987c478bd9Sstevel@tonic-gate { 23997c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 24007c478bd9Sstevel@tonic-gate sm_dprintf(" (ignored)\n"); 24017c478bd9Sstevel@tonic-gate return; 24027c478bd9Sstevel@tonic-gate } 24037c478bd9Sstevel@tonic-gate 24047c478bd9Sstevel@tonic-gate /* 24057c478bd9Sstevel@tonic-gate ** Check to see if this option can be specified by this user. 24067c478bd9Sstevel@tonic-gate */ 24077c478bd9Sstevel@tonic-gate 24087c478bd9Sstevel@tonic-gate if (!safe && RealUid == 0) 24097c478bd9Sstevel@tonic-gate safe = true; 24107c478bd9Sstevel@tonic-gate if (!safe && !bitset(OI_SAFE, o->o_flags)) 24117c478bd9Sstevel@tonic-gate { 24127c478bd9Sstevel@tonic-gate if (opt != 'M' || (val[0] != 'r' && val[0] != 's')) 24137c478bd9Sstevel@tonic-gate { 24147c478bd9Sstevel@tonic-gate int dp; 24157c478bd9Sstevel@tonic-gate 24167c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 24177c478bd9Sstevel@tonic-gate sm_dprintf(" (unsafe)"); 24187c478bd9Sstevel@tonic-gate dp = drop_privileges(true); 24197c478bd9Sstevel@tonic-gate setstat(dp); 24207c478bd9Sstevel@tonic-gate } 24217c478bd9Sstevel@tonic-gate } 24227c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 24237c478bd9Sstevel@tonic-gate sm_dprintf("\n"); 24247c478bd9Sstevel@tonic-gate 24257c478bd9Sstevel@tonic-gate switch (opt & 0xff) 24267c478bd9Sstevel@tonic-gate { 24277c478bd9Sstevel@tonic-gate case '7': /* force seven-bit input */ 24287c478bd9Sstevel@tonic-gate SevenBitInput = atobool(val); 24297c478bd9Sstevel@tonic-gate break; 24307c478bd9Sstevel@tonic-gate 24317c478bd9Sstevel@tonic-gate case '8': /* handling of 8-bit input */ 24327c478bd9Sstevel@tonic-gate #if MIME8TO7 24337c478bd9Sstevel@tonic-gate switch (*val) 24347c478bd9Sstevel@tonic-gate { 24357c478bd9Sstevel@tonic-gate case 'p': /* pass 8 bit, convert MIME */ 24367c478bd9Sstevel@tonic-gate MimeMode = MM_CVTMIME|MM_PASS8BIT; 24377c478bd9Sstevel@tonic-gate break; 24387c478bd9Sstevel@tonic-gate 24397c478bd9Sstevel@tonic-gate case 'm': /* convert 8-bit, convert MIME */ 24407c478bd9Sstevel@tonic-gate MimeMode = MM_CVTMIME|MM_MIME8BIT; 24417c478bd9Sstevel@tonic-gate break; 24427c478bd9Sstevel@tonic-gate 24437c478bd9Sstevel@tonic-gate case 's': /* strict adherence */ 24447c478bd9Sstevel@tonic-gate MimeMode = MM_CVTMIME; 24457c478bd9Sstevel@tonic-gate break; 24467c478bd9Sstevel@tonic-gate 24477c478bd9Sstevel@tonic-gate # if 0 24487c478bd9Sstevel@tonic-gate case 'r': /* reject 8-bit, don't convert MIME */ 24497c478bd9Sstevel@tonic-gate MimeMode = 0; 24507c478bd9Sstevel@tonic-gate break; 24517c478bd9Sstevel@tonic-gate 24527c478bd9Sstevel@tonic-gate case 'j': /* "just send 8" */ 24537c478bd9Sstevel@tonic-gate MimeMode = MM_PASS8BIT; 24547c478bd9Sstevel@tonic-gate break; 24557c478bd9Sstevel@tonic-gate 24567c478bd9Sstevel@tonic-gate case 'a': /* encode 8 bit if available */ 24577c478bd9Sstevel@tonic-gate MimeMode = MM_MIME8BIT|MM_PASS8BIT|MM_CVTMIME; 24587c478bd9Sstevel@tonic-gate break; 24597c478bd9Sstevel@tonic-gate 24607c478bd9Sstevel@tonic-gate case 'c': /* convert 8 bit to MIME, never 7 bit */ 24617c478bd9Sstevel@tonic-gate MimeMode = MM_MIME8BIT; 24627c478bd9Sstevel@tonic-gate break; 24637c478bd9Sstevel@tonic-gate # endif /* 0 */ 24647c478bd9Sstevel@tonic-gate 24657c478bd9Sstevel@tonic-gate default: 24667c478bd9Sstevel@tonic-gate syserr("Unknown 8-bit mode %c", *val); 24677c478bd9Sstevel@tonic-gate finis(false, true, EX_USAGE); 24687c478bd9Sstevel@tonic-gate } 24697c478bd9Sstevel@tonic-gate #else /* MIME8TO7 */ 24707c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 24717c478bd9Sstevel@tonic-gate "Warning: Option: %s requires MIME8TO7 support\n", 24727c478bd9Sstevel@tonic-gate OPTNAME); 24737c478bd9Sstevel@tonic-gate #endif /* MIME8TO7 */ 24747c478bd9Sstevel@tonic-gate break; 24757c478bd9Sstevel@tonic-gate 24767c478bd9Sstevel@tonic-gate case 'A': /* set default alias file */ 24777c478bd9Sstevel@tonic-gate if (val[0] == '\0') 24787c478bd9Sstevel@tonic-gate { 24797c478bd9Sstevel@tonic-gate char *al; 24807c478bd9Sstevel@tonic-gate 24817c478bd9Sstevel@tonic-gate SET_OPT_DEFAULT(al, "aliases"); 24827c478bd9Sstevel@tonic-gate setalias(al); 24837c478bd9Sstevel@tonic-gate } 24847c478bd9Sstevel@tonic-gate else 24857c478bd9Sstevel@tonic-gate setalias(val); 24867c478bd9Sstevel@tonic-gate break; 24877c478bd9Sstevel@tonic-gate 24887c478bd9Sstevel@tonic-gate case 'a': /* look N minutes for "@:@" in alias file */ 24897c478bd9Sstevel@tonic-gate if (val[0] == '\0') 24907c478bd9Sstevel@tonic-gate SafeAlias = 5 MINUTES; 24917c478bd9Sstevel@tonic-gate else 24927c478bd9Sstevel@tonic-gate SafeAlias = convtime(val, 'm'); 24937c478bd9Sstevel@tonic-gate break; 24947c478bd9Sstevel@tonic-gate 24957c478bd9Sstevel@tonic-gate case 'B': /* substitution for blank character */ 24967c478bd9Sstevel@tonic-gate SpaceSub = val[0]; 24977c478bd9Sstevel@tonic-gate if (SpaceSub == '\0') 24987c478bd9Sstevel@tonic-gate SpaceSub = ' '; 24997c478bd9Sstevel@tonic-gate break; 25007c478bd9Sstevel@tonic-gate 25017c478bd9Sstevel@tonic-gate case 'b': /* min blocks free on queue fs/max msg size */ 25027c478bd9Sstevel@tonic-gate p = strchr(val, '/'); 25037c478bd9Sstevel@tonic-gate if (p != NULL) 25047c478bd9Sstevel@tonic-gate { 25057c478bd9Sstevel@tonic-gate *p++ = '\0'; 25067c478bd9Sstevel@tonic-gate MaxMessageSize = atol(p); 25077c478bd9Sstevel@tonic-gate } 25087c478bd9Sstevel@tonic-gate MinBlocksFree = atol(val); 25097c478bd9Sstevel@tonic-gate break; 25107c478bd9Sstevel@tonic-gate 25117c478bd9Sstevel@tonic-gate case 'c': /* don't connect to "expensive" mailers */ 25127c478bd9Sstevel@tonic-gate NoConnect = atobool(val); 25137c478bd9Sstevel@tonic-gate break; 25147c478bd9Sstevel@tonic-gate 25157c478bd9Sstevel@tonic-gate case 'C': /* checkpoint every N addresses */ 25167c478bd9Sstevel@tonic-gate if (safe || CheckpointInterval > atoi(val)) 25177c478bd9Sstevel@tonic-gate CheckpointInterval = atoi(val); 25187c478bd9Sstevel@tonic-gate break; 25197c478bd9Sstevel@tonic-gate 25207c478bd9Sstevel@tonic-gate case 'd': /* delivery mode */ 25217c478bd9Sstevel@tonic-gate switch (*val) 25227c478bd9Sstevel@tonic-gate { 25237c478bd9Sstevel@tonic-gate case '\0': 25247c478bd9Sstevel@tonic-gate set_delivery_mode(SM_DELIVER, e); 25257c478bd9Sstevel@tonic-gate break; 25267c478bd9Sstevel@tonic-gate 25277c478bd9Sstevel@tonic-gate case SM_QUEUE: /* queue only */ 25287c478bd9Sstevel@tonic-gate case SM_DEFER: /* queue only and defer map lookups */ 25297c478bd9Sstevel@tonic-gate case SM_DELIVER: /* do everything */ 25307c478bd9Sstevel@tonic-gate case SM_FORK: /* fork after verification */ 2531445f2479Sjbeck #if _FFR_DM_ONE 2532445f2479Sjbeck /* deliver first TA in background, then queue */ 2533445f2479Sjbeck case SM_DM_ONE: 2534445f2479Sjbeck #endif /* _FFR_DM_ONE */ 25357c478bd9Sstevel@tonic-gate set_delivery_mode(*val, e); 25367c478bd9Sstevel@tonic-gate break; 25377c478bd9Sstevel@tonic-gate 25387c478bd9Sstevel@tonic-gate default: 25397c478bd9Sstevel@tonic-gate syserr("Unknown delivery mode %c", *val); 25407c478bd9Sstevel@tonic-gate finis(false, true, EX_USAGE); 25417c478bd9Sstevel@tonic-gate } 25427c478bd9Sstevel@tonic-gate break; 25437c478bd9Sstevel@tonic-gate 25447c478bd9Sstevel@tonic-gate case 'E': /* error message header/header file */ 25457c478bd9Sstevel@tonic-gate if (*val != '\0') 25467c478bd9Sstevel@tonic-gate ErrMsgFile = newstr(val); 25477c478bd9Sstevel@tonic-gate break; 25487c478bd9Sstevel@tonic-gate 25497c478bd9Sstevel@tonic-gate case 'e': /* set error processing mode */ 25507c478bd9Sstevel@tonic-gate switch (*val) 25517c478bd9Sstevel@tonic-gate { 25527c478bd9Sstevel@tonic-gate case EM_QUIET: /* be silent about it */ 25537c478bd9Sstevel@tonic-gate case EM_MAIL: /* mail back */ 25547c478bd9Sstevel@tonic-gate case EM_BERKNET: /* do berknet error processing */ 25557c478bd9Sstevel@tonic-gate case EM_WRITE: /* write back (or mail) */ 25567c478bd9Sstevel@tonic-gate case EM_PRINT: /* print errors normally (default) */ 25577c478bd9Sstevel@tonic-gate e->e_errormode = *val; 25587c478bd9Sstevel@tonic-gate break; 25597c478bd9Sstevel@tonic-gate } 25607c478bd9Sstevel@tonic-gate break; 25617c478bd9Sstevel@tonic-gate 25627c478bd9Sstevel@tonic-gate case 'F': /* file mode */ 25637c478bd9Sstevel@tonic-gate FileMode = atooct(val) & 0777; 25647c478bd9Sstevel@tonic-gate break; 25657c478bd9Sstevel@tonic-gate 25667c478bd9Sstevel@tonic-gate case 'f': /* save Unix-style From lines on front */ 25677c478bd9Sstevel@tonic-gate SaveFrom = atobool(val); 25687c478bd9Sstevel@tonic-gate break; 25697c478bd9Sstevel@tonic-gate 25707c478bd9Sstevel@tonic-gate case 'G': /* match recipients against GECOS field */ 25717c478bd9Sstevel@tonic-gate MatchGecos = atobool(val); 25727c478bd9Sstevel@tonic-gate break; 25737c478bd9Sstevel@tonic-gate 25747c478bd9Sstevel@tonic-gate case 'g': /* default gid */ 25757c478bd9Sstevel@tonic-gate g_opt: 25767c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 25777c478bd9Sstevel@tonic-gate DefGid = atoi(val); 25787c478bd9Sstevel@tonic-gate else 25797c478bd9Sstevel@tonic-gate { 25807c478bd9Sstevel@tonic-gate register struct group *gr; 25817c478bd9Sstevel@tonic-gate 25827c478bd9Sstevel@tonic-gate DefGid = -1; 25837c478bd9Sstevel@tonic-gate gr = getgrnam(val); 25847c478bd9Sstevel@tonic-gate if (gr == NULL) 25857c478bd9Sstevel@tonic-gate syserr("readcf: option %c: unknown group %s", 25867c478bd9Sstevel@tonic-gate opt, val); 25877c478bd9Sstevel@tonic-gate else 25887c478bd9Sstevel@tonic-gate DefGid = gr->gr_gid; 25897c478bd9Sstevel@tonic-gate } 25907c478bd9Sstevel@tonic-gate break; 25917c478bd9Sstevel@tonic-gate 25927c478bd9Sstevel@tonic-gate case 'H': /* help file */ 25937c478bd9Sstevel@tonic-gate if (val[0] == '\0') 25947c478bd9Sstevel@tonic-gate { 25957c478bd9Sstevel@tonic-gate SET_OPT_DEFAULT(HelpFile, "helpfile"); 25967c478bd9Sstevel@tonic-gate } 25977c478bd9Sstevel@tonic-gate else 25987c478bd9Sstevel@tonic-gate { 25997c478bd9Sstevel@tonic-gate CANONIFY(val); 26007c478bd9Sstevel@tonic-gate HelpFile = newstr(val); 26017c478bd9Sstevel@tonic-gate } 26027c478bd9Sstevel@tonic-gate break; 26037c478bd9Sstevel@tonic-gate 26047c478bd9Sstevel@tonic-gate case 'h': /* maximum hop count */ 26057c478bd9Sstevel@tonic-gate MaxHopCount = atoi(val); 26067c478bd9Sstevel@tonic-gate break; 26077c478bd9Sstevel@tonic-gate 26087c478bd9Sstevel@tonic-gate case 'I': /* use internet domain name server */ 26097c478bd9Sstevel@tonic-gate #if NAMED_BIND 26107c478bd9Sstevel@tonic-gate for (p = val; *p != 0; ) 26117c478bd9Sstevel@tonic-gate { 26127c478bd9Sstevel@tonic-gate bool clearmode; 26137c478bd9Sstevel@tonic-gate char *q; 26147c478bd9Sstevel@tonic-gate struct resolverflags *rfp; 26157c478bd9Sstevel@tonic-gate 26167c478bd9Sstevel@tonic-gate while (*p == ' ') 26177c478bd9Sstevel@tonic-gate p++; 26187c478bd9Sstevel@tonic-gate if (*p == '\0') 26197c478bd9Sstevel@tonic-gate break; 26207c478bd9Sstevel@tonic-gate clearmode = false; 26217c478bd9Sstevel@tonic-gate if (*p == '-') 26227c478bd9Sstevel@tonic-gate clearmode = true; 26237c478bd9Sstevel@tonic-gate else if (*p != '+') 26247c478bd9Sstevel@tonic-gate p--; 26257c478bd9Sstevel@tonic-gate p++; 26267c478bd9Sstevel@tonic-gate q = p; 26277c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 26287c478bd9Sstevel@tonic-gate p++; 26297c478bd9Sstevel@tonic-gate if (*p != '\0') 26307c478bd9Sstevel@tonic-gate *p++ = '\0'; 26317c478bd9Sstevel@tonic-gate if (sm_strcasecmp(q, "HasWildcardMX") == 0) 26327c478bd9Sstevel@tonic-gate { 26337c478bd9Sstevel@tonic-gate HasWildcardMX = !clearmode; 26347c478bd9Sstevel@tonic-gate continue; 26357c478bd9Sstevel@tonic-gate } 26367c478bd9Sstevel@tonic-gate if (sm_strcasecmp(q, "WorkAroundBrokenAAAA") == 0) 26377c478bd9Sstevel@tonic-gate { 26387c478bd9Sstevel@tonic-gate WorkAroundBrokenAAAA = !clearmode; 26397c478bd9Sstevel@tonic-gate continue; 26407c478bd9Sstevel@tonic-gate } 26417c478bd9Sstevel@tonic-gate for (rfp = ResolverFlags; rfp->rf_name != NULL; rfp++) 26427c478bd9Sstevel@tonic-gate { 26437c478bd9Sstevel@tonic-gate if (sm_strcasecmp(q, rfp->rf_name) == 0) 26447c478bd9Sstevel@tonic-gate break; 26457c478bd9Sstevel@tonic-gate } 26467c478bd9Sstevel@tonic-gate if (rfp->rf_name == NULL) 26477c478bd9Sstevel@tonic-gate syserr("readcf: I option value %s unrecognized", q); 26487c478bd9Sstevel@tonic-gate else if (clearmode) 26497c478bd9Sstevel@tonic-gate _res.options &= ~rfp->rf_bits; 26507c478bd9Sstevel@tonic-gate else 26517c478bd9Sstevel@tonic-gate _res.options |= rfp->rf_bits; 26527c478bd9Sstevel@tonic-gate } 26537c478bd9Sstevel@tonic-gate if (tTd(8, 2)) 26547c478bd9Sstevel@tonic-gate sm_dprintf("_res.options = %x, HasWildcardMX = %d\n", 26557c478bd9Sstevel@tonic-gate (unsigned int) _res.options, HasWildcardMX); 26567c478bd9Sstevel@tonic-gate #else /* NAMED_BIND */ 26577c478bd9Sstevel@tonic-gate usrerr("name server (I option) specified but BIND not compiled in"); 26587c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */ 26597c478bd9Sstevel@tonic-gate break; 26607c478bd9Sstevel@tonic-gate 26617c478bd9Sstevel@tonic-gate case 'i': /* ignore dot lines in message */ 26627c478bd9Sstevel@tonic-gate IgnrDot = atobool(val); 26637c478bd9Sstevel@tonic-gate break; 26647c478bd9Sstevel@tonic-gate 26657c478bd9Sstevel@tonic-gate case 'j': /* send errors in MIME (RFC 1341) format */ 26667c478bd9Sstevel@tonic-gate SendMIMEErrors = atobool(val); 26677c478bd9Sstevel@tonic-gate break; 26687c478bd9Sstevel@tonic-gate 26697c478bd9Sstevel@tonic-gate case 'J': /* .forward search path */ 26707c478bd9Sstevel@tonic-gate CANONIFY(val); 26717c478bd9Sstevel@tonic-gate ForwardPath = newstr(val); 26727c478bd9Sstevel@tonic-gate break; 26737c478bd9Sstevel@tonic-gate 26747c478bd9Sstevel@tonic-gate case 'k': /* connection cache size */ 26757c478bd9Sstevel@tonic-gate MaxMciCache = atoi(val); 26767c478bd9Sstevel@tonic-gate if (MaxMciCache < 0) 26777c478bd9Sstevel@tonic-gate MaxMciCache = 0; 26787c478bd9Sstevel@tonic-gate break; 26797c478bd9Sstevel@tonic-gate 26807c478bd9Sstevel@tonic-gate case 'K': /* connection cache timeout */ 26817c478bd9Sstevel@tonic-gate MciCacheTimeout = convtime(val, 'm'); 26827c478bd9Sstevel@tonic-gate break; 26837c478bd9Sstevel@tonic-gate 26847c478bd9Sstevel@tonic-gate case 'l': /* use Errors-To: header */ 26857c478bd9Sstevel@tonic-gate UseErrorsTo = atobool(val); 26867c478bd9Sstevel@tonic-gate break; 26877c478bd9Sstevel@tonic-gate 26887c478bd9Sstevel@tonic-gate case 'L': /* log level */ 26897c478bd9Sstevel@tonic-gate if (safe || LogLevel < atoi(val)) 26907c478bd9Sstevel@tonic-gate LogLevel = atoi(val); 26917c478bd9Sstevel@tonic-gate break; 26927c478bd9Sstevel@tonic-gate 26937c478bd9Sstevel@tonic-gate case 'M': /* define macro */ 26947c478bd9Sstevel@tonic-gate sticky = false; 26957c478bd9Sstevel@tonic-gate mid = macid_parse(val, &ep); 26967c478bd9Sstevel@tonic-gate if (mid == 0) 26977c478bd9Sstevel@tonic-gate break; 26987c478bd9Sstevel@tonic-gate p = newstr(ep); 26997c478bd9Sstevel@tonic-gate if (!safe) 27007c478bd9Sstevel@tonic-gate cleanstrcpy(p, p, strlen(p) + 1); 27017c478bd9Sstevel@tonic-gate macdefine(&CurEnv->e_macro, A_TEMP, mid, p); 27027c478bd9Sstevel@tonic-gate break; 27037c478bd9Sstevel@tonic-gate 27047c478bd9Sstevel@tonic-gate case 'm': /* send to me too */ 27057c478bd9Sstevel@tonic-gate MeToo = atobool(val); 27067c478bd9Sstevel@tonic-gate break; 27077c478bd9Sstevel@tonic-gate 27087c478bd9Sstevel@tonic-gate case 'n': /* validate RHS in newaliases */ 27097c478bd9Sstevel@tonic-gate CheckAliases = atobool(val); 27107c478bd9Sstevel@tonic-gate break; 27117c478bd9Sstevel@tonic-gate 27127c478bd9Sstevel@tonic-gate /* 'N' available -- was "net name" */ 27137c478bd9Sstevel@tonic-gate 27147c478bd9Sstevel@tonic-gate case 'O': /* daemon options */ 27157c478bd9Sstevel@tonic-gate if (!setdaemonoptions(val)) 27167c478bd9Sstevel@tonic-gate syserr("too many daemons defined (%d max)", MAXDAEMONS); 27177c478bd9Sstevel@tonic-gate break; 27187c478bd9Sstevel@tonic-gate 27197c478bd9Sstevel@tonic-gate case 'o': /* assume old style headers */ 27207c478bd9Sstevel@tonic-gate if (atobool(val)) 27217c478bd9Sstevel@tonic-gate CurEnv->e_flags |= EF_OLDSTYLE; 27227c478bd9Sstevel@tonic-gate else 27237c478bd9Sstevel@tonic-gate CurEnv->e_flags &= ~EF_OLDSTYLE; 27247c478bd9Sstevel@tonic-gate break; 27257c478bd9Sstevel@tonic-gate 27267c478bd9Sstevel@tonic-gate case 'p': /* select privacy level */ 27277c478bd9Sstevel@tonic-gate p = val; 27287c478bd9Sstevel@tonic-gate for (;;) 27297c478bd9Sstevel@tonic-gate { 27307c478bd9Sstevel@tonic-gate register struct prival *pv; 27317c478bd9Sstevel@tonic-gate extern struct prival PrivacyValues[]; 27327c478bd9Sstevel@tonic-gate 27337c478bd9Sstevel@tonic-gate while (isascii(*p) && (isspace(*p) || ispunct(*p))) 27347c478bd9Sstevel@tonic-gate p++; 27357c478bd9Sstevel@tonic-gate if (*p == '\0') 27367c478bd9Sstevel@tonic-gate break; 27377c478bd9Sstevel@tonic-gate val = p; 27387c478bd9Sstevel@tonic-gate while (isascii(*p) && isalnum(*p)) 27397c478bd9Sstevel@tonic-gate p++; 27407c478bd9Sstevel@tonic-gate if (*p != '\0') 27417c478bd9Sstevel@tonic-gate *p++ = '\0'; 27427c478bd9Sstevel@tonic-gate 27437c478bd9Sstevel@tonic-gate for (pv = PrivacyValues; pv->pv_name != NULL; pv++) 27447c478bd9Sstevel@tonic-gate { 27457c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, pv->pv_name) == 0) 27467c478bd9Sstevel@tonic-gate break; 27477c478bd9Sstevel@tonic-gate } 27487c478bd9Sstevel@tonic-gate if (pv->pv_name == NULL) 27497c478bd9Sstevel@tonic-gate syserr("readcf: Op line: %s unrecognized", val); 27507c478bd9Sstevel@tonic-gate else 27517c478bd9Sstevel@tonic-gate PrivacyFlags |= pv->pv_flag; 27527c478bd9Sstevel@tonic-gate } 27537c478bd9Sstevel@tonic-gate sticky = false; 27547c478bd9Sstevel@tonic-gate break; 27557c478bd9Sstevel@tonic-gate 27567c478bd9Sstevel@tonic-gate case 'P': /* postmaster copy address for returned mail */ 27577c478bd9Sstevel@tonic-gate PostMasterCopy = newstr(val); 27587c478bd9Sstevel@tonic-gate break; 27597c478bd9Sstevel@tonic-gate 27607c478bd9Sstevel@tonic-gate case 'q': /* slope of queue only function */ 27617c478bd9Sstevel@tonic-gate QueueFactor = atoi(val); 27627c478bd9Sstevel@tonic-gate break; 27637c478bd9Sstevel@tonic-gate 27647c478bd9Sstevel@tonic-gate case 'Q': /* queue directory */ 27657c478bd9Sstevel@tonic-gate if (val[0] == '\0') 27667c478bd9Sstevel@tonic-gate { 27677c478bd9Sstevel@tonic-gate QueueDir = "mqueue"; 27687c478bd9Sstevel@tonic-gate } 27697c478bd9Sstevel@tonic-gate else 27707c478bd9Sstevel@tonic-gate { 27717c478bd9Sstevel@tonic-gate QueueDir = newstr(val); 27727c478bd9Sstevel@tonic-gate } 27737c478bd9Sstevel@tonic-gate if (RealUid != 0 && !safe) 27747c478bd9Sstevel@tonic-gate Warn_Q_option = true; 27757c478bd9Sstevel@tonic-gate break; 27767c478bd9Sstevel@tonic-gate 27777c478bd9Sstevel@tonic-gate case 'R': /* don't prune routes */ 27787c478bd9Sstevel@tonic-gate DontPruneRoutes = atobool(val); 27797c478bd9Sstevel@tonic-gate break; 27807c478bd9Sstevel@tonic-gate 27817c478bd9Sstevel@tonic-gate case 'r': /* read timeout */ 27827c478bd9Sstevel@tonic-gate if (subopt == NULL) 27837c478bd9Sstevel@tonic-gate inittimeouts(val, sticky); 27847c478bd9Sstevel@tonic-gate else 27857c478bd9Sstevel@tonic-gate settimeout(subopt, val, sticky); 27867c478bd9Sstevel@tonic-gate break; 27877c478bd9Sstevel@tonic-gate 27887c478bd9Sstevel@tonic-gate case 'S': /* status file */ 27897c478bd9Sstevel@tonic-gate if (val[0] == '\0') 27907c478bd9Sstevel@tonic-gate { 27917c478bd9Sstevel@tonic-gate SET_OPT_DEFAULT(StatFile, "statistics"); 27927c478bd9Sstevel@tonic-gate } 27937c478bd9Sstevel@tonic-gate else 27947c478bd9Sstevel@tonic-gate { 27957c478bd9Sstevel@tonic-gate CANONIFY(val); 27967c478bd9Sstevel@tonic-gate StatFile = newstr(val); 27977c478bd9Sstevel@tonic-gate } 27987c478bd9Sstevel@tonic-gate break; 27997c478bd9Sstevel@tonic-gate 28007c478bd9Sstevel@tonic-gate case 's': /* be super safe, even if expensive */ 28017c478bd9Sstevel@tonic-gate if (tolower(*val) == 'i') 28027c478bd9Sstevel@tonic-gate SuperSafe = SAFE_INTERACTIVE; 28037c478bd9Sstevel@tonic-gate else if (tolower(*val) == 'p') 28047c478bd9Sstevel@tonic-gate #if MILTER 28057c478bd9Sstevel@tonic-gate SuperSafe = SAFE_REALLY_POSTMILTER; 28067c478bd9Sstevel@tonic-gate #else /* MILTER */ 28077c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 28087c478bd9Sstevel@tonic-gate "Warning: SuperSafe=PostMilter requires Milter support (-DMILTER)\n"); 28097c478bd9Sstevel@tonic-gate #endif /* MILTER */ 28107c478bd9Sstevel@tonic-gate else 28117c478bd9Sstevel@tonic-gate SuperSafe = atobool(val) ? SAFE_REALLY : SAFE_NO; 28127c478bd9Sstevel@tonic-gate break; 28137c478bd9Sstevel@tonic-gate 28147c478bd9Sstevel@tonic-gate case 'T': /* queue timeout */ 28157c478bd9Sstevel@tonic-gate p = strchr(val, '/'); 28167c478bd9Sstevel@tonic-gate if (p != NULL) 28177c478bd9Sstevel@tonic-gate { 28187c478bd9Sstevel@tonic-gate *p++ = '\0'; 28197c478bd9Sstevel@tonic-gate settimeout("queuewarn", p, sticky); 28207c478bd9Sstevel@tonic-gate } 28217c478bd9Sstevel@tonic-gate settimeout("queuereturn", val, sticky); 28227c478bd9Sstevel@tonic-gate break; 28237c478bd9Sstevel@tonic-gate 28247c478bd9Sstevel@tonic-gate case 't': /* time zone name */ 28257c478bd9Sstevel@tonic-gate TimeZoneSpec = newstr(val); 28267c478bd9Sstevel@tonic-gate break; 28277c478bd9Sstevel@tonic-gate 28287c478bd9Sstevel@tonic-gate case 'U': /* location of user database */ 28297c478bd9Sstevel@tonic-gate UdbSpec = newstr(val); 28307c478bd9Sstevel@tonic-gate break; 28317c478bd9Sstevel@tonic-gate 28327c478bd9Sstevel@tonic-gate case 'u': /* set default uid */ 28337c478bd9Sstevel@tonic-gate for (p = val; *p != '\0'; p++) 28347c478bd9Sstevel@tonic-gate { 28357c478bd9Sstevel@tonic-gate # if _FFR_DOTTED_USERNAMES 28367c478bd9Sstevel@tonic-gate if (*p == '/' || *p == ':') 28377c478bd9Sstevel@tonic-gate # else /* _FFR_DOTTED_USERNAMES */ 28387c478bd9Sstevel@tonic-gate if (*p == '.' || *p == '/' || *p == ':') 28397c478bd9Sstevel@tonic-gate # endif /* _FFR_DOTTED_USERNAMES */ 28407c478bd9Sstevel@tonic-gate { 28417c478bd9Sstevel@tonic-gate *p++ = '\0'; 28427c478bd9Sstevel@tonic-gate break; 28437c478bd9Sstevel@tonic-gate } 28447c478bd9Sstevel@tonic-gate } 28457c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 28467c478bd9Sstevel@tonic-gate { 28477c478bd9Sstevel@tonic-gate DefUid = atoi(val); 28487c478bd9Sstevel@tonic-gate setdefuser(); 28497c478bd9Sstevel@tonic-gate } 28507c478bd9Sstevel@tonic-gate else 28517c478bd9Sstevel@tonic-gate { 28527c478bd9Sstevel@tonic-gate register struct passwd *pw; 28537c478bd9Sstevel@tonic-gate 28547c478bd9Sstevel@tonic-gate DefUid = -1; 28557c478bd9Sstevel@tonic-gate pw = sm_getpwnam(val); 28567c478bd9Sstevel@tonic-gate if (pw == NULL) 28577c478bd9Sstevel@tonic-gate { 28587c478bd9Sstevel@tonic-gate syserr("readcf: option u: unknown user %s", val); 28597c478bd9Sstevel@tonic-gate break; 28607c478bd9Sstevel@tonic-gate } 28617c478bd9Sstevel@tonic-gate else 28627c478bd9Sstevel@tonic-gate { 28637c478bd9Sstevel@tonic-gate DefUid = pw->pw_uid; 28647c478bd9Sstevel@tonic-gate DefGid = pw->pw_gid; 28657c478bd9Sstevel@tonic-gate DefUser = newstr(pw->pw_name); 28667c478bd9Sstevel@tonic-gate } 28677c478bd9Sstevel@tonic-gate } 28687c478bd9Sstevel@tonic-gate 28697c478bd9Sstevel@tonic-gate # ifdef UID_MAX 28707c478bd9Sstevel@tonic-gate if (DefUid > UID_MAX) 28717c478bd9Sstevel@tonic-gate { 28727c478bd9Sstevel@tonic-gate syserr("readcf: option u: uid value (%ld) > UID_MAX (%ld); ignored", 28737c478bd9Sstevel@tonic-gate (long)DefUid, (long)UID_MAX); 28747c478bd9Sstevel@tonic-gate break; 28757c478bd9Sstevel@tonic-gate } 28767c478bd9Sstevel@tonic-gate # endif /* UID_MAX */ 28777c478bd9Sstevel@tonic-gate 28787c478bd9Sstevel@tonic-gate /* handle the group if it is there */ 28797c478bd9Sstevel@tonic-gate if (*p == '\0') 28807c478bd9Sstevel@tonic-gate break; 28817c478bd9Sstevel@tonic-gate val = p; 28827c478bd9Sstevel@tonic-gate goto g_opt; 28837c478bd9Sstevel@tonic-gate 28847c478bd9Sstevel@tonic-gate case 'V': /* fallback MX host */ 28857c478bd9Sstevel@tonic-gate if (val[0] != '\0') 28867c478bd9Sstevel@tonic-gate FallbackMX = newstr(val); 28877c478bd9Sstevel@tonic-gate break; 28887c478bd9Sstevel@tonic-gate 28897c478bd9Sstevel@tonic-gate case 'v': /* run in verbose mode */ 28907c478bd9Sstevel@tonic-gate Verbose = atobool(val) ? 1 : 0; 28917c478bd9Sstevel@tonic-gate break; 28927c478bd9Sstevel@tonic-gate 28937c478bd9Sstevel@tonic-gate case 'w': /* if we are best MX, try host directly */ 28947c478bd9Sstevel@tonic-gate TryNullMXList = atobool(val); 28957c478bd9Sstevel@tonic-gate break; 28967c478bd9Sstevel@tonic-gate 28977c478bd9Sstevel@tonic-gate /* 'W' available -- was wizard password */ 28987c478bd9Sstevel@tonic-gate 28997c478bd9Sstevel@tonic-gate case 'x': /* load avg at which to auto-queue msgs */ 29007c478bd9Sstevel@tonic-gate QueueLA = atoi(val); 29017c478bd9Sstevel@tonic-gate break; 29027c478bd9Sstevel@tonic-gate 29037c478bd9Sstevel@tonic-gate case 'X': /* load avg at which to auto-reject connections */ 29047c478bd9Sstevel@tonic-gate RefuseLA = atoi(val); 29057c478bd9Sstevel@tonic-gate break; 29067c478bd9Sstevel@tonic-gate 29077c478bd9Sstevel@tonic-gate case O_DELAY_LA: /* load avg at which to delay connections */ 29087c478bd9Sstevel@tonic-gate DelayLA = atoi(val); 29097c478bd9Sstevel@tonic-gate break; 29107c478bd9Sstevel@tonic-gate 29117c478bd9Sstevel@tonic-gate case 'y': /* work recipient factor */ 29127c478bd9Sstevel@tonic-gate WkRecipFact = atoi(val); 29137c478bd9Sstevel@tonic-gate break; 29147c478bd9Sstevel@tonic-gate 29157c478bd9Sstevel@tonic-gate case 'Y': /* fork jobs during queue runs */ 29167c478bd9Sstevel@tonic-gate ForkQueueRuns = atobool(val); 29177c478bd9Sstevel@tonic-gate break; 29187c478bd9Sstevel@tonic-gate 29197c478bd9Sstevel@tonic-gate case 'z': /* work message class factor */ 29207c478bd9Sstevel@tonic-gate WkClassFact = atoi(val); 29217c478bd9Sstevel@tonic-gate break; 29227c478bd9Sstevel@tonic-gate 29237c478bd9Sstevel@tonic-gate case 'Z': /* work time factor */ 29247c478bd9Sstevel@tonic-gate WkTimeFact = atoi(val); 29257c478bd9Sstevel@tonic-gate break; 29267c478bd9Sstevel@tonic-gate 29277c478bd9Sstevel@tonic-gate 29287c478bd9Sstevel@tonic-gate #if _FFR_QUEUE_GROUP_SORTORDER 29297c478bd9Sstevel@tonic-gate /* coordinate this with makequeue() */ 29307c478bd9Sstevel@tonic-gate #endif /* _FFR_QUEUE_GROUP_SORTORDER */ 29317c478bd9Sstevel@tonic-gate case O_QUEUESORTORD: /* queue sorting order */ 29327c478bd9Sstevel@tonic-gate switch (*val) 29337c478bd9Sstevel@tonic-gate { 29347c478bd9Sstevel@tonic-gate case 'f': /* File Name */ 29357c478bd9Sstevel@tonic-gate case 'F': 29367c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYFILENAME; 29377c478bd9Sstevel@tonic-gate break; 29387c478bd9Sstevel@tonic-gate 29397c478bd9Sstevel@tonic-gate case 'h': /* Host first */ 29407c478bd9Sstevel@tonic-gate case 'H': 29417c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYHOST; 29427c478bd9Sstevel@tonic-gate break; 29437c478bd9Sstevel@tonic-gate 29447c478bd9Sstevel@tonic-gate case 'm': /* Modification time */ 29457c478bd9Sstevel@tonic-gate case 'M': 29467c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYMODTIME; 29477c478bd9Sstevel@tonic-gate break; 29487c478bd9Sstevel@tonic-gate 29497c478bd9Sstevel@tonic-gate case 'p': /* Priority order */ 29507c478bd9Sstevel@tonic-gate case 'P': 29517c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYPRIORITY; 29527c478bd9Sstevel@tonic-gate break; 29537c478bd9Sstevel@tonic-gate 29547c478bd9Sstevel@tonic-gate case 't': /* Submission time */ 29557c478bd9Sstevel@tonic-gate case 'T': 29567c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYTIME; 29577c478bd9Sstevel@tonic-gate break; 29587c478bd9Sstevel@tonic-gate 29597c478bd9Sstevel@tonic-gate case 'r': /* Random */ 29607c478bd9Sstevel@tonic-gate case 'R': 29617c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_RANDOM; 29627c478bd9Sstevel@tonic-gate break; 29637c478bd9Sstevel@tonic-gate 29647c478bd9Sstevel@tonic-gate #if _FFR_RHS 29657c478bd9Sstevel@tonic-gate case 's': /* Shuffled host name */ 29667c478bd9Sstevel@tonic-gate case 'S': 29677c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_BYSHUFFLE; 29687c478bd9Sstevel@tonic-gate break; 29697c478bd9Sstevel@tonic-gate #endif /* _FFR_RHS */ 29707c478bd9Sstevel@tonic-gate 29717c478bd9Sstevel@tonic-gate case 'n': /* none */ 29727c478bd9Sstevel@tonic-gate case 'N': 29737c478bd9Sstevel@tonic-gate QueueSortOrder = QSO_NONE; 29747c478bd9Sstevel@tonic-gate break; 29757c478bd9Sstevel@tonic-gate 29767c478bd9Sstevel@tonic-gate default: 29777c478bd9Sstevel@tonic-gate syserr("Invalid queue sort order \"%s\"", val); 29787c478bd9Sstevel@tonic-gate } 29797c478bd9Sstevel@tonic-gate break; 29807c478bd9Sstevel@tonic-gate 29817c478bd9Sstevel@tonic-gate case O_HOSTSFILE: /* pathname of /etc/hosts file */ 29827c478bd9Sstevel@tonic-gate CANONIFY(val); 29837c478bd9Sstevel@tonic-gate HostsFile = newstr(val); 29847c478bd9Sstevel@tonic-gate break; 29857c478bd9Sstevel@tonic-gate 29867c478bd9Sstevel@tonic-gate case O_MQA: /* minimum queue age between deliveries */ 29877c478bd9Sstevel@tonic-gate MinQueueAge = convtime(val, 'm'); 29887c478bd9Sstevel@tonic-gate break; 29897c478bd9Sstevel@tonic-gate 29907c478bd9Sstevel@tonic-gate case O_DEFCHARSET: /* default character set for mimefying */ 29917c478bd9Sstevel@tonic-gate DefaultCharSet = newstr(denlstring(val, true, true)); 29927c478bd9Sstevel@tonic-gate break; 29937c478bd9Sstevel@tonic-gate 29947c478bd9Sstevel@tonic-gate case O_SSFILE: /* service switch file */ 29957c478bd9Sstevel@tonic-gate CANONIFY(val); 29967c478bd9Sstevel@tonic-gate ServiceSwitchFile = newstr(val); 29977c478bd9Sstevel@tonic-gate break; 29987c478bd9Sstevel@tonic-gate 29997c478bd9Sstevel@tonic-gate case O_DIALDELAY: /* delay for dial-on-demand operation */ 30007c478bd9Sstevel@tonic-gate DialDelay = convtime(val, 's'); 30017c478bd9Sstevel@tonic-gate break; 30027c478bd9Sstevel@tonic-gate 30037c478bd9Sstevel@tonic-gate case O_NORCPTACTION: /* what to do if no recipient */ 30047c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, "none") == 0) 30057c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_NO_ACTION; 30067c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-to") == 0) 30077c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_TO; 30087c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-apparently-to") == 0) 30097c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_APPARENTLY_TO; 30107c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-bcc") == 0) 30117c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_BCC; 30127c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(val, "add-to-undisclosed") == 0) 30137c478bd9Sstevel@tonic-gate NoRecipientAction = NRA_ADD_TO_UNDISCLOSED; 30147c478bd9Sstevel@tonic-gate else 30157c478bd9Sstevel@tonic-gate syserr("Invalid NoRecipientAction: %s", val); 30167c478bd9Sstevel@tonic-gate break; 30177c478bd9Sstevel@tonic-gate 30187c478bd9Sstevel@tonic-gate case O_SAFEFILEENV: /* chroot() environ for writing to files */ 30197c478bd9Sstevel@tonic-gate if (*val == '\0') 30207c478bd9Sstevel@tonic-gate break; 30217c478bd9Sstevel@tonic-gate 30227c478bd9Sstevel@tonic-gate /* strip trailing slashes */ 30237c478bd9Sstevel@tonic-gate p = val + strlen(val) - 1; 30247c478bd9Sstevel@tonic-gate while (p >= val && *p == '/') 30257c478bd9Sstevel@tonic-gate *p-- = '\0'; 30267c478bd9Sstevel@tonic-gate 30277c478bd9Sstevel@tonic-gate if (*val == '\0') 30287c478bd9Sstevel@tonic-gate break; 30297c478bd9Sstevel@tonic-gate 30307c478bd9Sstevel@tonic-gate SafeFileEnv = newstr(val); 30317c478bd9Sstevel@tonic-gate break; 30327c478bd9Sstevel@tonic-gate 30337c478bd9Sstevel@tonic-gate case O_MAXMSGSIZE: /* maximum message size */ 30347c478bd9Sstevel@tonic-gate MaxMessageSize = atol(val); 30357c478bd9Sstevel@tonic-gate break; 30367c478bd9Sstevel@tonic-gate 30377c478bd9Sstevel@tonic-gate case O_COLONOKINADDR: /* old style handling of colon addresses */ 30387c478bd9Sstevel@tonic-gate ColonOkInAddr = atobool(val); 30397c478bd9Sstevel@tonic-gate break; 30407c478bd9Sstevel@tonic-gate 30417c478bd9Sstevel@tonic-gate case O_MAXQUEUERUN: /* max # of jobs in a single queue run */ 30427c478bd9Sstevel@tonic-gate MaxQueueRun = atoi(val); 30437c478bd9Sstevel@tonic-gate break; 30447c478bd9Sstevel@tonic-gate 30457c478bd9Sstevel@tonic-gate case O_MAXCHILDREN: /* max # of children of daemon */ 30467c478bd9Sstevel@tonic-gate MaxChildren = atoi(val); 30477c478bd9Sstevel@tonic-gate break; 30487c478bd9Sstevel@tonic-gate 30497c478bd9Sstevel@tonic-gate case O_MAXQUEUECHILDREN: /* max # of children of daemon */ 30507c478bd9Sstevel@tonic-gate MaxQueueChildren = atoi(val); 30517c478bd9Sstevel@tonic-gate break; 30527c478bd9Sstevel@tonic-gate 30537c478bd9Sstevel@tonic-gate case O_MAXRUNNERSPERQUEUE: /* max # runners in a queue group */ 30547c478bd9Sstevel@tonic-gate MaxRunnersPerQueue = atoi(val); 30557c478bd9Sstevel@tonic-gate break; 30567c478bd9Sstevel@tonic-gate 30577c478bd9Sstevel@tonic-gate case O_NICEQUEUERUN: /* nice queue runs */ 30587c478bd9Sstevel@tonic-gate #if !HASNICE 30597c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 30607c478bd9Sstevel@tonic-gate "Warning: NiceQueueRun set on system that doesn't support nice()\n"); 30617c478bd9Sstevel@tonic-gate #endif /* !HASNICE */ 30627c478bd9Sstevel@tonic-gate 30637c478bd9Sstevel@tonic-gate /* XXX do we want to check the range? > 0 ? */ 30647c478bd9Sstevel@tonic-gate NiceQueueRun = atoi(val); 30657c478bd9Sstevel@tonic-gate break; 30667c478bd9Sstevel@tonic-gate 30677c478bd9Sstevel@tonic-gate case O_SHMKEY: /* shared memory key */ 30687c478bd9Sstevel@tonic-gate #if SM_CONF_SHM 30697c478bd9Sstevel@tonic-gate ShmKey = atol(val); 30707c478bd9Sstevel@tonic-gate #else /* SM_CONF_SHM */ 30717c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 30727c478bd9Sstevel@tonic-gate "Warning: Option: %s requires shared memory support (-DSM_CONF_SHM)\n", 30737c478bd9Sstevel@tonic-gate OPTNAME); 30747c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SHM */ 30757c478bd9Sstevel@tonic-gate break; 30767c478bd9Sstevel@tonic-gate 30777c478bd9Sstevel@tonic-gate case O_SHMKEYFILE: /* shared memory key file */ 30787c478bd9Sstevel@tonic-gate #if SM_CONF_SHM 30797c478bd9Sstevel@tonic-gate SET_STRING_EXP(ShmKeyFile); 30807c478bd9Sstevel@tonic-gate #else /* SM_CONF_SHM */ 30817c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 30827c478bd9Sstevel@tonic-gate "Warning: Option: %s requires shared memory support (-DSM_CONF_SHM)\n", 30837c478bd9Sstevel@tonic-gate OPTNAME); 30847c478bd9Sstevel@tonic-gate break; 30857c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SHM */ 30867c478bd9Sstevel@tonic-gate 30877c478bd9Sstevel@tonic-gate #if _FFR_MAX_FORWARD_ENTRIES 30887c478bd9Sstevel@tonic-gate case O_MAXFORWARD: /* max # of forward entries */ 30897c478bd9Sstevel@tonic-gate MaxForwardEntries = atoi(val); 30907c478bd9Sstevel@tonic-gate break; 30917c478bd9Sstevel@tonic-gate #endif /* _FFR_MAX_FORWARD_ENTRIES */ 30927c478bd9Sstevel@tonic-gate 30937c478bd9Sstevel@tonic-gate case O_KEEPCNAMES: /* don't expand CNAME records */ 30947c478bd9Sstevel@tonic-gate DontExpandCnames = atobool(val); 30957c478bd9Sstevel@tonic-gate break; 30967c478bd9Sstevel@tonic-gate 30977c478bd9Sstevel@tonic-gate case O_MUSTQUOTE: /* must quote these characters in phrases */ 3098*058561cbSjbeck (void) sm_strlcpy(buf, "@,;:\\()[]", sizeof(buf)); 3099*058561cbSjbeck if (strlen(val) < sizeof(buf) - 10) 3100*058561cbSjbeck (void) sm_strlcat(buf, val, sizeof(buf)); 31017c478bd9Sstevel@tonic-gate else 31027c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 31037c478bd9Sstevel@tonic-gate "Warning: MustQuoteChars too long, ignored.\n"); 31047c478bd9Sstevel@tonic-gate MustQuoteChars = newstr(buf); 31057c478bd9Sstevel@tonic-gate break; 31067c478bd9Sstevel@tonic-gate 31077c478bd9Sstevel@tonic-gate case O_SMTPGREETING: /* SMTP greeting message (old $e macro) */ 31087c478bd9Sstevel@tonic-gate SmtpGreeting = newstr(munchstring(val, NULL, '\0')); 31097c478bd9Sstevel@tonic-gate break; 31107c478bd9Sstevel@tonic-gate 31117c478bd9Sstevel@tonic-gate case O_UNIXFROM: /* UNIX From_ line (old $l macro) */ 31127c478bd9Sstevel@tonic-gate UnixFromLine = newstr(munchstring(val, NULL, '\0')); 31137c478bd9Sstevel@tonic-gate break; 31147c478bd9Sstevel@tonic-gate 31157c478bd9Sstevel@tonic-gate case O_OPCHARS: /* operator characters (old $o macro) */ 31167c478bd9Sstevel@tonic-gate if (OperatorChars != NULL) 31177c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 31187c478bd9Sstevel@tonic-gate "Warning: OperatorChars is being redefined.\n It should only be set before ruleset definitions.\n"); 31197c478bd9Sstevel@tonic-gate OperatorChars = newstr(munchstring(val, NULL, '\0')); 31207c478bd9Sstevel@tonic-gate break; 31217c478bd9Sstevel@tonic-gate 31227c478bd9Sstevel@tonic-gate case O_DONTINITGRPS: /* don't call initgroups(3) */ 31237c478bd9Sstevel@tonic-gate DontInitGroups = atobool(val); 31247c478bd9Sstevel@tonic-gate break; 31257c478bd9Sstevel@tonic-gate 31267c478bd9Sstevel@tonic-gate case O_SLFH: /* make sure from fits on one line */ 31277c478bd9Sstevel@tonic-gate SingleLineFromHeader = atobool(val); 31287c478bd9Sstevel@tonic-gate break; 31297c478bd9Sstevel@tonic-gate 31307c478bd9Sstevel@tonic-gate case O_ABH: /* allow HELO commands with syntax errors */ 31317c478bd9Sstevel@tonic-gate AllowBogusHELO = atobool(val); 31327c478bd9Sstevel@tonic-gate break; 31337c478bd9Sstevel@tonic-gate 31347c478bd9Sstevel@tonic-gate case O_CONNTHROT: /* connection rate throttle */ 31357c478bd9Sstevel@tonic-gate ConnRateThrottle = atoi(val); 31367c478bd9Sstevel@tonic-gate break; 31377c478bd9Sstevel@tonic-gate 31387c478bd9Sstevel@tonic-gate case O_UGW: /* group writable files are unsafe */ 31397c478bd9Sstevel@tonic-gate if (!atobool(val)) 31407c478bd9Sstevel@tonic-gate { 31417c478bd9Sstevel@tonic-gate setbitn(DBS_GROUPWRITABLEFORWARDFILESAFE, 31427c478bd9Sstevel@tonic-gate DontBlameSendmail); 31437c478bd9Sstevel@tonic-gate setbitn(DBS_GROUPWRITABLEINCLUDEFILESAFE, 31447c478bd9Sstevel@tonic-gate DontBlameSendmail); 31457c478bd9Sstevel@tonic-gate } 31467c478bd9Sstevel@tonic-gate break; 31477c478bd9Sstevel@tonic-gate 31487c478bd9Sstevel@tonic-gate case O_DBLBOUNCE: /* address to which to send double bounces */ 31497c478bd9Sstevel@tonic-gate DoubleBounceAddr = newstr(val); 31507c478bd9Sstevel@tonic-gate break; 31517c478bd9Sstevel@tonic-gate 31527c478bd9Sstevel@tonic-gate case O_HSDIR: /* persistent host status directory */ 31537c478bd9Sstevel@tonic-gate if (val[0] != '\0') 31547c478bd9Sstevel@tonic-gate { 31557c478bd9Sstevel@tonic-gate CANONIFY(val); 31567c478bd9Sstevel@tonic-gate HostStatDir = newstr(val); 31577c478bd9Sstevel@tonic-gate } 31587c478bd9Sstevel@tonic-gate break; 31597c478bd9Sstevel@tonic-gate 31607c478bd9Sstevel@tonic-gate case O_SINGTHREAD: /* single thread deliveries (requires hsdir) */ 31617c478bd9Sstevel@tonic-gate SingleThreadDelivery = atobool(val); 31627c478bd9Sstevel@tonic-gate break; 31637c478bd9Sstevel@tonic-gate 31647c478bd9Sstevel@tonic-gate case O_RUNASUSER: /* run bulk of code as this user */ 31657c478bd9Sstevel@tonic-gate for (p = val; *p != '\0'; p++) 31667c478bd9Sstevel@tonic-gate { 31677c478bd9Sstevel@tonic-gate # if _FFR_DOTTED_USERNAMES 31687c478bd9Sstevel@tonic-gate if (*p == '/' || *p == ':') 31697c478bd9Sstevel@tonic-gate # else /* _FFR_DOTTED_USERNAMES */ 31707c478bd9Sstevel@tonic-gate if (*p == '.' || *p == '/' || *p == ':') 31717c478bd9Sstevel@tonic-gate # endif /* _FFR_DOTTED_USERNAMES */ 31727c478bd9Sstevel@tonic-gate { 31737c478bd9Sstevel@tonic-gate *p++ = '\0'; 31747c478bd9Sstevel@tonic-gate break; 31757c478bd9Sstevel@tonic-gate } 31767c478bd9Sstevel@tonic-gate } 31777c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 31787c478bd9Sstevel@tonic-gate { 31797c478bd9Sstevel@tonic-gate if (can_setuid) 31807c478bd9Sstevel@tonic-gate RunAsUid = atoi(val); 31817c478bd9Sstevel@tonic-gate } 31827c478bd9Sstevel@tonic-gate else 31837c478bd9Sstevel@tonic-gate { 31847c478bd9Sstevel@tonic-gate register struct passwd *pw; 31857c478bd9Sstevel@tonic-gate 31867c478bd9Sstevel@tonic-gate pw = sm_getpwnam(val); 31877c478bd9Sstevel@tonic-gate if (pw == NULL) 31887c478bd9Sstevel@tonic-gate { 31897c478bd9Sstevel@tonic-gate syserr("readcf: option RunAsUser: unknown user %s", val); 31907c478bd9Sstevel@tonic-gate break; 31917c478bd9Sstevel@tonic-gate } 31927c478bd9Sstevel@tonic-gate else if (can_setuid) 31937c478bd9Sstevel@tonic-gate { 31947c478bd9Sstevel@tonic-gate if (*p == '\0') 31957c478bd9Sstevel@tonic-gate RunAsUserName = newstr(val); 31967c478bd9Sstevel@tonic-gate RunAsUid = pw->pw_uid; 31977c478bd9Sstevel@tonic-gate RunAsGid = pw->pw_gid; 31987c478bd9Sstevel@tonic-gate } 31997c478bd9Sstevel@tonic-gate else if (EffGid == pw->pw_gid) 32007c478bd9Sstevel@tonic-gate RunAsGid = pw->pw_gid; 32017c478bd9Sstevel@tonic-gate else if (UseMSP && *p == '\0') 32027c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 32037c478bd9Sstevel@tonic-gate "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n", 32047c478bd9Sstevel@tonic-gate (int) EffGid, 32057c478bd9Sstevel@tonic-gate (int) pw->pw_gid); 32067c478bd9Sstevel@tonic-gate } 32077c478bd9Sstevel@tonic-gate # ifdef UID_MAX 32087c478bd9Sstevel@tonic-gate if (RunAsUid > UID_MAX) 32097c478bd9Sstevel@tonic-gate { 32107c478bd9Sstevel@tonic-gate syserr("readcf: option RunAsUser: uid value (%ld) > UID_MAX (%ld); ignored", 32117c478bd9Sstevel@tonic-gate (long) RunAsUid, (long) UID_MAX); 32127c478bd9Sstevel@tonic-gate break; 32137c478bd9Sstevel@tonic-gate } 32147c478bd9Sstevel@tonic-gate # endif /* UID_MAX */ 32157c478bd9Sstevel@tonic-gate if (*p != '\0') 32167c478bd9Sstevel@tonic-gate { 32177c478bd9Sstevel@tonic-gate if (isascii(*p) && isdigit(*p)) 32187c478bd9Sstevel@tonic-gate { 32197c478bd9Sstevel@tonic-gate gid_t runasgid; 32207c478bd9Sstevel@tonic-gate 32217c478bd9Sstevel@tonic-gate runasgid = (gid_t) atoi(p); 32227c478bd9Sstevel@tonic-gate if (can_setuid || EffGid == runasgid) 32237c478bd9Sstevel@tonic-gate RunAsGid = runasgid; 32247c478bd9Sstevel@tonic-gate else if (UseMSP) 32257c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, 32267c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 32277c478bd9Sstevel@tonic-gate "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n", 32287c478bd9Sstevel@tonic-gate (int) EffGid, 32297c478bd9Sstevel@tonic-gate (int) runasgid); 32307c478bd9Sstevel@tonic-gate } 32317c478bd9Sstevel@tonic-gate else 32327c478bd9Sstevel@tonic-gate { 32337c478bd9Sstevel@tonic-gate register struct group *gr; 32347c478bd9Sstevel@tonic-gate 32357c478bd9Sstevel@tonic-gate gr = getgrnam(p); 32367c478bd9Sstevel@tonic-gate if (gr == NULL) 32377c478bd9Sstevel@tonic-gate syserr("readcf: option RunAsUser: unknown group %s", 32387c478bd9Sstevel@tonic-gate p); 32397c478bd9Sstevel@tonic-gate else if (can_setuid || EffGid == gr->gr_gid) 32407c478bd9Sstevel@tonic-gate RunAsGid = gr->gr_gid; 32417c478bd9Sstevel@tonic-gate else if (UseMSP) 32427c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, 32437c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 32447c478bd9Sstevel@tonic-gate "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n", 32457c478bd9Sstevel@tonic-gate (int) EffGid, 32467c478bd9Sstevel@tonic-gate (int) gr->gr_gid); 32477c478bd9Sstevel@tonic-gate } 32487c478bd9Sstevel@tonic-gate } 32497c478bd9Sstevel@tonic-gate if (tTd(47, 5)) 32507c478bd9Sstevel@tonic-gate sm_dprintf("readcf: RunAsUser = %d:%d\n", 32517c478bd9Sstevel@tonic-gate (int) RunAsUid, (int) RunAsGid); 32527c478bd9Sstevel@tonic-gate break; 32537c478bd9Sstevel@tonic-gate 32547c478bd9Sstevel@tonic-gate case O_DSN_RRT: 32557c478bd9Sstevel@tonic-gate RrtImpliesDsn = atobool(val); 32567c478bd9Sstevel@tonic-gate break; 32577c478bd9Sstevel@tonic-gate 32587c478bd9Sstevel@tonic-gate case O_PIDFILE: 32597c478bd9Sstevel@tonic-gate PSTRSET(PidFile, val); 32607c478bd9Sstevel@tonic-gate break; 32617c478bd9Sstevel@tonic-gate 32627c478bd9Sstevel@tonic-gate case O_DONTBLAMESENDMAIL: 32637c478bd9Sstevel@tonic-gate p = val; 32647c478bd9Sstevel@tonic-gate for (;;) 32657c478bd9Sstevel@tonic-gate { 32667c478bd9Sstevel@tonic-gate register struct dbsval *dbs; 32677c478bd9Sstevel@tonic-gate extern struct dbsval DontBlameSendmailValues[]; 32687c478bd9Sstevel@tonic-gate 32697c478bd9Sstevel@tonic-gate while (isascii(*p) && (isspace(*p) || ispunct(*p))) 32707c478bd9Sstevel@tonic-gate p++; 32717c478bd9Sstevel@tonic-gate if (*p == '\0') 32727c478bd9Sstevel@tonic-gate break; 32737c478bd9Sstevel@tonic-gate val = p; 32747c478bd9Sstevel@tonic-gate while (isascii(*p) && isalnum(*p)) 32757c478bd9Sstevel@tonic-gate p++; 32767c478bd9Sstevel@tonic-gate if (*p != '\0') 32777c478bd9Sstevel@tonic-gate *p++ = '\0'; 32787c478bd9Sstevel@tonic-gate 32797c478bd9Sstevel@tonic-gate for (dbs = DontBlameSendmailValues; 32807c478bd9Sstevel@tonic-gate dbs->dbs_name != NULL; dbs++) 32817c478bd9Sstevel@tonic-gate { 32827c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, dbs->dbs_name) == 0) 32837c478bd9Sstevel@tonic-gate break; 32847c478bd9Sstevel@tonic-gate } 32857c478bd9Sstevel@tonic-gate if (dbs->dbs_name == NULL) 32867c478bd9Sstevel@tonic-gate syserr("readcf: DontBlameSendmail option: %s unrecognized", val); 32877c478bd9Sstevel@tonic-gate else if (dbs->dbs_flag == DBS_SAFE) 32887c478bd9Sstevel@tonic-gate clrbitmap(DontBlameSendmail); 32897c478bd9Sstevel@tonic-gate else 32907c478bd9Sstevel@tonic-gate setbitn(dbs->dbs_flag, DontBlameSendmail); 32917c478bd9Sstevel@tonic-gate } 32927c478bd9Sstevel@tonic-gate sticky = false; 32937c478bd9Sstevel@tonic-gate break; 32947c478bd9Sstevel@tonic-gate 32957c478bd9Sstevel@tonic-gate case O_DPI: 32967c478bd9Sstevel@tonic-gate if (sm_strcasecmp(val, "loopback") == 0) 32977c478bd9Sstevel@tonic-gate DontProbeInterfaces = DPI_SKIPLOOPBACK; 32987c478bd9Sstevel@tonic-gate else if (atobool(val)) 32997c478bd9Sstevel@tonic-gate DontProbeInterfaces = DPI_PROBENONE; 33007c478bd9Sstevel@tonic-gate else 33017c478bd9Sstevel@tonic-gate DontProbeInterfaces = DPI_PROBEALL; 33027c478bd9Sstevel@tonic-gate break; 33037c478bd9Sstevel@tonic-gate 33047c478bd9Sstevel@tonic-gate case O_MAXRCPT: 33057c478bd9Sstevel@tonic-gate MaxRcptPerMsg = atoi(val); 33067c478bd9Sstevel@tonic-gate break; 33077c478bd9Sstevel@tonic-gate 33087c478bd9Sstevel@tonic-gate case O_RCPTTHROT: 33097c478bd9Sstevel@tonic-gate BadRcptThrottle = atoi(val); 33107c478bd9Sstevel@tonic-gate break; 33117c478bd9Sstevel@tonic-gate 33127c478bd9Sstevel@tonic-gate case O_DEADLETTER: 33137c478bd9Sstevel@tonic-gate CANONIFY(val); 33147c478bd9Sstevel@tonic-gate PSTRSET(DeadLetterDrop, val); 33157c478bd9Sstevel@tonic-gate break; 33167c478bd9Sstevel@tonic-gate 33177c478bd9Sstevel@tonic-gate #if _FFR_DONTLOCKFILESFORREAD_OPTION 33187c478bd9Sstevel@tonic-gate case O_DONTLOCK: 33197c478bd9Sstevel@tonic-gate DontLockReadFiles = atobool(val); 33207c478bd9Sstevel@tonic-gate break; 33217c478bd9Sstevel@tonic-gate #endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */ 33227c478bd9Sstevel@tonic-gate 33237c478bd9Sstevel@tonic-gate case O_MAXALIASRCSN: 33247c478bd9Sstevel@tonic-gate MaxAliasRecursion = atoi(val); 33257c478bd9Sstevel@tonic-gate break; 33267c478bd9Sstevel@tonic-gate 33277c478bd9Sstevel@tonic-gate case O_CNCTONLYTO: 33287c478bd9Sstevel@tonic-gate /* XXX should probably use gethostbyname */ 33297c478bd9Sstevel@tonic-gate #if NETINET || NETINET6 33307c478bd9Sstevel@tonic-gate ConnectOnlyTo.sa.sa_family = AF_UNSPEC; 33317c478bd9Sstevel@tonic-gate # if NETINET6 33327c478bd9Sstevel@tonic-gate if (anynet_pton(AF_INET6, val, 33337c478bd9Sstevel@tonic-gate &ConnectOnlyTo.sin6.sin6_addr) != 1) 33347c478bd9Sstevel@tonic-gate ConnectOnlyTo.sa.sa_family = AF_INET6; 33357c478bd9Sstevel@tonic-gate else 33367c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 33377c478bd9Sstevel@tonic-gate # if NETINET 33387c478bd9Sstevel@tonic-gate { 33397c478bd9Sstevel@tonic-gate ConnectOnlyTo.sin.sin_addr.s_addr = inet_addr(val); 33407c478bd9Sstevel@tonic-gate if (ConnectOnlyTo.sin.sin_addr.s_addr != INADDR_NONE) 33417c478bd9Sstevel@tonic-gate ConnectOnlyTo.sa.sa_family = AF_INET; 33427c478bd9Sstevel@tonic-gate } 33437c478bd9Sstevel@tonic-gate 33447c478bd9Sstevel@tonic-gate # endif /* NETINET */ 33457c478bd9Sstevel@tonic-gate if (ConnectOnlyTo.sa.sa_family == AF_UNSPEC) 33467c478bd9Sstevel@tonic-gate { 33477c478bd9Sstevel@tonic-gate syserr("readcf: option ConnectOnlyTo: invalid IP address %s", 33487c478bd9Sstevel@tonic-gate val); 33497c478bd9Sstevel@tonic-gate break; 33507c478bd9Sstevel@tonic-gate } 33517c478bd9Sstevel@tonic-gate #endif /* NETINET || NETINET6 */ 33527c478bd9Sstevel@tonic-gate break; 33537c478bd9Sstevel@tonic-gate 33547c478bd9Sstevel@tonic-gate case O_TRUSTUSER: 33557c478bd9Sstevel@tonic-gate # if !HASFCHOWN && !defined(_FFR_DROP_TRUSTUSER_WARNING) 33567c478bd9Sstevel@tonic-gate if (!UseMSP) 33577c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 33587c478bd9Sstevel@tonic-gate "readcf: option TrustedUser may cause problems on systems\n which do not support fchown() if UseMSP is not set.\n"); 33597c478bd9Sstevel@tonic-gate # endif /* !HASFCHOWN && !defined(_FFR_DROP_TRUSTUSER_WARNING) */ 33607c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 33617c478bd9Sstevel@tonic-gate TrustedUid = atoi(val); 33627c478bd9Sstevel@tonic-gate else 33637c478bd9Sstevel@tonic-gate { 33647c478bd9Sstevel@tonic-gate register struct passwd *pw; 33657c478bd9Sstevel@tonic-gate 33667c478bd9Sstevel@tonic-gate TrustedUid = 0; 33677c478bd9Sstevel@tonic-gate pw = sm_getpwnam(val); 33687c478bd9Sstevel@tonic-gate if (pw == NULL) 33697c478bd9Sstevel@tonic-gate { 33707c478bd9Sstevel@tonic-gate syserr("readcf: option TrustedUser: unknown user %s", val); 33717c478bd9Sstevel@tonic-gate break; 33727c478bd9Sstevel@tonic-gate } 33737c478bd9Sstevel@tonic-gate else 33747c478bd9Sstevel@tonic-gate TrustedUid = pw->pw_uid; 33757c478bd9Sstevel@tonic-gate } 33767c478bd9Sstevel@tonic-gate 33777c478bd9Sstevel@tonic-gate # ifdef UID_MAX 33787c478bd9Sstevel@tonic-gate if (TrustedUid > UID_MAX) 33797c478bd9Sstevel@tonic-gate { 33807c478bd9Sstevel@tonic-gate syserr("readcf: option TrustedUser: uid value (%ld) > UID_MAX (%ld)", 33817c478bd9Sstevel@tonic-gate (long) TrustedUid, (long) UID_MAX); 33827c478bd9Sstevel@tonic-gate TrustedUid = 0; 33837c478bd9Sstevel@tonic-gate } 33847c478bd9Sstevel@tonic-gate # endif /* UID_MAX */ 33857c478bd9Sstevel@tonic-gate break; 33867c478bd9Sstevel@tonic-gate 33877c478bd9Sstevel@tonic-gate case O_MAXMIMEHDRLEN: 33887c478bd9Sstevel@tonic-gate p = strchr(val, '/'); 33897c478bd9Sstevel@tonic-gate if (p != NULL) 33907c478bd9Sstevel@tonic-gate *p++ = '\0'; 33917c478bd9Sstevel@tonic-gate MaxMimeHeaderLength = atoi(val); 33927c478bd9Sstevel@tonic-gate if (p != NULL && *p != '\0') 33937c478bd9Sstevel@tonic-gate MaxMimeFieldLength = atoi(p); 33947c478bd9Sstevel@tonic-gate else 33957c478bd9Sstevel@tonic-gate MaxMimeFieldLength = MaxMimeHeaderLength / 2; 33967c478bd9Sstevel@tonic-gate 33977c478bd9Sstevel@tonic-gate if (MaxMimeHeaderLength <= 0) 33987c478bd9Sstevel@tonic-gate MaxMimeHeaderLength = 0; 33997c478bd9Sstevel@tonic-gate else if (MaxMimeHeaderLength < 128) 34007c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 34017c478bd9Sstevel@tonic-gate "Warning: MaxMimeHeaderLength: header length limit set lower than 128\n"); 34027c478bd9Sstevel@tonic-gate 34037c478bd9Sstevel@tonic-gate if (MaxMimeFieldLength <= 0) 34047c478bd9Sstevel@tonic-gate MaxMimeFieldLength = 0; 34057c478bd9Sstevel@tonic-gate else if (MaxMimeFieldLength < 40) 34067c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 34077c478bd9Sstevel@tonic-gate "Warning: MaxMimeHeaderLength: field length limit set lower than 40\n"); 3408*058561cbSjbeck 3409*058561cbSjbeck /* 3410*058561cbSjbeck ** Headers field values now include leading space, so let's 3411*058561cbSjbeck ** adjust the values to be "backward compatible". 3412*058561cbSjbeck */ 3413*058561cbSjbeck 3414*058561cbSjbeck if (MaxMimeHeaderLength > 0) 3415*058561cbSjbeck MaxMimeHeaderLength++; 3416*058561cbSjbeck if (MaxMimeFieldLength > 0) 3417*058561cbSjbeck MaxMimeFieldLength++; 34187c478bd9Sstevel@tonic-gate break; 34197c478bd9Sstevel@tonic-gate 34207c478bd9Sstevel@tonic-gate case O_CONTROLSOCKET: 34217c478bd9Sstevel@tonic-gate PSTRSET(ControlSocketName, val); 34227c478bd9Sstevel@tonic-gate break; 34237c478bd9Sstevel@tonic-gate 34247c478bd9Sstevel@tonic-gate case O_MAXHDRSLEN: 34257c478bd9Sstevel@tonic-gate MaxHeadersLength = atoi(val); 34267c478bd9Sstevel@tonic-gate 34277c478bd9Sstevel@tonic-gate if (MaxHeadersLength > 0 && 34287c478bd9Sstevel@tonic-gate MaxHeadersLength < (MAXHDRSLEN / 2)) 34297c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 34307c478bd9Sstevel@tonic-gate "Warning: MaxHeadersLength: headers length limit set lower than %d\n", 34317c478bd9Sstevel@tonic-gate (MAXHDRSLEN / 2)); 34327c478bd9Sstevel@tonic-gate break; 34337c478bd9Sstevel@tonic-gate 34347c478bd9Sstevel@tonic-gate case O_PROCTITLEPREFIX: 34357c478bd9Sstevel@tonic-gate PSTRSET(ProcTitlePrefix, val); 34367c478bd9Sstevel@tonic-gate break; 34377c478bd9Sstevel@tonic-gate 34387c478bd9Sstevel@tonic-gate #if SASL 34397c478bd9Sstevel@tonic-gate case O_SASLINFO: 34407c478bd9Sstevel@tonic-gate # if _FFR_ALLOW_SASLINFO 34417c478bd9Sstevel@tonic-gate /* 34427c478bd9Sstevel@tonic-gate ** Allow users to select their own authinfo file 34437c478bd9Sstevel@tonic-gate ** under certain circumstances, otherwise just ignore 34447c478bd9Sstevel@tonic-gate ** the option. If the option isn't ignored, several 34457c478bd9Sstevel@tonic-gate ** commands don't work very well, e.g., mailq. 34467c478bd9Sstevel@tonic-gate ** However, this is not a "perfect" solution. 34477c478bd9Sstevel@tonic-gate ** If mail is queued, the authentication info 34487c478bd9Sstevel@tonic-gate ** will not be used in subsequent delivery attempts. 34497c478bd9Sstevel@tonic-gate ** If we really want to support this, then it has 34507c478bd9Sstevel@tonic-gate ** to be stored in the queue file. 34517c478bd9Sstevel@tonic-gate */ 34527c478bd9Sstevel@tonic-gate if (!bitset(SUBMIT_MSA, SubmitMode) && RealUid != 0 && 34537c478bd9Sstevel@tonic-gate RunAsUid != RealUid) 34547c478bd9Sstevel@tonic-gate break; 34557c478bd9Sstevel@tonic-gate # endif /* _FFR_ALLOW_SASLINFO */ 34567c478bd9Sstevel@tonic-gate PSTRSET(SASLInfo, val); 34577c478bd9Sstevel@tonic-gate break; 34587c478bd9Sstevel@tonic-gate 34597c478bd9Sstevel@tonic-gate case O_SASLMECH: 34607c478bd9Sstevel@tonic-gate if (AuthMechanisms != NULL) 34617c478bd9Sstevel@tonic-gate sm_free(AuthMechanisms); /* XXX */ 34627c478bd9Sstevel@tonic-gate if (*val != '\0') 34637c478bd9Sstevel@tonic-gate AuthMechanisms = newstr(val); 34647c478bd9Sstevel@tonic-gate else 34657c478bd9Sstevel@tonic-gate AuthMechanisms = NULL; 34667c478bd9Sstevel@tonic-gate break; 34677c478bd9Sstevel@tonic-gate 34687c478bd9Sstevel@tonic-gate case O_SASLREALM: 34697c478bd9Sstevel@tonic-gate if (AuthRealm != NULL) 34707c478bd9Sstevel@tonic-gate sm_free(AuthRealm); 34717c478bd9Sstevel@tonic-gate if (*val != '\0') 34727c478bd9Sstevel@tonic-gate AuthRealm = newstr(val); 34737c478bd9Sstevel@tonic-gate else 34747c478bd9Sstevel@tonic-gate AuthRealm = NULL; 34757c478bd9Sstevel@tonic-gate break; 34767c478bd9Sstevel@tonic-gate 34777c478bd9Sstevel@tonic-gate case O_SASLOPTS: 34787c478bd9Sstevel@tonic-gate while (val != NULL && *val != '\0') 34797c478bd9Sstevel@tonic-gate { 34807c478bd9Sstevel@tonic-gate switch (*val) 34817c478bd9Sstevel@tonic-gate { 34827c478bd9Sstevel@tonic-gate case 'A': 34837c478bd9Sstevel@tonic-gate SASLOpts |= SASL_AUTH_AUTH; 34847c478bd9Sstevel@tonic-gate break; 34857c478bd9Sstevel@tonic-gate 34867c478bd9Sstevel@tonic-gate case 'a': 34877c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NOACTIVE; 34887c478bd9Sstevel@tonic-gate break; 34897c478bd9Sstevel@tonic-gate 34907c478bd9Sstevel@tonic-gate case 'c': 34917c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_PASS_CREDENTIALS; 34927c478bd9Sstevel@tonic-gate break; 34937c478bd9Sstevel@tonic-gate 34947c478bd9Sstevel@tonic-gate case 'd': 34957c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NODICTIONARY; 34967c478bd9Sstevel@tonic-gate break; 34977c478bd9Sstevel@tonic-gate 34987c478bd9Sstevel@tonic-gate case 'f': 34997c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_FORWARD_SECRECY; 35007c478bd9Sstevel@tonic-gate break; 35017c478bd9Sstevel@tonic-gate 35027c478bd9Sstevel@tonic-gate # if SASL >= 20101 35037c478bd9Sstevel@tonic-gate case 'm': 35047c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_MUTUAL_AUTH; 35057c478bd9Sstevel@tonic-gate break; 35067c478bd9Sstevel@tonic-gate # endif /* SASL >= 20101 */ 35077c478bd9Sstevel@tonic-gate 35087c478bd9Sstevel@tonic-gate case 'p': 35097c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NOPLAINTEXT; 35107c478bd9Sstevel@tonic-gate break; 35117c478bd9Sstevel@tonic-gate 35127c478bd9Sstevel@tonic-gate case 'y': 35137c478bd9Sstevel@tonic-gate SASLOpts |= SASL_SEC_NOANONYMOUS; 35147c478bd9Sstevel@tonic-gate break; 35157c478bd9Sstevel@tonic-gate 35167c478bd9Sstevel@tonic-gate case ' ': /* ignore */ 35177c478bd9Sstevel@tonic-gate case '\t': /* ignore */ 35187c478bd9Sstevel@tonic-gate case ',': /* ignore */ 35197c478bd9Sstevel@tonic-gate break; 35207c478bd9Sstevel@tonic-gate 35217c478bd9Sstevel@tonic-gate default: 35227c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 35237c478bd9Sstevel@tonic-gate "Warning: Option: %s unknown parameter '%c'\n", 35247c478bd9Sstevel@tonic-gate OPTNAME, 35257c478bd9Sstevel@tonic-gate (isascii(*val) && 35267c478bd9Sstevel@tonic-gate isprint(*val)) 35277c478bd9Sstevel@tonic-gate ? *val : '?'); 35287c478bd9Sstevel@tonic-gate break; 35297c478bd9Sstevel@tonic-gate } 35307c478bd9Sstevel@tonic-gate ++val; 35317c478bd9Sstevel@tonic-gate val = strpbrk(val, ", \t"); 35327c478bd9Sstevel@tonic-gate if (val != NULL) 35337c478bd9Sstevel@tonic-gate ++val; 35347c478bd9Sstevel@tonic-gate } 35357c478bd9Sstevel@tonic-gate break; 35367c478bd9Sstevel@tonic-gate 35377c478bd9Sstevel@tonic-gate case O_SASLBITS: 35387c478bd9Sstevel@tonic-gate MaxSLBits = atoi(val); 35397c478bd9Sstevel@tonic-gate break; 35407c478bd9Sstevel@tonic-gate 35417c478bd9Sstevel@tonic-gate #else /* SASL */ 35427c478bd9Sstevel@tonic-gate case O_SASLINFO: 35437c478bd9Sstevel@tonic-gate case O_SASLMECH: 35447c478bd9Sstevel@tonic-gate case O_SASLREALM: 35457c478bd9Sstevel@tonic-gate case O_SASLOPTS: 35467c478bd9Sstevel@tonic-gate case O_SASLBITS: 35477c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 35487c478bd9Sstevel@tonic-gate "Warning: Option: %s requires SASL support (-DSASL)\n", 35497c478bd9Sstevel@tonic-gate OPTNAME); 35507c478bd9Sstevel@tonic-gate break; 35517c478bd9Sstevel@tonic-gate #endif /* SASL */ 35527c478bd9Sstevel@tonic-gate 35537c478bd9Sstevel@tonic-gate #if STARTTLS 35547c478bd9Sstevel@tonic-gate case O_SRVCERTFILE: 35557c478bd9Sstevel@tonic-gate SET_STRING_EXP(SrvCertFile); 35567c478bd9Sstevel@tonic-gate case O_SRVKEYFILE: 35577c478bd9Sstevel@tonic-gate SET_STRING_EXP(SrvKeyFile); 35587c478bd9Sstevel@tonic-gate case O_CLTCERTFILE: 35597c478bd9Sstevel@tonic-gate SET_STRING_EXP(CltCertFile); 35607c478bd9Sstevel@tonic-gate case O_CLTKEYFILE: 35617c478bd9Sstevel@tonic-gate SET_STRING_EXP(CltKeyFile); 35627c478bd9Sstevel@tonic-gate case O_CACERTFILE: 35637c478bd9Sstevel@tonic-gate SET_STRING_EXP(CACertFile); 35647c478bd9Sstevel@tonic-gate case O_CACERTPATH: 35657c478bd9Sstevel@tonic-gate SET_STRING_EXP(CACertPath); 35667c478bd9Sstevel@tonic-gate case O_DHPARAMS: 35677c478bd9Sstevel@tonic-gate SET_STRING_EXP(DHParams); 35687c478bd9Sstevel@tonic-gate # if _FFR_TLS_1 35697c478bd9Sstevel@tonic-gate case O_DHPARAMS5: 35707c478bd9Sstevel@tonic-gate SET_STRING_EXP(DHParams5); 35717c478bd9Sstevel@tonic-gate case O_CIPHERLIST: 35727c478bd9Sstevel@tonic-gate SET_STRING_EXP(CipherList); 35737c478bd9Sstevel@tonic-gate # endif /* _FFR_TLS_1 */ 35747c478bd9Sstevel@tonic-gate case O_CRLFILE: 35757c478bd9Sstevel@tonic-gate # if OPENSSL_VERSION_NUMBER > 0x00907000L 35767c478bd9Sstevel@tonic-gate SET_STRING_EXP(CRLFile); 35777c478bd9Sstevel@tonic-gate # else /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 35787c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 35797c478bd9Sstevel@tonic-gate "Warning: Option: %s requires at least OpenSSL 0.9.7\n", 35807c478bd9Sstevel@tonic-gate OPTNAME); 35817c478bd9Sstevel@tonic-gate break; 35827c478bd9Sstevel@tonic-gate # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 35837c478bd9Sstevel@tonic-gate 35847c478bd9Sstevel@tonic-gate # if _FFR_CRLPATH 35857c478bd9Sstevel@tonic-gate case O_CRLPATH: 35867c478bd9Sstevel@tonic-gate # if OPENSSL_VERSION_NUMBER > 0x00907000L 35877c478bd9Sstevel@tonic-gate SET_STRING_EXP(CRLPath); 35887c478bd9Sstevel@tonic-gate # else /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 35897c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 35907c478bd9Sstevel@tonic-gate "Warning: Option: %s requires at least OpenSSL 0.9.7\n", 35917c478bd9Sstevel@tonic-gate OPTNAME); 35927c478bd9Sstevel@tonic-gate break; 35937c478bd9Sstevel@tonic-gate # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ 35947c478bd9Sstevel@tonic-gate # endif /* _FFR_CRLPATH */ 35957c478bd9Sstevel@tonic-gate 35967c478bd9Sstevel@tonic-gate /* 35977c478bd9Sstevel@tonic-gate ** XXX How about options per daemon/client instead of globally? 35987c478bd9Sstevel@tonic-gate ** This doesn't work well for some options, e.g., no server cert, 35997c478bd9Sstevel@tonic-gate ** but fine for others. 36007c478bd9Sstevel@tonic-gate ** 36017c478bd9Sstevel@tonic-gate ** XXX Some people may want different certs per server. 36027c478bd9Sstevel@tonic-gate ** 36037c478bd9Sstevel@tonic-gate ** See also srvfeatures() 36047c478bd9Sstevel@tonic-gate */ 36057c478bd9Sstevel@tonic-gate 36067c478bd9Sstevel@tonic-gate case O_TLS_SRV_OPTS: 36077c478bd9Sstevel@tonic-gate while (val != NULL && *val != '\0') 36087c478bd9Sstevel@tonic-gate { 36097c478bd9Sstevel@tonic-gate switch (*val) 36107c478bd9Sstevel@tonic-gate { 36117c478bd9Sstevel@tonic-gate case 'V': 36127c478bd9Sstevel@tonic-gate TLS_Srv_Opts |= TLS_I_NO_VRFY; 36137c478bd9Sstevel@tonic-gate break; 36147c478bd9Sstevel@tonic-gate # if _FFR_TLS_1 36157c478bd9Sstevel@tonic-gate /* 36167c478bd9Sstevel@tonic-gate ** Server without a cert? That works only if 36177c478bd9Sstevel@tonic-gate ** AnonDH is enabled as cipher, which is not in the 36187c478bd9Sstevel@tonic-gate ** default list. Hence the CipherList option must 36197c478bd9Sstevel@tonic-gate ** be available. Moreover: which clients support this 36207c478bd9Sstevel@tonic-gate ** besides sendmail with this setting? 36217c478bd9Sstevel@tonic-gate */ 36227c478bd9Sstevel@tonic-gate 36237c478bd9Sstevel@tonic-gate case 'C': 36247c478bd9Sstevel@tonic-gate TLS_Srv_Opts &= ~TLS_I_SRV_CERT; 36257c478bd9Sstevel@tonic-gate break; 36267c478bd9Sstevel@tonic-gate # endif /* _FFR_TLS_1 */ 36277c478bd9Sstevel@tonic-gate case ' ': /* ignore */ 36287c478bd9Sstevel@tonic-gate case '\t': /* ignore */ 36297c478bd9Sstevel@tonic-gate case ',': /* ignore */ 36307c478bd9Sstevel@tonic-gate break; 36317c478bd9Sstevel@tonic-gate default: 36327c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 36337c478bd9Sstevel@tonic-gate "Warning: Option: %s unknown parameter '%c'\n", 36347c478bd9Sstevel@tonic-gate OPTNAME, 36357c478bd9Sstevel@tonic-gate (isascii(*val) && 36367c478bd9Sstevel@tonic-gate isprint(*val)) 36377c478bd9Sstevel@tonic-gate ? *val : '?'); 36387c478bd9Sstevel@tonic-gate break; 36397c478bd9Sstevel@tonic-gate } 36407c478bd9Sstevel@tonic-gate ++val; 36417c478bd9Sstevel@tonic-gate val = strpbrk(val, ", \t"); 36427c478bd9Sstevel@tonic-gate if (val != NULL) 36437c478bd9Sstevel@tonic-gate ++val; 36447c478bd9Sstevel@tonic-gate } 36457c478bd9Sstevel@tonic-gate break; 36467c478bd9Sstevel@tonic-gate 36477c478bd9Sstevel@tonic-gate case O_RANDFILE: 36487c478bd9Sstevel@tonic-gate PSTRSET(RandFile, val); 36497c478bd9Sstevel@tonic-gate break; 36507c478bd9Sstevel@tonic-gate 36517c478bd9Sstevel@tonic-gate #else /* STARTTLS */ 36527c478bd9Sstevel@tonic-gate case O_SRVCERTFILE: 36537c478bd9Sstevel@tonic-gate case O_SRVKEYFILE: 36547c478bd9Sstevel@tonic-gate case O_CLTCERTFILE: 36557c478bd9Sstevel@tonic-gate case O_CLTKEYFILE: 36567c478bd9Sstevel@tonic-gate case O_CACERTFILE: 36577c478bd9Sstevel@tonic-gate case O_CACERTPATH: 36587c478bd9Sstevel@tonic-gate case O_DHPARAMS: 36597c478bd9Sstevel@tonic-gate # if _FFR_TLS_1 36607c478bd9Sstevel@tonic-gate case O_DHPARAMS5: 36617c478bd9Sstevel@tonic-gate case O_CIPHERLIST: 36627c478bd9Sstevel@tonic-gate # endif /* _FFR_TLS_1 */ 36637c478bd9Sstevel@tonic-gate case O_CRLFILE: 36647c478bd9Sstevel@tonic-gate # if _FFR_CRLPATH 36657c478bd9Sstevel@tonic-gate case O_CRLPATH: 36667c478bd9Sstevel@tonic-gate # endif /* _FFR_CRLPATH */ 36677c478bd9Sstevel@tonic-gate case O_RANDFILE: 36687c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 36697c478bd9Sstevel@tonic-gate "Warning: Option: %s requires TLS support\n", 36707c478bd9Sstevel@tonic-gate OPTNAME); 36717c478bd9Sstevel@tonic-gate break; 36727c478bd9Sstevel@tonic-gate 36737c478bd9Sstevel@tonic-gate #endif /* STARTTLS */ 36747c478bd9Sstevel@tonic-gate 36757c478bd9Sstevel@tonic-gate case O_CLIENTPORT: 36767c478bd9Sstevel@tonic-gate setclientoptions(val); 36777c478bd9Sstevel@tonic-gate break; 36787c478bd9Sstevel@tonic-gate 36797c478bd9Sstevel@tonic-gate case O_DF_BUFSIZE: 36807c478bd9Sstevel@tonic-gate DataFileBufferSize = atoi(val); 36817c478bd9Sstevel@tonic-gate break; 36827c478bd9Sstevel@tonic-gate 36837c478bd9Sstevel@tonic-gate case O_XF_BUFSIZE: 36847c478bd9Sstevel@tonic-gate XscriptFileBufferSize = atoi(val); 36857c478bd9Sstevel@tonic-gate break; 36867c478bd9Sstevel@tonic-gate 36877c478bd9Sstevel@tonic-gate case O_LDAPDEFAULTSPEC: 36887c478bd9Sstevel@tonic-gate #if LDAPMAP 36897c478bd9Sstevel@tonic-gate ldapmap_set_defaults(val); 36907c478bd9Sstevel@tonic-gate #else /* LDAPMAP */ 36917c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 36927c478bd9Sstevel@tonic-gate "Warning: Option: %s requires LDAP support (-DLDAPMAP)\n", 36937c478bd9Sstevel@tonic-gate OPTNAME); 36947c478bd9Sstevel@tonic-gate #endif /* LDAPMAP */ 36957c478bd9Sstevel@tonic-gate break; 36967c478bd9Sstevel@tonic-gate 36977c478bd9Sstevel@tonic-gate case O_INPUTMILTER: 36987c478bd9Sstevel@tonic-gate #if MILTER 36997c478bd9Sstevel@tonic-gate InputFilterList = newstr(val); 37007c478bd9Sstevel@tonic-gate #else /* MILTER */ 37017c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 37027c478bd9Sstevel@tonic-gate "Warning: Option: %s requires Milter support (-DMILTER)\n", 37037c478bd9Sstevel@tonic-gate OPTNAME); 37047c478bd9Sstevel@tonic-gate #endif /* MILTER */ 37057c478bd9Sstevel@tonic-gate break; 37067c478bd9Sstevel@tonic-gate 37077c478bd9Sstevel@tonic-gate case O_MILTER: 37087c478bd9Sstevel@tonic-gate #if MILTER 37097c478bd9Sstevel@tonic-gate milter_set_option(subopt, val, sticky); 37107c478bd9Sstevel@tonic-gate #else /* MILTER */ 37117c478bd9Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 37127c478bd9Sstevel@tonic-gate "Warning: Option: %s requires Milter support (-DMILTER)\n", 37137c478bd9Sstevel@tonic-gate OPTNAME); 37147c478bd9Sstevel@tonic-gate #endif /* MILTER */ 37157c478bd9Sstevel@tonic-gate break; 37167c478bd9Sstevel@tonic-gate 37177c478bd9Sstevel@tonic-gate case O_QUEUE_FILE_MODE: /* queue file mode */ 37187c478bd9Sstevel@tonic-gate QueueFileMode = atooct(val) & 0777; 37197c478bd9Sstevel@tonic-gate break; 37207c478bd9Sstevel@tonic-gate 37217c478bd9Sstevel@tonic-gate case O_DLVR_MIN: /* deliver by minimum time */ 37227c478bd9Sstevel@tonic-gate DeliverByMin = convtime(val, 's'); 37237c478bd9Sstevel@tonic-gate break; 37247c478bd9Sstevel@tonic-gate 37257c478bd9Sstevel@tonic-gate /* modifiers {daemon_flags} for direct submissions */ 37267c478bd9Sstevel@tonic-gate case O_DIRECTSUBMODIFIERS: 37277c478bd9Sstevel@tonic-gate { 37287c478bd9Sstevel@tonic-gate BITMAP256 m; /* ignored */ 37297c478bd9Sstevel@tonic-gate extern ENVELOPE BlankEnvelope; 37307c478bd9Sstevel@tonic-gate 37317c478bd9Sstevel@tonic-gate macdefine(&BlankEnvelope.e_macro, A_PERM, 37327c478bd9Sstevel@tonic-gate macid("{daemon_flags}"), 37337c478bd9Sstevel@tonic-gate getmodifiers(val, m)); 37347c478bd9Sstevel@tonic-gate } 37357c478bd9Sstevel@tonic-gate break; 37367c478bd9Sstevel@tonic-gate 37377c478bd9Sstevel@tonic-gate case O_FASTSPLIT: 37387c478bd9Sstevel@tonic-gate FastSplit = atoi(val); 37397c478bd9Sstevel@tonic-gate break; 37407c478bd9Sstevel@tonic-gate 37417c478bd9Sstevel@tonic-gate case O_MBDB: 37427c478bd9Sstevel@tonic-gate Mbdb = newstr(val); 37437c478bd9Sstevel@tonic-gate break; 37447c478bd9Sstevel@tonic-gate 37457c478bd9Sstevel@tonic-gate case O_MSQ: 37467c478bd9Sstevel@tonic-gate UseMSP = atobool(val); 37477c478bd9Sstevel@tonic-gate break; 37487c478bd9Sstevel@tonic-gate 37497c478bd9Sstevel@tonic-gate case O_SOFTBOUNCE: 37507c478bd9Sstevel@tonic-gate SoftBounce = atobool(val); 37517c478bd9Sstevel@tonic-gate break; 37527c478bd9Sstevel@tonic-gate 37537c478bd9Sstevel@tonic-gate case O_REJECTLOGINTERVAL: /* time btwn log msgs while refusing */ 37547c478bd9Sstevel@tonic-gate RejectLogInterval = convtime(val, 'h'); 37557c478bd9Sstevel@tonic-gate break; 37567c478bd9Sstevel@tonic-gate 37577c478bd9Sstevel@tonic-gate case O_REQUIRES_DIR_FSYNC: 37587c478bd9Sstevel@tonic-gate #if REQUIRES_DIR_FSYNC 37597c478bd9Sstevel@tonic-gate RequiresDirfsync = atobool(val); 37607c478bd9Sstevel@tonic-gate #else /* REQUIRES_DIR_FSYNC */ 37617c478bd9Sstevel@tonic-gate /* silently ignored... required for cf file option */ 37627c478bd9Sstevel@tonic-gate #endif /* REQUIRES_DIR_FSYNC */ 37637c478bd9Sstevel@tonic-gate break; 37647c478bd9Sstevel@tonic-gate 37657c478bd9Sstevel@tonic-gate case O_CONNECTION_RATE_WINDOW_SIZE: 37667c478bd9Sstevel@tonic-gate ConnectionRateWindowSize = convtime(val, 's'); 37677c478bd9Sstevel@tonic-gate break; 37687c478bd9Sstevel@tonic-gate 37697c478bd9Sstevel@tonic-gate case O_FALLBACKSMARTHOST: /* fallback smart host */ 37707c478bd9Sstevel@tonic-gate if (val[0] != '\0') 37717c478bd9Sstevel@tonic-gate FallbackSmartHost = newstr(val); 37727c478bd9Sstevel@tonic-gate break; 37737c478bd9Sstevel@tonic-gate 37747c478bd9Sstevel@tonic-gate case O_HELONAME: 37757c478bd9Sstevel@tonic-gate HeloName = newstr(val); 37767c478bd9Sstevel@tonic-gate break; 3777*058561cbSjbeck 3778445f2479Sjbeck #if _FFR_MEMSTAT 3779445f2479Sjbeck case O_REFUSELOWMEM: 3780445f2479Sjbeck RefuseLowMem = atoi(val); 3781445f2479Sjbeck break; 3782445f2479Sjbeck case O_QUEUELOWMEM: 3783445f2479Sjbeck QueueLowMem = atoi(val); 3784445f2479Sjbeck break; 3785445f2479Sjbeck case O_MEMRESOURCE: 3786445f2479Sjbeck MemoryResource = newstr(val); 3787445f2479Sjbeck break; 3788445f2479Sjbeck #endif /* _FFR_MEMSTAT */ 3789445f2479Sjbeck 3790445f2479Sjbeck case O_MAXNOOPCOMMANDS: 3791445f2479Sjbeck MaxNOOPCommands = atoi(val); 3792445f2479Sjbeck break; 3793445f2479Sjbeck 3794445f2479Sjbeck #if _FFR_MSG_ACCEPT 3795445f2479Sjbeck case O_MSG_ACCEPT: 3796445f2479Sjbeck MessageAccept = newstr(val); 3797445f2479Sjbeck break; 3798445f2479Sjbeck #endif /* _FFR_MSG_ACCEPT */ 3799445f2479Sjbeck 3800445f2479Sjbeck #if _FFR_QUEUE_RUN_PARANOIA 3801445f2479Sjbeck case O_CHK_Q_RUNNERS: 3802445f2479Sjbeck CheckQueueRunners = atoi(val); 3803445f2479Sjbeck break; 3804445f2479Sjbeck #endif /* _FFR_QUEUE_RUN_PARANOIA */ 38057c478bd9Sstevel@tonic-gate 3806*058561cbSjbeck #if _FFR_EIGHT_BIT_ADDR_OK 3807*058561cbSjbeck case O_EIGHT_BIT_ADDR_OK: 3808*058561cbSjbeck EightBitAddrOK = atobool(val); 3809*058561cbSjbeck break; 3810*058561cbSjbeck #endif /* _FFR_EIGHT_BIT_ADDR_OK */ 3811*058561cbSjbeck 38127c478bd9Sstevel@tonic-gate default: 38137c478bd9Sstevel@tonic-gate if (tTd(37, 1)) 38147c478bd9Sstevel@tonic-gate { 38157c478bd9Sstevel@tonic-gate if (isascii(opt) && isprint(opt)) 38167c478bd9Sstevel@tonic-gate sm_dprintf("Warning: option %c unknown\n", opt); 38177c478bd9Sstevel@tonic-gate else 38187c478bd9Sstevel@tonic-gate sm_dprintf("Warning: option 0x%x unknown\n", opt); 38197c478bd9Sstevel@tonic-gate } 38207c478bd9Sstevel@tonic-gate break; 38217c478bd9Sstevel@tonic-gate } 38227c478bd9Sstevel@tonic-gate 38237c478bd9Sstevel@tonic-gate /* 38247c478bd9Sstevel@tonic-gate ** Options with suboptions are responsible for taking care 38257c478bd9Sstevel@tonic-gate ** of sticky-ness (e.g., that a command line setting is kept 38267c478bd9Sstevel@tonic-gate ** when reading in the sendmail.cf file). This has to be done 38277c478bd9Sstevel@tonic-gate ** when the suboptions are parsed since each suboption must be 38287c478bd9Sstevel@tonic-gate ** sticky, not the root option. 38297c478bd9Sstevel@tonic-gate */ 38307c478bd9Sstevel@tonic-gate 38317c478bd9Sstevel@tonic-gate if (sticky && !bitset(OI_SUBOPT, o->o_flags)) 38327c478bd9Sstevel@tonic-gate setbitn(opt, StickyOpt); 38337c478bd9Sstevel@tonic-gate } 38347c478bd9Sstevel@tonic-gate /* 38357c478bd9Sstevel@tonic-gate ** SETCLASS -- set a string into a class 38367c478bd9Sstevel@tonic-gate ** 38377c478bd9Sstevel@tonic-gate ** Parameters: 38387c478bd9Sstevel@tonic-gate ** class -- the class to put the string in. 38397c478bd9Sstevel@tonic-gate ** str -- the string to enter 38407c478bd9Sstevel@tonic-gate ** 38417c478bd9Sstevel@tonic-gate ** Returns: 38427c478bd9Sstevel@tonic-gate ** none. 38437c478bd9Sstevel@tonic-gate ** 38447c478bd9Sstevel@tonic-gate ** Side Effects: 38457c478bd9Sstevel@tonic-gate ** puts the word into the symbol table. 38467c478bd9Sstevel@tonic-gate */ 38477c478bd9Sstevel@tonic-gate 38487c478bd9Sstevel@tonic-gate void 38497c478bd9Sstevel@tonic-gate setclass(class, str) 38507c478bd9Sstevel@tonic-gate int class; 38517c478bd9Sstevel@tonic-gate char *str; 38527c478bd9Sstevel@tonic-gate { 38537c478bd9Sstevel@tonic-gate register STAB *s; 38547c478bd9Sstevel@tonic-gate 3855*058561cbSjbeck if ((str[0] & 0377) == MATCHCLASS) 38567c478bd9Sstevel@tonic-gate { 38577c478bd9Sstevel@tonic-gate int mid; 38587c478bd9Sstevel@tonic-gate 38597c478bd9Sstevel@tonic-gate str++; 38607c478bd9Sstevel@tonic-gate mid = macid(str); 38617c478bd9Sstevel@tonic-gate if (mid == 0) 38627c478bd9Sstevel@tonic-gate return; 38637c478bd9Sstevel@tonic-gate 38647c478bd9Sstevel@tonic-gate if (tTd(37, 8)) 38657c478bd9Sstevel@tonic-gate sm_dprintf("setclass(%s, $=%s)\n", 38667c478bd9Sstevel@tonic-gate macname(class), macname(mid)); 38677c478bd9Sstevel@tonic-gate copy_class(mid, class); 38687c478bd9Sstevel@tonic-gate } 38697c478bd9Sstevel@tonic-gate else 38707c478bd9Sstevel@tonic-gate { 38717c478bd9Sstevel@tonic-gate if (tTd(37, 8)) 38727c478bd9Sstevel@tonic-gate sm_dprintf("setclass(%s, %s)\n", macname(class), str); 38737c478bd9Sstevel@tonic-gate 38747c478bd9Sstevel@tonic-gate s = stab(str, ST_CLASS, ST_ENTER); 38757c478bd9Sstevel@tonic-gate setbitn(bitidx(class), s->s_class); 38767c478bd9Sstevel@tonic-gate } 38777c478bd9Sstevel@tonic-gate } 38787c478bd9Sstevel@tonic-gate /* 38797c478bd9Sstevel@tonic-gate ** MAKEMAPENTRY -- create a map entry 38807c478bd9Sstevel@tonic-gate ** 38817c478bd9Sstevel@tonic-gate ** Parameters: 38827c478bd9Sstevel@tonic-gate ** line -- the config file line 38837c478bd9Sstevel@tonic-gate ** 38847c478bd9Sstevel@tonic-gate ** Returns: 38857c478bd9Sstevel@tonic-gate ** A pointer to the map that has been created. 38867c478bd9Sstevel@tonic-gate ** NULL if there was a syntax error. 38877c478bd9Sstevel@tonic-gate ** 38887c478bd9Sstevel@tonic-gate ** Side Effects: 38897c478bd9Sstevel@tonic-gate ** Enters the map into the dictionary. 38907c478bd9Sstevel@tonic-gate */ 38917c478bd9Sstevel@tonic-gate 38927c478bd9Sstevel@tonic-gate MAP * 38937c478bd9Sstevel@tonic-gate makemapentry(line) 38947c478bd9Sstevel@tonic-gate char *line; 38957c478bd9Sstevel@tonic-gate { 38967c478bd9Sstevel@tonic-gate register char *p; 38977c478bd9Sstevel@tonic-gate char *mapname; 38987c478bd9Sstevel@tonic-gate char *classname; 38997c478bd9Sstevel@tonic-gate register STAB *s; 39007c478bd9Sstevel@tonic-gate STAB *class; 39017c478bd9Sstevel@tonic-gate 39027c478bd9Sstevel@tonic-gate for (p = line; isascii(*p) && isspace(*p); p++) 39037c478bd9Sstevel@tonic-gate continue; 39047c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isalnum(*p))) 39057c478bd9Sstevel@tonic-gate { 39067c478bd9Sstevel@tonic-gate syserr("readcf: config K line: no map name"); 39077c478bd9Sstevel@tonic-gate return NULL; 39087c478bd9Sstevel@tonic-gate } 39097c478bd9Sstevel@tonic-gate 39107c478bd9Sstevel@tonic-gate mapname = p; 39117c478bd9Sstevel@tonic-gate while ((isascii(*++p) && isalnum(*p)) || *p == '_' || *p == '.') 39127c478bd9Sstevel@tonic-gate continue; 39137c478bd9Sstevel@tonic-gate if (*p != '\0') 39147c478bd9Sstevel@tonic-gate *p++ = '\0'; 39157c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 39167c478bd9Sstevel@tonic-gate p++; 39177c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isalnum(*p))) 39187c478bd9Sstevel@tonic-gate { 39197c478bd9Sstevel@tonic-gate syserr("readcf: config K line, map %s: no map class", mapname); 39207c478bd9Sstevel@tonic-gate return NULL; 39217c478bd9Sstevel@tonic-gate } 39227c478bd9Sstevel@tonic-gate classname = p; 39237c478bd9Sstevel@tonic-gate while (isascii(*++p) && isalnum(*p)) 39247c478bd9Sstevel@tonic-gate continue; 39257c478bd9Sstevel@tonic-gate if (*p != '\0') 39267c478bd9Sstevel@tonic-gate *p++ = '\0'; 39277c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 39287c478bd9Sstevel@tonic-gate p++; 39297c478bd9Sstevel@tonic-gate 39307c478bd9Sstevel@tonic-gate /* look up the class */ 39317c478bd9Sstevel@tonic-gate class = stab(classname, ST_MAPCLASS, ST_FIND); 39327c478bd9Sstevel@tonic-gate if (class == NULL) 39337c478bd9Sstevel@tonic-gate { 39347c478bd9Sstevel@tonic-gate syserr("readcf: map %s: class %s not available", mapname, 39357c478bd9Sstevel@tonic-gate classname); 39367c478bd9Sstevel@tonic-gate return NULL; 39377c478bd9Sstevel@tonic-gate } 39387c478bd9Sstevel@tonic-gate 39397c478bd9Sstevel@tonic-gate /* enter the map */ 39407c478bd9Sstevel@tonic-gate s = stab(mapname, ST_MAP, ST_ENTER); 39417c478bd9Sstevel@tonic-gate s->s_map.map_class = &class->s_mapclass; 39427c478bd9Sstevel@tonic-gate s->s_map.map_mname = newstr(mapname); 39437c478bd9Sstevel@tonic-gate 39447c478bd9Sstevel@tonic-gate if (class->s_mapclass.map_parse(&s->s_map, p)) 39457c478bd9Sstevel@tonic-gate s->s_map.map_mflags |= MF_VALID; 39467c478bd9Sstevel@tonic-gate 39477c478bd9Sstevel@tonic-gate if (tTd(37, 5)) 39487c478bd9Sstevel@tonic-gate { 39497c478bd9Sstevel@tonic-gate sm_dprintf("map %s, class %s, flags %lx, file %s,\n", 39507c478bd9Sstevel@tonic-gate s->s_map.map_mname, s->s_map.map_class->map_cname, 39517c478bd9Sstevel@tonic-gate s->s_map.map_mflags, s->s_map.map_file); 39527c478bd9Sstevel@tonic-gate sm_dprintf("\tapp %s, domain %s, rebuild %s\n", 39537c478bd9Sstevel@tonic-gate s->s_map.map_app, s->s_map.map_domain, 39547c478bd9Sstevel@tonic-gate s->s_map.map_rebuild); 39557c478bd9Sstevel@tonic-gate } 39567c478bd9Sstevel@tonic-gate return &s->s_map; 39577c478bd9Sstevel@tonic-gate } 39587c478bd9Sstevel@tonic-gate /* 39597c478bd9Sstevel@tonic-gate ** STRTORWSET -- convert string to rewriting set number 39607c478bd9Sstevel@tonic-gate ** 39617c478bd9Sstevel@tonic-gate ** Parameters: 39627c478bd9Sstevel@tonic-gate ** p -- the pointer to the string to decode. 39637c478bd9Sstevel@tonic-gate ** endp -- if set, store the trailing delimiter here. 39647c478bd9Sstevel@tonic-gate ** stabmode -- ST_ENTER to create this entry, ST_FIND if 39657c478bd9Sstevel@tonic-gate ** it must already exist. 39667c478bd9Sstevel@tonic-gate ** 39677c478bd9Sstevel@tonic-gate ** Returns: 39687c478bd9Sstevel@tonic-gate ** The appropriate ruleset number. 39697c478bd9Sstevel@tonic-gate ** -1 if it is not valid (error already printed) 39707c478bd9Sstevel@tonic-gate */ 39717c478bd9Sstevel@tonic-gate 39727c478bd9Sstevel@tonic-gate int 39737c478bd9Sstevel@tonic-gate strtorwset(p, endp, stabmode) 39747c478bd9Sstevel@tonic-gate char *p; 39757c478bd9Sstevel@tonic-gate char **endp; 39767c478bd9Sstevel@tonic-gate int stabmode; 39777c478bd9Sstevel@tonic-gate { 39787c478bd9Sstevel@tonic-gate int ruleset; 39797c478bd9Sstevel@tonic-gate static int nextruleset = MAXRWSETS; 39807c478bd9Sstevel@tonic-gate 39817c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 39827c478bd9Sstevel@tonic-gate p++; 39837c478bd9Sstevel@tonic-gate if (!isascii(*p)) 39847c478bd9Sstevel@tonic-gate { 39857c478bd9Sstevel@tonic-gate syserr("invalid ruleset name: \"%.20s\"", p); 39867c478bd9Sstevel@tonic-gate return -1; 39877c478bd9Sstevel@tonic-gate } 39887c478bd9Sstevel@tonic-gate if (isdigit(*p)) 39897c478bd9Sstevel@tonic-gate { 39907c478bd9Sstevel@tonic-gate ruleset = strtol(p, endp, 10); 39917c478bd9Sstevel@tonic-gate if (ruleset >= MAXRWSETS / 2 || ruleset < 0) 39927c478bd9Sstevel@tonic-gate { 39937c478bd9Sstevel@tonic-gate syserr("bad ruleset %d (%d max)", 39947c478bd9Sstevel@tonic-gate ruleset, MAXRWSETS / 2); 39957c478bd9Sstevel@tonic-gate ruleset = -1; 39967c478bd9Sstevel@tonic-gate } 39977c478bd9Sstevel@tonic-gate } 39987c478bd9Sstevel@tonic-gate else 39997c478bd9Sstevel@tonic-gate { 40007c478bd9Sstevel@tonic-gate STAB *s; 40017c478bd9Sstevel@tonic-gate char delim; 40027c478bd9Sstevel@tonic-gate char *q = NULL; 40037c478bd9Sstevel@tonic-gate 40047c478bd9Sstevel@tonic-gate q = p; 40057c478bd9Sstevel@tonic-gate while (*p != '\0' && isascii(*p) && 40067c478bd9Sstevel@tonic-gate (isalnum(*p) || *p == '_')) 40077c478bd9Sstevel@tonic-gate p++; 40087c478bd9Sstevel@tonic-gate if (q == p || !(isascii(*q) && isalpha(*q))) 40097c478bd9Sstevel@tonic-gate { 40107c478bd9Sstevel@tonic-gate /* no valid characters */ 40117c478bd9Sstevel@tonic-gate syserr("invalid ruleset name: \"%.20s\"", q); 40127c478bd9Sstevel@tonic-gate return -1; 40137c478bd9Sstevel@tonic-gate } 40147c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 40157c478bd9Sstevel@tonic-gate *p++ = '\0'; 40167c478bd9Sstevel@tonic-gate delim = *p; 40177c478bd9Sstevel@tonic-gate if (delim != '\0') 40187c478bd9Sstevel@tonic-gate *p = '\0'; 40197c478bd9Sstevel@tonic-gate s = stab(q, ST_RULESET, stabmode); 40207c478bd9Sstevel@tonic-gate if (delim != '\0') 40217c478bd9Sstevel@tonic-gate *p = delim; 40227c478bd9Sstevel@tonic-gate 40237c478bd9Sstevel@tonic-gate if (s == NULL) 40247c478bd9Sstevel@tonic-gate return -1; 40257c478bd9Sstevel@tonic-gate 40267c478bd9Sstevel@tonic-gate if (stabmode == ST_ENTER && delim == '=') 40277c478bd9Sstevel@tonic-gate { 40287c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 40297c478bd9Sstevel@tonic-gate continue; 40307c478bd9Sstevel@tonic-gate if (!(isascii(*p) && isdigit(*p))) 40317c478bd9Sstevel@tonic-gate { 40327c478bd9Sstevel@tonic-gate syserr("bad ruleset definition \"%s\" (number required after `=')", q); 40337c478bd9Sstevel@tonic-gate ruleset = -1; 40347c478bd9Sstevel@tonic-gate } 40357c478bd9Sstevel@tonic-gate else 40367c478bd9Sstevel@tonic-gate { 40377c478bd9Sstevel@tonic-gate ruleset = strtol(p, endp, 10); 40387c478bd9Sstevel@tonic-gate if (ruleset >= MAXRWSETS / 2 || ruleset < 0) 40397c478bd9Sstevel@tonic-gate { 40407c478bd9Sstevel@tonic-gate syserr("bad ruleset number %d in \"%s\" (%d max)", 40417c478bd9Sstevel@tonic-gate ruleset, q, MAXRWSETS / 2); 40427c478bd9Sstevel@tonic-gate ruleset = -1; 40437c478bd9Sstevel@tonic-gate } 40447c478bd9Sstevel@tonic-gate } 40457c478bd9Sstevel@tonic-gate } 40467c478bd9Sstevel@tonic-gate else 40477c478bd9Sstevel@tonic-gate { 40487c478bd9Sstevel@tonic-gate if (endp != NULL) 40497c478bd9Sstevel@tonic-gate *endp = p; 40507c478bd9Sstevel@tonic-gate if (s->s_ruleset >= 0) 40517c478bd9Sstevel@tonic-gate ruleset = s->s_ruleset; 40527c478bd9Sstevel@tonic-gate else if ((ruleset = --nextruleset) < MAXRWSETS / 2) 40537c478bd9Sstevel@tonic-gate { 40547c478bd9Sstevel@tonic-gate syserr("%s: too many named rulesets (%d max)", 40557c478bd9Sstevel@tonic-gate q, MAXRWSETS / 2); 40567c478bd9Sstevel@tonic-gate ruleset = -1; 40577c478bd9Sstevel@tonic-gate } 40587c478bd9Sstevel@tonic-gate } 40597c478bd9Sstevel@tonic-gate if (s->s_ruleset >= 0 && 40607c478bd9Sstevel@tonic-gate ruleset >= 0 && 40617c478bd9Sstevel@tonic-gate ruleset != s->s_ruleset) 40627c478bd9Sstevel@tonic-gate { 40637c478bd9Sstevel@tonic-gate syserr("%s: ruleset changed value (old %d, new %d)", 40647c478bd9Sstevel@tonic-gate q, s->s_ruleset, ruleset); 40657c478bd9Sstevel@tonic-gate ruleset = s->s_ruleset; 40667c478bd9Sstevel@tonic-gate } 40677c478bd9Sstevel@tonic-gate else if (ruleset >= 0) 40687c478bd9Sstevel@tonic-gate { 40697c478bd9Sstevel@tonic-gate s->s_ruleset = ruleset; 40707c478bd9Sstevel@tonic-gate } 40717c478bd9Sstevel@tonic-gate if (stabmode == ST_ENTER && ruleset >= 0) 40727c478bd9Sstevel@tonic-gate { 40737c478bd9Sstevel@tonic-gate char *h = NULL; 40747c478bd9Sstevel@tonic-gate 40757c478bd9Sstevel@tonic-gate if (RuleSetNames[ruleset] != NULL) 40767c478bd9Sstevel@tonic-gate sm_free(RuleSetNames[ruleset]); /* XXX */ 40777c478bd9Sstevel@tonic-gate if (delim != '\0' && (h = strchr(q, delim)) != NULL) 40787c478bd9Sstevel@tonic-gate *h = '\0'; 40797c478bd9Sstevel@tonic-gate RuleSetNames[ruleset] = newstr(q); 40807c478bd9Sstevel@tonic-gate if (delim == '/' && h != NULL) 40817c478bd9Sstevel@tonic-gate *h = delim; /* put back delim */ 40827c478bd9Sstevel@tonic-gate } 40837c478bd9Sstevel@tonic-gate } 40847c478bd9Sstevel@tonic-gate return ruleset; 40857c478bd9Sstevel@tonic-gate } 40867c478bd9Sstevel@tonic-gate /* 40877c478bd9Sstevel@tonic-gate ** SETTIMEOUT -- set an individual timeout 40887c478bd9Sstevel@tonic-gate ** 40897c478bd9Sstevel@tonic-gate ** Parameters: 40907c478bd9Sstevel@tonic-gate ** name -- the name of the timeout. 40917c478bd9Sstevel@tonic-gate ** val -- the value of the timeout. 40927c478bd9Sstevel@tonic-gate ** sticky -- if set, don't let other setoptions override 40937c478bd9Sstevel@tonic-gate ** this value. 40947c478bd9Sstevel@tonic-gate ** 40957c478bd9Sstevel@tonic-gate ** Returns: 40967c478bd9Sstevel@tonic-gate ** none. 40977c478bd9Sstevel@tonic-gate */ 40987c478bd9Sstevel@tonic-gate 40997c478bd9Sstevel@tonic-gate /* set if Timeout sub-option is stuck */ 41007c478bd9Sstevel@tonic-gate static BITMAP256 StickyTimeoutOpt; 41017c478bd9Sstevel@tonic-gate 41027c478bd9Sstevel@tonic-gate static struct timeoutinfo 41037c478bd9Sstevel@tonic-gate { 41047c478bd9Sstevel@tonic-gate char *to_name; /* long name of timeout */ 41057c478bd9Sstevel@tonic-gate unsigned char to_code; /* code for option */ 41067c478bd9Sstevel@tonic-gate } TimeOutTab[] = 41077c478bd9Sstevel@tonic-gate { 41087c478bd9Sstevel@tonic-gate #define TO_INITIAL 0x01 41097c478bd9Sstevel@tonic-gate { "initial", TO_INITIAL }, 41107c478bd9Sstevel@tonic-gate #define TO_MAIL 0x02 41117c478bd9Sstevel@tonic-gate { "mail", TO_MAIL }, 41127c478bd9Sstevel@tonic-gate #define TO_RCPT 0x03 41137c478bd9Sstevel@tonic-gate { "rcpt", TO_RCPT }, 41147c478bd9Sstevel@tonic-gate #define TO_DATAINIT 0x04 41157c478bd9Sstevel@tonic-gate { "datainit", TO_DATAINIT }, 41167c478bd9Sstevel@tonic-gate #define TO_DATABLOCK 0x05 41177c478bd9Sstevel@tonic-gate { "datablock", TO_DATABLOCK }, 41187c478bd9Sstevel@tonic-gate #define TO_DATAFINAL 0x06 41197c478bd9Sstevel@tonic-gate { "datafinal", TO_DATAFINAL }, 41207c478bd9Sstevel@tonic-gate #define TO_COMMAND 0x07 41217c478bd9Sstevel@tonic-gate { "command", TO_COMMAND }, 41227c478bd9Sstevel@tonic-gate #define TO_RSET 0x08 41237c478bd9Sstevel@tonic-gate { "rset", TO_RSET }, 41247c478bd9Sstevel@tonic-gate #define TO_HELO 0x09 41257c478bd9Sstevel@tonic-gate { "helo", TO_HELO }, 41267c478bd9Sstevel@tonic-gate #define TO_QUIT 0x0A 41277c478bd9Sstevel@tonic-gate { "quit", TO_QUIT }, 41287c478bd9Sstevel@tonic-gate #define TO_MISC 0x0B 41297c478bd9Sstevel@tonic-gate { "misc", TO_MISC }, 41307c478bd9Sstevel@tonic-gate #define TO_IDENT 0x0C 41317c478bd9Sstevel@tonic-gate { "ident", TO_IDENT }, 41327c478bd9Sstevel@tonic-gate #define TO_FILEOPEN 0x0D 41337c478bd9Sstevel@tonic-gate { "fileopen", TO_FILEOPEN }, 41347c478bd9Sstevel@tonic-gate #define TO_CONNECT 0x0E 41357c478bd9Sstevel@tonic-gate { "connect", TO_CONNECT }, 41367c478bd9Sstevel@tonic-gate #define TO_ICONNECT 0x0F 41377c478bd9Sstevel@tonic-gate { "iconnect", TO_ICONNECT }, 41387c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN 0x10 41397c478bd9Sstevel@tonic-gate { "queuewarn", TO_QUEUEWARN }, 41407c478bd9Sstevel@tonic-gate { "queuewarn.*", TO_QUEUEWARN }, 41417c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_NORMAL 0x11 41427c478bd9Sstevel@tonic-gate { "queuewarn.normal", TO_QUEUEWARN_NORMAL }, 41437c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_URGENT 0x12 41447c478bd9Sstevel@tonic-gate { "queuewarn.urgent", TO_QUEUEWARN_URGENT }, 41457c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_NON_URGENT 0x13 41467c478bd9Sstevel@tonic-gate { "queuewarn.non-urgent", TO_QUEUEWARN_NON_URGENT }, 41477c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN 0x14 41487c478bd9Sstevel@tonic-gate { "queuereturn", TO_QUEUERETURN }, 41497c478bd9Sstevel@tonic-gate { "queuereturn.*", TO_QUEUERETURN }, 41507c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_NORMAL 0x15 41517c478bd9Sstevel@tonic-gate { "queuereturn.normal", TO_QUEUERETURN_NORMAL }, 41527c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_URGENT 0x16 41537c478bd9Sstevel@tonic-gate { "queuereturn.urgent", TO_QUEUERETURN_URGENT }, 41547c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_NON_URGENT 0x17 41557c478bd9Sstevel@tonic-gate { "queuereturn.non-urgent", TO_QUEUERETURN_NON_URGENT }, 41567c478bd9Sstevel@tonic-gate #define TO_HOSTSTATUS 0x18 41577c478bd9Sstevel@tonic-gate { "hoststatus", TO_HOSTSTATUS }, 41587c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRANS 0x19 41597c478bd9Sstevel@tonic-gate { "resolver.retrans", TO_RESOLVER_RETRANS }, 41607c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRANS_NORMAL 0x1A 41617c478bd9Sstevel@tonic-gate { "resolver.retrans.normal", TO_RESOLVER_RETRANS_NORMAL }, 41627c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRANS_FIRST 0x1B 41637c478bd9Sstevel@tonic-gate { "resolver.retrans.first", TO_RESOLVER_RETRANS_FIRST }, 41647c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRY 0x1C 41657c478bd9Sstevel@tonic-gate { "resolver.retry", TO_RESOLVER_RETRY }, 41667c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRY_NORMAL 0x1D 41677c478bd9Sstevel@tonic-gate { "resolver.retry.normal", TO_RESOLVER_RETRY_NORMAL }, 41687c478bd9Sstevel@tonic-gate #define TO_RESOLVER_RETRY_FIRST 0x1E 41697c478bd9Sstevel@tonic-gate { "resolver.retry.first", TO_RESOLVER_RETRY_FIRST }, 41707c478bd9Sstevel@tonic-gate #define TO_CONTROL 0x1F 41717c478bd9Sstevel@tonic-gate { "control", TO_CONTROL }, 41727c478bd9Sstevel@tonic-gate #define TO_LHLO 0x20 41737c478bd9Sstevel@tonic-gate { "lhlo", TO_LHLO }, 41747c478bd9Sstevel@tonic-gate #define TO_AUTH 0x21 41757c478bd9Sstevel@tonic-gate { "auth", TO_AUTH }, 41767c478bd9Sstevel@tonic-gate #define TO_STARTTLS 0x22 41777c478bd9Sstevel@tonic-gate { "starttls", TO_STARTTLS }, 41787c478bd9Sstevel@tonic-gate #define TO_ACONNECT 0x23 41797c478bd9Sstevel@tonic-gate { "aconnect", TO_ACONNECT }, 41807c478bd9Sstevel@tonic-gate #define TO_QUEUEWARN_DSN 0x24 41817c478bd9Sstevel@tonic-gate { "queuewarn.dsn", TO_QUEUEWARN_DSN }, 41827c478bd9Sstevel@tonic-gate #define TO_QUEUERETURN_DSN 0x25 41837c478bd9Sstevel@tonic-gate { "queuereturn.dsn", TO_QUEUERETURN_DSN }, 41847c478bd9Sstevel@tonic-gate { NULL, 0 }, 41857c478bd9Sstevel@tonic-gate }; 41867c478bd9Sstevel@tonic-gate 41877c478bd9Sstevel@tonic-gate 41887c478bd9Sstevel@tonic-gate static void 41897c478bd9Sstevel@tonic-gate settimeout(name, val, sticky) 41907c478bd9Sstevel@tonic-gate char *name; 41917c478bd9Sstevel@tonic-gate char *val; 41927c478bd9Sstevel@tonic-gate bool sticky; 41937c478bd9Sstevel@tonic-gate { 41947c478bd9Sstevel@tonic-gate register struct timeoutinfo *to; 41957c478bd9Sstevel@tonic-gate int i, addopts; 41967c478bd9Sstevel@tonic-gate time_t toval; 41977c478bd9Sstevel@tonic-gate 41987c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 41997c478bd9Sstevel@tonic-gate sm_dprintf("settimeout(%s = %s)", name, val); 42007c478bd9Sstevel@tonic-gate 42017c478bd9Sstevel@tonic-gate for (to = TimeOutTab; to->to_name != NULL; to++) 42027c478bd9Sstevel@tonic-gate { 42037c478bd9Sstevel@tonic-gate if (sm_strcasecmp(to->to_name, name) == 0) 42047c478bd9Sstevel@tonic-gate break; 42057c478bd9Sstevel@tonic-gate } 42067c478bd9Sstevel@tonic-gate 42077c478bd9Sstevel@tonic-gate if (to->to_name == NULL) 42087c478bd9Sstevel@tonic-gate { 42097c478bd9Sstevel@tonic-gate errno = 0; /* avoid bogus error text */ 42107c478bd9Sstevel@tonic-gate syserr("settimeout: invalid timeout %s", name); 42117c478bd9Sstevel@tonic-gate return; 42127c478bd9Sstevel@tonic-gate } 42137c478bd9Sstevel@tonic-gate 42147c478bd9Sstevel@tonic-gate /* 42157c478bd9Sstevel@tonic-gate ** See if this option is preset for us. 42167c478bd9Sstevel@tonic-gate */ 42177c478bd9Sstevel@tonic-gate 42187c478bd9Sstevel@tonic-gate if (!sticky && bitnset(to->to_code, StickyTimeoutOpt)) 42197c478bd9Sstevel@tonic-gate { 42207c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 42217c478bd9Sstevel@tonic-gate sm_dprintf(" (ignored)\n"); 42227c478bd9Sstevel@tonic-gate return; 42237c478bd9Sstevel@tonic-gate } 42247c478bd9Sstevel@tonic-gate 42257c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 42267c478bd9Sstevel@tonic-gate sm_dprintf("\n"); 42277c478bd9Sstevel@tonic-gate 42287c478bd9Sstevel@tonic-gate toval = convtime(val, 'm'); 42297c478bd9Sstevel@tonic-gate addopts = 0; 42307c478bd9Sstevel@tonic-gate 42317c478bd9Sstevel@tonic-gate switch (to->to_code) 42327c478bd9Sstevel@tonic-gate { 42337c478bd9Sstevel@tonic-gate case TO_INITIAL: 42347c478bd9Sstevel@tonic-gate TimeOuts.to_initial = toval; 42357c478bd9Sstevel@tonic-gate break; 42367c478bd9Sstevel@tonic-gate 42377c478bd9Sstevel@tonic-gate case TO_MAIL: 42387c478bd9Sstevel@tonic-gate TimeOuts.to_mail = toval; 42397c478bd9Sstevel@tonic-gate break; 42407c478bd9Sstevel@tonic-gate 42417c478bd9Sstevel@tonic-gate case TO_RCPT: 42427c478bd9Sstevel@tonic-gate TimeOuts.to_rcpt = toval; 42437c478bd9Sstevel@tonic-gate break; 42447c478bd9Sstevel@tonic-gate 42457c478bd9Sstevel@tonic-gate case TO_DATAINIT: 42467c478bd9Sstevel@tonic-gate TimeOuts.to_datainit = toval; 42477c478bd9Sstevel@tonic-gate break; 42487c478bd9Sstevel@tonic-gate 42497c478bd9Sstevel@tonic-gate case TO_DATABLOCK: 42507c478bd9Sstevel@tonic-gate TimeOuts.to_datablock = toval; 42517c478bd9Sstevel@tonic-gate break; 42527c478bd9Sstevel@tonic-gate 42537c478bd9Sstevel@tonic-gate case TO_DATAFINAL: 42547c478bd9Sstevel@tonic-gate TimeOuts.to_datafinal = toval; 42557c478bd9Sstevel@tonic-gate break; 42567c478bd9Sstevel@tonic-gate 42577c478bd9Sstevel@tonic-gate case TO_COMMAND: 42587c478bd9Sstevel@tonic-gate TimeOuts.to_nextcommand = toval; 42597c478bd9Sstevel@tonic-gate break; 42607c478bd9Sstevel@tonic-gate 42617c478bd9Sstevel@tonic-gate case TO_RSET: 42627c478bd9Sstevel@tonic-gate TimeOuts.to_rset = toval; 42637c478bd9Sstevel@tonic-gate break; 42647c478bd9Sstevel@tonic-gate 42657c478bd9Sstevel@tonic-gate case TO_HELO: 42667c478bd9Sstevel@tonic-gate TimeOuts.to_helo = toval; 42677c478bd9Sstevel@tonic-gate break; 42687c478bd9Sstevel@tonic-gate 42697c478bd9Sstevel@tonic-gate case TO_QUIT: 42707c478bd9Sstevel@tonic-gate TimeOuts.to_quit = toval; 42717c478bd9Sstevel@tonic-gate break; 42727c478bd9Sstevel@tonic-gate 42737c478bd9Sstevel@tonic-gate case TO_MISC: 42747c478bd9Sstevel@tonic-gate TimeOuts.to_miscshort = toval; 42757c478bd9Sstevel@tonic-gate break; 42767c478bd9Sstevel@tonic-gate 42777c478bd9Sstevel@tonic-gate case TO_IDENT: 42787c478bd9Sstevel@tonic-gate TimeOuts.to_ident = toval; 42797c478bd9Sstevel@tonic-gate break; 42807c478bd9Sstevel@tonic-gate 42817c478bd9Sstevel@tonic-gate case TO_FILEOPEN: 42827c478bd9Sstevel@tonic-gate TimeOuts.to_fileopen = toval; 42837c478bd9Sstevel@tonic-gate break; 42847c478bd9Sstevel@tonic-gate 42857c478bd9Sstevel@tonic-gate case TO_CONNECT: 42867c478bd9Sstevel@tonic-gate TimeOuts.to_connect = toval; 42877c478bd9Sstevel@tonic-gate break; 42887c478bd9Sstevel@tonic-gate 42897c478bd9Sstevel@tonic-gate case TO_ICONNECT: 42907c478bd9Sstevel@tonic-gate TimeOuts.to_iconnect = toval; 42917c478bd9Sstevel@tonic-gate break; 42927c478bd9Sstevel@tonic-gate 42937c478bd9Sstevel@tonic-gate case TO_ACONNECT: 42947c478bd9Sstevel@tonic-gate TimeOuts.to_aconnect = toval; 42957c478bd9Sstevel@tonic-gate break; 42967c478bd9Sstevel@tonic-gate 42977c478bd9Sstevel@tonic-gate case TO_QUEUEWARN: 42987c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 42997c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NORMAL] = toval; 43007c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_URGENT] = toval; 43017c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NONURGENT] = toval; 43027c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_DSN] = toval; 43037c478bd9Sstevel@tonic-gate addopts = 2; 43047c478bd9Sstevel@tonic-gate break; 43057c478bd9Sstevel@tonic-gate 43067c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_NORMAL: 43077c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 43087c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NORMAL] = toval; 43097c478bd9Sstevel@tonic-gate break; 43107c478bd9Sstevel@tonic-gate 43117c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_URGENT: 43127c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 43137c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_URGENT] = toval; 43147c478bd9Sstevel@tonic-gate break; 43157c478bd9Sstevel@tonic-gate 43167c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_NON_URGENT: 43177c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 43187c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_NONURGENT] = toval; 43197c478bd9Sstevel@tonic-gate break; 43207c478bd9Sstevel@tonic-gate 43217c478bd9Sstevel@tonic-gate case TO_QUEUEWARN_DSN: 43227c478bd9Sstevel@tonic-gate toval = convtime(val, 'h'); 43237c478bd9Sstevel@tonic-gate TimeOuts.to_q_warning[TOC_DSN] = toval; 43247c478bd9Sstevel@tonic-gate break; 43257c478bd9Sstevel@tonic-gate 43267c478bd9Sstevel@tonic-gate case TO_QUEUERETURN: 43277c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 43287c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NORMAL] = toval; 43297c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_URGENT] = toval; 43307c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NONURGENT] = toval; 43317c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_DSN] = toval; 43327c478bd9Sstevel@tonic-gate addopts = 2; 43337c478bd9Sstevel@tonic-gate break; 43347c478bd9Sstevel@tonic-gate 43357c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_NORMAL: 43367c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 43377c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NORMAL] = toval; 43387c478bd9Sstevel@tonic-gate break; 43397c478bd9Sstevel@tonic-gate 43407c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_URGENT: 43417c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 43427c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_URGENT] = toval; 43437c478bd9Sstevel@tonic-gate break; 43447c478bd9Sstevel@tonic-gate 43457c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_NON_URGENT: 43467c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 43477c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_NONURGENT] = toval; 43487c478bd9Sstevel@tonic-gate break; 43497c478bd9Sstevel@tonic-gate 43507c478bd9Sstevel@tonic-gate case TO_QUEUERETURN_DSN: 43517c478bd9Sstevel@tonic-gate toval = convtime(val, 'd'); 43527c478bd9Sstevel@tonic-gate TimeOuts.to_q_return[TOC_DSN] = toval; 43537c478bd9Sstevel@tonic-gate break; 43547c478bd9Sstevel@tonic-gate 43557c478bd9Sstevel@tonic-gate case TO_HOSTSTATUS: 43567c478bd9Sstevel@tonic-gate MciInfoTimeout = toval; 43577c478bd9Sstevel@tonic-gate break; 43587c478bd9Sstevel@tonic-gate 43597c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRANS: 43607c478bd9Sstevel@tonic-gate toval = convtime(val, 's'); 43617c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_DEFAULT] = toval; 43627c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_FIRST] = toval; 43637c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_NORMAL] = toval; 43647c478bd9Sstevel@tonic-gate addopts = 2; 43657c478bd9Sstevel@tonic-gate break; 43667c478bd9Sstevel@tonic-gate 43677c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRY: 43687c478bd9Sstevel@tonic-gate i = atoi(val); 43697c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_DEFAULT] = i; 43707c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_FIRST] = i; 43717c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_NORMAL] = i; 43727c478bd9Sstevel@tonic-gate addopts = 2; 43737c478bd9Sstevel@tonic-gate break; 43747c478bd9Sstevel@tonic-gate 43757c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRANS_NORMAL: 43767c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_NORMAL] = convtime(val, 's'); 43777c478bd9Sstevel@tonic-gate break; 43787c478bd9Sstevel@tonic-gate 43797c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRY_NORMAL: 43807c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_NORMAL] = atoi(val); 43817c478bd9Sstevel@tonic-gate break; 43827c478bd9Sstevel@tonic-gate 43837c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRANS_FIRST: 43847c478bd9Sstevel@tonic-gate TimeOuts.res_retrans[RES_TO_FIRST] = convtime(val, 's'); 43857c478bd9Sstevel@tonic-gate break; 43867c478bd9Sstevel@tonic-gate 43877c478bd9Sstevel@tonic-gate case TO_RESOLVER_RETRY_FIRST: 43887c478bd9Sstevel@tonic-gate TimeOuts.res_retry[RES_TO_FIRST] = atoi(val); 43897c478bd9Sstevel@tonic-gate break; 43907c478bd9Sstevel@tonic-gate 43917c478bd9Sstevel@tonic-gate case TO_CONTROL: 43927c478bd9Sstevel@tonic-gate TimeOuts.to_control = toval; 43937c478bd9Sstevel@tonic-gate break; 43947c478bd9Sstevel@tonic-gate 43957c478bd9Sstevel@tonic-gate case TO_LHLO: 43967c478bd9Sstevel@tonic-gate TimeOuts.to_lhlo = toval; 43977c478bd9Sstevel@tonic-gate break; 43987c478bd9Sstevel@tonic-gate 43997c478bd9Sstevel@tonic-gate #if SASL 44007c478bd9Sstevel@tonic-gate case TO_AUTH: 44017c478bd9Sstevel@tonic-gate TimeOuts.to_auth = toval; 44027c478bd9Sstevel@tonic-gate break; 44037c478bd9Sstevel@tonic-gate #endif /* SASL */ 44047c478bd9Sstevel@tonic-gate 44057c478bd9Sstevel@tonic-gate #if STARTTLS 44067c478bd9Sstevel@tonic-gate case TO_STARTTLS: 44077c478bd9Sstevel@tonic-gate TimeOuts.to_starttls = toval; 44087c478bd9Sstevel@tonic-gate break; 44097c478bd9Sstevel@tonic-gate #endif /* STARTTLS */ 44107c478bd9Sstevel@tonic-gate 44117c478bd9Sstevel@tonic-gate default: 44127c478bd9Sstevel@tonic-gate syserr("settimeout: invalid timeout %s", name); 44137c478bd9Sstevel@tonic-gate break; 44147c478bd9Sstevel@tonic-gate } 44157c478bd9Sstevel@tonic-gate 44167c478bd9Sstevel@tonic-gate if (sticky) 44177c478bd9Sstevel@tonic-gate { 44187c478bd9Sstevel@tonic-gate for (i = 0; i <= addopts; i++) 44197c478bd9Sstevel@tonic-gate setbitn(to->to_code + i, StickyTimeoutOpt); 44207c478bd9Sstevel@tonic-gate } 44217c478bd9Sstevel@tonic-gate } 44227c478bd9Sstevel@tonic-gate /* 44237c478bd9Sstevel@tonic-gate ** INITTIMEOUTS -- parse and set timeout values 44247c478bd9Sstevel@tonic-gate ** 44257c478bd9Sstevel@tonic-gate ** Parameters: 44267c478bd9Sstevel@tonic-gate ** val -- a pointer to the values. If NULL, do initial 44277c478bd9Sstevel@tonic-gate ** settings. 44287c478bd9Sstevel@tonic-gate ** sticky -- if set, don't let other setoptions override 44297c478bd9Sstevel@tonic-gate ** this suboption value. 44307c478bd9Sstevel@tonic-gate ** 44317c478bd9Sstevel@tonic-gate ** Returns: 44327c478bd9Sstevel@tonic-gate ** none. 44337c478bd9Sstevel@tonic-gate ** 44347c478bd9Sstevel@tonic-gate ** Side Effects: 44357c478bd9Sstevel@tonic-gate ** Initializes the TimeOuts structure 44367c478bd9Sstevel@tonic-gate */ 44377c478bd9Sstevel@tonic-gate 44387c478bd9Sstevel@tonic-gate void 44397c478bd9Sstevel@tonic-gate inittimeouts(val, sticky) 44407c478bd9Sstevel@tonic-gate register char *val; 44417c478bd9Sstevel@tonic-gate bool sticky; 44427c478bd9Sstevel@tonic-gate { 44437c478bd9Sstevel@tonic-gate register char *p; 44447c478bd9Sstevel@tonic-gate 44457c478bd9Sstevel@tonic-gate if (tTd(37, 2)) 44467c478bd9Sstevel@tonic-gate sm_dprintf("inittimeouts(%s)\n", val == NULL ? "<NULL>" : val); 44477c478bd9Sstevel@tonic-gate if (val == NULL) 44487c478bd9Sstevel@tonic-gate { 44497c478bd9Sstevel@tonic-gate TimeOuts.to_connect = (time_t) 0 SECONDS; 44507c478bd9Sstevel@tonic-gate TimeOuts.to_aconnect = (time_t) 0 SECONDS; 44517c478bd9Sstevel@tonic-gate TimeOuts.to_iconnect = (time_t) 0 SECONDS; 44527c478bd9Sstevel@tonic-gate TimeOuts.to_initial = (time_t) 5 MINUTES; 44537c478bd9Sstevel@tonic-gate TimeOuts.to_helo = (time_t) 5 MINUTES; 44547c478bd9Sstevel@tonic-gate TimeOuts.to_mail = (time_t) 10 MINUTES; 44557c478bd9Sstevel@tonic-gate TimeOuts.to_rcpt = (time_t) 1 HOUR; 44567c478bd9Sstevel@tonic-gate TimeOuts.to_datainit = (time_t) 5 MINUTES; 44577c478bd9Sstevel@tonic-gate TimeOuts.to_datablock = (time_t) 1 HOUR; 44587c478bd9Sstevel@tonic-gate TimeOuts.to_datafinal = (time_t) 1 HOUR; 44597c478bd9Sstevel@tonic-gate TimeOuts.to_rset = (time_t) 5 MINUTES; 44607c478bd9Sstevel@tonic-gate TimeOuts.to_quit = (time_t) 2 MINUTES; 44617c478bd9Sstevel@tonic-gate TimeOuts.to_nextcommand = (time_t) 1 HOUR; 44627c478bd9Sstevel@tonic-gate TimeOuts.to_miscshort = (time_t) 2 MINUTES; 44637c478bd9Sstevel@tonic-gate #if IDENTPROTO 44647c478bd9Sstevel@tonic-gate TimeOuts.to_ident = (time_t) 5 SECONDS; 44657c478bd9Sstevel@tonic-gate #else /* IDENTPROTO */ 44667c478bd9Sstevel@tonic-gate TimeOuts.to_ident = (time_t) 0 SECONDS; 44677c478bd9Sstevel@tonic-gate #endif /* IDENTPROTO */ 44687c478bd9Sstevel@tonic-gate TimeOuts.to_fileopen = (time_t) 60 SECONDS; 44697c478bd9Sstevel@tonic-gate TimeOuts.to_control = (time_t) 2 MINUTES; 44707c478bd9Sstevel@tonic-gate TimeOuts.to_lhlo = (time_t) 2 MINUTES; 44717c478bd9Sstevel@tonic-gate #if SASL 44727c478bd9Sstevel@tonic-gate TimeOuts.to_auth = (time_t) 10 MINUTES; 44737c478bd9Sstevel@tonic-gate #endif /* SASL */ 44747c478bd9Sstevel@tonic-gate #if STARTTLS 44757c478bd9Sstevel@tonic-gate TimeOuts.to_starttls = (time_t) 1 HOUR; 44767c478bd9Sstevel@tonic-gate #endif /* STARTTLS */ 44777c478bd9Sstevel@tonic-gate if (tTd(37, 5)) 44787c478bd9Sstevel@tonic-gate { 44797c478bd9Sstevel@tonic-gate sm_dprintf("Timeouts:\n"); 44807c478bd9Sstevel@tonic-gate sm_dprintf(" connect = %ld\n", 44817c478bd9Sstevel@tonic-gate (long) TimeOuts.to_connect); 44827c478bd9Sstevel@tonic-gate sm_dprintf(" aconnect = %ld\n", 44837c478bd9Sstevel@tonic-gate (long) TimeOuts.to_aconnect); 44847c478bd9Sstevel@tonic-gate sm_dprintf(" initial = %ld\n", 44857c478bd9Sstevel@tonic-gate (long) TimeOuts.to_initial); 44867c478bd9Sstevel@tonic-gate sm_dprintf(" helo = %ld\n", (long) TimeOuts.to_helo); 44877c478bd9Sstevel@tonic-gate sm_dprintf(" mail = %ld\n", (long) TimeOuts.to_mail); 44887c478bd9Sstevel@tonic-gate sm_dprintf(" rcpt = %ld\n", (long) TimeOuts.to_rcpt); 44897c478bd9Sstevel@tonic-gate sm_dprintf(" datainit = %ld\n", 44907c478bd9Sstevel@tonic-gate (long) TimeOuts.to_datainit); 44917c478bd9Sstevel@tonic-gate sm_dprintf(" datablock = %ld\n", 44927c478bd9Sstevel@tonic-gate (long) TimeOuts.to_datablock); 44937c478bd9Sstevel@tonic-gate sm_dprintf(" datafinal = %ld\n", 44947c478bd9Sstevel@tonic-gate (long) TimeOuts.to_datafinal); 44957c478bd9Sstevel@tonic-gate sm_dprintf(" rset = %ld\n", (long) TimeOuts.to_rset); 44967c478bd9Sstevel@tonic-gate sm_dprintf(" quit = %ld\n", (long) TimeOuts.to_quit); 44977c478bd9Sstevel@tonic-gate sm_dprintf(" nextcommand = %ld\n", 44987c478bd9Sstevel@tonic-gate (long) TimeOuts.to_nextcommand); 44997c478bd9Sstevel@tonic-gate sm_dprintf(" miscshort = %ld\n", 45007c478bd9Sstevel@tonic-gate (long) TimeOuts.to_miscshort); 45017c478bd9Sstevel@tonic-gate sm_dprintf(" ident = %ld\n", (long) TimeOuts.to_ident); 45027c478bd9Sstevel@tonic-gate sm_dprintf(" fileopen = %ld\n", 45037c478bd9Sstevel@tonic-gate (long) TimeOuts.to_fileopen); 45047c478bd9Sstevel@tonic-gate sm_dprintf(" lhlo = %ld\n", 45057c478bd9Sstevel@tonic-gate (long) TimeOuts.to_lhlo); 45067c478bd9Sstevel@tonic-gate sm_dprintf(" control = %ld\n", 45077c478bd9Sstevel@tonic-gate (long) TimeOuts.to_control); 45087c478bd9Sstevel@tonic-gate } 45097c478bd9Sstevel@tonic-gate return; 45107c478bd9Sstevel@tonic-gate } 45117c478bd9Sstevel@tonic-gate 45127c478bd9Sstevel@tonic-gate for (;; val = p) 45137c478bd9Sstevel@tonic-gate { 45147c478bd9Sstevel@tonic-gate while (isascii(*val) && isspace(*val)) 45157c478bd9Sstevel@tonic-gate val++; 45167c478bd9Sstevel@tonic-gate if (*val == '\0') 45177c478bd9Sstevel@tonic-gate break; 45187c478bd9Sstevel@tonic-gate for (p = val; *p != '\0' && *p != ','; p++) 45197c478bd9Sstevel@tonic-gate continue; 45207c478bd9Sstevel@tonic-gate if (*p != '\0') 45217c478bd9Sstevel@tonic-gate *p++ = '\0'; 45227c478bd9Sstevel@tonic-gate 45237c478bd9Sstevel@tonic-gate if (isascii(*val) && isdigit(*val)) 45247c478bd9Sstevel@tonic-gate { 45257c478bd9Sstevel@tonic-gate /* old syntax -- set everything */ 45267c478bd9Sstevel@tonic-gate TimeOuts.to_mail = convtime(val, 'm'); 45277c478bd9Sstevel@tonic-gate TimeOuts.to_rcpt = TimeOuts.to_mail; 45287c478bd9Sstevel@tonic-gate TimeOuts.to_datainit = TimeOuts.to_mail; 45297c478bd9Sstevel@tonic-gate TimeOuts.to_datablock = TimeOuts.to_mail; 45307c478bd9Sstevel@tonic-gate TimeOuts.to_datafinal = TimeOuts.to_mail; 45317c478bd9Sstevel@tonic-gate TimeOuts.to_nextcommand = TimeOuts.to_mail; 45327c478bd9Sstevel@tonic-gate if (sticky) 45337c478bd9Sstevel@tonic-gate { 45347c478bd9Sstevel@tonic-gate setbitn(TO_MAIL, StickyTimeoutOpt); 45357c478bd9Sstevel@tonic-gate setbitn(TO_RCPT, StickyTimeoutOpt); 45367c478bd9Sstevel@tonic-gate setbitn(TO_DATAINIT, StickyTimeoutOpt); 45377c478bd9Sstevel@tonic-gate setbitn(TO_DATABLOCK, StickyTimeoutOpt); 45387c478bd9Sstevel@tonic-gate setbitn(TO_DATAFINAL, StickyTimeoutOpt); 45397c478bd9Sstevel@tonic-gate setbitn(TO_COMMAND, StickyTimeoutOpt); 45407c478bd9Sstevel@tonic-gate } 45417c478bd9Sstevel@tonic-gate continue; 45427c478bd9Sstevel@tonic-gate } 45437c478bd9Sstevel@tonic-gate else 45447c478bd9Sstevel@tonic-gate { 45457c478bd9Sstevel@tonic-gate register char *q = strchr(val, ':'); 45467c478bd9Sstevel@tonic-gate 45477c478bd9Sstevel@tonic-gate if (q == NULL && (q = strchr(val, '=')) == NULL) 45487c478bd9Sstevel@tonic-gate { 45497c478bd9Sstevel@tonic-gate /* syntax error */ 45507c478bd9Sstevel@tonic-gate continue; 45517c478bd9Sstevel@tonic-gate } 45527c478bd9Sstevel@tonic-gate *q++ = '\0'; 45537c478bd9Sstevel@tonic-gate settimeout(val, q, sticky); 45547c478bd9Sstevel@tonic-gate } 45557c478bd9Sstevel@tonic-gate } 45567c478bd9Sstevel@tonic-gate } 4557