Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Nov 1997 23:27:57 -0200 (EDT)
From:      Joao Carlos Mendes Luis <jonny@coppe.ufrj.br>
To:        wpaul@skynet.ctr.columbia.edu (Bill Paul)
Cc:        jonny@coppe.ufrj.br, perhaps@yes.no, hackers@FreeBSD.ORG
Subject:   Re: Password verification (Was: cvs commit: ports/x11/kdebase - Imported sources)
Message-ID:  <199711040127.XAA11439@gaia.coppe.ufrj.br>
In-Reply-To: <199711032256.RAA24611@skynet.ctr.columbia.edu> from Bill Paul at "Nov 3, 97 05:56:35 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
#define quoting(Bill Paul)
// > Humm...  This needs some change from the sender point of view, right ?
// > Maybe it could be more useful if it messed only with the receiver side.
// > Is it possible ?  Probably not, for datagram stuff.
// 
// Both the sender and the receiver have to cooperate a bit. The sender
// must use sendmsg() and the receiver must use recvmsg(). But the receiver
// is able to enforce the use of credentials: a sender can use send() or
// write() or whatever, but in this case the receiver will not get any
// ancillary data and the cmsg_type flag will not be set. The receiver then
// knows that there aren't any creds to look at so it can return an error
// to the sender and ignore the unauthenticated message.

I'm not thinking in the shadow problem right now.  I'm thinking about
the new flag.  Maybe it could be a bit more useful if it needed a change
(an ioctl() ?) just on the receiver side.  IFF the receiver needs to
check, check.  If not, don't.

I can't think in an application right now, but I don't like to put
limits where they need not to be.

// > // 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.
// > 
// > I thought about that.  Just make the program use this as an option, and
// > not the default behavior.  Maybe, even, not automatic.
// 
// You would have to fall back to the directly reading the password database.
// The problem is that this checking to see which method to use incurrs 
// overhead, which is something you'd like to avoid.

Back to the shadow problem.

What about this ?

Use the default method to get the records (shadow protected)
If pw->uid == uid || pw->uid == euid then
   try to use daemon to get the password field.
   if ok
     add to record
   else
     leave the '*'
   endif
endif

Only the first if will be an overhead.  And this could be reduced to
some instructions with apropriate coding.

Note: The input to the daemon must not be the uid, but the login name.
But the input to the above condicional is the uid.
     
// > // - 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.
// > 
// > Sure.  To make a head start, maybe a very simple forking connection
// > daemon could work.
// 
// What if I'm a mean widdle user and I write a program to constantly
// bombard the 'passwd database daemon' with requests? You have to be
// careful: this could make the daemon fork() all over the place and eat
// up system resources. I 'fixed' ypserv so that it can only have a certain
// number of children going at any one time; if you try to go over the
// limit, the request fails. (Ypserv only fork()s for YPPROC_ALL requests
// at this point; the only command that uses the YPPROC_ALL service is
// ypcat, so it's a reasonable tradeoff.)

DoS's are always a problem, and not always have a solution.  I have shut
down a V7 system once, by running lots of setuid programs, until eat up
all proc table.  And nobody has convinced me it's not possible anymore.

In the above case, the user will may see this as a "wrong password".
Since root programs do not need this, it's not a big trouble, IMHO.

But, solutions are always good, of course.  They're welcome.

// >  Multithreading is always an option, of course.
// 
// Only if you're into that sort of kinky stuff.

:)

// > // - Consider getpwent(3). You have to make the daemon be able to handle
// > //   things like enumerating the passwd database, not just retrieving
// > //   arbitrary records.
// > 
// > Could you please elaborate on this ?
// 
// I can do pw = getpwnam("wpaul") to retrieve just my record from the
// passwd database, or I can do:
// 
// 	while((pw = getpwent()) != NULL) {
// 		if (strcmp(pw->pw_name, "wpaul"))
// 			continue;
// 	}
// 
// In the latter case, we start from the 'top' of the database and read
// every record until we find the one we want. The former case is just a
// matter of matching a key in the database: you find the record that goes
// with the key and return it. The latter case is more disgusting: it's
// not a problem if you're reading from a file or database directly, but when
// reading from a remote process, it's tough to handle such an 'enumeration'
// request. It's even thougher if you have several of them going at once:
// the server has to juggle multiple clients and send each one the right
// records in the right order.

You will not read every record from the remote process.  Just those
entries which match your uid.

// > Do we have something similar for AF_UNIX sockets ?
// 
// I have made it ridiculously easy to make RPC client/server programs
// that use AF_UNIX sockets in -current. :) For an example, see keyserv.

I know it's easy.  As it's easy to have lot's of waiting processes
instead of just a single inetd superserver.  My question if does 
already exist such a beast.  Or even, if this could be done with
inetd (probably not, but I've never used the AF_UNIX features to
know for sure).

// VMS gets by with allowing unprivileged users to see only their password
// information in the SYSUAF.DAT database. (I'm not entirely sure how this
// is done: I vaguely remember that there were some library routines for
// doing authentication checks and that the SYSUAF.DAT file was not readable
// by normal users. You could only perform authentication checks using the 
// library interface.) I'm not sure how VMS http servers deal with this
// restriction; perhaps they INSTALL the web server image with a particular
// privilege bit set that lets it do authentication for any user.

VMS has a lot more control with ACLs than any other system I have seen.
It's not simple, but it's powerful.  Maybe they have lots of bugs, but
they solve lots of problems unix has.  Is it good ?  Maybe.

Even Unix is in need of ACLs, but it requires a lot of changes in the
system behaviour.  And I'm not talking only about file ACLs here.
But this is another history.

// In any case, there are arguments for both. The former method is, as you
// say, more compatible with existing code. The latter allows you isolate
// the use of the crypt(3) function to a single process, which is handy
// since it means you'd never have to worry about linking new programs with
// -lcrypt ever again. I took this approach with _des_crypt() in Secure RPC:
// keyserv is the only program that actually calls the libdes library;
// everyone else just calls keyserv.

Then you will have the problem with dead servers and performance
requirements.  I'm not proposing a change, just an "adjustment".

					Jonny

--
Joao Carlos Mendes Luis			jonny@gta.ufrj.br
+55 21 290-4698				jonny@coppe.ufrj.br
Universidade Federal do Rio de Janeiro	UFRJ/COPPE/CISI
PGP fingerprint: 29 C0 50 B9 B6 3E 58 F2  83 5F E3 26 BF 0F EA 67



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711040127.XAA11439>