From Fedora Project Wiki
(Mostly Formatting)
(Some rewording and reorg. Change gatekeeper to FPC.)
Line 2: Line 2:


The guidelines provide two options: letting each individual system allocate UID and GID values individually or using a "soft static" allocation that attempts to allocate uids and gids consistently.  In both cases pre-allocation of UID and GID by the system administrator can be used to set the used uid and gid to a specific value at that site.
The guidelines provide two options: letting each individual system allocate UID and GID values individually or using a "soft static" allocation that attempts to allocate uids and gids consistently.  In both cases pre-allocation of UID and GID by the system administrator can be used to set the used uid and gid to a specific value at that site.
== Common notes ==
{{admon/question|Need to organize and merge|This section needs to be reorganized and parts of it integrated into the dynamic or soft static allocation sections}}}
<code>HOMEDIR</code> should usually be a directory created and owned by the package, with appropriately restrictive permissions.  One good choice for the location of the directory is the package's data directory in case it has one.
User accounts created by packages are rarely used for interactive logons, and should thus generally use <code>/sbin/nologin</code> as the user's shell.
We want to invoke <code>groupadd</code> explicitly instead of relying on <code>useradd</code> to create the group for us.  This is because <code>useradd</code> alone would fail if the group it tries to create already existed.
The <code>exit 0</code> at the end will result in the <code>%pre</code> scriptlet passing through even if the user/group creation fails for some reason.  This is suboptimal but has less potential for system wide breakage than allowing it to fail.  If the user/group aren't available at the time the package's payload is unpacked, rpm will fall back to getting those files owned by root.
We run <code>getent</code> before <code>groupadd</code> and <code>useradd</code> to check whether the user/group we're about to create already exists, and we skip the creation if they do.  This is in order to provide a possibility for local system administrators to create the users/groups beforehand (perhaps in LDAP) in case they wish to get a predefined static UID/GID mapping for those users.  Similarly, we verify whether the ID values allocated in the "setup" package aren't already allocated by the local system administrators.
Using a non-default ID mapping eg. when using unattended kickstart installations is a case where creating users/groups beforehand is a bit tricky; one way to accomplish that is to create a customized version of the "<code>setup</code>" package with the desired users/groups along with their static UID/GID mappings are in place, and to make sure the install transaction uses that package instead of the vanilla distro one.
We run the <code>groupadd</code>/<code>useradd</code> always -- both on initial installs and upgrades -- in <code>%pre</code>.  This is made possible by the <code>getent</code> checks above, and should fix things up if the user/group has disappeared after the package to be upgraded was initially installed (just like file permissions get reset on upgrades etc).
We never remove users or groups created by packages.  There's no sane way to check if files owned by those users/groups are left behind (and even if there would, what would we do to them?), and leaving those behind with ownerships pointing to now nonexistent users/groups may result in security issues when a semantically unrelated user/group is created later and reuses the UID/GID.  Also, in some setups deleting the user/group might not be possible or/nor desirable (eg. when using a shared remote user/group database). Cleanup of unused users/groups is left to the system administrators to take care of if they so desire.
In some cases it is desirable to create only a group without a user account.  Usually this is because there are some system resources to which we want to control access by using that group, and a separate user account would add no value.  Examples of common such cases include (but are not limited to) games whose executables are setgid for the purpose of sharing  high score files or the like, and/or software that needs exceptional permissions to some hardware devices and it wouldn't be appropriate to grant those to all system users nor even only those logged in on the console.  In these cases, apply only the <code>groupadd</code> parts of the above recipe.
Note that the practice of not creating users/groups if they exist has a drawback of possibly unrelated but coincidentally same named existing system users and/or groups unnecessarily and undesirably getting access to things in a package that uses the same user/group names.  This version of the users/groups guideline does not address that issue in any way, but it is possible that future revisions will if a good enough way to do that is found.


== Dynamic allocation ==
== Dynamic allocation ==


Any package can use dynamic allocation; it is especially appropriate for packages that use separate identities only for privilege separation and don't create any files owned by that group/user account.
Any package can use dynamic allocation; it is especially appropriate for packages that use separate identities only for privilege separation and don't create any files owned by that group/user account. Because of the limited number of soft static uids and gids available, it is better to use dynamic allocation if in doubt.
 
=== Recipe ===


To create users and groups in packages, use the following:
To create users and groups in packages, use the following:
Line 22: Line 49:
== Soft static allocation ==
== Soft static allocation ==


Soft static allocation ensures that multiple independently installed systems use the same GID/UID values, either GID/UID values allocated by Fedora, or optionally by the system administrator (e.g. by pre-creating user and group accounts in LDAP).  Don't use soft static allocation unnecessarily, the number of available values is limited.  Soft static allocation is appropriate for packages that create files owned by the group/user, especially long-lived filesSoft static allocation is strongly recommended if such files are likely to be shared on NFS (e.g. if the user/group can own or have ACL entries on files in users' home directories).
Soft static allocation ensures that multiple independently installed systems use the same GID/UID values, either GID/UID values allocated by Fedora, or optionally by the system administrator (e.g. by pre-creating user and group accounts in LDAP).  Don't use soft static allocation unnecessarily, the number of available values is limited.  Soft static allocation is only appropriate for packages where the uid and gid is shared between computersFor instance, if the package creates files with the assigned UID or GID that are likely to be shared on NFS.


To allocate a GID and/or UID, [https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=setup file a bug against the "setup" package].  Packages ''must not'' use GID or UID values that are not reserved in <code>/usr/share/doc/setup-*/uidgid</code>.
To allocate a GID and/or UID, [https://fedorahosted.org/fpc/newticket file a ticket for FPC to evaluate].  If the FPC finds that your package needs a soft static UID or GID, they will assign you one and add an entry documenting it to the [https://git.fedorahosted.org/cgit/setup.git/tree/uidgid /usr/share/doc/setup-*/uidgid] file in the setup package.  Because the number of UIDs and GIDs is limited, you need to justify your package's need for a soft static uid in the FPC ticket.  Explain how the uids and gids are being shared between computers.  If applicable, also explain why the program can't be adapted to use symbolic names (username and groupname) instead.


=== Recipe ===
To create users and groups in packages, use the following:
To create users and groups in packages, use the following:


Line 42: Line 70:
exit 0
exit 0
</pre>
</pre>
== Common notes ==
<code>HOMEDIR</code> should usually be a directory created and owned by the package, with appropriately restrictive permissions.  One good choice for the location of the directory is the package's data directory in case it has one.
User accounts created by packages are rarely used for interactive logons, and should thus generally use <code>/sbin/nologin</code> as the user's shell.
We want to invoke <code>groupadd</code> explicitly instead of relying on <code>useradd</code> to create the group for us.  This is because <code>useradd</code> alone would fail if the group it tries to create already existed.
The <code>exit 0</code> at the end will result in the <code>%pre</code> scriptlet passing through even if the user/group creation fails for some reason.  This is suboptimal but has less potential for system wide breakage than allowing it to fail.  If the user/group aren't available at the time the package's payload is unpacked, rpm will fall back to getting those files owned by root.
We run <code>getent</code> before <code>groupadd</code> and <code>useradd</code> to check whether the user/group we're about to create already exists, and we skip the creation if they do.  This is in order to provide a possibility for local system administrators to create the users/groups beforehand (perhaps in LDAP) in case they wish to get a predefined static UID/GID mapping for those users.  Similarly, we verify whether the ID values allocated in the "setup" package aren't already allocated by the local system administrators.
Using a non-default ID mapping eg. when using unattended kickstart installations is a case where creating users/groups beforehand is a bit tricky; one way to accomplish that is to create a customized version of the "<code>setup</code>" package with the desired users/groups along with their static UID/GID mappings are in place, and to make sure the install transaction uses that package instead of the vanilla distro one.
We run the <code>groupadd</code>/<code>useradd</code> always -- both on initial installs and upgrades -- in <code>%pre</code>.  This is made possible by the <code>getent</code> checks above, and should fix things up if the user/group has disappeared after the package to be upgraded was initially installed (just like file permissions get reset on upgrades etc).
We never remove users or groups created by packages.  There's no sane way to check if files owned by those users/groups are left behind (and even if there would, what would we do to them?), and leaving those behind with ownerships pointing to now nonexistent users/groups may result in security issues when a semantically unrelated user/group is created later and reuses the UID/GID.  Also, in some setups deleting the user/group might not be possible or/nor desirable (eg. when using a shared remote user/group database). Cleanup of unused users/groups is left to the system administrators to take care of if they so desire.
In some cases it is desirable to create only a group without a user account.  Usually this is because there are some system resources to which we want to control access by using that group, and a separate user account would add no value.  Examples of common such cases include (but are not limited to) games whose executables are setgid for the purpose of sharing  high score files or the like, and/or software that needs exceptional permissions to some hardware devices and it wouldn't be appropriate to grant those to all system users nor even only those logged in on the console.  In these cases, apply only the <code>groupadd</code> parts of the above recipe.
Note that the practice of not creating users/groups if they exist has a drawback of possibly unrelated but coincidentally same named existing system users and/or groups unnecessarily and undesirably getting access to things in a package that uses the same user/group names.  This version of the users/groups guideline does not address that issue in any way, but it is possible that future revisions will if a good enough way to do that is found.


[[Category:Packaging guidelines]]
[[Category:Packaging guidelines]]

Revision as of 01:38, 17 April 2013

This guideline is for packaging cases that require creation of users and groups.

The guidelines provide two options: letting each individual system allocate UID and GID values individually or using a "soft static" allocation that attempts to allocate uids and gids consistently. In both cases pre-allocation of UID and GID by the system administrator can be used to set the used uid and gid to a specific value at that site.

Common notes

Questionmark.png
Need to organize and merge
This section needs to be reorganized and parts of it integrated into the dynamic or soft static allocation sections

}

HOMEDIR should usually be a directory created and owned by the package, with appropriately restrictive permissions. One good choice for the location of the directory is the package's data directory in case it has one.

User accounts created by packages are rarely used for interactive logons, and should thus generally use /sbin/nologin as the user's shell.

We want to invoke groupadd explicitly instead of relying on useradd to create the group for us. This is because useradd alone would fail if the group it tries to create already existed.

The exit 0 at the end will result in the %pre scriptlet passing through even if the user/group creation fails for some reason. This is suboptimal but has less potential for system wide breakage than allowing it to fail. If the user/group aren't available at the time the package's payload is unpacked, rpm will fall back to getting those files owned by root.

We run getent before groupadd and useradd to check whether the user/group we're about to create already exists, and we skip the creation if they do. This is in order to provide a possibility for local system administrators to create the users/groups beforehand (perhaps in LDAP) in case they wish to get a predefined static UID/GID mapping for those users. Similarly, we verify whether the ID values allocated in the "setup" package aren't already allocated by the local system administrators.

Using a non-default ID mapping eg. when using unattended kickstart installations is a case where creating users/groups beforehand is a bit tricky; one way to accomplish that is to create a customized version of the "setup" package with the desired users/groups along with their static UID/GID mappings are in place, and to make sure the install transaction uses that package instead of the vanilla distro one.

We run the groupadd/useradd always -- both on initial installs and upgrades -- in %pre. This is made possible by the getent checks above, and should fix things up if the user/group has disappeared after the package to be upgraded was initially installed (just like file permissions get reset on upgrades etc).

We never remove users or groups created by packages. There's no sane way to check if files owned by those users/groups are left behind (and even if there would, what would we do to them?), and leaving those behind with ownerships pointing to now nonexistent users/groups may result in security issues when a semantically unrelated user/group is created later and reuses the UID/GID. Also, in some setups deleting the user/group might not be possible or/nor desirable (eg. when using a shared remote user/group database). Cleanup of unused users/groups is left to the system administrators to take care of if they so desire.

In some cases it is desirable to create only a group without a user account. Usually this is because there are some system resources to which we want to control access by using that group, and a separate user account would add no value. Examples of common such cases include (but are not limited to) games whose executables are setgid for the purpose of sharing high score files or the like, and/or software that needs exceptional permissions to some hardware devices and it wouldn't be appropriate to grant those to all system users nor even only those logged in on the console. In these cases, apply only the groupadd parts of the above recipe.

Note that the practice of not creating users/groups if they exist has a drawback of possibly unrelated but coincidentally same named existing system users and/or groups unnecessarily and undesirably getting access to things in a package that uses the same user/group names. This version of the users/groups guideline does not address that issue in any way, but it is possible that future revisions will if a good enough way to do that is found.


Dynamic allocation

Any package can use dynamic allocation; it is especially appropriate for packages that use separate identities only for privilege separation and don't create any files owned by that group/user account. Because of the limited number of soft static uids and gids available, it is better to use dynamic allocation if in doubt.

Recipe

To create users and groups in packages, use the following:

Requires(pre): shadow-utils
[...] 
%pre
getent group GROUPNAME >/dev/null || groupadd -r GROUPNAME
getent passwd USERNAME >/dev/null || \
    useradd -r -g GROUPNAME -d HOMEDIR -s /sbin/nologin \
    -c "Useful comment about the purpose of this account" USERNAME
exit 0

Soft static allocation

Soft static allocation ensures that multiple independently installed systems use the same GID/UID values, either GID/UID values allocated by Fedora, or optionally by the system administrator (e.g. by pre-creating user and group accounts in LDAP). Don't use soft static allocation unnecessarily, the number of available values is limited. Soft static allocation is only appropriate for packages where the uid and gid is shared between computers. For instance, if the package creates files with the assigned UID or GID that are likely to be shared on NFS.

To allocate a GID and/or UID, file a ticket for FPC to evaluate. If the FPC finds that your package needs a soft static UID or GID, they will assign you one and add an entry documenting it to the /usr/share/doc/setup-*/uidgid file in the setup package. Because the number of UIDs and GIDs is limited, you need to justify your package's need for a soft static uid in the FPC ticket. Explain how the uids and gids are being shared between computers. If applicable, also explain why the program can't be adapted to use symbolic names (username and groupname) instead.

Recipe

To create users and groups in packages, use the following:

Requires(pre): shadow-utils
[...] 
%pre
getent group GROUPNAME >/dev/null || groupadd -f -g ALLOCATED_GID -r GROUPNAME
if ! getent passwd USERNAME >/dev/null ; then
    if ! getent passwd ALLOCATED_UID >/dev/null ; then
      useradd -r -u ALLOCATED_UID -g GROUPNAME -d HOMEDIR -s /sbin/nologin -c "Useful comment about the purpose of this account" USERNAME
    else
      useradd -r -g GROUPNAME -d HOMEDIR -s /sbin/nologin -c "Useful comment about the purpose of this account" USERNAME
    fi
fi
exit 0