Subject: Re: bin/8428: uucpd truncates login names at 8 characters
To: Greg A. Woods <woods@most.weird.com>
From: Eric Schnoebelen <eric@cirr.com>
List: netbsd-bugs
Date: 09/24/1999 10:28:29
------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <18252.938186852.1@cirr.com>

Greg A. Woods writes:
- [ On Friday, September 17, 1999 at 10:12:57 (-0500), eric@cirr.com wrote: ]
- > Subject: bin/8428: uucpd truncates login names at 8 characters
- >       uucpd truncates login names at 8 characters causing uucp users
- >       with longer login names to be denied access.
- 
- Yes, it has always done that.

	I guess I had never noticed, or never tracked the problem
down to uucpd before. It is different behavior than provided by
login.

- >       (as I recall, either 1.3 or 1.4 of NetBSD raised the length on
- >       user names above 8 characters.)
- 
- Not that I've seen (not where it really matters UT_NAMESIZE == 8 &&
- L_cuserid == 9), but FreeBSD has done this.

	I must have mis-remembered a conversation in the past.
In any event, getpwnam() does not appear to have any
restrictions on the lenght of the string it will search for, nor
on the lentgth of the string it will return (if it had the 8
character limit, this problem would not have demonstrated
itself.)

- > >Fix:
- >       [ the following fix is in service on uucp.cirr.com]
- >       --- uucpd.c~    Fri Sep 17 09:57:44 1999
- >       +++ uucpd.c     Fri Sep 17 09:56:31 1999
- >       @@ -159,8 +159,7 @@
- >                               return;
- >                       }
- >               } while (user[0] == '\0');
- >       -       /* truncate username to 8 characters */
- >       -       user[8] = '\0';
- >       +
- >               pw = getpwnam(user);
- >               if (pw == NULL || (pw->pw_passwd && *pw->pw_passwd != '\0')) {
- >                       printf("Password: ");
- 
- Did you check through the rest of the code to see if there are any
- possible bugs opened up by allowing the "user" full control over the
- size and content of the username?

	Yes, I have.

	The only program _ever_ execued by uucpd is
_PATH_UUCICO, which doesn't do anything with the USER
environment variable. (not that the code would get that far, as
getpwnam() wouldn't find a bogus name, and uucpd would bail
before that.)

	user[] shouldbe truncated to MAXLOGNAME to keep
setlogin() happy, and I've incorporated that into a new patch
below.  I've also forced user[] to be null terminated after
leaving readline(), in case someone attempts a buffer overflow
by sending more than 64 characters (sizeof user).

--
Eric Schnoebelen		eric@cirr.com		http://www.cirr.com
	    When confronted by a difficult problem just reduce it
	    to the question, "How would Captain Kirk handle this?"

------- =_aaaaaaaaaa0
Content-Type: text/plain
Content-ID: <18252.938186852.2@cirr.com>

*** uucpd.c~	Thu Sep 23 15:25:39 1999
--- uucpd.c	Thu Sep 23 15:29:53 1999
***************
*** 57,62 ****
--- 57,63 ----
  #include <sys/ioctl.h>
  #include <sys/socket.h>
  #include <sys/syslog.h>
+ #include <sys/param.h>	/* for MAXLOGNAME */
  
  #include <netinet/in.h>
  
***************
*** 159,166 ****
  			return;
  		}
  	} while (user[0] == '\0');
! 	/* truncate username to 8 characters */
! 	user[8] = '\0';
  	pw = getpwnam(user);
  	if (pw == NULL || (pw->pw_passwd && *pw->pw_passwd != '\0')) {
  		printf("Password: ");
--- 160,167 ----
  			return;
  		}
  	} while (user[0] == '\0');
! 	/* force a trailing NULL*/
! 	user[sizeof user] = '\0';
  	pw = getpwnam(user);
  	if (pw == NULL || (pw->pw_passwd && *pw->pw_passwd != '\0')) {
  		printf("Password: ");
***************
*** 192,197 ****
--- 193,202 ----
  	alarm(0);
  	sprintf(Username, "USER=%s", user);
  	dologin(pw, sinp);
+ 
+ 	/* truncate to MAXLOGNAME to keep setlogin() happy */
+ 	user[MAXLOGNAME] = '\0';
+ 
  	if (initgroups(pw->pw_name, pw->pw_gid) < 0 ||
  	    setgid(pw->pw_gid) < 0 ||
  	    chdir(pw->pw_dir) < 0 ||

------- =_aaaaaaaaaa0--