1N/A * Copyright (c) 1998 Sendmail, Inc. All rights reserved. 1N/A * Copyright (c) 1990, 1993, 1994 1N/A * The Regents of the University of California. All rights reserved. 1N/A * By using this file, you agree to the terms and conditions set 1N/A * forth in the LICENSE file which can be found at the top level 1N/A * of the sendmail distribution. 1N/A * Copyright 1994-2007 Sun Microsystems, Inc. All rights reserved. 1N/A * Use is subject to license terms. 1N/A"@(#) Copyright (c) 1990, 1993, 1994\n\ 1N/A The Regents of the University of California. All rights reserved.\n";
1N/A#
endif /* not lint */ 1N/A#
pragma ident "%Z%%M% %I% %E% SMI" 1N/A#
endif /* not lint */ 1N/A** If you don't have flock, you could try using lockf instead. 1N/A#
endif /* LOCK_EX */ 1N/A#
endif /* LDA_USE_LOCKF */ 1N/A#
endif /* ! LOCK_EX */ 1N/Astatic void mailerr(
const char *,
const char *, ...);
1N/A case '7':
/* Do not advertise 8BITMIME */ 1N/A case 'b':
/* bounce mail when over quota. */ 1N/A case 'd':
/* Backward compatible. */ 1N/A case 'r':
/* Backward compatible. */ 1N/A * We expect sendmail will invoke us with saved id 0 1N/A * We then do setgid and setuid defore delivery 1N/A * setgid to mail group 1N/A warn(
"only super-user can use -l option");
1N/A * If from not specified, use the name from getlogin() if the 1N/A * uid matches, otherwise, use the name from the password file 1N/A * corresponding to the uid. 1N/A * There is no way to distinguish the error status of one delivery 1N/A * from the rest of the deliveries. So, if we failed hard on one 1N/A * or more deliveries, but had no failures on any of the others, we 1N/A * return a hard failure. If we failed temporarily on one or more 1N/A * deliveries, we return a temporary failure regardless of the other 1N/A * failures. This results in the delivery being reattempted later 1N/A * at the expense of repeated failures and multiple deliveries. 1N/A /* at-domain-list */ 1N/A *p ==
'-' || *p ==
':'))
1N/A if (*p ==
',' && p[
1] ==
'@')
1N/A else if (*p ==
':' && p[
1] !=
'@')
1N/A while (*p && *p !=
'\"') {
1N/A while (*p && *p !=
'@' && *p !=
'>') {
1N/A if (*p <=
' ' || (*p &
128) ||
1N/A *p ==
'-' || *p ==
':'))
1N/A if (*p && *p !=
' ')
1N/A return "550 5.1.1 user unknown";
1N/A /* check for duplicate per RFC 1651 4.2 */ 1N/A printf(
"501 5.5.4 Syntax error in parameters\r\n");
1N/A printf(
"501 5.5.4 Syntax error in parameters\r\n");
1N/A printf(
"252 2.3.3 try RCPT to attempt delivery\r\n");
1N/A bool prevfl;
/* previous line was terminated */ 1N/A printf(
"451 4.3.0 unable to open temporary file\r\n");
1N/A mailerr(
"451 4.3.0",
"unable to open temporary file");
1N/A err(
"unable to open temporary file");
1N/A /* Check for dot-stuffing */ 1N/A /* Check to see if we have the full line from fgets() */ 1N/A /* Did we just miss the CRLF? */ 1N/A printf(
"451 4.3.0 temporary file write error\r\n");
1N/A "temporary file write error");
1N/A continue;
/* skip this header */ 1N/A printf(
"451 4.3.0 temporary file write error\r\n");
1N/A "temporary file write error");
1N/A /* Got a premature EOF -- toss message and exit */ 1N/A /* If message not newline terminated, need an extra. */ 1N/A /* Output a newline; note, empty messages are allowed. */ 1N/A printf(
"451 4.3.0 temporary file write error\r\n");
1N/A mailerr(
"451 4.3.0",
"temporary file write error");
1N/A * Disallow delivery to unknown names -- special mailboxes 1N/A * can be handled in the sendmail aliases file. 1N/A /* mailbox may be NFS mounted, seteuid to user */ 1N/A * If saved_uid == 0 (root), anything is OK; this is 1N/A * as it should be. But to prevent a random user from 1N/A * calling "mail.local foo" in an attempt to hijack 1N/A * foo's mail-box, make sure src_uid == targ_uid o/w. 1N/A warn(
"%s: wrong owner (is %d, should be %d)",
1N/A * If the mailbox is linked or a symlink, fail. There's an obvious 1N/A * race here, that the file was replaced with a symbolic link after 1N/A * the lstat returned, but before the open. We attempt to detect 1N/A * this by comparing the original stat information and information 1N/A * returned by an fstat of the file descriptor returned by the open. 1N/A * NB: this is a symptom of a larger problem, that the mail spooling 1N/A * directory is writeable by the wrong users. If that directory is 1N/A * writeable, system security is compromised for other reasons, and 1N/A * it cannot be fixed here. 1N/A * just return. Another process may have already opened it, so we 1N/A * each mail delivery. We no longer do this, assuming that if the 1N/A * ownership or permissions were changed there was a reason. 1N/A * open(2) should support flock'ing the file. 1N/A /* should check lock status, but... maillock return no value */ 1N/A "%s: fstat: file changed after open",
path);
1N/A /* Get the starting offset of the new message for biff. */ 1N/A /* Copy the message into the file. */ 1N/A /* Copy the message into the file. */ 1N/A /* Flush to disk, don't wait for update. */ 1N/A ** Save the current size so if the close() fails below 1N/A ** we can make sure no other process has changed the mailbox 1N/A ** between the failed close and the re-open()/re-lock(). 1N/A ** If something else has changed the size, we shouldn't 1N/A ** try to truncate it as we may do more harm then good 1N/A ** (e.g., truncate a later message delivery). 1N/A /* Close and check -- NFS doesn't write until the close. */ 1N/A /* Don't use a bogus file */ 1N/A /* Attempt to truncate back to pre-write size */ 1N/A /* Be silent if biff service not available. */ 1N/A return;
/* did not initialize */ 1N/A err(
"usage: mail.local [-l] [-f from] user ...");
1N/A * Log the message to stderr. 1N/A * Don't use LOG_PERROR as an openlog() flag to do this, 1N/A * it's not portable enough. 1N/A /* Log the message to syslog. */ 1N/A * Guess which errno's are temporary. Gag me. 1N/A /* Temporary failures override hard errors. */ 1N/A switch (
num)
/* Hopefully temporary errors. */ 1N/A case EAGAIN:
/* Resource temporarily unavailable */ 1N/A case ENFILE:
/* Too many open files in system */