We need declarative system user and group handling. This should be done from dpkg itself, because eventually it will also be aware of the files metadata which includes users/group information.
Analysis of pre-existing implementations
Using adduser is not satisfactory because:
- It's written in perl, which dpkg.deb does not use anymore.
- Several things are configurable which should not be, such as the valid name regexes (and that forces packages to use --force-badname in case the admin has configured something else).
- Uses the shadow package underneath, which is not portable to other systems dpkg runs on.
I've checked the systemd sysusers.conf stuff, and it also seems unsatisfactory, because it lacks things from the list below. Also being tied to what systemd might or might not agree with does not seem wise.
What we'd need from this new interface and declarative file would be:
- Hardcoded (at least per-vendor) to:
- Accept only "[_a-z][_a-z0-9-]*" names.
- Always create system accounts.
- Default to:
- Home set to something like /nonexistent (not /).
- User disabled.
- User w/o password.
- User shell set to /bin/false.
- GECOS set to empty.
- Create matching user and group.
- Lock the user on last ref.
- Make it possible to:
- Create users or groups.
- Rename users or groups.
- Lock and unlock users.
- Add users to a group.
- Update the user/group metadata.
- Refresh/invalidate data in external daemons (NIS, NSCD), ideally via hooks/plugins, to not hardcode stuff (like adduser does).
- Create the home directory?
- Specify modes for the created home directory?
- Not create a group matching a user.
- Use the same id for both uid and gid.
- Set non-default home.
- Set non-default shell.
- Set a GECOS.
- SE Linux user stuff perhaps?
- Let the admin, set the default home?
- Let the admin, change whether to remove instead of lock on last ref.
- Let the admin, change the range of allowed uid/gids.
This would be either implemented by a new dpkg command or internally, because in theory everything above would be expressable with the declarative file format, so there should be no need to call anything explicitly?
If this is implemented by a new command then the actions could probably be:
- --ref-user user --ref-group group --unref-user user --unref-group group
For sysadmins, shadow and or adduser would still be the interface to use, as those are really fine for those jobs.
For a first iteration I guess we could use the shadow commands as backend, but ideally this should be implemented natively in dpkg, to make it "portable". But there's no standard API to handle the gshadow file, if it even exists.
- */Linux uses /etc/passwd, /etc/shadow, /etc/group, /etc/gshadow.
- BSDs uses /etc/passwd and /etc/master.passwd, /etc/group.
- FreeBSD pw(8), adduser(8), pwd_mkdb(8).
- DragonFlyBSD pw(8), adduser(8), pwd_mkdb(8).
- NetBSD user(8), useradd(8), usermod(8), userdel(8), group(8), groupadd(8), groupmod(8), groupdel(8), pwd_mkdb(8).
- OpenBSD adduser(8), rmuser(8), pwd_mkdb(8).
- AIX uses /etc/passwd and /etc/security/passwd, /etc/group, /etc/security/group.
- mkuser(8), rmuser(8), mkgroup(8), rmgroup(8), pwdadm(8), chuser(8), lsuser(8), chgroup(8), chgrpmem(8), lsgroup(8), useradd(8), userdel(8), usermod(8).
- Mac OS X uses the Directory Service, or legacy /etc/master.passwd.
- Legacy pwd_mkdb(8).
- New dscl(8), Directory Service command-line utility