Deliver 1.00 patch #2

Chip Salzenberg chip at ateng.ateng.com
Sat Nov 19 04:07:39 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