TomCallaway/UsersAndGroupsDraft

= User and group handling in packages =

Author:  Tom 'spot' Callaway  Revision: 0.01 Initial Draft: Wednesday June 13, 2007 Last Revised: Wednesday, June 13, 2007

The need for caution
It is important to be extremely careful when adding users and groups at installtime. We need to be sure of the following:


 * We do not create easily exploitable security vulnerabilities
 * We do not break RPM transactions trying to manage users and groups

When adding a user or group at package install-time, there are four system states:


 * The user/group does not exist on the system
 * The user/group exists from a previous package creating it
 * The user/group is a normal user, overlapping the namespace (e.g. amanda)
 * The user/group is pre-created by the administrator with a specific UID/GID

We need to cover all four of these cases.

Case 1: The user/group does not exist on the system
This is the simplest case, we would simply create the new user/group.

Case 2: The user/group exists from a previous package creating it
This is difficult to detect. We cannot assume that a created user/group came from the previous package simply because we're in an upgrade transaction.

By creating and leveraging a "Fedora User Manifest" and "Fedora Group Manifest" we can track when packages add users or groups, and refer to that manifest. The package can check to see if the user/group exists on the system, and then check to see if the user/group is logged in the local system manifest. If so, we do not need to do anything.

Case 3: The user/group is a normal user, overlapping the namespace (e.g. amanda)
The user and group manifests provide a mechanism to determine whether the user is an overlapping "normal" user/group, as opposed to a package added user/group. When the package sees that the user/group exists, and is not in the manifest, it knows it is in this case. This is also a case where security is a concern, someone who gains access to the "amanda" user, then has an admin install the Fedora amanda package could forseeably then gain access to the amanda package. The package needs to take actions to prevent this case from occurring.

Case 4: The user/group is pre-created by the administrator with a specific UID/GID
The user and group manifests provide a controlled, simple mechanism for administrators to "pre-create" users and groups to specific UID/GID settings that would otherwise be defined by packages. This task can be accomplished before adding packages to an installed system, or during the kickstart (don't install packages which add users during the install, then, in %post, create the users/groups, add entries to the manifests and yum install the additional "user creating" packages). Packages which create users and groups will be required to register on a wiki page at fedoraproject.org, so SAs can track which packages add users.

Avoidance
If an existing system user/group would function effectively for an application, it should use that user/group instead of creating its own. Packagers should avoid user/group creation whenever possible, as it adds significant complication to the packaging.

fedora-uidgid-tools
In order to try to simplify user/group creation in Fedora packages, I've created a simple toolkit called fedora-uidgid-tools. This package provides:


 * /etc/sysconfig/fedora-user-manifest : A text manifest where packages record adding users.
 * /etc/sysconfig/fedora-group-manifest : A text manifest where packages record adding groups.
 * /sbin/fedora-uidgidcheck.sh : A script that checks a username or groupname for presence on the system and the fedora user/group manifest files, and returns exit codes for the various cases.

The sources can be found here: http://people.redhat.com/tcallawa/fedora-uidgid-tools/

A sample implementation
Here is a sample spec file, showing how a user and a group can be added, using the fedora-uidgid-tools:

%global username tester %global groupname testing

Name: test Version: 1.0 Release: 1 License: GPL Summary: Test Group: Applications/System URL: http://test.com Source0: testfiles.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: noarch Requires(pre): shadow-utils, fedora-uidgid-tools Requires(post): coreutils, fedora-uidgid-tools

%description test

%prep

%setup

%build

%install rm -rf %{buildroot}

mkdir -p %{buildroot}%{_datadir}/%{name}/ install *fish %{buildroot}%{_datadir}/%{name}/ find %{buildroot} -type f | sed 's|^%{buildroot}||g' &> %{username}-user-owned-files.list echo %{_datadir}/%{name}/ >> %{username}-user-owned-files.list cp %{username}-user-owned-files.list %{buildroot}%{_datadir}/%{name}/ cp %{buildroot}%{_datadir}/%{name}/%{username}-user-owned-files.list %{buildroot}%{_datadir}/%{name}/%{groupname}-group-owned-files.list

%clean rm -rf %{buildroot}

%pre /sbin/fedora-uidgidcheck.sh -g %{groupname} || GROUPCHECK=$? if [ -n $GROUPCHECK ] ; then if [ "$GROUPCHECK" == "75" ] ; then groupadd -f -r %{groupname} && \ echo %{groupname}:%{name} >> %{_sysconfdir}/sysconfig/fedora-group-registry || : fi fi /sbin/fedora-uidgidcheck.sh -u %{username} || USERCHECK=$? if [ -n $USERCHECK ] ; then if [ "$USERCHECK" == "75" ] ; then useradd -r -g %{groupname} -d %{_datadir}/%{name} -s /sbin/nologin \ -c "Spot Test User" %{username} && \ echo %{username}:%{name} >> %{_sysconfdir}/sysconfig/fedora-user-registry || : fi fi

%post /sbin/fedora-uidgidcheck.sh -u %{username} || USERCHECK=$? if [ -n $USERCHECK ] ; then if [ "$USERCHECK" == "70" ] ; then for i in ; do chown --quiet root $i done fi fi /sbin/fedora-uidgidcheck.sh -g %{groupname} || GROUPCHECK=$? if [ -n $GROUPCHECK ] ; then if [ "$GROUPCHECK" == "70" ] ; then for i in ; do chgrp --quiet root $i done fi fi

%files %defattr(-,root,root) %attr(-,%{username},%{groupname}) %{_datadir}/test/

%changelog - test
 * Wed Jun 13 2007 Tom "spot" Callaway  1.0-1