envelope.c
上传用户:xu_441
上传日期:2007-01-04
资源大小:1640k
文件大小:23k
源码类别:

Email客户端

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
  3.  * All rights reserved.
  4.  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
  5.  * Copyright (c) 1988, 1993
  6.  * The Regents of the University of California.  All rights reserved.
  7.  *
  8.  * By using this file, you agree to the terms and conditions set
  9.  * forth in the LICENSE file which can be found at the top level of
  10.  * the sendmail distribution.
  11.  *
  12.  */
  13. #ifndef lint
  14. static char id[] = "@(#)$Id: envelope.c,v 8.180 1999/12/03 03:39:44 gshapiro Exp $";
  15. #endif /* ! lint */
  16. #include <sendmail.h>
  17. /*
  18. **  NEWENVELOPE -- allocate a new envelope
  19. **
  20. ** Supports inheritance.
  21. **
  22. ** Parameters:
  23. ** e -- the new envelope to fill in.
  24. ** parent -- the envelope to be the parent of e.
  25. **
  26. ** Returns:
  27. ** e.
  28. **
  29. ** Side Effects:
  30. ** none.
  31. */
  32. ENVELOPE *
  33. newenvelope(e, parent)
  34. register ENVELOPE *e;
  35. register ENVELOPE *parent;
  36. {
  37. if (e == parent && e->e_parent != NULL)
  38. parent = e->e_parent;
  39. clearenvelope(e, TRUE);
  40. if (e == CurEnv)
  41. memmove((char *) &e->e_from,
  42. (char *) &NullAddress,
  43. sizeof e->e_from);
  44. else
  45. memmove((char *) &e->e_from,
  46. (char *) &CurEnv->e_from,
  47. sizeof e->e_from);
  48. e->e_parent = parent;
  49. assign_queueid(e);
  50. e->e_ctime = curtime();
  51. if (parent != NULL)
  52. e->e_msgpriority = parent->e_msgsize;
  53. e->e_puthdr = putheader;
  54. e->e_putbody = putbody;
  55. if (CurEnv->e_xfp != NULL)
  56. (void) fflush(CurEnv->e_xfp);
  57. return e;
  58. }
  59. /*
  60. **  DROPENVELOPE -- deallocate an envelope.
  61. **
  62. ** Parameters:
  63. ** e -- the envelope to deallocate.
  64. ** fulldrop -- if set, do return receipts.
  65. **
  66. ** Returns:
  67. ** none.
  68. **
  69. ** Side Effects:
  70. ** housekeeping necessary to dispose of an envelope.
  71. ** Unlocks this queue file.
  72. */
  73. void
  74. dropenvelope(e, fulldrop)
  75. register ENVELOPE *e;
  76. bool fulldrop;
  77. {
  78. bool queueit = FALSE;
  79. bool message_timeout = FALSE;
  80. bool failure_return = FALSE;
  81. bool delay_return = FALSE;
  82. bool success_return = FALSE;
  83. bool pmnotify = bitset(EF_PM_NOTIFY, e->e_flags);
  84. register ADDRESS *q;
  85. char *id = e->e_id;
  86. char buf[MAXLINE];
  87. if (tTd(50, 1))
  88. {
  89. dprintf("dropenvelope %lx: id=", (u_long) e);
  90. xputs(e->e_id);
  91. dprintf(", flags=");
  92. printenvflags(e);
  93. if (tTd(50, 10))
  94. {
  95. dprintf("sendq=");
  96. printaddr(e->e_sendqueue, TRUE);
  97. }
  98. }
  99. if (LogLevel > 84)
  100. sm_syslog(LOG_DEBUG, id,
  101.   "dropenvelope, e_flags=0x%lx, OpMode=%c, pid=%d",
  102.   e->e_flags, OpMode, getpid());
  103. /* we must have an id to remove disk files */
  104. if (id == NULL)
  105. return;
  106. /* if verify-only mode, we can skip most of this */
  107. if (OpMode == MD_VERIFY)
  108. goto simpledrop;
  109. if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
  110. logsender(e, NULL);
  111. e->e_flags &= ~EF_LOGSENDER;
  112. /* post statistics */
  113. poststats(StatFile);
  114. /*
  115. **  Extract state information from dregs of send list.
  116. */
  117. if (curtime() > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass])
  118. message_timeout = TRUE;
  119. if (TimeOuts.to_q_return[e->e_timeoutclass] == NOW &&
  120.     !bitset(EF_RESPONSE, e->e_flags))
  121. {
  122. message_timeout = TRUE;
  123. e->e_flags |= EF_FATALERRS|EF_CLRQUEUE;
  124. }
  125. e->e_flags &= ~EF_QUEUERUN;
  126. for (q = e->e_sendqueue; q != NULL; q = q->q_next)
  127. {
  128. if (QS_IS_UNDELIVERED(q->q_state))
  129. queueit = TRUE;
  130. /* see if a notification is needed */
  131. if (bitset(QPINGONFAILURE, q->q_flags) &&
  132.     ((message_timeout && QS_IS_QUEUEUP(q->q_state)) ||
  133.      QS_IS_BADADDR(q->q_state)))
  134. {
  135. failure_return = TRUE;
  136. if (q->q_owner == NULL && !emptyaddr(&e->e_from))
  137. (void) sendtolist(e->e_from.q_paddr, NULLADDR,
  138.   &e->e_errorqueue, 0, e);
  139. }
  140. else if (bitset(QPINGONSUCCESS, q->q_flags) &&
  141.  ((QS_IS_SENT(q->q_state) &&
  142.    bitnset(M_LOCALMAILER, q->q_mailer->m_flags)) ||
  143.   bitset(QRELAYED|QEXPANDED|QDELIVERED, q->q_flags)))
  144. {
  145. success_return = TRUE;
  146. }
  147. }
  148. if (e->e_class < 0)
  149. e->e_flags |= EF_NO_BODY_RETN;
  150. /*
  151. **  See if the message timed out.
  152. */
  153. if (!queueit)
  154. /* EMPTY */
  155. /* nothing to do */ ;
  156. else if (message_timeout)
  157. {
  158. if (failure_return)
  159. {
  160. (void) snprintf(buf, sizeof buf,
  161. "Cannot send message within %s",
  162. pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
  163. if (e->e_message != NULL)
  164. free(e->e_message);
  165. e->e_message = newstr(buf);
  166. message(buf);
  167. e->e_flags |= EF_CLRQUEUE;
  168. }
  169. fprintf(e->e_xfp, "Message could not be delivered for %sn",
  170. pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
  171. fprintf(e->e_xfp, "Message will be deleted from queuen");
  172. for (q = e->e_sendqueue; q != NULL; q = q->q_next)
  173. {
  174. if (QS_IS_UNDELIVERED(q->q_state))
  175. {
  176. q->q_state = QS_BADADDR;
  177. q->q_status = "4.4.7";
  178. }
  179. }
  180. }
  181. else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 &&
  182.     curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass])
  183. {
  184. if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) &&
  185.     e->e_class >= 0 &&
  186.     e->e_from.q_paddr != NULL &&
  187.     strcmp(e->e_from.q_paddr, "<>") != 0 &&
  188.     strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 &&
  189.     (strlen(e->e_from.q_paddr) <= (SIZE_T) 8 ||
  190.      strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0))
  191. {
  192. for (q = e->e_sendqueue; q != NULL; q = q->q_next)
  193. {
  194. if (QS_IS_QUEUEUP(q->q_state) &&
  195. #if _FFR_NODELAYDSN_ON_HOLD
  196.     !bitnset(M_HOLD, q->q_mailer->m_flags) &&
  197. #endif /* _FFR_NODELAYDSN_ON_HOLD */
  198.     bitset(QPINGONDELAY, q->q_flags))
  199. {
  200. q->q_flags |= QDELAYED;
  201. delay_return = TRUE;
  202. }
  203. }
  204. }
  205. if (delay_return)
  206. {
  207. (void) snprintf(buf, sizeof buf,
  208. "Warning: could not send message for past %s",
  209. pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
  210. if (e->e_message != NULL)
  211. free(e->e_message);
  212. e->e_message = newstr(buf);
  213. message(buf);
  214. e->e_flags |= EF_WARNING;
  215. }
  216. fprintf(e->e_xfp,
  217. "Warning: message still undelivered after %sn",
  218. pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
  219. fprintf(e->e_xfp, "Will keep trying until message is %s oldn",
  220. pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
  221. }
  222. if (tTd(50, 2))
  223. dprintf("failure_return=%d delay_return=%d success_return=%d queueit=%dn",
  224. failure_return, delay_return, success_return, queueit);
  225. /*
  226. **  If we had some fatal error, but no addresses are marked as
  227. **  bad, mark them _all_ as bad.
  228. */
  229. if (bitset(EF_FATALERRS, e->e_flags) && !failure_return)
  230. {
  231. for (q = e->e_sendqueue; q != NULL; q = q->q_next)
  232. {
  233. if (QS_IS_UNDELIVERED(q->q_state) &&
  234.     bitset(QPINGONFAILURE, q->q_flags))
  235. {
  236. failure_return = TRUE;
  237. q->q_state = QS_BADADDR;
  238. }
  239. }
  240. }
  241. /*
  242. **  Send back return receipts as requested.
  243. */
  244. if (success_return && !failure_return && !delay_return && fulldrop &&
  245.     !bitset(PRIV_NORECEIPTS, PrivacyFlags) &&
  246.     strcmp(e->e_from.q_paddr, "<>") != 0)
  247. {
  248. auto ADDRESS *rlist = NULL;
  249. if (tTd(50, 8))
  250. dprintf("dropenvelope(%s): sending return receiptn",
  251. id);
  252. e->e_flags |= EF_SENDRECEIPT;
  253. (void) sendtolist(e->e_from.q_paddr, NULLADDR, &rlist, 0, e);
  254. (void) returntosender("Return receipt", rlist, RTSF_NO_BODY, e);
  255. }
  256. e->e_flags &= ~EF_SENDRECEIPT;
  257. /*
  258. **  Arrange to send error messages if there are fatal errors.
  259. */
  260. if ((failure_return || delay_return) && e->e_errormode != EM_QUIET)
  261. {
  262. if (tTd(50, 8))
  263. dprintf("dropenvelope(%s): saving mailn", id);
  264. savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags));
  265. }
  266. /*
  267. **  Arrange to send warning messages to postmaster as requested.
  268. */
  269. if ((failure_return || pmnotify) &&
  270.     PostMasterCopy != NULL &&
  271.     !bitset(EF_RESPONSE, e->e_flags) &&
  272.     e->e_class >= 0)
  273. {
  274. auto ADDRESS *rlist = NULL;
  275. char pcopy[MAXNAME];
  276. if (failure_return)
  277. {
  278. expand(PostMasterCopy, pcopy, sizeof pcopy, e);
  279. if (tTd(50, 8))
  280. dprintf("dropenvelope(%s): sending postmaster copy to %sn",
  281. id, pcopy);
  282. (void) sendtolist(pcopy, NULLADDR, &rlist, 0, e);
  283. }
  284. if (pmnotify)
  285. (void) sendtolist("postmaster", NULLADDR,
  286.   &rlist, 0, e);
  287. (void) returntosender(e->e_message, rlist,
  288.       RTSF_PM_BOUNCE|RTSF_NO_BODY, e);
  289. }
  290. /*
  291. **  Instantiate or deinstantiate the queue.
  292. */
  293. simpledrop:
  294. if (tTd(50, 8))
  295. dprintf("dropenvelope(%s): at simpledrop, queueit=%dn",
  296. id, queueit);
  297. if (!queueit || bitset(EF_CLRQUEUE, e->e_flags))
  298. {
  299. if (tTd(50, 1))
  300. {
  301. dprintf("n===== Dropping [dq]f%s... queueit=%d, e_flags=",
  302. e->e_id, queueit);
  303. printenvflags(e);
  304. }
  305. xunlink(queuename(e, 'd'));
  306. xunlink(queuename(e, 'q'));
  307. if (e->e_ntries > 0 && LogLevel > 9)
  308. sm_syslog(LOG_INFO, id, "done; delay=%s, ntries=%d",
  309.   pintvl(curtime() - e->e_ctime, TRUE),
  310.   e->e_ntries);
  311. }
  312. else if (queueit || !bitset(EF_INQUEUE, e->e_flags))
  313. {
  314. #if QUEUE
  315. queueup(e, FALSE);
  316. #else /* QUEUE */
  317. syserr("554 5.3.0 dropenvelope: queueup");
  318. #endif /* QUEUE */
  319. }
  320. /* now unlock the job */
  321. if (tTd(50, 8))
  322. dprintf("dropenvelope(%s): unlocking jobn", id);
  323. closexscript(e);
  324. unlockqueue(e);
  325. /* make sure that this envelope is marked unused */
  326. if (e->e_dfp != NULL)
  327. (void) bfclose(e->e_dfp);
  328. e->e_dfp = NULL;
  329. e->e_id = NULL;
  330. e->e_flags &= ~EF_HAS_DF;
  331. }
  332. /*
  333. **  CLEARENVELOPE -- clear an envelope without unlocking
  334. **
  335. ** This is normally used by a child process to get a clean
  336. ** envelope without disturbing the parent.
  337. **
  338. ** Parameters:
  339. ** e -- the envelope to clear.
  340. ** fullclear - if set, the current envelope is total
  341. ** garbage and should be ignored; otherwise,
  342. ** release any resources it may indicate.
  343. **
  344. ** Returns:
  345. ** none.
  346. **
  347. ** Side Effects:
  348. ** Closes files associated with the envelope.
  349. ** Marks the envelope as unallocated.
  350. */
  351. void
  352. clearenvelope(e, fullclear)
  353. register ENVELOPE *e;
  354. bool fullclear;
  355. {
  356. register HDR *bh;
  357. register HDR **nhp;
  358. extern ENVELOPE BlankEnvelope;
  359. if (!fullclear)
  360. {
  361. /* clear out any file information */
  362. if (e->e_xfp != NULL)
  363. (void) bfclose(e->e_xfp);
  364. if (e->e_dfp != NULL)
  365. (void) bfclose(e->e_dfp);
  366. e->e_xfp = e->e_dfp = NULL;
  367. }
  368. /* now clear out the data */
  369. STRUCTCOPY(BlankEnvelope, *e);
  370. e->e_message = NULL;
  371. if (Verbose)
  372. set_delivery_mode(SM_DELIVER, e);
  373. bh = BlankEnvelope.e_header;
  374. nhp = &e->e_header;
  375. while (bh != NULL)
  376. {
  377. *nhp = (HDR *) xalloc(sizeof *bh);
  378. memmove((char *) *nhp, (char *) bh, sizeof *bh);
  379. bh = bh->h_link;
  380. nhp = &(*nhp)->h_link;
  381. }
  382. }
  383. /*
  384. **  INITSYS -- initialize instantiation of system
  385. **
  386. ** In Daemon mode, this is done in the child.
  387. **
  388. ** Parameters:
  389. ** e -- the envelope to use.
  390. **
  391. ** Returns:
  392. ** none.
  393. **
  394. ** Side Effects:
  395. ** Initializes the system macros, some global variables,
  396. ** etc.  In particular, the current time in various
  397. ** forms is set.
  398. */
  399. void
  400. initsys(e)
  401. register ENVELOPE *e;
  402. {
  403. char cbuf[5]; /* holds hop count */
  404. char pbuf[10]; /* holds pid */
  405. #ifdef TTYNAME
  406. static char ybuf[60]; /* holds tty id */
  407. register char *p;
  408. extern char *ttyname();
  409. #endif /* TTYNAME */
  410. /*
  411. **  Give this envelope a reality.
  412. ** I.e., an id, a transcript, and a creation time.
  413. */
  414. setnewqueue(e);
  415. openxscript(e);
  416. e->e_ctime = curtime();
  417. #if _FFR_QUEUEDELAY
  418. e->e_queuealg = QueueAlg;
  419. e->e_queuedelay = QueueInitDelay;
  420. #endif /* _FFR_QUEUEDELAY */
  421. /*
  422. **  Set OutChannel to something useful if stdout isn't it.
  423. ** This arranges that any extra stuff the mailer produces
  424. ** gets sent back to the user on error (because it is
  425. ** tucked away in the transcript).
  426. */
  427. if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) &&
  428.     e->e_xfp != NULL)
  429. OutChannel = e->e_xfp;
  430. /*
  431. **  Set up some basic system macros.
  432. */
  433. /* process id */
  434. (void) snprintf(pbuf, sizeof pbuf, "%d", (int) getpid());
  435. define('p', newstr(pbuf), e);
  436. /* hop count */
  437. (void) snprintf(cbuf, sizeof cbuf, "%d", e->e_hopcount);
  438. define('c', newstr(cbuf), e);
  439. /* time as integer, unix time, arpa time */
  440. settime(e);
  441. /* Load average */
  442. (void)sm_getla(e);
  443. #ifdef TTYNAME
  444. /* tty name */
  445. if (macvalue('y', e) == NULL)
  446. {
  447. p = ttyname(2);
  448. if (p != NULL)
  449. {
  450. if (strrchr(p, '/') != NULL)
  451. p = strrchr(p, '/') + 1;
  452. snprintf(ybuf, sizeof ybuf, "%s", p);
  453. define('y', ybuf, e);
  454. }
  455. }
  456. #endif /* TTYNAME */
  457. }
  458. /*
  459. **  SETTIME -- set the current time.
  460. **
  461. ** Parameters:
  462. ** e -- the envelope in which the macros should be set.
  463. **
  464. ** Returns:
  465. ** none.
  466. **
  467. ** Side Effects:
  468. ** Sets the various time macros -- $a, $b, $d, $t.
  469. */
  470. void
  471. settime(e)
  472. register ENVELOPE *e;
  473. {
  474. register char *p;
  475. auto time_t now;
  476. char tbuf[20]; /* holds "current" time */
  477. char dbuf[30]; /* holds ctime(tbuf) */
  478. register struct tm *tm;
  479. now = curtime();
  480. tm = gmtime(&now);
  481. (void) snprintf(tbuf, sizeof tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
  482. tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
  483. define('t', newstr(tbuf), e);
  484. (void) strlcpy(dbuf, ctime(&now), sizeof dbuf);
  485. p = strchr(dbuf, 'n');
  486. if (p != NULL)
  487. *p = '';
  488. define('d', newstr(dbuf), e);
  489. p = arpadate(dbuf);
  490. p = newstr(p);
  491. if (macvalue('a', e) == NULL)
  492. define('a', p, e);
  493. define('b', p, e);
  494. }
  495. /*
  496. **  OPENXSCRIPT -- Open transcript file
  497. **
  498. ** Creates a transcript file for possible eventual mailing or
  499. ** sending back.
  500. **
  501. ** Parameters:
  502. ** e -- the envelope to create the transcript in/for.
  503. **
  504. ** Returns:
  505. ** none
  506. **
  507. ** Side Effects:
  508. ** Creates the transcript file.
  509. */
  510. #ifndef O_APPEND
  511. # define O_APPEND 0
  512. #endif /* ! O_APPEND */
  513. void
  514. openxscript(e)
  515. register ENVELOPE *e;
  516. {
  517. register char *p;
  518. if (e->e_xfp != NULL)
  519. return;
  520. #if 0
  521. if (e->e_lockfp == NULL && bitset(EF_INQUEUE, e->e_flags))
  522. syserr("openxscript: job not locked");
  523. #endif /* 0 */
  524. p = queuename(e, 'x');
  525. e->e_xfp = bfopen(p, FileMode, XscriptFileBufferSize,
  526.   SFF_NOTEXCL|SFF_OPENASROOT);
  527. if (e->e_xfp == NULL)
  528. {
  529. syserr("Can't create transcript file %s", p);
  530. e->e_xfp = fopen("/dev/null", "r+");
  531. if (e->e_xfp == NULL)
  532. syserr("!Can't open /dev/null");
  533. }
  534. #if HASSETVBUF
  535. (void) setvbuf(e->e_xfp, NULL, _IOLBF, 0);
  536. #else /* HASSETVBUF */
  537. (void) setlinebuf(e->e_xfp);
  538. #endif /* HASSETVBUF */
  539. if (tTd(46, 9))
  540. {
  541. dprintf("openxscript(%s):n  ", p);
  542. dumpfd(fileno(e->e_xfp), TRUE, FALSE);
  543. }
  544. }
  545. /*
  546. **  CLOSEXSCRIPT -- close the transcript file.
  547. **
  548. ** Parameters:
  549. ** e -- the envelope containing the transcript to close.
  550. **
  551. ** Returns:
  552. ** none.
  553. **
  554. ** Side Effects:
  555. ** none.
  556. */
  557. void
  558. closexscript(e)
  559. register ENVELOPE *e;
  560. {
  561. if (e->e_xfp == NULL)
  562. return;
  563. #if 0
  564. if (e->e_lockfp == NULL)
  565. syserr("closexscript: job not locked");
  566. #endif /* 0 */
  567. (void) bfclose(e->e_xfp);
  568. e->e_xfp = NULL;
  569. }
  570. /*
  571. **  SETSENDER -- set the person who this message is from
  572. **
  573. ** Under certain circumstances allow the user to say who
  574. ** s/he is (using -f or -r).  These are:
  575. ** 1.  The user's uid is zero (root).
  576. ** 2.  The user's login name is in an approved list (typically
  577. **     from a network server).
  578. ** 3.  The address the user is trying to claim has a
  579. **     "!" character in it (since #2 doesn't do it for
  580. **     us if we are dialing out for UUCP).
  581. ** A better check to replace #3 would be if the
  582. ** effective uid is "UUCP" -- this would require me
  583. ** to rewrite getpwent to "grab" uucp as it went by,
  584. ** make getname more nasty, do another passwd file
  585. ** scan, or compile the UID of "UUCP" into the code,
  586. ** all of which are reprehensible.
  587. **
  588. ** Assuming all of these fail, we figure out something
  589. ** ourselves.
  590. **
  591. ** Parameters:
  592. ** from -- the person we would like to believe this message
  593. ** is from, as specified on the command line.
  594. ** e -- the envelope in which we would like the sender set.
  595. ** delimptr -- if non-NULL, set to the location of the
  596. ** trailing delimiter.
  597. ** delimchar -- the character that will delimit the sender
  598. ** address.
  599. ** internal -- set if this address is coming from an internal
  600. ** source such as an owner alias.
  601. **
  602. ** Returns:
  603. ** none.
  604. **
  605. ** Side Effects:
  606. ** sets sendmail's notion of who the from person is.
  607. */
  608. void
  609. setsender(from, e, delimptr, delimchar, internal)
  610. char *from;
  611. register ENVELOPE *e;
  612. char **delimptr;
  613. int delimchar;
  614. bool internal;
  615. {
  616. register char **pvp;
  617. char *realname = NULL;
  618. register struct passwd *pw;
  619. char *bp;
  620. char buf[MAXNAME + 2];
  621. char pvpbuf[PSBUFSIZE];
  622. extern char *FullName;
  623. if (tTd(45, 1))
  624. dprintf("setsender(%s)n", from == NULL ? "" : from);
  625. /*
  626. **  Figure out the real user executing us.
  627. ** Username can return errno != 0 on non-errors.
  628. */
  629. if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP ||
  630.     OpMode == MD_ARPAFTP || OpMode == MD_DAEMON)
  631. realname = from;
  632. if (realname == NULL || realname[0] == '')
  633. realname = username();
  634. if (ConfigLevel < 2)
  635. SuprErrs = TRUE;
  636. #if _FFR_ADDR_TYPE
  637. define(macid("{addr_type}", NULL), "e s", e);
  638. #endif /* _FFR_ADDR_TYPE */
  639. /* preset state for then clause in case from == NULL */
  640. e->e_from.q_state = QS_BADADDR;
  641. e->e_from.q_flags = 0;
  642. if (from == NULL ||
  643.     parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR,
  644.       delimchar, delimptr, e) == NULL ||
  645.     QS_IS_BADADDR(e->e_from.q_state) ||
  646.     e->e_from.q_mailer == ProgMailer ||
  647.     e->e_from.q_mailer == FileMailer ||
  648.     e->e_from.q_mailer == InclMailer)
  649. {
  650. /* log garbage addresses for traceback */
  651. if (from != NULL && LogLevel > 2)
  652. {
  653. char *p;
  654. char ebuf[MAXNAME * 2 + 2];
  655. p = macvalue('_', e);
  656. if (p == NULL)
  657. {
  658. char *host = RealHostName;
  659. if (host == NULL)
  660. host = MyHostName;
  661. (void) snprintf(ebuf, sizeof ebuf, "%.*s@%.*s",
  662. MAXNAME, realname,
  663. MAXNAME, host);
  664. p = ebuf;
  665. }
  666. sm_syslog(LOG_NOTICE, e->e_id,
  667.   "setsender: %s: invalid or unparsable, received from %s",
  668.   shortenstring(from, 83), p);
  669. }
  670. if (from != NULL)
  671. {
  672. if (!QS_IS_BADADDR(e->e_from.q_state))
  673. {
  674. /* it was a bogus mailer in the from addr */
  675. e->e_status = "5.1.7";
  676. usrerrenh(e->e_status,
  677.   "553 Invalid sender address");
  678. }
  679. SuprErrs = TRUE;
  680. }
  681. if (from == realname ||
  682.     parseaddr(from = newstr(realname), &e->e_from,
  683.       RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL)
  684. {
  685. char nbuf[100];
  686. SuprErrs = TRUE;
  687. expand("201n", nbuf, sizeof nbuf, e);
  688. if (parseaddr(from = newstr(nbuf), &e->e_from,
  689.       RF_COPYALL, ' ', NULL, e) == NULL &&
  690.     parseaddr(from = "postmaster", &e->e_from,
  691.       RF_COPYALL, ' ', NULL, e) == NULL)
  692. syserr("553 5.3.0 setsender: can't even parse postmaster!");
  693. }
  694. }
  695. else
  696. FromFlag = TRUE;
  697. e->e_from.q_state = QS_SENDER;
  698. if (tTd(45, 5))
  699. {
  700. dprintf("setsender: QS_SENDER ");
  701. printaddr(&e->e_from, FALSE);
  702. }
  703. SuprErrs = FALSE;
  704. #if USERDB
  705. if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags))
  706. {
  707. register char *p;
  708. p = udbsender(e->e_from.q_user);
  709. if (p != NULL)
  710. from = p;
  711. }
  712. #endif /* USERDB */
  713. if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags))
  714. {
  715. if (!internal)
  716. {
  717. /* if the user already given fullname don't redefine */
  718. if (FullName == NULL)
  719. FullName = macvalue('x', e);
  720. if (FullName != NULL && FullName[0] == '')
  721. FullName = NULL;
  722. }
  723. if (e->e_from.q_user[0] != '' &&
  724.     (pw = sm_getpwnam(e->e_from.q_user)) != NULL)
  725. {
  726. /*
  727. **  Process passwd file entry.
  728. */
  729. /* extract home directory */
  730. if (strcmp(pw->pw_dir, "/") == 0)
  731. e->e_from.q_home = newstr("");
  732. else
  733. e->e_from.q_home = newstr(pw->pw_dir);
  734. define('z', e->e_from.q_home, e);
  735. /* extract user and group id */
  736. e->e_from.q_uid = pw->pw_uid;
  737. e->e_from.q_gid = pw->pw_gid;
  738. e->e_from.q_flags |= QGOODUID;
  739. /* extract full name from passwd file */
  740. if (FullName == NULL && pw->pw_gecos != NULL &&
  741.     strcmp(pw->pw_name, e->e_from.q_user) == 0 &&
  742.     !internal)
  743. {
  744. buildfname(pw->pw_gecos, e->e_from.q_user, buf, sizeof buf);
  745. if (buf[0] != '')
  746. FullName = newstr(buf);
  747. }
  748. }
  749. else
  750. {
  751. e->e_from.q_home = NULL;
  752. }
  753. if (FullName != NULL && !internal)
  754. define('x', FullName, e);
  755. }
  756. else if (!internal && OpMode != MD_DAEMON && OpMode != MD_SMTP)
  757. {
  758. if (e->e_from.q_home == NULL)
  759. {
  760. e->e_from.q_home = getenv("HOME");
  761. if (e->e_from.q_home != NULL &&
  762.     strcmp(e->e_from.q_home, "/") == 0)
  763. e->e_from.q_home++;
  764. }
  765. e->e_from.q_uid = RealUid;
  766. e->e_from.q_gid = RealGid;
  767. e->e_from.q_flags |= QGOODUID;
  768. }
  769. /*
  770. **  Rewrite the from person to dispose of possible implicit
  771. ** links in the net.
  772. */
  773. pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL, NULL);
  774. if (pvp == NULL)
  775. {
  776. /* don't need to give error -- prescan did that already */
  777. if (LogLevel > 2)
  778. sm_syslog(LOG_NOTICE, e->e_id,
  779.   "cannot prescan from (%s)",
  780.   shortenstring(from, MAXSHORTSTR));
  781. finis(TRUE, ExitStat);
  782. }
  783. (void) rewrite(pvp, 3, 0, e);
  784. (void) rewrite(pvp, 1, 0, e);
  785. (void) rewrite(pvp, 4, 0, e);
  786. #if _FFR_ADDR_TYPE
  787. define(macid("{addr_type}", NULL), NULL, e);
  788. #endif /* _FFR_ADDR_TYPE */
  789. bp = buf + 1;
  790. cataddr(pvp, NULL, bp, sizeof buf - 2, '');
  791. if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags))
  792. {
  793. /* heuristic: route-addr: add angle brackets */
  794. (void) strlcat(bp, ">", sizeof buf - 1);
  795. *--bp = '<';
  796. }
  797. e->e_sender = newstr(bp);
  798. define('f', e->e_sender, e);
  799. /* save the domain spec if this mailer wants it */
  800. if (e->e_from.q_mailer != NULL &&
  801.     bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
  802. {
  803. char **lastat;
  804. /* get rid of any pesky angle brackets */
  805. #if _FFR_ADDR_TYPE
  806. define(macid("{addr_type}", NULL), "e s", e);
  807. #endif /* _FFR_ADDR_TYPE */
  808. (void) rewrite(pvp, 3, 0, e);
  809. (void) rewrite(pvp, 1, 0, e);
  810. (void) rewrite(pvp, 4, 0, e);
  811. #if _FFR_ADDR_TYPE
  812. define(macid("{addr_type}", NULL), NULL, e);
  813. #endif /* _FFR_ADDR_TYPE */
  814. /* strip off to the last "@" sign */
  815. for (lastat = NULL; *pvp != NULL; pvp++)
  816. if (strcmp(*pvp, "@") == 0)
  817. lastat = pvp;
  818. if (lastat != NULL)
  819. {
  820. e->e_fromdomain = copyplist(lastat, TRUE);
  821. if (tTd(45, 3))
  822. {
  823. dprintf("Saving from domain: ");
  824. printav(e->e_fromdomain);
  825. }
  826. }
  827. }
  828. }
  829. /*
  830. **  PRINTENVFLAGS -- print envelope flags for debugging
  831. **
  832. ** Parameters:
  833. ** e -- the envelope with the flags to be printed.
  834. **
  835. ** Returns:
  836. ** none.
  837. */
  838. struct eflags
  839. {
  840. char *ef_name;
  841. u_long ef_bit;
  842. };
  843. static struct eflags EnvelopeFlags[] =
  844. {
  845. { "OLDSTYLE", EF_OLDSTYLE },
  846. { "INQUEUE", EF_INQUEUE },
  847. { "NO_BODY_RETN", EF_NO_BODY_RETN },
  848. { "CLRQUEUE", EF_CLRQUEUE },
  849. { "SENDRECEIPT", EF_SENDRECEIPT },
  850. { "FATALERRS", EF_FATALERRS },
  851. { "DELETE_BCC", EF_DELETE_BCC },
  852. { "RESPONSE", EF_RESPONSE },
  853. { "RESENT", EF_RESENT },
  854. { "VRFYONLY", EF_VRFYONLY },
  855. { "WARNING", EF_WARNING },
  856. { "QUEUERUN", EF_QUEUERUN },
  857. { "GLOBALERRS", EF_GLOBALERRS },
  858. { "PM_NOTIFY", EF_PM_NOTIFY },
  859. { "METOO", EF_METOO },
  860. { "LOGSENDER", EF_LOGSENDER },
  861. { "NORECEIPT", EF_NORECEIPT },
  862. { "HAS8BIT", EF_HAS8BIT },
  863. { "NL_NOT_EOL", EF_NL_NOT_EOL },
  864. { "CRLF_NOT_EOL", EF_CRLF_NOT_EOL },
  865. { "RET_PARAM", EF_RET_PARAM },
  866. { "HAS_DF", EF_HAS_DF },
  867. { "IS_MIME", EF_IS_MIME },
  868. { "DONT_MIME", EF_DONT_MIME },
  869. { NULL }
  870. };
  871. void
  872. printenvflags(e)
  873. register ENVELOPE *e;
  874. {
  875. register struct eflags *ef;
  876. bool first = TRUE;
  877. printf("%lx", e->e_flags);
  878. for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++)
  879. {
  880. if (!bitset(ef->ef_bit, e->e_flags))
  881. continue;
  882. if (first)
  883. printf("<%s", ef->ef_name);
  884. else
  885. printf(",%s", ef->ef_name);
  886. first = FALSE;
  887. }
  888. if (!first)
  889. printf(">n");
  890. }