Lines Matching +full:early +full:- +full:to +full:- +full:mid
2 * Copyright (c) 1998-2006, 2008, 2009, 2011 Proofpoint, Inc. and its suppliers.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
8 * By using this file, you agree to the terms and conditions set
29 "@(#) Copyright (c) 1998-2013 Proofpoint, Inc. and its suppliers.\n\
31 Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.\n\
36 SM_RCSID("@(#)$Id: main.c,v 8.988 2013-11-23 02:52:37 gshapiro Exp $")
52 "@(#)$Debug: no_persistent_restart - don't restart, log only $");
68 ** SENDMAIL -- Post mail to a set of destinations.
71 ** call this routine to actually deliver mail. Sendmail in
85 ** Britton-Lee, Inc., purveyors of fine
86 ** database computers (11/81 - 10/88).
88 ** (11/88 - 9/89).
89 ** UCB/Mammoth Project (10/89 - 7/95).
90 ** InReference, Inc. (8/95 - 1/97).
91 ** Sendmail, Inc. (1/98 - 9/13).
93 ** Few of them (Britton-Lee in particular) have had
94 ** anything to gain from my involvement in this project.
98 ** Sendmail, Inc. (3/98 - 10/13).
99 ** Proofpoint, Inc. (10/13 - present).
102 ** Sendmail, Inc. (12/98 - 10/13).
103 ** Proofpoint, Inc. (10/13 - present).
114 char *Mbdb = "pw"; /* mailbox database defaults to /etc/passwd */
140 /* Some options are dangerous to allow users to use in non-submit mode */
149 "WARNING: Ignoring submission mode -%c option (not in submission mode)\n", \
156 "WARNING: Ignoring submission mode -%c option with -q\n", \
182 int qgrp = NOQGRP; /* queue group to process */
186 bool auth = true; /* whether to set e_auth_param */
188 bool run_in_foreground = false; /* -bD mode */
196 char *queuegroup = NULL; /* queue group to process */
202 bool save_val; /* to save some bool var. */
203 int cftype; /* which cf file to use? */
235 /* set the default in/out channel so errors reported to screen */
240 ** Check to see if we reentered.
312 /* do machine-dependent initializations */
316 SyslogPrefixLen = PIDLEN + (MAXQFNAME - 3) + SL_FUDGE + SLDLL;
331 tTsetup(tTdvect, sizeof(tTdvect), "0-99.1,*_trace_*.1");
338 InitialGidSet[0] = (GID_T) -1;
350 /* Only allow root (or non-set-*-ID binaries) to use SIGUSR1 */
353 /* arrange to dump state on user-1 signal */
358 /* ignore user-1 signal */
366 /* Handle any non-getoptable constructions. */
401 /* Set to 0 to allow -b; need to check optarg before using it! */
403 while ((j = getopt(argc, argv, OPTIONS)) != -1)
454 syserr("-D file must be before -d");
487 "option requires an argument -- '%c'",
494 SyslogPrefixLen = PIDLEN + (MAXQFNAME - 3) +
511 "WARNING: Can not use -d with -q. Disabling debugging.\n");
554 DaemonPid = CurrentPid; /* needed for finis() to work */
558 (void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof(rnamebuf));
573 ** if running non-set-user-ID binary as non-root, pretend
580 sm_dprintf("Non-set-user-ID binary: RunAsUid = RealUid = %d\n",
618 j -= h + 1;
687 ** determined - or early log messages may get bogus time stamps
714 ** Initialize name server if it is going to be used.
788 for (av = hp->h_aliases; av != NULL && *av != NULL; av++)
795 for (i = 0; i >= 0 && hp->h_addr_list[i] != NULL; i++)
808 switch (hp->h_addrtype)
812 if (hp->h_length != INADDRSZ)
815 memmove(&ia, hp->h_addr_list[i], INADDRSZ);
823 if (hp->h_length != IN6ADDRSZ)
826 memmove(&ia6, hp->h_addr_list[i], IN6ADDRSZ);
864 while ((j = getopt(argc, argv, OPTIONS)) != -1)
897 case 'r': /* obsolete -f flag */
967 usrerr("Invalid -N argument");
1012 usrerr("Can not use -Q with -b%c", OpMode);
1034 usrerr("Can not use -q with -b%c", OpMode);
1039 /* don't override -bd, -bD or -bp */
1056 usrerr("Can not use -q!G");
1062 usrerr("Can not use multiple -qG options");
1071 new->queue_match = newstr(&optarg[1]);
1072 new->queue_negate = negate;
1073 new->queue_next = QueueLimitId;
1079 new->queue_match = newstr(&optarg[1]);
1080 new->queue_negate = negate;
1081 new->queue_next = QueueLimitRecipient;
1087 new->queue_match = newstr(&optarg[1]);
1088 new->queue_negate = negate;
1089 new->queue_next = QueueLimitSender;
1101 new->queue_match = newstr(&optarg[1]);
1102 new->queue_negate = negate;
1103 new->queue_next = QueueLimitQuarantine;
1127 usrerr("Invalid -q value");
1138 case 'R': /* DSN RET: what to return */
1142 usrerr("Duplicate -R flag");
1151 usrerr("Invalid -R value");
1174 usrerr("Invalid syntax in -V flag");
1210 case 'c': /* connect to non-local mailers */
1212 case 'm': /* send to me too */
1214 case 'v': /* give blow-by-blow description */
1311 /* Remove the ability for a normal user to send signals */
1320 ** can't send signals. However, it doesn't need to be
1327 sm_dprintf("Changing real uid to %d\n", (int) new_uid);
1340 ** Have to change both effective and real so need to
1341 ** change them both to effective to keep privs.
1345 sm_dprintf("Changing uid to %d\n", (int) new_uid);
1363 if (SuperSafe == SAFE_INTERACTIVE && !SM_IS_INTERACTIVE(CurEnv->e_sendmode))
1383 usrerr("-U requires SMTPUTF8");
1411 /* avoid denial-of-service attacks */
1426 /* drop privileges -- daemon mode done after socket/bind */
1431 usrerr("Mail submission program must have RunAsUser set to non root user");
1453 /* set up the $=m class now, after .cf has a chance to redefine $m */
1488 ** Do more command line checking -- these are things that
1489 ** have to modify the results of reading the config file.
1494 auth_warning(&BlankEnvelope, "Processed by %s with -C %s",
1525 /* need MCI cache to have persistence */
1533 /* need HostStatusDir in order to have SingleThreadDelivery */
1585 sm_dprintf("Deny user %d attempt to %s\n",
1590 "user %d attempted to %s",
1602 ** If -bv and RestrictExpand,
1603 ** drop privs to prevent normal
1609 sm_dprintf("Drop privs for user %d attempt to expand (RestrictExpand)\n",
1622 sm_dprintf("Failed to drop privs for user %d attempt to expand, exiting\n",
1624 CurEnv->e_id = NULL;
1637 /* Nothing special to check */
1644 sm_dprintf("Deny user %d attempt to rebuild the alias map\n",
1648 "user %d attempted to rebuild the alias map",
1670 ** If -v and RestrictExpand, reset
1671 ** Verbose to prevent normal users
1705 /* arrange to exit cleanly on hangup signal */
1710 "Notice: -bv may give misleading output for non-privileged user\n");
1725 /* arrange to restart on hangup signal */
1728 "daemon invoked without full pathname; kill -1 won't work");
1738 /* arrange to exit cleanly on hangup signal */
1756 /* check for characters that may have to be quoted */
1837 set_def_queueval(st->s_quegrp, true);
1839 /* the indices of built-in mailers */
1842 LocalMailer = st->s_mailer;
1851 ProgMailer = st->s_mailer;
1852 clrbitn(M_MUSER, ProgMailer->m_flags);
1860 FileMailer = st->s_mailer;
1861 clrbitn(M_MUSER, FileMailer->m_flags);
1868 InclMailer = st->s_mailer;
1875 setbitn(M_ALIASABLE, LocalMailer->m_flags);
1876 setbitn(M_HASPWENT, LocalMailer->m_flags);
1877 setbitn(M_TRYRULESET5, LocalMailer->m_flags);
1878 setbitn(M_CHECKINCLUDE, LocalMailer->m_flags);
1879 setbitn(M_CHECKPROG, LocalMailer->m_flags);
1880 setbitn(M_CHECKFILE, LocalMailer->m_flags);
1881 setbitn(M_CHECKUDB, LocalMailer->m_flags);
1884 setbitn(M_RUNASRCPT, ProgMailer->m_flags);
1886 setbitn(M_RUNASRCPT, FileMailer->m_flags);
1891 setbitn(M_VRFY250, LocalMailer->m_flags);
1893 setbitn(M_VRFY250, ProgMailer->m_flags);
1895 setbitn(M_VRFY250, FileMailer->m_flags);
1898 /* MIME Content-Types that cannot be transfer encoded */
1907 /* MIME Content-Transfer-Encodings that can be encoded */
1913 /* MIME Content-Types that should be treated as binary */
1917 setclass('b', "application/octet-stream");
1920 /* MIME headers which have fields to check for overflow */
1921 setclass(macid("{checkMIMEFieldHeaders}"), "content-disposition");
1922 setclass(macid("{checkMIMEFieldHeaders}"), "content-type");
1924 /* MIME headers to check for length overflow */
1925 setclass(macid("{checkMIMETextHeaders}"), "content-description");
1927 /* MIME headers to check for overflow and rebalance */
1928 setclass(macid("{checkMIMEHeaders}"), "content-disposition");
1929 setclass(macid("{checkMIMEHeaders}"), "content-id");
1930 setclass(macid("{checkMIMEHeaders}"), "content-transfer-encoding");
1931 setclass(macid("{checkMIMEHeaders}"), "content-type");
1932 setclass(macid("{checkMIMEHeaders}"), "mime-version");
1934 /* Macros to save in the queue file -- don't remove any */
1971 /* check to see if we own the queue directory */
1978 usrerr("You do not have permission to process the queue");
1993 /* Convert queuegroup string to qgrp number */
2021 ** Do operation-mode-dependent initialization.
2033 /* Selecting a particular queue group to run */
2034 for (j = 0; j < Queue[qgrp]->qg_numqueues; j++)
2066 usrerr("Can not use -Q with -q%c", QueueMode);
2108 /* don't open maps for daemon -- done below in child */
2125 ** Switch to the main envelope.
2178 ** sendmail is extended to raise additional
2216 "ERROR: TLS failed to initialize\n");
2236 pid_t pid = -1;
2245 ** to stay around for a possible SIGTERM. The SIGTERM will
2247 ** need to be sent SIGTERM as well. At the same time, we
2248 ** want to return control to the command line. So we do an
2255 ** If the fork() failed we should still try to do
2257 ** is going to start the run and wait for all
2258 ** of the children to finish.
2278 ** To run a specific queue group mark it to
2285 Queue[i]->qg_nextrun = (time_t) -1;
2286 Queue[qgrp]->qg_nextrun = 0;
2292 (void) run_work_group(Queue[qgrp]->qg_wgrp,
2299 /* set the title to make it easier to find */
2315 ** non-existent children
2368 PROC_DAEMON, 0, -1, NULL);
2376 ** getrequests() will return in a child (unless -d93.100 is used).
2429 ? "+persistent-queueing@"
2451 /* workaround: can't seem to release the signal in the parent */
2469 ** To run a specific queue group mark it to
2476 Queue[i]->qg_nextrun = (time_t) -1;
2477 Queue[qgrp]->qg_nextrun = 0;
2483 (void) run_work_group(Queue[qgrp]->qg_wgrp,
2493 ** we're going to do the queue runner monitoring here.
2501 ** Write the pid to file
2507 /* set the title to make it easier to find */
2521 ** Waiting for non-existent
2559 group, -1);
2582 -1);
2595 ** Write the pid to file
2601 /* set the title to make it easier to find */
2646 RealHostName[MAXNAME] = '\0'; /* XXX - 1 ? */
2668 /* WARNING: "non-braced" else */
2802 /* interactive -- all errors are global */
2814 fromaddr_x = fromaddr; /* for logging - see below -- just in case */
2821 usrerr("non-ASCII sender address %s requires SMTPUTF8",
2831 (!bitnset(M_LOCALMAILER, MainEnvelope.e_from.q_mailer->m_flags) ||
2834 auth_warning(&MainEnvelope, "%s set sender to %s using -%c",
2844 /* set the initial sender for AUTH= to $f@$j */
2887 ** Scan argv and deliver the message to everyone.
2901 ** If using -t, force not sending to argv recipients, even
2909 for (q = MainEnvelope.e_sendqueue; q != NULL; q = q->q_next)
2910 q->q_state = QS_REMOVED;
2938 /* Log who the mail would have gone to */
2946 return -1;
2955 return -1;
2990 i = FastSplit > 0 ? 0 : -1;
2991 for (e = &MainEnvelope; e != NULL; e = e->e_sibling, i++)
2995 e->e_from.q_state = QS_SENDER;
2999 printaddr(sm_debug_file(), &e->e_from, false);
3001 e->e_to = NULL;
3008 next = e->e_sibling;
3009 e->e_sibling = NULL;
3013 e->e_sibling = next;
3026 ** STOP_SENDMAIL -- Stop the running program
3047 ** FINIS -- Clean up and exit.
3050 ** drop -- whether or not to drop CurEnv envelope
3051 ** cleanup -- call exit() or _exit()?
3052 ** exitstat -- exit status to use for exit() call
3070 /* Still want to process new timeouts added below */
3093 CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id);
3105 CurEnv->e_to = NULL;
3108 if (CurEnv->e_id != NULL)
3115 sm_rpool_free(CurEnv->e_rpool);
3116 CurEnv->e_rpool = NULL;
3118 /* these may have pointed to the rpool */
3119 CurEnv->e_to = NULL;
3120 CurEnv->e_message = NULL;
3121 CurEnv->e_statmsg = NULL;
3122 CurEnv->e_quarmsg = NULL;
3123 CurEnv->e_bodytype = NULL;
3124 CurEnv->e_id = NULL;
3125 CurEnv->e_envid = NULL;
3126 CurEnv->e_auth_param = NULL;
3135 /* close maps belonging to this pid */
3158 sm_syslog(LOG_DEBUG, CurEnv->e_id, "finis, pid=%d",
3161 CurEnv->e_errormode == EM_BERKNET)
3191 sm_rpool_free(CurEnv->e_rpool);
3196 sm_debug_level(&SmHeapCheck) - 1);
3207 ** INTINDEBUG -- signal handler for SIGINT in -bt mode
3210 ** sig -- incoming signal.
3216 ** longjmps back to test mode loop.
3219 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
3249 ** SIGTERM -- SIGTERM handler for the daemon
3252 ** sig -- signal number.
3259 ** the daemon to exit.
3262 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
3283 ** SIGHUP -- handle a SIGHUP signal
3286 ** sig -- incoming signal.
3293 ** to restart.
3296 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
3313 ** SIGPIPE -- signal handler for SIGPIPE
3316 ** sig -- incoming signal.
3323 ** display to stop.
3326 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
3343 ** INTSIG -- clean up on interrupt
3345 ** This just arranges to exit. It pessimizes in that it
3349 ** sig -- incoming signal.
3358 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
3378 /* Clean-up on aborted stdin message submission */
3383 if (CurEnv->e_id != NULL)
3399 sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt");
3407 ** DISCONNECT -- remove our connection with any foreground process
3410 ** droplev -- how "deeply" we should drop the line.
3411 ** 0 -- ignore signals, mail back errors, make sure
3412 ** output goes to stdout.
3413 ** 1 -- also, make stdout go to /dev/null.
3414 ** 2 -- also, disconnect from controlling terminal
3416 ** e -- the current envelope.
3422 ** Try to insure that we are immune to vagaries of
3431 #define LOGID(e) (((e) != NULL && (e)->e_id != NULL) ? (e)->e_id : NOQID)
3455 CurEnv->e_errormode = EM_MAIL;
3472 ** output to the transcript
3474 ** might be a layer on top of smioout due to encryption
3492 if (smioout->sm_magic == NULL &&
3503 if (fd == -1)
3543 /* Return if "--" or not an option of any form. */
3544 if (ap[0] != '-' || ap[1] == '-')
3547 /* Don't allow users to use "-Q." or "-Q ." */
3553 "Can not use -Q.\n");
3564 argv[1] != NULL && argv[1][0] != '-')
3570 /* If -C doesn't have an argument, use sendmail.cf. */
3576 "-C", __DEFPATH);
3579 /* If -q doesn't have an argument, run it once. */
3581 *argv = "-q0";
3583 /* If -Q doesn't have an argument, disable quarantining */
3585 *argv = "-Q.";
3587 /* if -d doesn't have an argument, use 0-99.1 */
3589 *argv = "-d0-99.1";
3592 /* if -E doesn't have an argument, use -EC */
3594 *argv = "-EC";
3596 /* if -J doesn't have an argument, use -JJ */
3598 *argv = "-JJ";
3603 ** AUTH_WARNING -- specify authorization warning
3606 ** e -- the current envelope.
3607 ** msg -- the text of the message.
3608 ** args -- arguments to the message.
3651 addheader("X-Authentication-Warning", buf, 0, e, true);
3653 sm_syslog(LOG_INFO, e->e_id,
3654 "Authentication-Warning: %.400s", buf);
3657 ** GETEXTENV -- get from external environment
3660 ** envar -- the name of the variable to retrieve
3682 ** SM_SETUSERENV -- set an environment variable in the propagated environment
3685 ** envar -- the name of the environment variable.
3686 ** value -- the value to which it should be set. If
3689 ** to sm_setuserenv is ignored.
3734 ** DUMPSTATE -- dump state
3747 sm_syslog(LOG_DEBUG, CurEnv->e_id,
3748 "--- dumping state on %s: $j = %s ---",
3754 sm_syslog(LOG_DEBUG, CurEnv->e_id,
3757 sm_syslog(LOG_DEBUG, CurEnv->e_id, "CurChildren = %d", CurChildren);
3758 sm_syslog(LOG_DEBUG, CurEnv->e_id, "NextMacroId = %d (Max %d)",
3760 sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- open file descriptors: ---");
3762 sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- connection cache: ---");
3773 sm_syslog(LOG_DEBUG, CurEnv->e_id,
3774 "--- ruleset debug_dumpstate returns stat %d, pv: ---",
3777 sm_syslog(LOG_DEBUG, CurEnv->e_id, "%s", *pvp);
3779 sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- end of state dump ---");
3784 ** SIGUSR1 -- Signal a request to dump state.
3787 ** sig -- calling signal.
3793 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
3819 ** DROP_PRIVILEGES -- reduce privileges to those of the RunAsUser option
3822 ** to_real_uid -- if set, drop to the real uid instead
3865 ** So for now we keep it as it is; if you want to change it, use
3866 ** if (geteuid() == 0 && setgroups(1, emptygidset) == -1)
3869 if (setgroups(1, emptygidset) == -1 && geteuid() == 0)
3880 ** Drop gid to real gid.
3882 ** and then use setgid() to finally drop all group privileges.
3925 syserr("drop_privileges: Unable to set effective gid=%ld to RunAsGid=%ld",
3937 ** Try to setuid(RunAsUid).
3940 ** and we didn't have to drop privileges to the real uid.
3952 ** setuid() to drop the saved-uid as well.
3957 if (setreuid(RunAsUid, -1) < 0)
3959 syserr("drop_privileges: setreuid(%d, -1) failed",
3983 ** allows a non-root process to override setuid()
3994 ** Some operating systems will keep the saved-uid
3995 ** if a non-root effective-uid calls setuid(real-uid)
3996 ** making it possible to set it back again later.
3999 syserr("drop_privileges: Unable to drop non-root set-user-ID privileges");
4030 ** FILL_FD -- make sure a file descriptor has been properly allocated
4032 ** Used to make sure that stdin/out/err are allocated on startup
4035 ** fd -- the file descriptor to be filled.
4036 ** where -- a string used for logging. If NULL, this is
4075 ** SM_PRINTOPTIONS -- print options
4078 ** options -- array of options.
4111 ** TO8BIT -- convert \octal sequences in a test mode input line
4114 ** str -- the input line.
4115 ** mq -- "quote" meta chars?
4152 oct += nxtc - '0';
4174 ** TESTMODELINE -- process a test mode input line
4177 ** line -- the input line.
4178 ** e -- the current environment.
4196 int mid; local
4231 help("-bt", e);
4234 case '.': /* config-style settings */
4238 mid = macid_parse(&line[2], &delimptr);
4239 if (mid == 0)
4243 macdefine(&e->e_macro, A_TEMP, mid, lbp);
4249 if (line[2] == '\0') /* not to call syserr() */
4252 mid = macid_parse(&line[2], &delimptr);
4253 if (mid == 0)
4274 setclass(mid, wd);
4291 case '=': /* config-style settings */
4309 s = rw->r_lhs;
4320 s = rw->r_rhs;
4329 } while ((rw = rw->r_next) != NULL);
4352 case '-': /* set command-line-like opts */
4361 "Usage: -d{debug arguments}\n");
4366 "Unknown \"-\" command %s\n", line);
4379 mid = macid(&line[2]);
4381 if (mid != 0 &&
4382 (st = stab(macname(mid), ST_DYNMAP, ST_FIND)) != NULL)
4384 dynmap = &st->s_dynclass;
4385 q = dynmap->map_class->map_cname;
4392 "makemap -u %s %s",
4393 q, dynmap->map_file);
4394 if (!SM_IS_EMPTY(dynmap->map_tag))
4397 " | grep -i '^%s:'",
4398 dynmap->map_tag);
4404 if (mid != 0)
4405 stabapply(dump_class, mid);
4408 mid = macid(&line[1]);
4409 if (mid == 0)
4411 p = macvalue(mid, e);
4425 while (--p >= line && SM_ISSPACE(*p))
4443 CurEnv->e_id = NULL;
4462 NULL, -1, NULL);
4528 if (!bitset(MF_OPEN, map->s_map.map_mflags) &&
4529 !openmap(&(map->s_map)))
4539 p = (*map->s_map.map_class->map_lookup)
4540 (&map->s_map, q, av, &rcode);
4555 e->e_from.q_user);
4593 m = st->s_mailer;
4611 e->e_to = NULL;
4650 macdefine(&e->e_macro, A_TEMP,
4693 a.q_mailer->m_name,
4701 a.q_mailer->m_name,
4703 e->e_to = NULL;
4796 m = st->s_mailer;
4882 if (s->s_symtype != ST_CLASS)
4884 if (bitnset(bitidx(id), s->s_class))
4886 "%s\n", s->s_name);
4890 ** An exception type used to create QuickAbort exceptions.
4891 ** This is my first cut at converting QuickAbort from longjmp to exceptions.
4893 ** to longjmp in the original code (either 1 or 2). I don't know the
4894 ** significance of 1 vs 2: the calls to setjmp don't care.