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 --- |