Subject: bin/2905: setting environment vars from login
To: None <gnats-bugs@gnats.netbsd.org>
From: None <andreas@planix.com>
List: netbsd-bugs
Date: 10/29/1996 15:05:24
>Number:         2905
>Category:       bin
>Synopsis:       setting environment variables from the login: prompt
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Oct 29 12:20:00 1996
>Last-Modified:
>Originator:     Andreas Wrede
>Organization:
Planix, Inc.
>Release:        <NetBSD-current source date> Oct 27 11:52 EST 1996
>Environment:
	
System: NetBSD woffi 1.2B NetBSD 1.2B (WOFFI) #0: Sun Oct 27 17:50:01 EST 1996 root@woffi:/local/src/netbsd-current/src/sys/arch/i386/compile/WOFFI i386


>Description:
	
This change to login allows a user to set environment variables from the 
login: prompt, via: 'login: username VAR1=value1 VAR2=value2'
This for example allows the use the same account for interactive (=shell)
and encapsulated (=PPP/SLIP) sessions by having the PPP/SLIP specify 
a variable at the login: prompt and the system profile act on it. The idea 
for this was shamelessly stolen from Solaris.


>How-To-Repeat:
	
N/A
>Fix:
	

diff -c /usr/src/usr.bin/login/login.1 ./login.1
*** /usr/src/usr.bin/login/login.1	Fri Oct 13 23:14:44 1995
--- ./login.1	Tue Oct 29 14:12:22 1996
***************
*** 44,49 ****
--- 44,50 ----
  .Op Fl fp
  .Op Fl h Ar hostname
  .Op Ar user
+ .Op Ar environ
  .Sh DESCRIPTION
  The
  .Nm login
***************
*** 115,120 ****
--- 116,128 ----
  specifying the user's home directory (HOME), command interpreter (SHELL),
  search path (PATH), terminal type (TERM) and user name (both LOGNAME and
  USER).
+ .Pp
+ Additional environment values may be specified via
+ .Op Ar environ
+ on the command line or after the username in response to the 
+ login: prompt. Each argument takes the form NAME=value, where NAME 
+ is the name of the environment variable and VALUE is the value to 
+ assigne to it.  Attempts to set PATH, HOME, SHELL, LOGNAME or USER are ignored.
  .Pp
  The standard shells,
  .Xr csh 1
diff -c /usr/src/usr.bin/login/login.c ./login.c
*** /usr/src/usr.bin/login/login.c	Mon Oct 14 12:55:01 1996
--- ./login.c	Tue Oct 29 14:13:48 1996
***************
*** 102,107 ****
--- 102,108 ----
   * be patched on machines where it's too small.
   */
  u_int	timeout = 300;
+ char nbuf[BUFSIZ];
  
  #if defined(KERBEROS) || defined(KERBEROS5)
  int	notickets = 1;
***************
*** 112,118 ****
  
  struct	passwd *pwd;
  int	failures;
! char	term[64], *envinit[1], *hostname, *username, *tty;
  
  int
  main(argc, argv)
--- 113,119 ----
  
  struct	passwd *pwd;
  int	failures;
! char	term[64], *envinit[1], *hostname, *username, *logenv, *tty;
  
  int
  main(argc, argv)
***************
*** 126,132 ****
  	struct utmp utmp;
  	int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval;
  	uid_t uid;
! 	char *domain, *p, *salt, *ttyn;
  	char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
  	char localhost[MAXHOSTNAMELEN];
  
--- 127,133 ----
  	struct utmp utmp;
  	int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval;
  	uid_t uid;
! 	char *domain, *p, *salt, *ttyn, *val;
  	char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
  	char localhost[MAXHOSTNAMELEN];
  
***************
*** 174,187 ****
  			if (!uid)
  				syslog(LOG_ERR, "invalid flag %c", ch);
  			(void)fprintf(stderr,
! 			    "usage: login [-fp] [-h hostname] [username]\n");
  			exit(1);
  		}
  	argc -= optind;
  	argv += optind;
  
  	if (*argv) {
! 		username = *argv;
  		ask = 0;
  	} else
  		ask = 1;
--- 175,194 ----
  			if (!uid)
  				syslog(LOG_ERR, "invalid flag %c", ch);
  			(void)fprintf(stderr,
! 			    "usage: login [-fp] [-h hostname] [username] [environ]\n");
  			exit(1);
  		}
  	argc -= optind;
  	argv += optind;
  
  	if (*argv) {
! 		nbuf[0]='\0';
! 		for (cnt = 0; cnt < argc; cnt++ ) {
! 			if (nbuf[0])
! 				strncat(nbuf," ",sizeof(nbuf)-strlen(nbuf)-1);
! 			strncat(nbuf,argv[cnt],sizeof(nbuf)-strlen(nbuf)-1);
! 		}
! 		username=nbuf;
  		ask = 0;
  	} else
  		ask = 1;
***************
*** 208,213 ****
--- 215,223 ----
  			getloginname();
  		}
  		rootlogin = 0;
+ 		if ((logenv = strchr(username, ' ')) != NULL) {
+ 			*logenv++ = '\0';
+ 		}
  #ifdef	KERBEROS
  		if ((instance = strchr(username, '.')) != NULL) {
  			if (strncmp(instance, ".root", 5) == 0)
***************
*** 394,399 ****
--- 404,414 ----
  	/* Destroy environment unless user has requested its preservation. */
  	if (!pflag)
  		environ = envinit;
+ 	for (p = logenv; p != NULL; ) {
+ 		while ((val = strsep(&p," \t")) != NULL && *val == '\0');
+ 		if (strncasecmp(val,"PATH=",5) != 0)
+ 			putenv(val);
+ 	}
  	(void)setenv("HOME", pwd->pw_dir, 1);
  	(void)setenv("SHELL", pwd->pw_shell, 1);
  	if (term[0] == '\0')
***************
*** 476,486 ****
  	return strcmp(crypt(p, salt), passwd);
  }
  
- #if defined(KERBEROS) || defined(KERBEROS5)
- #define	NBUFSIZ		(UT_NAMESIZE + 1 + 5)	/* .root suffix */
- #else
- #define	NBUFSIZ		(UT_NAMESIZE + 1)
- #endif
  
  #if defined(KERBEROS) || defined(KERBEROS5)
  /*
--- 491,496 ----
***************
*** 517,523 ****
  {
  	int ch;
  	char *p;
- 	static char nbuf[NBUFSIZ];
  
  	for (;;) {
  		(void)printf("login: ");
--- 527,532 ----
***************
*** 526,532 ****
  				badlogin(username);
  				exit(0);
  			}
! 			if (p < nbuf + (NBUFSIZ - 1))
  				*p++ = ch;
  		}
  		if (p > nbuf)
--- 535,541 ----
  				badlogin(username);
  				exit(0);
  			}
! 			if (p < nbuf + (BUFSIZ - 1))
  				*p++ = ch;
  		}
  		if (p > nbuf)
>Audit-Trail:
>Unformatted: