[net.unix-wizards] getpwnam bug

sscalsk@nswc-wo.arpa (08/25/86)

Anybody ever had a blank line as the first line in your password file? It 
happened to me a few weeks ago and the system would not let any user at all
log on. Su did not work either. In looking at the source I found the following
situation:

	getty: calls
	  login: calls
	    getpwnam: calls
	      getpwent: calls
		fgetpwent: which does the following 

		p = fgets(line, BUFSIZ, f);
		if (p == NULL)
  		    return(NULL);
 
Since fgets returns NULL if error or end-of-file or if p read 0 bytes it
seems that the search done by fgetpwent terminates without searching any
further, even though there are further valid entries. Is this the way getpwnam
always works? (I am currently running 4.2BSD/SYS III on a vax 780). I have
not seen any bug reports filed on this particular problem. Now while getting a
null entry in the passwd file may be an infrequent occurence the only way to 
recover this is to crash the system and come up single-user to repair the
passwd file. Thankfully my system doesn't prompt for an id coming into
single-user mode like some systems I've seen. Under that case I think you
would have no recourse but to restore from a backup.

What I think is odd here is that there are other version of getpwnam in 
other utilites that implement the read differently. For example: 
csh/getpwnam implements the fgets as i = read(pwf, line, BUFSIZ). Anybody
know why csh chose not to use the pw routines?
		

rbj@icst-cmr.arpa (Root Boy Jim) (08/27/86)

	Anybody ever had a blank line as the first line in your
	password file? It happened to me a few weeks ago and the system
	would not let any user at all log on. Su did not work either.
	In looking at the source I found the following situation:

		getty: calls
		  login: calls
		    getpwnam: calls
		      getpwent: calls
			fgetpwent: which does the following 
	
			p = fgets(line, BUFSIZ, f);
			if (p == NULL)
	  		    return(NULL);
	 
	Since fgets returns NULL if error or end-of-file or if p read 0
	bytes it seems that the search done by fgetpwent terminates
	without searching any further, even though there are further
	valid entries. Is this the way getpwnam always works? (I am
	currently running 4.2BSD/SYS III on a vax 780). I have not seen
	any bug reports filed on this particular problem. Now while
	getting a null entry in the passwd file may be an infrequent
	occurence the only way to recover this is to crash the system
	and come up single-user to repair the passwd file. Thankfully
	my system doesn't prompt for an id coming into single-user mode
	like some systems I've seen. Under that case I think you would
	have no recourse but to restore from a backup.

You are wrong on both accounts. I added a blank line at the head
of my /etc/passwd with no problems. Also, fgets returns a pointer
to a line containing only a newline when reading a blank line.

We run vanilla 4.2BSD on a VAX 750. Perhaps it is the SYS III part
of your system that is messing up, altho I doubt for the reasons
you mention. Fgets is too old a routine to have variations.

	What I think is odd here is that there are other version of
	getpwnam in other utilites that implement the read differently.
	For example:  csh/getpwnam implements the fgets as i =
	read(pwf, line, BUFSIZ).

	Anybody know why csh chose not to use the pw routines?
			
Perhaps it is because of efficiency.

	(Root Boy) Jim Cottrell		<rbj@icst-cmr.arpa>
	..I have read the INSTRUCTIONS...

P.S. Say hi to my dad (same name) if you know him.

sscalsk@nswc-wo.arpa (08/27/86)

Jim,
	You are correct. Adding a blank line to the head of the passwd file
on a vanilla 4.2BSD system does not have a problem because of the following:
On a vanilla 4.2BSD (which I also have) the routine fgetpwent does not exist.
Is this true for you? (NOTE: fgetpwent takes 1 parm - a file pointer to the 
passwd file). The routine getpwent does all the necessary processing.
Processing of the line read by the fgets is done even if the fgets returned
a line containing only a '\n'. The source shows no further checking on the
contents of the line read by the fgets. In taking a closer look at the code 
on my system it proceeds as follows:

		getpwent: calls
		  fgetpwent: which does the following

		  p=fgets(line, BUFSIZ, f);
		  if (p == NULL)
		    return(NULL);
		  assign pw_name from p
		  p = pwskip(p)
		  assign pw_passwd from p
		  p = pwskip(p)
		  if (p == NULL || *p == ':')
		    return (NULL)

I was incorrect in saying it was the fgets returning the NULL when in fact
it is the final return of the example (after the pwskip processing) that
is returning the NULL. You might also be correct in that it is the SYS III
part of the system that this code is from. It sure doesnt look like vendor
modified code, but not having access to anything but 4.2BSD it is hard to
verify.

Stan Scalsky	Naval Surface Weapons Center - White Oak
ARPA:		sscalsk@nswc-wo.arpa
Compuserve:	70337,2015

hutch@sdcsvax.UUCP (Jim Hutchison) (09/01/86)

In article <3343@brl-smoke.ARPA> rbj@icst-cmr.arpa (Root Boy Jim) writes:
>
>	Anybody ever had a blank line as the first line in your
>	password file? It happened to me a few weeks ago and the system
>	would not let any user at all log on. Su did not work either.
>	In looking at the source I found the following situation:
>
>		getty: calls
>		  login: calls
>		    getpwnam: calls
>		      getpwent: calls
>			fgetpwent: which does the following 
>	
>			p = fgets(line, BUFSIZ, f);
>			if (p == NULL)
>	  		    return(NULL);
>	 
>	Since fgets returns NULL if error or end-of-file or if p read 0
>	bytes it seems that the search done by fgetpwent terminates
>	without searching any further, even though there are further
>	valid entries. Is this the way getpwnam always works? (I am
>	currently running 4.2BSD/SYS III on a vax 780). I have not seen
>	any bug reports filed on this particular problem. Now while
>	getting a null entry in the passwd file may be an infrequent
>	occurence the only way to recover this is to crash the system
>	and come up single-user to repair the passwd file. Thankfully
>	my system doesn't prompt for an id coming into single-user mode
>	like some systems I've seen. Under that case I think you would
>	have no recourse but to restore from a backup.
>
>You are wrong on both accounts. I added a blank line at the head
>of my /etc/passwd with no problems. Also, fgets returns a pointer
>to a line containing only a newline when reading a blank line.
>
>We run vanilla 4.2BSD on a VAX 750. Perhaps it is the SYS III part
>of your system that is messing up, altho I doubt for the reasons
>you mention. Fgets is too old a routine to have variations.
>
>	What I think is odd here is that there are other version of
>	getpwnam in other utilites that implement the read differently.
>	For example:  csh/getpwnam implements the fgets as i =
>	read(pwf, line, BUFSIZ).
>
>	Anybody know why csh chose not to use the pw routines?
>			
>Perhaps it is because of efficiency.
>
>	(Root Boy) Jim Cottrell		<rbj@icst-cmr.arpa>
>	..I have read the INSTRUCTIONS...
>
>P.S. Say hi to my dad (same name) if you know him.


-- 
    Jim Hutchison   UUCP:	{dcdwest,ucbvax}!sdcsvax!hutch
		    ARPA:	Hutch@sdcsvax.ucsd.edu
	"The fog crept in on little cats feet" -CS