Subject: Politically Correct way of doing password authentication?

From: Greg Earle <[email-masked]>

I needed a screen locker for my NetBSD/SPARC X11 R6 setup, so I pulled over my
favorite multi-purpose "xlock" successor, "xlockmore" (xlockmore-1.12, for
those of you playing along at home).  After getting around a couple of thorny
porting problems, I got it working - except for the password authentication.

"xlockmore"/"xlock" wants to do "traditional" password authentication; i.e.,
get the password entry via "getpwnam()" or "getpwuid()", ask the user for a
password and encrypt it with the salt and compare the strings.

Of course, in NetBSD these routines return "*" for the encrypted password field
if the program doesn't run as "root", so no matchee da password.

There is a (half-hearted?) effort at a FreeBSD port included; it punts on this
in the Imakefile via

	#if defined(i386FreeBsd)
	   INSTPGMFLAGS = -s -m 4751
	#endif

(The "i386FreeBsd" is wrong anyway; should be "FreeBSDArchitecture" instead.)

Normally I'm nervous about installing programs that read the password file (or
database?) setuid root, especially when they only need that priviledge for a
few lines of source :-)

Other than the canonical "login" program, what is the correct (PC or otherwise)
way to deal with this in NetBSD?  Leave it installed setuid root and punt?  Or
figure out a "proper" way to bracket the password checking code with the
appropriate uid-setting/unsetting calls?

(Sorry, but trying to remember all of the semantics of how - and which - to use
 out of setreuid/setruid/setrgid/setuid/seteuid/setgid/setegid just gives me a
 headache ... (-: )

	- Greg

---

From: Alan Barrett <[email-masked]>

> Other than the canonical "login" program, what is the correct (PC or
> otherwise) way to deal with this in NetBSD?

Write a tiny setuid-root program to do the authentication.  Write a
function to talk to the authentication program over a Unix domain socket,
or over some pipes.  Put that function in a library.  Call the library
function from your program.  For extra credit, modify all the other
programs that do authentication (login, su, ftpd, ...) to do it the same
way. 

No, I haven't done this, but I think it's the right thing to do.

--apb (Alan Barrett)

---

From: Brian Moore <[email-masked]>

Speaking of using setreuid, should the version of pppd that is included with
NetBSD-current circa 9/16/94 be using setreuid and setregid?  They are in
/usr/src/usr.sbin/pppd/main.c.  Looking at the man page for setreuid and
setregid, it seems that they should be changed to setuid and setgid since they
just set the same value to the real and effective user/group ID.  I'm not
exactly sure if changing these things would effect the rest of the code ( hell,
I just use pppd I don't understand it :) ), I just mentioned it in case nobody
else noticed.

Cheers,
	--Brian

---

From: John Kohl <[email-masked]>

I've compiled pppd with setuid(getuid()) and setgid(getgid()), and it
works just fine.  I also made pppd open the device in O_NDELAY mode--I
don't know why it was commented out, but modems react much better if you
open them this way.

Here are patches:
===================================================================
RCS file: RCS/main.c,v
retrieving revision 1.11
diff -c -r1.11 main.c
*** 1.11	1994/07/04 19:30:22
--- main.c	1994/09/18 22:19:36
***************
*** 348,354 ****
      /*
       * Open the serial device and set it up to be the ppp interface.
       */
!     if ((fd = open(devnam, O_RDWR /*| O_NDELAY*/)) < 0) {
  	syslog(LOG_ERR, "open(%s): %m", devnam);
  	die(1);
      }
--- 348,354 ----
      /*
       * Open the serial device and set it up to be the ppp interface.
       */
!     if ((fd = open(devnam, O_RDWR | O_NDELAY)) < 0) {
  	syslog(LOG_ERR, "open(%s): %m", devnam);
  	die(1);
      }
***************
*** 1144,1151 ****
      }
  
      if (pid == 0) {
! 	setreuid(getuid(), getuid());
! 	setregid(getgid(), getgid());
  	sigprocmask(SIG_SETMASK, &mask, NULL);
  	dup2(in, 0);
  	dup2(out, 1);
--- 1144,1151 ----
      }
  
      if (pid == 0) {
! 	setuid(getuid());
! 	setgid(getgid());
  	sigprocmask(SIG_SETMASK, &mask, NULL);
  	dup2(in, 0);
  	dup2(out, 1);

---

From: Peter Galbavy <[email-masked]>

>                   I also made pppd open the device in O_NDELAY mode--I

My guess would be (not saying your fix is incorrect) that in most cases
the "chat" program would be used to open the port and dial. Just a thought.

Regards,
-- 
Peter Galbavy					work: [email-masked]
Wonderland					rest: [email-masked]
						play: http://www.wonderland.org/
"The 'net interprets censorship as damage and routes around it." - John Gilmore

---

From: "Gary D. Duzan" <[email-masked]>

In Message <[email-masked]> ,
   Ken Hornstein <[email-masked]> wrote:

=>>>                   I also made pppd open the device in O_NDELAY mode--I
=>>> don't know why it was commented out, but modems react much better if you
=>>> open them this way.
=>>
=>>My guess would be (not saying your fix is incorrect) that in most cases
=>>the "chat" program would be used to open the port and dial. Just a thought.
=>
=>As far as I can tell, it only makes sense to have pppd open the device and
=>then call chat; that's how I use it, and I can't see any other way to do it
=>that makes sense.
=>
=>FWIW, I made the very same O_NDELAY hack to pppd a while back so it would work
=>on the home machine, so of course I think it's a good idea :-)

   FYI, I tried removing the comments around O_NDELAY and my ppp login
script, included below, no longer works. This message is logged:

Sep 19 19:58:10 wheel pppd[99]: could not set up connection

And here is the script:

#!/bin/sh

exec pppd defaultroute connect 'chat -f /etc/ppp/totiac' lock passive noipdefault mru 296 mtu 296 tty02 19200 > /dev/null 2>&1

   Removing O_NDELAY got rid of the problem. Perhaps a change to chat would
be required?

                                      Gary D. Duzan
                         Humble Practitioner of the Computer Arts

---

From: John Kohl <[email-masked]>

Oh, right, you need this patch for usr.sbin/pppd/chat/chat.c:

===================================================================
RCS file: RCS/chat.c,v
retrieving revision 1.1
diff -c -r1.1 chat.c
*** 1.1	1994/09/02 02:59:02
--- usr.sbin/pppd/chat/chat.c	1994/09/13 02:33:00
***************
*** 873,879 ****
--- 873,881 ----
      {
      int status;
      char c;
+     int rounds = 0;
  
+ again:
      status = read(0, &c, 1);
  
      switch (status)
***************
*** 886,897 ****
  		   status);
  
  	case -1:
! 	    if ((status = fcntl(0, F_GETFL, 0)) == -1)
! 		sysfatal("Can't get file mode flags on stdin");
! 	    else
! 		if (fcntl(0, F_SETFL, status & ~FNDELAY) == -1)
! 		    sysfatal("Can't set file mode flags on stdin");
! 
  	    return (-1);
  	}
      }
--- 888,904 ----
  		   status);
  
  	case -1:
! 	    if (verbose)
! 		syslog(LOG_WARNING, "get_char(): %m");
! 	    if (errno == EWOULDBLOCK) {
! 		if ((status = fcntl(0, F_GETFL, 0)) == -1)
! 		    sysfatal("Can't get file mode flags on stdin");
! 		else
! 		    if (fcntl(0, F_SETFL, status & ~FNDELAY) == -1)
! 			sysfatal("Can't set file mode flags on stdin");
! 		if (rounds++ == 0)
! 		    goto again;
! 	    }
  	    return (-1);
  	}
      }

---

From: "Gary D. Duzan" <[email-masked]>

In Message <[email-masked]> ,
   John Kohl <[email-masked]> wrote:

=>Oh, right, you need this patch for usr.sbin/pppd/chat/chat.c:
=>
   Yes, that seems to have done it. On a possibly related note,
I'm seeing errs popping up in pppstats periodically, which
really slows things down. Would this most likely be due to a
cheap internal modem or something else? Thanks.

                                      Gary D. Duzan