pam_cap.so
The libcap distribution includes a PAM module: pam_cap.so. The module can be used to specify Inheritable capabilities to process trees rooted in the PAM application.
The module also supports blocking Bounding vector capabilities and potentially adding Ambient vector capabilities. However, typically, PAM applications are not able to support the latter as of libcap version <= 2.57. From 2.58 on, compliant Linux-PAM applications should be able to support Ambient vector Capability inheritance.
For general PAM apps to work correctly, the application must be run with at least CAP_SETPCAP raised in its Permitted capability flag. Many PAM applications run as root, which has all of the bits in the Bounding set raised, so this requirement is typically met. To grant an Ambient vector capability, the corresponding Permitted bit must be available to the application too.
Note: we've also developed a demonstration of a Fully Capable PAM application (i.e., a non-setuid-root implementation of su) that, of course, works with most PAM modules including pam_cap.so.
Module invocation
Note: since libcap-2.52 pam_cap.so can actually be run as a standalone executable. That is ./pam_cap.so --help will display some information about it's version and supported module arguments.
The pam_cap.so module is a Linux-PAM auth module. It provides functionality to back pam_sm_authenticate() and pam_sm_setcred(). It is the latter that actually modifies the inheritable 3-tuple of capability vectors: the configured IAB. In a typical application configuration you might have a line like this:
auth optional pam_cap.so
Module arguments
debug
while supported, this is a no-op at present.
config=/pick/this/file
override the default config for the module. See below for the syntax and features of the config file. The unspecified default value for this file is /etc/security/capability.conf. Note, config=/dev/null is a valid value. See default=IAB below for situations in which this might be appropriate.
(libcap-2.50+) keepcaps
this is as much as the pam_cap.so module can do to help an application support use of the Ambient capability vector. The application support for the Ambient set is poor at the present time (2021-06-28).
(libcap-2.51+) autoauth
this argument causes the pam_cap.so module to return PAM_SUCCESS if the PAM_USER being authenticated exists. The absence of this argument will cause pam_cap.so to only return PAM_SUCCESS if the PAM_USER is covered by a specific rule in the prevailing config file.
(libcap-2.52+) default=IAB
this argument is ignored if the prevailing configuration file contains a "*" rule. If there is no such rule, the IAB 3-tuple is inserted at the end of the config file and applies to all PAM_USERs not covered by an earlier rule. Note, if you want all PAM_USERs to be covered by this default rule, you can supply the module argument config=/dev/null.
(libcap-2.58+) defer
this argument arranges for the IAB capabilities granted to a user to be added sufficiently late in the Linux-PAM authentication stack that they stick. That is, after the application does its setuid(UID) call. As such, in conjunction with the keepcaps module argument, such compliant applications can support granting Ambient vector Capabilities with pam_cap.so.
Configuration file syntax
The configuration file for the pam_cap.so module is, by default, the file /etc/security/capability.conf. This location can be overridden by the module argument, config=/other/path. The syntax for lines in this configuration file is:
# <-- '#' precedes a comment
<IAB><SPACE><WHO>
Where <IAB> refers to the text format for an inheritable IAB capability tuple, or the words all or none.
The reserved word all does not grant all the inheritable capabilities, but acts as a simple pass-through for any prevailing IAB tuple capabilities. The reserved word none refers to an empty Inheritable capability set (and by extension an empty Ambient vector).
Here <WHO> refers to the space separated PAM username values that will be granted the specified IAB tuple. A name prefixed with the character @ refers to the locally defined /etc/group etc users listed under that group name.
The parsing of the file chooses the first line that applies to the authenticating user, and attempts to apply that and only that.
Examples of valid syntax are:
# only root gets to keep what it had
all root
# this should fire for user beta only, who will have
# cap_chown dropped from their bounding set.
!cap_chown beta
# the next one should snag the members of the 'three' group
# granting them cap_setuid and cap_chown
cap_setuid,cap_chown @three
# this would apply to beta and gamma, but beta is already
# granted a lack of cap_chown above. Further, if gamma is
# in the 'three' group, it would not reach this line.
cap_chown beta gamma
# members of the 'one' group are granted the cap_setuid Inheritable
# capability, but cap_chown is dropped from their bounding set.
!cap_chown,cap_setuid @one
# user alpha gets an ambient capability (unless it is also
# a member of the groups 'one' or 'three').
^cap_setuid alpha
# user delta (if not a member of groups 'one' and 'three') will get
# cap_chown and cap_setgid Ambient capabilities, but have cap_setuid
# dropped from its bounding set.
^cap_chown,^cap_setgid,!cap_setuid delta
# any remaining members of group 'four' will get the cap_setuid
# Inheritable capability.
cap_setuid @four
License for pam_cap.so
The SPDX-License-Identifier for pam_cap.so distribution is: "BSD-3-Clause OR LGPL-2.0-or-later".