[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Shadow passwords...

Peter Tobias:
> Setting the binary to 2755 root.shadow is only necessary if the
> program will be run by normal users. Programs that are only started
> by root (for example system daemons) can (and should) be 755 root.root.

A few more comments...

Most programs that need to be able to read shadow passwords already
run as root anyway, to be able to do other things (like switching
to the new user's UID).  These don't need any special attention.

Programs that are run by normal users, and don't need any special
privileges (except to get the current user's encrypted password) -
such as xlock, vlock, xtrlock, ... - should ideally be modified to
read the user's encrypted password at startup, close the shadow
file using endspent(), and completely drop privileges as soon as
possible.  This way, only a few lines of code run with increased
privileges (all these fancy screen savers run as the ordinary user),
and the possibility of a security hole is greatly reduced.  (Note
that even with just setgid shadow, any exploitable buffer overrun
can be used to gain read access to /etc/shadow.)  See xtrlock for
an example how this should be done - it's so simple that it should
be reasonably safe to install setuid root.

Now for the setuid root vs setgid shadow thing.  I agree that
setgid shadow is sufficient in most cases (when shadow passwords
are stored in the /etc/shadow file, readable by group "shadow").
But please keep in mind that there are cases where setgid shadow
is not sufficient - especially with glibc and the Name Service
Switch, /etc/shadow is not the only possible source of shadow
password information for getspnam().  Sometimes the passwords
need to be read over the network, using privileged ports to
prevent ordinary users from reading them directly.  As far as
I know, the NIS server that comes with Debian can be configured
this way, for example.  This is the case where programs such as
xlock need to be setuid root - setgid shadow is not sufficient
to use privileged ports.  (Agreed, privileged ports are not the
most secure thing under the sun, but are useful on a carefully
controlled network, and free from US crypto export restrictions.)

Now I see that all the *lock* programs are being changed from
setuid root to setgid shadow.  Please consider the above before
doing so, at least for cleanly written programs such as xtrlock.

One more security issue: these programs do setuid(getuid()) to
drop setuid root privileges.  Now, if they are changed to setgid
shadow, this has no effect, and they continue to run with the
shadow group privileges.  Unfortunately, it is not possible to
drop setgid privileges using only the POSIX setgid() function.
It can (and should) be done using setregid(getgid(), getgid()).

So, to be safe when installed both setuid and setgid, the *lock*
programs should do something like the following at startup:

main(int argc, char **argv)
	struct passwd *pw;
	char *saved_passwd;
	struct spwd *sp;

	pw = getpwuid(getuid());  /* or use getlogin() */
	if (!pw) {
		/* ... error ... */
	sp = getspnam(pw->pw_name);
	if (sp)
		pw->pw_passwd = sp->sp_pwdp;
	saved_passwd = strdup(pw->pw_passwd);
	endspent();  /* close /etc/shadow after getspnam() */
	setregid(getgid(), getgid());  /* drop setgid privileges */
	setuid(getuid());  /* drop setuid root privileges */

	... untrusted code follows ...
	use saved_passwd to verify the password
	entered by the user

The problem with xlockmore was that it was not easy to modify
it to do things as described above.  The current versions are
much cleaner than the one I was modifying for shadow support.


Reply to: