Restricting the domains a PAM service can auth against¶
Related ticket(s):
Problem statement¶
Some environments require that different PAM applications can use a
different set of SSSD domains. The legacy PAM modules, such as
pam_ldap
were able to use a different configuration file altogether
as a parameter for the PAM module. This wiki page describes a similar
feature for the SSSD.
Use case¶
An example use-case is an environment that allows external users to authenticate to an FTP server. This server is running as a separate non-privileged user and should only be able to authenticate to a selected SSSD domain, separate from the internal company accounts. The administrator is able to leverage this new feature to mark allow the FTP user to only authenticate against one of the domains in the FTP PAM config file.
Overview of the solution¶
On the PAM client side, the PAM module should receive a new option that
specifies the SSSD domains to authenticate against. However, the SSSD
daemon can’t fully trust all PAM services. We can’t rely on the PAM
service fields either, as the data the PAM client sends to the PAM
application can be faked by the client, especially by users who posses
shell access or can start custom applications. Instead, there needs to
be a list of users who we trust. Typically, this would be a list of
users who run the PAM aware applications we wish to restrict (such as
vsftpd
or openvpn
). This list would default to root
only.
These trusted users would be allowed to authenticate against any domain and would also be able to restrict the domains further using a new pam_sss option. For the untrusted users, we need to keep a list of domains allowed to authenticate against, too. Since by default there are no restrictions on the allowed domains, this list would default to “all domains are allowed”.
Implementation details¶
This section breaks down the Overview of the solution into consumable pieces.
Add a new option pam_trusted_users
¶
A new option must be added to the PAM responder. This option will be a
list of numerical UIDs or group names that are trusted or a special
keyword “ALL”. This list will be parsed during PAM responder
initialization (pam_process_init
call) using the
csv_string_to_uid_array
function and stored in the PAM responder
context (struct pam_ctx
). The PAC responder does pretty much the
same in the pac_process_init
function.
In the responder, we already have the credentials of the client stored
in the cli_ctx
structure. When a new request comes into the
pam_forwarder
function, we will match the client UID against the
list of trusted IDs and determine whether the client is trusted or not.
The default will be the special keyword ALL, meaning all users are trusted. This is in line with the current behaviour where any user can access any domain.
Add a option to limit the domains for untrusted users¶
Another option, called pam_allowed_auth_domains
shall be added to
the PAM responder. This option will list the SSSD domains an untrusted
client can authenticate against. The option will accept either a
comma-separated list of SSSD domains or any of two special values
all
and none
. The default value will be none
to make sure
the administrator is required to spell out the domains that can be
contacted by an untrusted client when he starts differentiating trusted
and untrusted domains.
The option will be parsed during pam_process_init
and stored in the
pam_ctx
structure. An untrusted client will only be allowed to send
a request to a domain that matches the list of allowed domains.
In order to keep the implementation simple, the all
keyword would
copy all domain names into pam_ctx
and the none
keyword would
set the variable holding the names to NULL. Then the check would be a
simple loop for all cases.
Care must be taken to ensure a sensible PAM error code for cases where the domain wouldn’t match.
Add a new pam module option to limit the domains¶
The PAM module will gain a new option, called domains
that will
allow the administrator to use a list of domains to authenticate this
PAM service against. In the PAM responder, this option will only be in
effect for trusted clients. If the client is trusted, only domains
listed in this PAM option will be considered for authentication.
Please note that a patch implementing most of the functionality of this PAM module option was contributed to the sssd-devel mailing list by Daniel Gollub already.
Password Changes¶
Password changes should be allowed against all domains, meaning that a user A (recognized via getpeercred) will be allow to perform a password change, i.e. implicitly allowed to access its own domain even if it is untrusted. Arbitrary password changes for other users should not be allowed.
Configuration Changes¶
Several new options, described in details in the previous section, will be introduced. No existing options will change defaults or gain new option values.
How To Test¶
- Prepare an SSSD installation with at least two domains A and B.
- Pick a PAM service that is running by a trusted user. One example
might be VPN service ran by the openvpn user or similar. Add this
user as a value of
pam_trusted_users
option in the[pam]
section. - Add one of the domains (domain A) as a
domain=
parameter into theauth
section of your service’s PAM config file - Authenticate using the selected PAM service as a user from domain A. The authentication should succeed.
- Authenticate using the same service as a user from domain B. The authentication should fail and there should be a reasonable (i.e. not System Error) return code returned to the application
- Authenticate using a different PAM service. Make sure this service is ran by an untrusted user (not root!). Logins against both A and B should fail.
- Set the value of
pam_allowed_auth_domains
to A. Login against A should succeed from a service running as untrusted user. - Change the value of
pam_allowed_auth_domains
to all. Login against both domains should succeed from a service running as untrusted user. - Remove the
domains=
option from the PAM config file. The trusted service should now be able to log in against both SSSD domains. - Perform a password change as an untrusted user against a domain that he should not normally be allowed to use. The password change must succeed.
Authors¶
- Daniel Gollub <dgollub@brocade.com>
- Jakub Hrozek <jhrozek@redhat.com>
- Simo Sorce <simo@redhat.com>