Deleted Added
full compact
mail.local.c (120259) mail.local.c (132946)
1/*
2 * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
4 * Copyright (c) 1990, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * By using this file, you agree to the terms and conditions set
8 * forth in the LICENSE file which can be found at the top level of
9 * the sendmail distribution.
10 *
1/*
2 * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
4 * Copyright (c) 1990, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * By using this file, you agree to the terms and conditions set
8 * forth in the LICENSE file which can be found at the top level of
9 * the sendmail distribution.
10 *
11 * $FreeBSD: head/contrib/sendmail/mail.local/mail.local.c 120259 2003-09-19 23:14:57Z gshapiro $
11 * $FreeBSD: head/contrib/sendmail/mail.local/mail.local.c 132946 2004-08-01 01:16:16Z gshapiro $
12 *
13 */
14
15#include <sm/gen.h>
16
17SM_IDSTR(copyright,
18"@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\
19 All rights reserved.\n\
20 Copyright (c) 1990, 1993, 1994\n\
21 The Regents of the University of California. All rights reserved.\n")
22
12 *
13 */
14
15#include <sm/gen.h>
16
17SM_IDSTR(copyright,
18"@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\
19 All rights reserved.\n\
20 Copyright (c) 1990, 1993, 1994\n\
21 The Regents of the University of California. All rights reserved.\n")
22
23SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.239.2.11 2003/09/01 01:49:46 gshapiro Exp $")
23SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.251 2003/11/03 18:38:29 ca Exp $")
24
25#include <stdlib.h>
26#include <sm/errstring.h>
27#include <sm/io.h>
28#include <sm/limits.h>
29# include <unistd.h>
30# ifdef EX_OK
31# undef EX_OK /* unistd.h may have another use for this */
32# endif /* EX_OK */
33# define LOCKFILE_PMODE 0
34#include <sm/mbdb.h>
35#include <sm/sysexits.h>
36
24
25#include <stdlib.h>
26#include <sm/errstring.h>
27#include <sm/io.h>
28#include <sm/limits.h>
29# include <unistd.h>
30# ifdef EX_OK
31# undef EX_OK /* unistd.h may have another use for this */
32# endif /* EX_OK */
33# define LOCKFILE_PMODE 0
34#include <sm/mbdb.h>
35#include <sm/sysexits.h>
36
37#ifndef HASHSPOOL
38# define HASHSPOOL 0
39#endif /* ! HASHSPOOL */
40#ifndef HASHSPOOLMD5
41# define HASHSPOOLMD5 0
42#endif /* ! HASHSPOOLMD5 */
43
37/*
38** This is not intended to work on System V derived systems
39** such as Solaris or HP-UX, since they use a totally different
40** approach to mailboxes (essentially, they have a set-group-ID program
41** rather than set-user-ID, and they rely on the ability to "give away"
42** files to do their work). IT IS NOT A BUG that this doesn't
43** work on such architectures.
44*/

--- 15 unchanged lines hidden (view full) ---

60
61#include <sm/string.h>
62#include <syslog.h>
63#include <ctype.h>
64
65#include <sm/conf.h>
66#include <sendmail/pathnames.h>
67
44/*
45** This is not intended to work on System V derived systems
46** such as Solaris or HP-UX, since they use a totally different
47** approach to mailboxes (essentially, they have a set-group-ID program
48** rather than set-user-ID, and they rely on the ability to "give away"
49** files to do their work). IT IS NOT A BUG that this doesn't
50** work on such architectures.
51*/

--- 15 unchanged lines hidden (view full) ---

67
68#include <sm/string.h>
69#include <syslog.h>
70#include <ctype.h>
71
72#include <sm/conf.h>
73#include <sendmail/pathnames.h>
74
75#if HASHSPOOL
76# define HASH_NONE 0
77# define HASH_USER 1
78# if HASHSPOOLMD5
79# define HASH_MD5 2
80# include <openssl/md5.h>
81# endif /* HASHSPOOLMD5 */
82#endif /* HASHSPOOL */
68
83
84
69#ifndef LOCKTO_RM
70# define LOCKTO_RM 300 /* timeout for stale lockfile removal */
71#endif /* ! LOCKTO_RM */
72#ifndef LOCKTO_GLOB
73# define LOCKTO_GLOB 400 /* global timeout for lockfile creation */
74#endif /* ! LOCKTO_GLOB */
75
76/* define a realloc() which works for NULL pointers */

--- 52 unchanged lines hidden (view full) ---

129int ExitVal = EX_OK; /* sysexits.h error value. */
130bool nobiff = false;
131bool nofsync = false;
132bool HoldErrs = false; /* Hold errors in ErrBuf */
133bool LMTPMode = false;
134bool BounceQuota = false; /* permanent error when over quota */
135char *HomeMailFile = NULL; /* store mail in homedir */
136
85#ifndef LOCKTO_RM
86# define LOCKTO_RM 300 /* timeout for stale lockfile removal */
87#endif /* ! LOCKTO_RM */
88#ifndef LOCKTO_GLOB
89# define LOCKTO_GLOB 400 /* global timeout for lockfile creation */
90#endif /* ! LOCKTO_GLOB */
91
92/* define a realloc() which works for NULL pointers */

--- 52 unchanged lines hidden (view full) ---

145int ExitVal = EX_OK; /* sysexits.h error value. */
146bool nobiff = false;
147bool nofsync = false;
148bool HoldErrs = false; /* Hold errors in ErrBuf */
149bool LMTPMode = false;
150bool BounceQuota = false; /* permanent error when over quota */
151char *HomeMailFile = NULL; /* store mail in homedir */
152
153#if HASHSPOOL
154int HashType = HASH_NONE;
155int HashDepth = 0;
156bool StripRcptDomain = true;
157#else /* HASHSPOOL */
158# define StripRcptDomain true
159#endif /* HASHSPOOL */
160char SpoolPath[MAXPATHLEN];
161
137void deliver __P((int, char *));
138int e_to_sys __P((int));
139void notifybiff __P((char *));
140int store __P((char *, bool *));
141void usage __P((void));
142int lockmbox __P((char *));
143void unlockmbox __P((void));
144void mailerr __P((const char *, const char *, ...));
145void flush_error __P((void));
162void deliver __P((int, char *));
163int e_to_sys __P((int));
164void notifybiff __P((char *));
165int store __P((char *, bool *));
166void usage __P((void));
167int lockmbox __P((char *));
168void unlockmbox __P((void));
169void mailerr __P((const char *, const char *, ...));
170void flush_error __P((void));
171#if HASHSPOOL
172const char *hashname __P((char *));
173#endif /* HASHSPOOL */
146
147
148int
149main(argc, argv)
150 int argc;
151 char *argv[];
152{
153 struct passwd *pw;

--- 15 unchanged lines hidden (view full) ---

169
170# ifdef LOG_MAIL
171 openlog("mail.local", 0, LOG_MAIL);
172# else /* LOG_MAIL */
173 openlog("mail.local", 0);
174# endif /* LOG_MAIL */
175
176 from = NULL;
174
175
176int
177main(argc, argv)
178 int argc;
179 char *argv[];
180{
181 struct passwd *pw;

--- 15 unchanged lines hidden (view full) ---

197
198# ifdef LOG_MAIL
199 openlog("mail.local", 0, LOG_MAIL);
200# else /* LOG_MAIL */
201 openlog("mail.local", 0);
202# endif /* LOG_MAIL */
203
204 from = NULL;
205 if (sm_strlcpy(SpoolPath, _PATH_MAILDIR, sizeof(SpoolPath)) >=
206 sizeof(SpoolPath))
207 {
208 mailerr("421", "Configuration error: _PATH_MAILDIR too large");
209 exit(EX_CONFIG);
210 }
211#if HASHSPOOL
212 while ((ch = getopt(argc, argv, "7BbdD:f:h:r:lH:p:ns")) != -1)
213#else /* HASHSPOOL */
177 while ((ch = getopt(argc, argv, "7BbdD:f:h:r:ls")) != -1)
214 while ((ch = getopt(argc, argv, "7BbdD:f:h:r:ls")) != -1)
215#endif /* HASHSPOOL */
178 {
179 switch(ch)
180 {
181 case '7': /* Do not advertise 8BITMIME */
182 EightBitMime = false;
183 break;
184
185 case 'B':

--- 34 unchanged lines hidden (view full) ---

220 case 'l':
221 LMTPMode = true;
222 break;
223
224 case 's':
225 nofsync++;
226 break;
227
216 {
217 switch(ch)
218 {
219 case '7': /* Do not advertise 8BITMIME */
220 EightBitMime = false;
221 break;
222
223 case 'B':

--- 34 unchanged lines hidden (view full) ---

258 case 'l':
259 LMTPMode = true;
260 break;
261
262 case 's':
263 nofsync++;
264 break;
265
266#if HASHSPOOL
267 case 'H':
268 if (optarg == NULL || *optarg == '\0')
269 {
270 mailerr(NULL, "-H: missing hashinfo");
271 usage();
272 }
273 switch(optarg[0])
274 {
275 case 'u':
276 HashType = HASH_USER;
277 break;
278
279# if HASHSPOOLMD5
280 case 'm':
281 HashType = HASH_MD5;
282 break;
283# endif /* HASHSPOOLMD5 */
284
285 default:
286 mailerr(NULL, "-H: unknown hash type");
287 usage();
288 }
289 if (optarg[1] == '\0')
290 {
291 mailerr(NULL, "-H: invalid hash depth");
292 usage();
293 }
294 HashDepth = atoi(&optarg[1]);
295 if ((HashDepth <= 0) || ((HashDepth * 2) >= MAXPATHLEN))
296 {
297 mailerr(NULL, "-H: invalid hash depth");
298 usage();
299 }
300 break;
301
302 case 'p':
303 if (optarg == NULL || *optarg == '\0')
304 {
305 mailerr(NULL, "-p: missing spool path");
306 usage();
307 }
308 if (sm_strlcpy(SpoolPath, optarg, sizeof(SpoolPath)) >=
309 sizeof(SpoolPath))
310 {
311 mailerr(NULL, "-p: invalid spool path");
312 usage();
313 }
314 break;
315
316 case 'n':
317 StripRcptDomain = false;
318 break;
319#endif /* HASHSPOOL */
320
228 case '?':
229 default:
230 usage();
231 }
232 }
233 argc -= optind;
234 argv += optind;
235

--- 352 unchanged lines hidden (view full) ---

588 {
589 mailerr("421 4.3.0",
590 "Memory exhausted");
591 exit(EX_TEMPFAIL);
592 }
593 }
594 if (sm_strncasecmp(buf + 5, "to:", 3) != 0 ||
595 ((rcpt_addr[rcpt_num] = parseaddr(buf + 8,
321 case '?':
322 default:
323 usage();
324 }
325 }
326 argc -= optind;
327 argv += optind;
328

--- 352 unchanged lines hidden (view full) ---

681 {
682 mailerr("421 4.3.0",
683 "Memory exhausted");
684 exit(EX_TEMPFAIL);
685 }
686 }
687 if (sm_strncasecmp(buf + 5, "to:", 3) != 0 ||
688 ((rcpt_addr[rcpt_num] = parseaddr(buf + 8,
596 true)) == NULL))
689 StripRcptDomain)) == NULL))
597 {
598 mailerr("501 5.5.4",
599 "Syntax error in parameters");
600 continue;
601 }
602 err = process_recipient(rcpt_addr[rcpt_num]);
603 if (err != NULL)
604 {

--- 306 unchanged lines hidden (view full) ---

911 /*
912 ** Keep name reasonably short to avoid buffer overruns.
913 ** This isn't necessary on BSD because of the proper
914 ** definition of snprintf(), but it can cause problems
915 ** on other systems.
916 ** Also, clear out any bogus characters.
917 */
918
690 {
691 mailerr("501 5.5.4",
692 "Syntax error in parameters");
693 continue;
694 }
695 err = process_recipient(rcpt_addr[rcpt_num]);
696 if (err != NULL)
697 {

--- 306 unchanged lines hidden (view full) ---

1004 /*
1005 ** Keep name reasonably short to avoid buffer overruns.
1006 ** This isn't necessary on BSD because of the proper
1007 ** definition of snprintf(), but it can cause problems
1008 ** on other systems.
1009 ** Also, clear out any bogus characters.
1010 */
1011
1012#if !HASHSPOOL
919 if (strlen(name) > 40)
920 name[40] = '\0';
921 for (p = name; *p != '\0'; p++)
922 {
923 if (!isascii(*p))
924 *p &= 0x7f;
925 else if (!isprint(*p))
926 *p = '.';
927 }
1013 if (strlen(name) > 40)
1014 name[40] = '\0';
1015 for (p = name; *p != '\0'; p++)
1016 {
1017 if (!isascii(*p))
1018 *p &= 0x7f;
1019 else if (!isprint(*p))
1020 *p = '.';
1021 }
1022#endif /* !HASHSPOOL */
928
929
930 if (HomeMailFile == NULL)
931 {
1023
1024
1025 if (HomeMailFile == NULL)
1026 {
932 if (sm_snprintf(path, sizeof(path), "%s/%s",
933 _PATH_MAILDIR, name) >= sizeof(path))
1027 if (sm_strlcpyn(path, sizeof(path),
1028#if HASHSPOOL
1029 4,
1030#else /* HASHSPOOL */
1031 3,
1032#endif /* HASHSPOOL */
1033 SpoolPath, "/",
1034#if HASHSPOOL
1035 hashname(name),
1036#endif /* HASHSPOOL */
1037 name) >= sizeof(path))
934 {
935 exitval = EX_UNAVAILABLE;
936 mailerr("550 5.1.1", "%s: Invalid mailbox path", name);
937 return;
938 }
939 }
940 else if (*user.mbdb_homedir == '\0')
941 {

--- 563 unchanged lines hidden (view full) ---

1505 else
1506 {
1507 if (ExitVal != EX_USAGE)
1508 (void) fprintf(stderr, "mail.local: ");
1509 fprintf(stderr, "%s\n", ErrBuf);
1510 }
1511}
1512
1038 {
1039 exitval = EX_UNAVAILABLE;
1040 mailerr("550 5.1.1", "%s: Invalid mailbox path", name);
1041 return;
1042 }
1043 }
1044 else if (*user.mbdb_homedir == '\0')
1045 {

--- 563 unchanged lines hidden (view full) ---

1609 else
1610 {
1611 if (ExitVal != EX_USAGE)
1612 (void) fprintf(stderr, "mail.local: ");
1613 fprintf(stderr, "%s\n", ErrBuf);
1614 }
1615}
1616
1617#if HASHSPOOL
1618const char *
1619hashname(name)
1620 char *name;
1621{
1622 static char p[MAXPATHLEN];
1623 int i;
1624 int len;
1625 char *str;
1626# if HASHSPOOLMD5
1627 char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_";
1628 MD5_CTX ctx;
1629 unsigned char md5[18];
1630# if MAXPATHLEN <= 24
1631 ERROR _MAXPATHLEN <= 24
1632# endif /* MAXPATHLEN <= 24 */
1633 char b64[24];
1634 MD5_LONG bits;
1635 int j;
1636# endif /* HASHSPOOLMD5 */
1637
1638 if (HashType == HASH_NONE || HashDepth * 2 >= MAXPATHLEN)
1639 {
1640 p[0] = '\0';
1641 return p;
1642 }
1643
1644 switch(HashType)
1645 {
1646 case HASH_USER:
1647 str = name;
1648 break;
1649
1650# if HASHSPOOLMD5
1651 case HASH_MD5:
1652 MD5_Init(&ctx);
1653 MD5_Update(&ctx, name, strlen(name));
1654 MD5_Final(md5, &ctx);
1655 md5[16] = 0;
1656 md5[17] = 0;
1657
1658 for (i = 0; i < 6; i++)
1659 {
1660 bits = (unsigned) md5[(3 * i)] << 16;
1661 bits |= (unsigned) md5[(3 * i) + 1] << 8;
1662 bits |= (unsigned) md5[(3 * i) + 2];
1663
1664 for (j = 3; j >= 0; j--)
1665 {
1666 b64[(4 * i) + j] = Base64[(bits & 0x3f)];
1667 bits >>= 6;
1668 }
1669 }
1670 b64[22] = '\0';
1671 str = b64;
1672 break;
1673# endif /* HASHSPOOLMD5 */
1674 }
1675
1676 len = strlen(str);
1677 for (i = 0; i < HashDepth; i++)
1678 {
1679 if (i < len)
1680 p[i * 2] = str[i];
1681 else
1682 p[i * 2] = '_';
1683 p[(i * 2) + 1] = '/';
1684 }
1685 p[HashDepth * 2] = '\0';
1686 return p;
1687}
1688#endif /* HASHSPOOL */
1689
1513/*
1514 * e_to_sys --
1515 * Guess which errno's are temporary. Gag me.
1516 */
1517
1518int
1519e_to_sys(num)
1520 int num;

--- 224 unchanged lines hidden ---
1690/*
1691 * e_to_sys --
1692 * Guess which errno's are temporary. Gag me.
1693 */
1694
1695int
1696e_to_sys(num)
1697 int num;

--- 224 unchanged lines hidden ---