REPOST: Deliver 1.00 patch #2
Chip Salzenberg
chip at ateng.ateng.com
Tue Nov 29 03:26:56 AEST 1988
This is an offical patch for deliver 1.00. Please apply it.
Patch number: 2
Date: 18 Nov 1988
Priority: MEDIUM
Changes:
Improved signal handling now allows SIGINT etc. to abort message
when stdin is a tty. (Signals are then disabled for delivery.)
Make sure all environment variables are always provided.
Trust some users to specify delivery files.
Index: patchlevel.h
Prereq: 1
***************
*** 1 ****
! #define PATCHLEVEL 1
--- 1 ----
! #define PATCHLEVEL 2
Index: config.h
***************
*** 1,8 ****
! /* $Header: config.h,v 1.3 88/09/14 19:41:35 network Exp $
*
* Deliver configuration.
*
* $Log: config.h,v $
* Revision 1.3 88/09/14 19:41:35 network
* Portability to System V and BSD.
* General fixup.
--- 1,13 ----
! /* $Header: config.h,v 1.4 88/11/18 12:16:39 network Exp $
*
* Deliver configuration.
*
* $Log: config.h,v $
+ * Revision 1.4 88/11/18 12:16:39 network
+ * patch2: Improved signal handling.
+ * patch2: Make sure all environment variables are always provided.
+ * patch2: Some users can be trusted to specify delivery files.
+ *
* Revision 1.3 88/09/14 19:41:35 network
* Portability to System V and BSD.
* General fixup.
***************
*** 15,20 ****
--- 20,45 ----
* Initial revision
*
*/
+
+ /*----------------------------------------------------------------------
+ * Trusted users.
+ * Deliver permits "trusted" users to specify delivery filenames
+ * without renouncing setuid privileges. Essentially, these users
+ * are given the root password. Beware!
+ */
+
+ #define TRUSTED_USERS "root", "uucp"
+
+ /*----------------------------------------------------------------------
+ * Signal flag type.
+ * Variables of this type may be set by signal catching routines.
+ */
+
+ #ifdef __STDC__
+ #define SIGFLAG sig_atomic_t
+ #else
+ #define SIGFLAG short /* or "volatile short" for aggressive optimizers */
+ #endif
/*----------------------------------------------------------------------
* Various kinds of mailbox locking.
Index: copymsg.c
***************
*** 1,9 ****
! /* $Header: copymsg.c,v 1.1 88/06/06 09:38:13 chip Exp $
*
* Take the message from standard input and write it to two temp files,
* one for the header (including the empty line) and one for the body.
*
* $Log: copymsg.c,v $
* Revision 1.1 88/06/06 09:38:13 chip
* Initial revision
*
--- 1,14 ----
! /* $Header: copymsg.c,v 1.2 88/11/18 12:17:40 network Exp $
*
* Take the message from standard input and write it to two temp files,
* one for the header (including the empty line) and one for the body.
*
* $Log: copymsg.c,v $
+ * Revision 1.2 88/11/18 12:17:40 network
+ * patch2: Improved signal handling.
+ * patch2: Make sure all environment variables are always provided.
+ * patch2: Some users can be trusted to specify delivery files.
+ *
* Revision 1.1 88/06/06 09:38:13 chip
* Initial revision
*
***************
*** 37,43 ****
{
char buf[BUFSIZ];
FILE *dfp[T_MAX];
! char *p, *fsender, *fremote, *osender, *oremote;
long now;
int t, b, empty_line;
int ret = 0;
--- 42,48 ----
{
char buf[BUFSIZ];
FILE *dfp[T_MAX];
! char *p, *fsender, *fremote;
long now;
int t, b, empty_line;
int ret = 0;
***************
*** 115,148 ****
/*
* Write a From_ line to the header file.
- * If the user specified a sender name, use it;
- * else if we found a From_ line, use the sender found therein;
- * else use the user name of our real UID.
*/
! if (sender && *sender)
! {
! osender = sender;
! oremote = NULL;
! }
else if (fsender)
{
! osender = fsender;
! oremote = fremote;
}
else
! {
! osender = real_ct->name;
! oremote = NULL;
! }
(void) fputs("From ", dfp[T_HEADER]);
! if (oremote)
! {
! (void) fputs(oremote, dfp[T_HEADER]);
! (void) fputc('!', dfp[T_HEADER]);
! }
! (void) fputs(osender, dfp[T_HEADER]);
(void) fputc(' ', dfp[T_HEADER]);
(void) time(&now);
(void) fputs(ctime(&now), dfp[T_HEADER]);
--- 120,159 ----
/*
* Write a From_ line to the header file.
*/
! /* if caller specified sender, use it */
! if (sender)
! ; /* fine */
!
! /* else if we found a From_ line, use it */
else if (fsender)
{
! if (fremote)
! {
! sender = zalloc(strlen(fremote) + sizeof("!")
! + strlen(fsender));
! (void) sprintf(sender, "%s!%s", fremote, fsender);
! }
! else
! sender = copystr(fsender);
}
+
+ /* else use our real ID */
else
! sender = real_ct->name;
+ /* debugging message */
+
+ if (verbose)
+ message("copy_msg: sender is \"%s\"\n", sender);
+
+ /*
+ * Finally! Write the From_ line.
+ */
+
(void) fputs("From ", dfp[T_HEADER]);
! (void) fputs(sender, dfp[T_HEADER]);
(void) fputc(' ', dfp[T_HEADER]);
(void) time(&now);
(void) fputs(ctime(&now), dfp[T_HEADER]);
***************
*** 151,157 ****
* Copy the rest of the header (if any).
*/
! for (; !feof(stdin); b = FALSE)
{
if (!b)
{
--- 162,168 ----
* Copy the rest of the header (if any).
*/
! for (; !feof(stdin) && !ferror(stdin); b = FALSE)
{
if (!b)
{
***************
*** 217,223 ****
*/
empty_line = FALSE;
! for (; !feof(stdin); b = FALSE)
{
if (!b)
{
--- 228,234 ----
*/
empty_line = FALSE;
! for (; !feof(stdin) && !ferror(stdin); b = FALSE)
{
if (!b)
{
***************
*** 242,247 ****
--- 253,259 ----
while (!strchr(buf, '\n')
&& !feof(stdin)
+ && !ferror(stdin)
&& fgets(buf, GETSIZE(buf), stdin))
(void) fputs(buf, dfp[T_BODY]);
}
Index: deliver.h
***************
*** 1,8 ****
! /* $Header: deliver.h,v 1.4 88/10/13 12:19:18 network Exp $
*
* General pull-it-together include file.
*
* $Log: deliver.h,v $
* Revision 1.4 88/10/13 12:19:18 network
* patch1: add "-n" option, and general bug fixes.
*
--- 1,13 ----
! /* $Header: deliver.h,v 1.5 88/11/18 12:16:55 network Exp $
*
* General pull-it-together include file.
*
* $Log: deliver.h,v $
+ * Revision 1.5 88/11/18 12:16:55 network
+ * patch2: Improved signal handling.
+ * patch2: Make sure all environment variables are always provided.
+ * patch2: Some users can be trusted to specify delivery files.
+ *
* Revision 1.4 88/10/13 12:19:18 network
* patch1: add "-n" option, and general bug fixes.
*
***************
*** 54,59 ****
--- 59,67 ----
extern CONTEXT *eff_ct; /* Context of effective uid */
extern CONTEXT *real_ct; /* Context of real uid */
+ extern int trust_user; /* Do we trust the user that called us? */
+ extern int trust_delfiles; /* Do we trust the delivery files? */
+
/* Temp file indices: */
#define T_HEADER 0 /* Temp file for message header */
#define T_BODY 1 /* Temp file for message body */
***************
*** 62,67 ****
--- 70,77 ----
extern char *ttype[T_MAX]; /* Temp file types (for messages) */
extern char *tfile[T_MAX]; /* Temp file names */
extern int tfd[T_MAX]; /* Temp file fd's */
+
+ extern SIGFLAG got_sig; /* We caught a signal and should exit */
/*----------------------------------------------------------------------
* Global functions
Index: main.c
***************
*** 1,8 ****
! /* $Header: main.c,v 1.6 88/10/13 12:19:27 network Exp $
*
* A program to deliver local mail with some flexibility.
*
* $Log: main.c,v $
* Revision 1.6 88/10/13 12:19:27 network
* patch1: add "-n" option, and general bug fixes.
*
--- 1,13 ----
! /* $Header: main.c,v 1.7 88/11/18 12:17:17 network Exp $
*
* A program to deliver local mail with some flexibility.
*
* $Log: main.c,v $
+ * Revision 1.7 88/11/18 12:17:17 network
+ * patch2: Improved signal handling.
+ * patch2: Make sure all environment variables are always provided.
+ * patch2: Some users can be trusted to specify delivery files.
+ *
* Revision 1.6 88/10/13 12:19:27 network
* patch1: add "-n" option, and general bug fixes.
*
***************
*** 41,46 ****
--- 46,58 ----
extern char *optarg;
/*
+ * Local data
+ */
+
+ static char sys_default[] = SYS_DELIVER;
+ static char user_default[] = USER_DELIVER;
+
+ /*
* Global data
*/
***************
*** 55,62 ****
char version[32] = "1.0";
char *shell = SHELL;
! char *sys_deliver = NULL;
! char *user_deliver = NULL;
char *sender = NULL;
char *hostname = NULL;
--- 67,74 ----
char version[32] = "1.0";
char *shell = SHELL;
! char *sys_deliver = sys_default;
! char *user_deliver = user_default;
char *sender = NULL;
char *hostname = NULL;
***************
*** 68,77 ****
--- 80,101 ----
CONTEXT *eff_ct = NULL;
CONTEXT *real_ct = NULL;
+ int tty_input = FALSE;
+ SIGFLAG got_sig = FALSE;
+
+ int trust_user = FALSE;
+ int trust_delfiles = FALSE;
+
char *ttype[T_MAX] = { "header", "body" };
char *tfile[T_MAX] = { NULL, NULL };
int tfd[T_MAX] = { -1, -1 };
+ /*
+ * Local functions.
+ */
+
+ static int sighup(), sigint(), sigquit();
+
/*----------------------------------------------------------------------
* The Program.
*/
***************
*** 81,87 ****
char **argv;
{
char *p;
! int u, c, errcount;
/* Make sure that stdout and stderr are interleaved correctly */
--- 105,111 ----
char **argv;
{
char *p;
! int u, c, errcount, copy;
/* Make sure that stdout and stderr are interleaved correctly */
***************
*** 105,110 ****
--- 129,147 ----
hostname);
}
+ /* Find effective and real uids and gids. */
+
+ eff_uid = geteuid();
+ eff_gid = getegid();
+ real_uid = getuid();
+ real_gid = getgid();
+
+ if (eff_uid != real_uid && eff_uid != 0)
+ {
+ error("if setuid, must be setuid root\n");
+ leave(1);
+ }
+
/* Process environment: handle recursive invocation */
if ((p = getenv(ENV_DFLAGS)) != NULL)
***************
*** 133,145 ****
}
}
}
! if ((p = getenv(ENV_SYSDEL)) != NULL)
sys_deliver = p;
! if ((p = getenv(ENV_USERDEL)) != NULL)
user_deliver = p;
! if ((p = getenv(ENV_SENDER)) != NULL)
sender = p;
! if ((p = getenv(ENV_HOSTNAME)) != NULL)
hostname = p;
/* Parse command line arguments */
--- 170,183 ----
}
}
}
!
! if ((p = getenv(ENV_SYSDEL)) != NULL && *p)
sys_deliver = p;
! if ((p = getenv(ENV_USERDEL)) != NULL && *p)
user_deliver = p;
! if ((p = getenv(ENV_SENDER)) != NULL && *p)
sender = p;
! if ((p = getenv(ENV_HOSTNAME)) != NULL && *p)
hostname = p;
/* Parse command line arguments */
***************
*** 169,184 ****
boxdelivery = TRUE;
break;
case 's':
! sys_deliver = optarg;
break;
case 'u':
! user_deliver = optarg;
break;
case 'r':
! sender = optarg;
break;
case 'h':
! hostname = optarg;
break;
case '?':
usage();
--- 207,226 ----
boxdelivery = TRUE;
break;
case 's':
! if (*optarg)
! sys_deliver = optarg;
break;
case 'u':
! if (*optarg)
! user_deliver = optarg;
break;
case 'r':
! if (*optarg)
! sender = optarg;
break;
case 'h':
! if (*optarg)
! hostname = optarg;
break;
case '?':
usage();
***************
*** 199,224 ****
{
message("%s %s running on host %s\n",
progname, version, hostname);
- if (sender && *sender)
- message("Sender is %s\n", sender);
}
! /* Find effective and real uids and gids. */
! eff_uid = geteuid();
! eff_gid = getegid();
! real_uid = getuid();
! real_gid = getgid();
! if (eff_uid != real_uid && eff_uid != 0)
! {
! error("if setuid, must be setuid root\n");
! leave(1);
! }
/* Renounce special privileges if something insecure was requested. */
! if (sys_deliver || user_deliver)
{
if (setgid(eff_gid = real_gid) == -1
|| setuid(eff_uid = real_uid) == -1)
--- 241,262 ----
{
message("%s %s running on host %s\n",
progname, version, hostname);
}
! /* Do we trust our caller? */
! if (trusted_uid(real_uid))
! trust_user = TRUE;
! /* Do we trust our delivery files? */
+ if (strcmp(sys_default, sys_deliver) == 0
+ && strcmp(user_default, user_deliver) == 0)
+ trust_delfiles = TRUE;
+
/* Renounce special privileges if something insecure was requested. */
! if (!trust_user && !trust_delfiles)
{
if (setgid(eff_gid = real_gid) == -1
|| setuid(eff_uid = real_uid) == -1)
***************
*** 253,273 ****
u |= 022; /* Let's be reasonably paranoid about writing. */
(void) umask(u);
! /* Turn off all intrusive signals (unless we're not delivering). */
! if (! dryrun)
! {
! (void) signal(SIGHUP, SIG_IGN);
! (void) signal(SIGINT, SIG_IGN);
! (void) signal(SIGQUIT, SIG_IGN);
! }
/*
* Create the temporary files and write the message to them.
*/
! if (copy_message() < 0)
leave(1);
/*
* Set up useful environment variables.
--- 291,337 ----
u |= 022; /* Let's be reasonably paranoid about writing. */
(void) umask(u);
! /*
! * Where is the message coming from?
! */
! if (isatty(0))
! tty_input = TRUE;
/*
+ * If we are not going to deliver, or if we are receiving the
+ * message from a tty, catch signals so we can remove temp files.
+ * Otherwise, ignore signals.
+ */
+
+ if (dryrun || tty_input)
+ catch_sigs();
+ else
+ ignore_sigs();
+
+ /*
* Create the temporary files and write the message to them.
*/
! copy = copy_message();
!
! /*
! * No more signals...
! */
!
! ignore_sigs();
!
! /*
! * ... but if we had already caught a signal,
! * or if copy_msg() had a problem, leave.
! */
!
! if ((copy < 0) || got_sig)
! {
! if (got_sig)
! error("caught signal - exiting\n");
leave(1);
+ }
/*
* Set up useful environment variables.
***************
*** 278,294 ****
setup_environ();
/*
- * Assign the default delivery file names.
- * Note that this must be after setup_environ(), or else the
- * environment won't reflect specified/unspecified options.
- */
-
- if (!sys_deliver)
- sys_deliver = SYS_DELIVER;
- if (!user_deliver)
- user_deliver = USER_DELIVER;
-
- /*
* Perhaps we should consider all arguments as mailbox names...
*/
--- 342,347 ----
***************
*** 389,405 ****
usage()
{
message("Usage: %s [-b][-A][-d][-v][-n][-t][-r from][-h host] args\n", progname);
! message("-b All arguments are mailbox filenames.\n");
! message(" (Default: arguments are user names.)\n");
! message("-A Resolve addresses but do not deliver.\n");
! message("-d Be verbose but do not deliver.\n");
! message("-v Be verbose and deliver.\n");
! message("-n Do not run any delivery files.\n");
! message("-t Do not remote temp files before exiting.\n");
! message("-r from Specify the address to appear in the \"From \" line.\n");
! message("-h host Specify the host name.\n");
! message(" (This option overrides any \"From \" line in the input.)\n");
! message("args Either user addresses or mailboxes (-b).\n");
leave(1);
}
--- 442,459 ----
usage()
{
message("Usage: %s [-b][-A][-d][-v][-n][-t][-r from][-h host] args\n", progname);
! message("-b All arguments are mailbox filenames.\n");
! message(" (Default: arguments are user names.)\n");
! message("-A Resolve addresses but do not deliver.\n");
! message("-d Be verbose but do not deliver.\n");
! message("-v Be verbose and deliver.\n");
! message("-n Do not run any delivery files.\n");
! message("-t Do not remote temp files before exiting.\n");
! message("-s file Specify the system delivery filename.\n");
! message("-u file Specify the user delivery filename.\n");
! message("-r from Specify the address to appear in the \"From \" line.\n");
! message("-h host Specify the host name.\n");
! message("args Either user addresses or mailboxes (-b).\n");
leave(1);
}
***************
*** 425,430 ****
--- 479,530 ----
}
/*----------------------------------------------------------------------
+ * Catch signals.
+ */
+
+ catch_sigs()
+ {
+ if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
+ (void) signal(SIGHUP, sighup);
+ if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+ (void) signal(SIGINT, sigint);
+ if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
+ (void) signal(SIGQUIT, sigquit);
+ }
+
+ /*----------------------------------------------------------------------
+ * Ignore signals.
+ */
+
+ ignore_sigs()
+ {
+ (void) signal(SIGHUP, SIG_IGN);
+ (void) signal(SIGINT, SIG_IGN);
+ (void) signal(SIGQUIT, SIG_IGN);
+ }
+
+ static int
+ sighup()
+ {
+ (void) signal(SIGHUP, sighup);
+ got_sig = TRUE;
+ }
+
+ static int
+ sigint()
+ {
+ (void) signal(SIGINT, sigint);
+ got_sig = TRUE;
+ }
+
+ static int
+ sigquit()
+ {
+ (void) signal(SIGQUIT, sigquit);
+ got_sig = TRUE;
+ }
+
+ /*----------------------------------------------------------------------
* Report any errors to stderr.
* Return an error count.
*/
***************
*** 454,459 ****
--- 554,580 ----
}
return count;
+ }
+
+ /*----------------------------------------------------------------------
+ * Is the given uid trusted?
+ */
+
+ int
+ trusted_uid(uid)
+ int uid;
+ {
+ CONTEXT *ct;
+ char **n;
+ static char *t[] = { TRUSTED_USERS, 0 };
+
+ for (n = t; *n; ++n)
+ {
+ if ((ct = name_context(*n)) != NULL && uid == ct->uid)
+ return TRUE;
+ }
+
+ return FALSE;
}
/*----------------------------------------------------------------------
--
Chip Salzenberg <chip at ateng.com> or <uunet!ateng!chip>
A T Engineering Me? Speak for my company? Surely you jest!
Beware of programmers carrying screwdrivers.
More information about the Comp.sources.bugs
mailing list