summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/mail.local/mail.local.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/mail.local/mail.local.c')
-rw-r--r--contrib/sendmail/mail.local/mail.local.c186
1 files changed, 182 insertions, 4 deletions
diff --git a/contrib/sendmail/mail.local/mail.local.c b/contrib/sendmail/mail.local/mail.local.c
index ff82a94..7230584 100644
--- a/contrib/sendmail/mail.local/mail.local.c
+++ b/contrib/sendmail/mail.local/mail.local.c
@@ -18,7 +18,7 @@ SM_IDSTR(copyright,
Copyright (c) 1990, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n")
-SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.239.2.11 2003/09/01 01:49:46 gshapiro Exp $")
+SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.251 2003/11/03 18:38:29 ca Exp $")
#include <stdlib.h>
#include <sm/errstring.h>
@@ -32,6 +32,13 @@ SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.239.2.11 2003/09/01 01:49:46 gshapiro Ex
#include <sm/mbdb.h>
#include <sm/sysexits.h>
+#ifndef HASHSPOOL
+# define HASHSPOOL 0
+#endif /* ! HASHSPOOL */
+#ifndef HASHSPOOLMD5
+# define HASHSPOOLMD5 0
+#endif /* ! HASHSPOOLMD5 */
+
/*
** This is not intended to work on System V derived systems
** such as Solaris or HP-UX, since they use a totally different
@@ -63,6 +70,15 @@ SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.239.2.11 2003/09/01 01:49:46 gshapiro Ex
#include <sm/conf.h>
#include <sendmail/pathnames.h>
+#if HASHSPOOL
+# define HASH_NONE 0
+# define HASH_USER 1
+# if HASHSPOOLMD5
+# define HASH_MD5 2
+# include <openssl/md5.h>
+# endif /* HASHSPOOLMD5 */
+#endif /* HASHSPOOL */
+
#ifndef LOCKTO_RM
# define LOCKTO_RM 300 /* timeout for stale lockfile removal */
@@ -130,6 +146,15 @@ bool LMTPMode = false;
bool BounceQuota = false; /* permanent error when over quota */
char *HomeMailFile = NULL; /* store mail in homedir */
+#if HASHSPOOL
+int HashType = HASH_NONE;
+int HashDepth = 0;
+bool StripRcptDomain = true;
+#else /* HASHSPOOL */
+# define StripRcptDomain true
+#endif /* HASHSPOOL */
+char SpoolPath[MAXPATHLEN];
+
void deliver __P((int, char *));
int e_to_sys __P((int));
void notifybiff __P((char *));
@@ -139,6 +164,9 @@ int lockmbox __P((char *));
void unlockmbox __P((void));
void mailerr __P((const char *, const char *, ...));
void flush_error __P((void));
+#if HASHSPOOL
+const char *hashname __P((char *));
+#endif /* HASHSPOOL */
int
@@ -170,7 +198,17 @@ main(argc, argv)
# endif /* LOG_MAIL */
from = NULL;
+ if (sm_strlcpy(SpoolPath, _PATH_MAILDIR, sizeof(SpoolPath)) >=
+ sizeof(SpoolPath))
+ {
+ mailerr("421", "Configuration error: _PATH_MAILDIR too large");
+ exit(EX_CONFIG);
+ }
+#if HASHSPOOL
+ while ((ch = getopt(argc, argv, "7bdD:f:h:r:lH:p:n")) != -1)
+#else /* HASHSPOOL */
while ((ch = getopt(argc, argv, "7bdD:f:h:r:l")) != -1)
+#endif /* HASHSPOOL */
{
switch(ch)
{
@@ -213,6 +251,62 @@ main(argc, argv)
LMTPMode = true;
break;
+
+#if HASHSPOOL
+ case 'H':
+ if (optarg == NULL || *optarg == '\0')
+ {
+ mailerr(NULL, "-H: missing hashinfo");
+ usage();
+ }
+ switch(optarg[0])
+ {
+ case 'u':
+ HashType = HASH_USER;
+ break;
+
+# if HASHSPOOLMD5
+ case 'm':
+ HashType = HASH_MD5;
+ break;
+# endif /* HASHSPOOLMD5 */
+
+ default:
+ mailerr(NULL, "-H: unknown hash type");
+ usage();
+ }
+ if (optarg[1] == '\0')
+ {
+ mailerr(NULL, "-H: invalid hash depth");
+ usage();
+ }
+ HashDepth = atoi(&optarg[1]);
+ if ((HashDepth <= 0) || ((HashDepth * 2) >= MAXPATHLEN))
+ {
+ mailerr(NULL, "-H: invalid hash depth");
+ usage();
+ }
+ break;
+
+ case 'p':
+ if (optarg == NULL || *optarg == '\0')
+ {
+ mailerr(NULL, "-p: missing spool path");
+ usage();
+ }
+ if (sm_strlcpy(SpoolPath, optarg, sizeof(SpoolPath)) >=
+ sizeof(SpoolPath))
+ {
+ mailerr(NULL, "-p: invalid spool path");
+ usage();
+ }
+ break;
+
+ case 'n':
+ StripRcptDomain = false;
+ break;
+#endif /* HASHSPOOL */
+
case '?':
default:
usage();
@@ -580,7 +674,7 @@ dolmtp()
}
if (sm_strncasecmp(buf + 5, "to:", 3) != 0 ||
((rcpt_addr[rcpt_num] = parseaddr(buf + 8,
- true)) == NULL))
+ StripRcptDomain)) == NULL))
{
mailerr("501 5.5.4",
"Syntax error in parameters");
@@ -903,6 +997,7 @@ deliver(fd, name)
** Also, clear out any bogus characters.
*/
+#if !HASHSPOOL
if (strlen(name) > 40)
name[40] = '\0';
for (p = name; *p != '\0'; p++)
@@ -912,12 +1007,22 @@ deliver(fd, name)
else if (!isprint(*p))
*p = '.';
}
+#endif /* !HASHSPOOL */
if (HomeMailFile == NULL)
{
- if (sm_snprintf(path, sizeof(path), "%s/%s",
- _PATH_MAILDIR, name) >= sizeof(path))
+ if (sm_strlcpyn(path, sizeof(path),
+#if HASHSPOOL
+ 4,
+#else /* HASHSPOOL */
+ 3,
+#endif /* HASHSPOOL */
+ SpoolPath, "/",
+#if HASHSPOOL
+ hashname(name),
+#endif /* HASHSPOOL */
+ name) >= sizeof(path))
{
exitval = EX_UNAVAILABLE;
mailerr("550 5.1.1", "%s: Invalid mailbox path", name);
@@ -1493,6 +1598,79 @@ flush_error()
}
}
+#if HASHSPOOL
+const char *
+hashname(name)
+ char *name;
+{
+ static char p[MAXPATHLEN];
+ int i;
+ int len;
+ char *str;
+# if HASHSPOOLMD5
+ char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_";
+ MD5_CTX ctx;
+ unsigned char md5[18];
+# if MAXPATHLEN <= 24
+ ERROR _MAXPATHLEN <= 24
+# endif /* MAXPATHLEN <= 24 */
+ char b64[24];
+ MD5_LONG bits;
+ int j;
+# endif /* HASHSPOOLMD5 */
+
+ if (HashType == HASH_NONE || HashDepth * 2 >= MAXPATHLEN)
+ {
+ p[0] = '\0';
+ return p;
+ }
+
+ switch(HashType)
+ {
+ case HASH_USER:
+ str = name;
+ break;
+
+# if HASHSPOOLMD5
+ case HASH_MD5:
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, name, strlen(name));
+ MD5_Final(md5, &ctx);
+ md5[16] = 0;
+ md5[17] = 0;
+
+ for (i = 0; i < 6; i++)
+ {
+ bits = (unsigned) md5[(3 * i)] << 16;
+ bits |= (unsigned) md5[(3 * i) + 1] << 8;
+ bits |= (unsigned) md5[(3 * i) + 2];
+
+ for (j = 3; j >= 0; j--)
+ {
+ b64[(4 * i) + j] = Base64[(bits & 0x3f)];
+ bits >>= 6;
+ }
+ }
+ b64[22] = '\0';
+ str = b64;
+ break;
+# endif /* HASHSPOOLMD5 */
+ }
+
+ len = strlen(str);
+ for (i = 0; i < HashDepth; i++)
+ {
+ if (i < len)
+ p[i * 2] = str[i];
+ else
+ p[i * 2] = '_';
+ p[(i * 2) + 1] = '/';
+ }
+ p[HashDepth * 2] = '\0';
+ return p;
+}
+#endif /* HASHSPOOL */
+
/*
* e_to_sys --
* Guess which errno's are temporary. Gag me.
OpenPOWER on IntegriCloud