[news.software.nntp] environ and myenviron

ge@dutlru1.tudelft.nl (Ge van Geldorp) (11/20/90)

I'm running NNTP 1.5.10 and C-News on our main news hosts. Some of our other
machines can post via this main news host using the NNTP-supplied mini-inews.
When posting something using this method, a problem occurs when the C-News
censor anne.jones gets its hands on the posted article. It can't figure out
who it is running as (needed to put a Sender: header in).
One of the first things anne.jones does to get the user name is look at the
environment variable LOGNAME. Testing showed me that this environment variable
was not set. This seemed strange since nntpd does a putenv(LOGNAME, ...) in
serve.c, before inews is spawn()ed to handle the post. Digging a little
further, I found that nntpd maintains two sets of environment variables, one
pointed to by char **environ and the other pointed to by char **myenviron. It
turns out that the putenv() updates the environ, but myenviron is used when
spawning inews, therefore the environment passed to inews doesn't contain a
LOGNAME variable.
What I can't figure out is why these two seperate environments are present.
The simplest solution to my problem would be to junk the myenviron and use
environ exclusively, but somebody obviously put some effort in to keep the
two environments separate. It seems to have something to do with SETPROCTITLE,
but I just can't figure out what. (As a side note, when you #undef SETPROCTITLE
in conf.h, myenviron is set equal to environ in main.c, however, when putenv()
adds a new environment variable, e.g. LOGNAME, environ is realloc()ed, so
myenviron which is not updated possibly points to garbage after this. Propably
not the intended behaviour...)
Any hints appreciated.


Ge van Geldorp
ge@dutlru2.tudelft.nl
...!uunet!hp4nl!dutlru2.tudelft.nl!ge

leres@ace.ee.lbl.gov (Craig Leres) (11/21/90)

I originally added this code to keep the SETPROCTITLE from trashing the
environment and really screwing up the child. But as Ge van Geldorp
points out, it breaks putenv(). And in fact, blindly passing the
environment to the child causes other problems (when you have cnews,
anyway). For example if I run nntp standalone and start it up while
su'ed to root from my normal account, postings that show up without a
From or Sender go out looking like I posted them since USER points to
me. (It can be pretty amusing when your buddies start asking you about
your recent posting to soc.feminism or whatever.)

The code I've been running for a few months now either gives the child
a null environment or defines USER and LOGNAME to POSTER. For the
adventurous, I've appended context diffs to batch.c and spawn.c.

		Craig
------
hell 55 % rcsdiff -c -r1.10 -r1.11 batch.c
*** /tmp/,RCSt1a21666	Tue Nov 20 13:40:15 1990
--- /tmp/,RCSt2a21666	Tue Nov 20 13:40:17 1990
***************
*** 30,36 ****
  /* imports */
  extern time_t time();
  extern char *malloc(), *mktemp(), *index(), *rindex();
- extern char **myenviron;
  
  /* forwards */
  static char *strsave();
--- 30,35 ----
***************
*** 344,349 ****
--- 343,353 ----
  	int pid, wpid, status, fd, exitstat;
  	char permname[MAXDIGITS], *number = permname, *newsrun;
  	struct stat stbuf;
+ #ifdef POSTER
+ 	char *envp[3], user[sizeof(POSTER) + 5], logname[sizeof(POSTER) + 8];
+ #else
+ 	char *envp[1];
+ #endif
  
  	(void) fclose(btch.file);
  	btch.file = NULL;
***************
*** 417,423 ****
  	newsrun = strsave(NEWSRUN);
  	if (newsrun == NULL)
  		newsrun = "/usr/lib/newsbin/input/newsrun";
! 	execle(newsrun, newsrun, (char *)NULL, myenviron);
  #ifdef SYSLOG
  	syslog(LOG_ERR, "enqueue: execle(%s): %m", newsrun);
  #endif
--- 421,439 ----
  	newsrun = strsave(NEWSRUN);
  	if (newsrun == NULL)
  		newsrun = "/usr/lib/newsbin/input/newsrun";
! 
! 	/* Empty environment keeps cnews inews from telling lies */
! #ifdef POSTER
! 	sprintf(user, "USER=%s", POSTER);
! 	sprintf(logname, "LOGNAME=%s", POSTER);
! 	envp[0] = user;
! 	envp[1] = logname;
! 	envp[2] = 0;
! #else
! 	envp[0] = 0;
! #endif
! 
! 	execle(newsrun, newsrun, (char *)NULL, envp);
  #ifdef SYSLOG
  	syslog(LOG_ERR, "enqueue: execle(%s): %m", newsrun);
  #endif
***************
*** 424,429 ****
--- 440,446 ----
  	exit(1);
  	/* NOTREACHED */
  }
+ 
  static char *
  strsave(s)
  register char *s;


hell 56 % rcsdiff -c -r1.9 -r1.10
*** /tmp/,RCSt1a21687	Tue Nov 20 13:40:39 1990
--- /tmp/,RCSt2a21687	Tue Nov 20 13:40:41 1990
***************
*** 13,21 ****
  static int	old_xfer_lines;
  #endif
  
- /* imports */
- extern char **myenviron;
- 
  static char	tempfile[256];
  #ifndef CNEWS
  static char	badfile[256];
--- 13,18 ----
***************
*** 57,62 ****
--- 54,64 ----
  	int		fds[2];
  	int		pid, npid;
  	int		exit_status;
+ #ifdef POSTER
+ 	char *envp[3], user[sizeof(POSTER) + 5], logname[sizeof(POSTER) + 8];
+ #else
+ 	char *envp[1];
+ #endif
  #ifdef XFER_TIMEOUT
  	int		xfer_timeout();
  #endif
***************
*** 194,200 ****
  			(void) close(fd);
  		}
  
! 		execle(path, name, flag, (char *) NULL, myenviron);
  		fprintf(stderr, "spawn: execle(%s)", path);
  		perror(path);
  #ifdef SYSLOG
--- 196,213 ----
  			(void) close(fd);
  		}
  
! 		/* Empty environment keeps cnews inews from telling lies */
! #ifdef POSTER
! 		sprintf(user, "USER=%s", POSTER);
! 		sprintf(logname, "LOGNAME=%s", POSTER);
! 		envp[0] = user;
! 		envp[1] = logname;
! 		envp[2] = 0;
! #else
! 		envp[0] = 0;
! #endif
! 
! 		execle(path, name, flag, (char *) NULL, envp);
  		fprintf(stderr, "spawn: execle(%s)", path);
  		perror(path);
  #ifdef SYSLOG