[net.bugs.4bsd] passwd bug, bug in getusershell

authorplaceholder@inmet.UUCP (07/16/86)

Subject: passwd -s won't let you change to any shell in /etc/shells
Index:	/usr/src/bin/passwd.c /usr/src/lib/libc/gen/getusershell.c 4.3bsd

Description:
There's a problem in the "passwd/chsh/chfn" program, and another one
in the c-library function getusershell().  The symptom is that one
cannot change one's shell to one of the shells in /etc/shells.  The
error message is something like "/bin/ksh is not an acceptable shell".

The simple fix is to put a setusershell() in passwd just before the loop
that tests the list of shells against the desired new shell.  The problem
is that setusershell() will not reset the list used by getusershell(),
and so does not really appear to "rewind the file".

Repeat-By:
	Try to change your shell to each of the shells listed in /etc/shells
	in turn.  Some will work.

Fix:
Install these patches to the files mentioned above:

*** /tmp/,RCSt1004772	Tue Jul 15 22:24:14 1986
--- /usr/src/lib/libc/gen/getusershell.c	Tue Jul 15 22:08:53 1986
***************
*** 22,28
  static char *okshells[] =
      { "/bin/sh", "/bin/csh", 0 };
  
! static int inprogress;
  static char **shells, *strings;
  extern char **initshells();
  

--- 22,28 -----
  static char *okshells[] =
      { "/bin/sh", "/bin/csh", 0 };
  
! static int inprogress, should_startover;
  static char **shells, *strings;
  extern char **initshells();
  
***************
*** 33,39
  getusershell()
  {
  	char *ret;
! 	static char **shells;
  
  	if (!inprogress)
  		shells = initshells();

--- 33,39 -----
  getusershell()
  {
  	char *ret;
! 	static char **mshells;
  
  	if (!inprogress)
  		mshells = initshells();
***************
*** 36,45
  	static char **shells;
  
  	if (!inprogress)
! 		shells = initshells();
! 	ret = *shells;
! 	if (*shells != NULL)
! 		shells++;
  	return (ret);
  }
  

--- 36,49 -----
  	static char **mshells;
  
  	if (!inprogress)
! 		mshells = initshells();
! 	if (should_startover) {
! 		mshells = shells;
! 		should_startover = 0;
! 	}
! 	ret = *mshells;
! 	if (*mshells != NULL)
! 		mshells++;
  	return (ret);
  }
  
***************
*** 69,75
  	struct stat statb;
  	extern char *malloc(), *calloc();
  
! 	inprogress = 1;
  	if (shells != NULL)
  		free((char *)shells);
  	shells = NULL;

--- 73,79 -----
  	struct stat statb;
  	extern char *malloc(), *calloc();
  
! 	should_startover = inprogress = 1;
  	if (shells != NULL)
  		free((char *)shells);
  	shells = NULL;
*** /tmp/,RCSt1004809	Tue Jul 15 22:27:48 1986
--- /usr/src/bin/passwd.c	Tue Jul 15 22:26:17 1986
***************
*** 373,378
  	if (u == 0) {
  		valid = newshell;
  	} else {
  		for (valid = getusershell(); valid; valid = getusershell()) {
  			if (newshell[0] == '/') {
  				cp = valid;

--- 373,379 -----
  	if (u == 0) {
  		valid = newshell;
  	} else {
+ 		setusershell();
  		for (valid = getusershell(); valid; valid = getusershell()) {
  			if (newshell[0] == '/') {
  				cp = valid;