Date: Mon, 3 Nov 1997 09:52:37 -0500 (EST) From: Bill Paul <wpaul@skynet.ctr.columbia.edu> To: perhaps@yes.no (Eivind Eklund) Cc: hackers@freebsd.org, perhaps@yes.no Subject: Re: Password verification (Was: cvs commit: ports/x11/kdebase - Imported sources) Message-ID: <199711031452.JAA24127@skynet.ctr.columbia.edu> In-Reply-To: <199711031005.LAA21994@bitbox.follo.net> from "Eivind Eklund" at Nov 3, 97 11:05:19 am
next in thread | previous in thread | raw e-mail | index | archive | help
Of all the gin joints in all the towns in all the world, Eivind Eklund had to walk into mine and say: > > > > On Sun, 2 Nov 1997, Joao Carlos Mendes Luis wrote: > > > > ... > > > But, how to allow users check only their own password, and still > > > have the added security of shadow passwords ? I can only think > > > in a kind of password checking daemon that would accept commands > > > on a AF_UNIX socket and some patches to libc pw commands. > > > > You can always use the pwcheck daemon from the Cyrus module (see ports). > > It opens a unix socket at /var/pwcheck/pwcheck. Permissions on the > > /var/pwcheck directory can be used to determine who can check passwords. Gee, this sounds familiar. I wonder why that is. Could it be that I agonized over _exactly_ _this_ _problem_ for a couple of months and went stark raving bananas trying to find a solution before finally breaking down and resorting to a kernel hack to do it? Nah, couldn't be that. > Is it restricted to only let a user check his own password? Or could > we make it only check a users own password fairly easily? Take a close look at the SCM_CREDS stuff in -current. Right now, only a few RPC programs use it (keyserv, rpc.yppasswdd, passwd, chpass and src/lib/libc/rpc/clnt_unix.c) but it can be used for something like this. > The simplest solution I can see is to create a /usr/bin/checkpw which > takes in a username/password on stdin, and checks that the username > has the same ID as the users real ID, and exits with OK/failure. (And > I don't care about the expense of exec'ing a program to check a password > - checking passwords are supposed to be expensive.) You've just described the evil and bletcherous keyenvoy program, only without a set-uid bit. > How is the feeling about this kind of program - too much bloat? > Security problem? Personally, I want it - less security problem than > making other programs setuid. > > Eivind. The SCM_CREDS hack will work better. For those who don't know, SCM_CREDS is an additional type of ancillary data that you can transmit with sendmsg()/recvmsg() via an AF_UNIX socket. It's similar to SCM_RIGHTS which, in 4.4BSD, is used to transfer a file descriptor between processes. The idea is that the calling process does a sendmsg() with the SCM_CREDS flag set and an empty controll emssage buffer, and when the kernel sees this in unp_internalize(), it fills in the empty buffer with the sending process's credentials (UID, EUID, GID, other GIDS). When the receiving process does a recvmsg(), it gets a copy of the filled-in buffer and can use the credential info to determine the identity of the sending process and do access checks. If the sender does not set the SCM_CREDS flag when it transmits, the receiver can tell and refuse to do business with the sender. Keyserv uses this trick to learn the identity of the user talking to it so it can protect its secret keys: each user stores his own secret key with keyserv, and keyserv wants to make sure that can only get at his key and no one else's. Sun originally did this using a program called keyenvoy, which was set-uid root. Keyserv was set up to only accept requests from reserved ports on the loopback address. The key_call.c module in the RPC library would talk to keyserv by vfork()ing and exec()ing keyenvoy and passing it things on the command line. In the context of RPC, the performace hit sucked: any program doing lots of Secure RPC transactions (like NIS+) would crawl. In Solaris 2.x, Sun got rid of keyenvoy and switched to a different scheme involing STREAMS/TLI. Turns out there's a way in SysV to learn the identity of a process on the other side of a transport endpoint using t_getinfo(). This is all well and good for Sun, but we don't have STREAMS, nor are we likely to get it anytime soon, so I needed another solution when I adapted keyenvoy for FreeBSD. After much hair-pulling, I realized that the sockets API had nothing equivalent to t_getinfo(), hence I was forced to invent my own. Now, all that aside, you could use the SCM_CREDS hack and AF_UNIX sockets to create a 'password database access' daemon and fix it so that a user can see his own encrypted password and noone else's. But consider the following: - If the system uses this daemon for login authentication and the daemon crashes, noone will be able to log in. - You have to code it in such a way that it won't fall apart in the face of heavy (and possibly concurrent) access by clients. - Consider getpwent(3). You have to make the daemon be able to handle things like enumerating the passwd database, not just retrieving arbitrary records. This is starting to sound suspiciously like ypserv(8). -Bill -- ============================================================================= -Bill Paul (212) 854-6020 | System Manager, Master of Unix-Fu Work: wpaul@ctr.columbia.edu | Center for Telecommunications Research Home: wpaul@skynet.ctr.columbia.edu | Columbia University, New York City ============================================================================= "It is not I who am crazy; it is I who am mad!" - Ren Hoek, "Space Madness" =============================================================================
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711031452.JAA24127>