Subject: central interface to password locking
To: None <tech-misc@NetBSD.ORG>
From: Luke Mewburn <lukem@telstra.com.au>
List: tech-misc
Date: 10/25/1996 17:52:24
With my nsswitch stuff about to be incorporated into -current, I came
up with some other stuff that I feel is necessary to cleanly support
distributed user information. The document explains more.

Comments?

--
	    Synchronising password file modifications
	    -----------------------------------------

			   Luke Mewburn
			<lukem@netbsd.org>

	$Id: passwd.locking,v 1.2 1996/10/25 07:47:11 lukem Exp $


0. Introduction
---------------

The current methods of modifying the passwd user database (passwd,
chfn, etc) are deficient, because:
- locking only supported for local databases, not YP or hesiod (`HS')
- vipw only for local files
- no way to synchronise modifications of src file for YP or HS
  databases with the respective network update daemons (rpc.yppasswdd,
  hesupd)
- no standard library interface to add, modify, or delete password
  entries 
- no useradd/usermod/userdel

Similar problems exist for the group database.

This document contains a proposed method on rectifying most or all of
these problems. Initially, the passwd update problem will be dealt
with.

This design assumes that the nsswitch() implementation I wrote is
installed, and the public interface header <nsswitch.h> exists.


1. New library interfaces
-------------------------

The following functions should be implemented and made available

lock_passwd
-----------

int
lock_passwd(dbtype, lockfile)
	int   dbtype
	char *lockfile[]

Attempt to lock the source file for 'dbtype', which can be one of
	value		source file			'lockfile'
	-----		-----------			----------
	NS_FILES	/etc/master.passwd		/etc/ptmp
	NS_DNS		/var/namedb/src/passwd		/var/namedb/src/ptmp
	NS_NIS		/var/yp/src/passwd		/var/yp/src/ptmp
	NS_NISPLUS	 (not supported yet)		  -

If the appropiate lock file doesn't exist, atomically create it.
Return a status code.

Returns:
	0	Lock succeeded, 'lockfile' contains name of
		lockfile, as a malloc(3)-ed string.
		Caller to free(3) when finished.
	1	Lock already exists, lock failed.
	2	'lockfile' couldn't be written, check errno.
	3	'dbtype' not supported.

unlock_passwd
-------------

int
unlock_passwd(dbtype, lockfile, discard)
	int  dbtype
	char lockfile[]
	int  discard

Attempt to unlock the source file for 'dbtype' (described above in
"1.1 lock_passwd"). If discard is defined, then just unlink 'lockfile'.
Otherwise, atomically rename 'lockfile' to the database file.

Returns:
	0	Unlock succeeded, 'lockfile' was renamed to the
		appropriate file.
	3	dbtype not supported.
	4	Lock doesn't exist, unlock failed.
	5	lockfile couldn't be renamed, check errno.

find_passwdent
--------------

int
find_passwdent(user, dbtype)
	char  user[]
	int  *dbtype

Determine which database that 'user' is first found in, and return
in 'dbtype'. Useful for applications that don't explicitly specify
which database to modify.

Returns:
	0	User found.
	1	User not found.


add_passwdent
-------------

int
add_passwdent(file, pwent)
	char          pwfile[]
	struct passwd pwent

Add 'pwent' to 'pwfile' (usually this will be the lock file returned by
lock_passwd).

Returns:
	0	Add succeeded.
	1	User already exists.
	2	Couldn't write to file, check errno.

modify_passwdent
----------------

int
modify_passwdent(pwfile, user, pwent, pwmask)
	char          pwfile[]
	char          user[]
	struct passwd pwent
	struct passwd pwmask

Modify 'user' in 'pwfile'. For each field in pwmask that is non-zero
or non-NULL, change the corresponding entry for the user to that of
the equivalent field in pwent.

Returns:
	0	Modify succeeded.
	2	Couldn't write to file, check errno.
	3	User doesn't exist.

delete_passwdent
----------------

int
delete_passwdent(pwfile, user)
	char pwfile[]
	char user[]

Delete 'user' from 'pwfile'.

Returns:
	0	Delete succeeded.
	2	Couldn't write to file, check errno.
	3	User doesn't exist.


2. Modifications to existing programs
-------------------------------------

The following programs will need to be converted to using this
interface:

program		functions
-------		---------
vipw		lock_passwd, unlock_passwd
passwd		lock_passwd, unlock_passwd, find_passwdent, modify_passwdent
chfn,chsh	lock_passwd, unlock_passwd, find_passwdent, modify_passwdent
rpc.yppasswdd	lock_passwd, unlock_passwd, modify_passwdent
hesupd		lock_passwd, unlock_passwd, modify_passwdent

It is proposed that vipw, passwd, chfn and chsh all accept a new option:
	'-r source'
This will explicitly make changes in the source file for 'source'.
If this isn't given, then the first source in which the user is found
is used (except for vipw which uses the first listed in
nsswitch.conf).


3. New programs
---------------

The following programs should be implemented, to enable sites to
implement their own user manipulation scripts that don't need to 
attempt to get the password locking correct:

program		description
-------		-----------
useradd		add a user
usermod		change a user
userdel		delete a user

The commands are based on those described in the man pages for the
commands on Solaris 2. Extra functionality should at least include the
provision for supplying the encrypted password string on the command
line (with '-p password').

--
Luke Mewburn                            UNIX Technical Support
<lukem@telstra.com.au>                CPR Project, ITG, Telstra.
Phone: +61 3 9634 2112