mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2025-01-26 12:39:36 -05:00
services: Add nslcd-service-type.
* gnu/services/authentication.scm (nslcd-service-type, nslcd-configuration, %nslcd-accounts): New variables. (uglify-field-name, value->string, serialize-field, serialize-list, ssl-option?, tls-reqcert-option?, deref-option?, comma-separated-list-of-strings?, serialize-ignore-users-option, log-option?, serialize-log-option, valid-map?, scope-option?, serialize-scope-option, map-entry?, list-of-map-entries?, filter-entry?, list-of-filter-entries?, serialize-filter-entry, serialize-list-of-filter-entries, serialize-map-entry, serialize-list-of-map-entries, nslcd-config-file, nslcd-etc-service, nslcd-shepherd-service, pam-ldap-pam-services, pam-ldap-pam-service, generate-nslcd-documentation): New procedures. * gnu/tests/ldap.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. * doc/guix.texi (LDAP Services): Document it.
This commit is contained in:
parent
bcf66fc2e7
commit
c16423f143
4 changed files with 1150 additions and 1 deletions
479
doc/guix.texi
479
doc/guix.texi
|
@ -11139,6 +11139,7 @@ declaration.
|
||||||
* Telephony Services:: Telephony services.
|
* Telephony Services:: Telephony services.
|
||||||
* Monitoring Services:: Monitoring services.
|
* Monitoring Services:: Monitoring services.
|
||||||
* Kerberos Services:: Kerberos services.
|
* Kerberos Services:: Kerberos services.
|
||||||
|
* LDAP Services:: LDAP services.
|
||||||
* Web Services:: Web servers.
|
* Web Services:: Web servers.
|
||||||
* Certificate Services:: TLS certificates via Let's Encrypt.
|
* Certificate Services:: TLS certificates via Let's Encrypt.
|
||||||
* DNS Services:: DNS daemons.
|
* DNS Services:: DNS daemons.
|
||||||
|
@ -17685,6 +17686,484 @@ Local accounts with lower values will silently fail to authenticate.
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
|
|
||||||
|
@node LDAP Services
|
||||||
|
@subsection LDAP Services
|
||||||
|
@cindex LDAP
|
||||||
|
@cindex nslcd, LDAP service
|
||||||
|
|
||||||
|
The @code{(gnu services authentication)} module provides the
|
||||||
|
@code{nslcd-service-type}, which can be used to authenticate against an LDAP
|
||||||
|
server. In addition to configuring the service itself, you may want to add
|
||||||
|
@code{ldap} as a name service to the Name Service Switch. @xref{Name Service
|
||||||
|
Switch} for detailed information.
|
||||||
|
|
||||||
|
Here is a simple operating system declaration with a default configuration of
|
||||||
|
the @code{nslcd-service-type} and a Name Service Switch configuration that
|
||||||
|
consults the @code{ldap} name service last:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(use-service-modules authentication)
|
||||||
|
(use-modules (gnu system nss))
|
||||||
|
...
|
||||||
|
(operating-system
|
||||||
|
...
|
||||||
|
(services
|
||||||
|
(cons*
|
||||||
|
(service nslcd-service-type)
|
||||||
|
(service dhcp-client-service-type)
|
||||||
|
%base-services))
|
||||||
|
(name-service-switch
|
||||||
|
(let ((services (list (name-service (name "db"))
|
||||||
|
(name-service (name "files"))
|
||||||
|
(name-service (name "ldap")))))
|
||||||
|
(name-service-switch
|
||||||
|
(inherit %mdns-host-lookup-nss)
|
||||||
|
(password services)
|
||||||
|
(shadow services)
|
||||||
|
(group services)
|
||||||
|
(netgroup services)
|
||||||
|
(gshadow services)))))
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@c %start of generated documentation for nslcd-configuration
|
||||||
|
|
||||||
|
Available @code{nslcd-configuration} fields are:
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} package nss-pam-ldapd
|
||||||
|
The @code{nss-pam-ldapd} package to use.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-number threads
|
||||||
|
The number of threads to start that can handle requests and perform LDAP
|
||||||
|
queries. Each thread opens a separate connection to the LDAP server.
|
||||||
|
The default is to start 5 threads.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} string uid
|
||||||
|
This specifies the user id with which the daemon should be run.
|
||||||
|
|
||||||
|
Defaults to @samp{"nslcd"}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} string gid
|
||||||
|
This specifies the group id with which the daemon should be run.
|
||||||
|
|
||||||
|
Defaults to @samp{"nslcd"}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} log-option log
|
||||||
|
This option controls the way logging is done via a list containing
|
||||||
|
SCHEME and LEVEL. The SCHEME argument may either be the symbols "none"
|
||||||
|
or "syslog", or an absolute file name. The LEVEL argument is optional
|
||||||
|
and specifies the log level. The log level may be one of the following
|
||||||
|
symbols: "crit", "error", "warning", "notice", "info" or "debug". All
|
||||||
|
messages with the specified log level or higher are logged.
|
||||||
|
|
||||||
|
Defaults to @samp{("/var/log/nslcd" info)}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} list uri
|
||||||
|
The list of LDAP server URIs. Normally, only the first server will be
|
||||||
|
used with the following servers as fall-back.
|
||||||
|
|
||||||
|
Defaults to @samp{("ldap://localhost:389/")}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string ldap-version
|
||||||
|
The version of the LDAP protocol to use. The default is to use the
|
||||||
|
maximum version supported by the LDAP library.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string binddn
|
||||||
|
Specifies the distinguished name with which to bind to the directory
|
||||||
|
server for lookups. The default is to bind anonymously.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string bindpw
|
||||||
|
Specifies the credentials with which to bind. This option is only
|
||||||
|
applicable when used with binddn.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string rootpwmoddn
|
||||||
|
Specifies the distinguished name to use when the root user tries to
|
||||||
|
modify a user's password using the PAM module.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string rootpwmodpw
|
||||||
|
Specifies the credentials with which to bind if the root user tries to
|
||||||
|
change a user's password. This option is only applicable when used with
|
||||||
|
rootpwmoddn
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string sasl-mech
|
||||||
|
Specifies the SASL mechanism to be used when performing SASL
|
||||||
|
authentication.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string sasl-realm
|
||||||
|
Specifies the SASL realm to be used when performing SASL authentication.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string sasl-authcid
|
||||||
|
Specifies the authentication identity to be used when performing SASL
|
||||||
|
authentication.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string sasl-authzid
|
||||||
|
Specifies the authorization identity to be used when performing SASL
|
||||||
|
authentication.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-boolean sasl-canonicalize?
|
||||||
|
Determines whether the LDAP server host name should be canonicalised. If
|
||||||
|
this is enabled the LDAP library will do a reverse host name lookup. By
|
||||||
|
default, it is left up to the LDAP library whether this check is
|
||||||
|
performed or not.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string krb5-ccname
|
||||||
|
Set the name for the GSS-API Kerberos credentials cache.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} string base
|
||||||
|
The directory search base.
|
||||||
|
|
||||||
|
Defaults to @samp{"dc=example,dc=com"}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} scope-option scope
|
||||||
|
Specifies the search scope (subtree, onelevel, base or children). The
|
||||||
|
default scope is subtree; base scope is almost never useful for name
|
||||||
|
service lookups; children scope is not supported on all servers.
|
||||||
|
|
||||||
|
Defaults to @samp{(subtree)}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-deref-option deref
|
||||||
|
Specifies the policy for dereferencing aliases. The default policy is
|
||||||
|
to never dereference aliases.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-boolean referrals
|
||||||
|
Specifies whether automatic referral chasing should be enabled. The
|
||||||
|
default behaviour is to chase referrals.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} list-of-map-entries maps
|
||||||
|
This option allows for custom attributes to be looked up instead of the
|
||||||
|
default RFC 2307 attributes. It is a list of maps, each consisting of
|
||||||
|
the name of a map, the RFC 2307 attribute to match and the query
|
||||||
|
expression for the attribute as it is available in the directory.
|
||||||
|
|
||||||
|
Defaults to @samp{()}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} list-of-filter-entries filters
|
||||||
|
A list of filters consisting of the name of a map to which the filter
|
||||||
|
applies and an LDAP search filter expression.
|
||||||
|
|
||||||
|
Defaults to @samp{()}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-number bind-timelimit
|
||||||
|
Specifies the time limit in seconds to use when connecting to the
|
||||||
|
directory server. The default value is 10 seconds.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-number timelimit
|
||||||
|
Specifies the time limit (in seconds) to wait for a response from the
|
||||||
|
LDAP server. A value of zero, which is the default, is to wait
|
||||||
|
indefinitely for searches to be completed.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-number idle-timelimit
|
||||||
|
Specifies the period if inactivity (in seconds) after which the con‐
|
||||||
|
nection to the LDAP server will be closed. The default is not to time
|
||||||
|
out connections.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-number reconnect-sleeptime
|
||||||
|
Specifies the number of seconds to sleep when connecting to all LDAP
|
||||||
|
servers fails. By default one second is waited between the first
|
||||||
|
failure and the first retry.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-number reconnect-retrytime
|
||||||
|
Specifies the time after which the LDAP server is considered to be
|
||||||
|
permanently unavailable. Once this time is reached retries will be done
|
||||||
|
only once per this time period. The default value is 10 seconds.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-ssl-option ssl
|
||||||
|
Specifies whether to use SSL/TLS or not (the default is not to). If
|
||||||
|
'start-tls is specified then StartTLS is used rather than raw LDAP over
|
||||||
|
SSL.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-tls-reqcert-option tls-reqcert
|
||||||
|
Specifies what checks to perform on a server-supplied certificate. The
|
||||||
|
meaning of the values is described in the ldap.conf(5) manual page.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string tls-cacertdir
|
||||||
|
Specifies the directory containing X.509 certificates for peer authen‐
|
||||||
|
tication. This parameter is ignored when using GnuTLS.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string tls-cacertfile
|
||||||
|
Specifies the path to the X.509 certificate for peer authentication.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string tls-randfile
|
||||||
|
Specifies the path to an entropy source. This parameter is ignored when
|
||||||
|
using GnuTLS.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string tls-ciphers
|
||||||
|
Specifies the ciphers to use for TLS as a string.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string tls-cert
|
||||||
|
Specifies the path to the file containing the local certificate for
|
||||||
|
client TLS authentication.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string tls-key
|
||||||
|
Specifies the path to the file containing the private key for client TLS
|
||||||
|
authentication.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-number pagesize
|
||||||
|
Set this to a number greater than 0 to request paged results from the
|
||||||
|
LDAP server in accordance with RFC2696. The default (0) is to not
|
||||||
|
request paged results.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-ignore-users-option nss-initgroups-ignoreusers
|
||||||
|
This option prevents group membership lookups through LDAP for the
|
||||||
|
specified users. Alternatively, the value 'all-local may be used. With
|
||||||
|
that value nslcd builds a full list of non-LDAP users on startup.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-number nss-min-uid
|
||||||
|
This option ensures that LDAP users with a numeric user id lower than
|
||||||
|
the specified value are ignored.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-number nss-uid-offset
|
||||||
|
This option specifies an offset that is added to all LDAP numeric user
|
||||||
|
ids. This can be used to avoid user id collisions with local users.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-number nss-gid-offset
|
||||||
|
This option specifies an offset that is added to all LDAP numeric group
|
||||||
|
ids. This can be used to avoid user id collisions with local groups.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-boolean nss-nested-groups
|
||||||
|
If this option is set, the member attribute of a group may point to
|
||||||
|
another group. Members of nested groups are also returned in the higher
|
||||||
|
level group and parent groups are returned when finding groups for a
|
||||||
|
specific user. The default is not to perform extra searches for nested
|
||||||
|
groups.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-boolean nss-getgrent-skipmembers
|
||||||
|
If this option is set, the group member list is not retrieved when
|
||||||
|
looking up groups. Lookups for finding which groups a user belongs to
|
||||||
|
will remain functional so the user will likely still get the correct
|
||||||
|
groups assigned on login.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-boolean nss-disable-enumeration
|
||||||
|
If this option is set, functions which cause all user/group entries to
|
||||||
|
be loaded from the directory will not succeed in doing so. This can
|
||||||
|
dramatically reduce LDAP server load in situations where there are a
|
||||||
|
great number of users and/or groups. This option is not recommended for
|
||||||
|
most configurations.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string validnames
|
||||||
|
This option can be used to specify how user and group names are verified
|
||||||
|
within the system. This pattern is used to check all user and group
|
||||||
|
names that are requested and returned from LDAP.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-boolean ignorecase
|
||||||
|
This specifies whether or not to perform searches using case-insensitive
|
||||||
|
matching. Enabling this could open up the system to authorization
|
||||||
|
bypass vulnerabilities and introduce nscd cache poisoning
|
||||||
|
vulnerabilities which allow denial of service.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-boolean pam-authc-ppolicy
|
||||||
|
This option specifies whether password policy controls are requested and
|
||||||
|
handled from the LDAP server when performing user authentication.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string pam-authc-search
|
||||||
|
By default nslcd performs an LDAP search with the user's credentials
|
||||||
|
after BIND (authentication) to ensure that the BIND operation was
|
||||||
|
successful. The default search is a simple check to see if the user's
|
||||||
|
DN exists. A search filter can be specified that will be used instead.
|
||||||
|
It should return at least one entry.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string pam-authz-search
|
||||||
|
This option allows flexible fine tuning of the authorisation check that
|
||||||
|
should be performed. The search filter specified is executed and if any
|
||||||
|
entries match, access is granted, otherwise access is denied.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} maybe-string pam-password-prohibit-message
|
||||||
|
If this option is set password modification using pam_ldap will be
|
||||||
|
denied and the specified message will be presented to the user instead.
|
||||||
|
The message can be used to direct the user to an alternative means of
|
||||||
|
changing their password.
|
||||||
|
|
||||||
|
Defaults to @samp{disabled}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@deftypevr {@code{nslcd-configuration} parameter} list pam-services
|
||||||
|
List of pam service names for which LDAP authentication should suffice.
|
||||||
|
|
||||||
|
Defaults to @samp{()}.
|
||||||
|
|
||||||
|
@end deftypevr
|
||||||
|
|
||||||
|
@c %end of generated documentation for nslcd-configuration
|
||||||
|
|
||||||
|
|
||||||
@node Web Services
|
@node Web Services
|
||||||
@subsection Web Services
|
@subsection Web Services
|
||||||
|
|
||||||
|
|
|
@ -569,6 +569,7 @@ GNU_SYSTEM_MODULES = \
|
||||||
%D%/tests/monitoring.scm \
|
%D%/tests/monitoring.scm \
|
||||||
%D%/tests/nfs.scm \
|
%D%/tests/nfs.scm \
|
||||||
%D%/tests/install.scm \
|
%D%/tests/install.scm \
|
||||||
|
%D%/tests/ldap.scm \
|
||||||
%D%/tests/mail.scm \
|
%D%/tests/mail.scm \
|
||||||
%D%/tests/messaging.scm \
|
%D%/tests/messaging.scm \
|
||||||
%D%/tests/networking.scm \
|
%D%/tests/networking.scm \
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2018 Danny Milosavljevic <dannym@scratchpost.org>
|
;;; Copyright © 2018 Danny Milosavljevic <dannym@scratchpost.org>
|
||||||
|
;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -18,13 +19,28 @@
|
||||||
|
|
||||||
(define-module (gnu services authentication)
|
(define-module (gnu services authentication)
|
||||||
#:use-module (gnu services)
|
#:use-module (gnu services)
|
||||||
|
#:use-module (gnu services base)
|
||||||
|
#:use-module (gnu services configuration)
|
||||||
#:use-module (gnu services dbus)
|
#:use-module (gnu services dbus)
|
||||||
|
#:use-module (gnu services shepherd)
|
||||||
|
#:use-module (gnu system pam)
|
||||||
|
#:use-module (gnu system shadow)
|
||||||
|
#:use-module (gnu packages admin)
|
||||||
#:use-module (gnu packages freedesktop)
|
#:use-module (gnu packages freedesktop)
|
||||||
|
#:use-module (gnu packages openldap)
|
||||||
#:use-module (guix gexp)
|
#:use-module (guix gexp)
|
||||||
#:use-module (guix records)
|
#:use-module (guix records)
|
||||||
|
#:use-module (guix packages)
|
||||||
|
#:use-module (ice-9 match)
|
||||||
|
#:use-module (srfi srfi-1)
|
||||||
|
#:use-module (srfi srfi-26)
|
||||||
#:export (fprintd-configuration
|
#:export (fprintd-configuration
|
||||||
fprintd-configuration?
|
fprintd-configuration?
|
||||||
fprintd-service-type))
|
fprintd-service-type
|
||||||
|
|
||||||
|
nslcd-configuration
|
||||||
|
nslcd-configuration?
|
||||||
|
nslcd-service-type))
|
||||||
|
|
||||||
(define-record-type* <fprintd-configuration>
|
(define-record-type* <fprintd-configuration>
|
||||||
fprintd-configuration make-fprintd-configuration
|
fprintd-configuration make-fprintd-configuration
|
||||||
|
@ -39,3 +55,496 @@ (define fprintd-service-type
|
||||||
list)))
|
list)))
|
||||||
(description
|
(description
|
||||||
"Run fprintd, a fingerprint management daemon.")))
|
"Run fprintd, a fingerprint management daemon.")))
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; NSS Pam LDAP service (nslcd)
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define (uglify-field-name name)
|
||||||
|
(match name
|
||||||
|
('filters "filter")
|
||||||
|
('maps "map")
|
||||||
|
(_ (string-map (match-lambda
|
||||||
|
(#\- #\_)
|
||||||
|
(chr chr))
|
||||||
|
(symbol->string name)))))
|
||||||
|
|
||||||
|
(define (value->string val)
|
||||||
|
(cond
|
||||||
|
((boolean? val)
|
||||||
|
(if val "on" "off"))
|
||||||
|
((number? val)
|
||||||
|
(number->string val))
|
||||||
|
((symbol? val)
|
||||||
|
(string-map (match-lambda
|
||||||
|
(#\- #\_)
|
||||||
|
(chr chr))
|
||||||
|
(symbol->string val)))
|
||||||
|
(else val)))
|
||||||
|
|
||||||
|
(define (serialize-field field-name val)
|
||||||
|
(if (eq? field-name 'pam-services)
|
||||||
|
#t
|
||||||
|
(format #t "~a ~a\n"
|
||||||
|
(uglify-field-name field-name)
|
||||||
|
(value->string val))))
|
||||||
|
|
||||||
|
(define serialize-string serialize-field)
|
||||||
|
(define serialize-boolean serialize-field)
|
||||||
|
(define serialize-number serialize-field)
|
||||||
|
(define (serialize-list field-name val)
|
||||||
|
(map (cut serialize-field field-name <>) val))
|
||||||
|
(define-maybe string)
|
||||||
|
(define-maybe boolean)
|
||||||
|
(define-maybe number)
|
||||||
|
|
||||||
|
(define (ssl-option? val)
|
||||||
|
(or (boolean? val)
|
||||||
|
(eq? val 'start-tls)))
|
||||||
|
(define serialize-ssl-option serialize-field)
|
||||||
|
(define-maybe ssl-option)
|
||||||
|
|
||||||
|
(define (tls-reqcert-option? val)
|
||||||
|
(member val '(never allow try demand hard)))
|
||||||
|
(define serialize-tls-reqcert-option serialize-field)
|
||||||
|
(define-maybe tls-reqcert-option)
|
||||||
|
|
||||||
|
(define (deref-option? val)
|
||||||
|
(member val '(never searching finding always)))
|
||||||
|
(define serialize-deref-option serialize-field)
|
||||||
|
(define-maybe deref-option)
|
||||||
|
|
||||||
|
(define (comma-separated-list-of-strings? val)
|
||||||
|
(and (list? val)
|
||||||
|
(every string? val)))
|
||||||
|
(define (ignore-users-option? val)
|
||||||
|
(or (comma-separated-list-of-strings? val)
|
||||||
|
(eq? 'all-local val)))
|
||||||
|
(define (serialize-ignore-users-option field-name val)
|
||||||
|
(serialize-field field-name (if (eq? 'all-local val)
|
||||||
|
val
|
||||||
|
(string-join val ","))))
|
||||||
|
(define-maybe ignore-users-option)
|
||||||
|
|
||||||
|
(define (log-option? val)
|
||||||
|
(let ((valid-scheme? (lambda (scheme)
|
||||||
|
(or (string? scheme)
|
||||||
|
(member scheme '(none syslog))))))
|
||||||
|
(match val
|
||||||
|
((scheme level)
|
||||||
|
(and (valid-scheme? scheme)
|
||||||
|
(member level '(crit error warning notice info debug))))
|
||||||
|
((scheme)
|
||||||
|
(valid-scheme? scheme)))))
|
||||||
|
(define (serialize-log-option field-name val)
|
||||||
|
(serialize-field field-name
|
||||||
|
(string-join (map (cut format #f "~a" <>) val))))
|
||||||
|
|
||||||
|
(define (valid-map? val)
|
||||||
|
"Is VAL a supported map name?"
|
||||||
|
(member val
|
||||||
|
'(alias aliases ether ethers group host hosts netgroup network networks
|
||||||
|
passwd protocol protocols rpc service services shadow)))
|
||||||
|
|
||||||
|
(define (scope-option? val)
|
||||||
|
(let ((valid-scopes '(subtree onelevel base children)))
|
||||||
|
(match val
|
||||||
|
((map-name scope)
|
||||||
|
(and (valid-map? map-name)
|
||||||
|
(member scope valid-scopes)))
|
||||||
|
((scope)
|
||||||
|
(member scope valid-scopes)))))
|
||||||
|
(define (serialize-scope-option field-name val)
|
||||||
|
(serialize-field field-name
|
||||||
|
(string-join (map (cut format #f "~a" <>) val))))
|
||||||
|
|
||||||
|
(define (map-entry? val)
|
||||||
|
(match val
|
||||||
|
(((? valid-map? map-name)
|
||||||
|
(? string? attribute)
|
||||||
|
(? string? new-attribute)) #t)
|
||||||
|
(_ #f)))
|
||||||
|
|
||||||
|
(define (list-of-map-entries? val)
|
||||||
|
(and (list? val)
|
||||||
|
(every map-entry? val)))
|
||||||
|
|
||||||
|
(define (filter-entry? val)
|
||||||
|
(match val
|
||||||
|
(((? valid-map? map-name)
|
||||||
|
(? string? filter-expression)) #t)
|
||||||
|
(_ #f)))
|
||||||
|
|
||||||
|
(define (list-of-filter-entries? val)
|
||||||
|
(and (list? val)
|
||||||
|
(every filter-entry? val)))
|
||||||
|
|
||||||
|
(define (serialize-filter-entry field-name val)
|
||||||
|
(serialize-field 'filter
|
||||||
|
(match val
|
||||||
|
(((? valid-map? map-name)
|
||||||
|
(? string? filter-expression))
|
||||||
|
(string-append (symbol->string map-name)
|
||||||
|
" " filter-expression)))))
|
||||||
|
|
||||||
|
(define (serialize-list-of-filter-entries field-name val)
|
||||||
|
(for-each (cut serialize-filter-entry field-name <>) val))
|
||||||
|
|
||||||
|
(define (serialize-map-entry field-name val)
|
||||||
|
(serialize-field 'map
|
||||||
|
(match val
|
||||||
|
(((? valid-map? map-name)
|
||||||
|
(? string? attribute)
|
||||||
|
(? string? new-attribute))
|
||||||
|
(string-append (symbol->string map-name)
|
||||||
|
" " attribute
|
||||||
|
" " new-attribute)))))
|
||||||
|
|
||||||
|
(define (serialize-list-of-map-entries field-name val)
|
||||||
|
(for-each (cut serialize-map-entry field-name <>) val))
|
||||||
|
|
||||||
|
|
||||||
|
(define-configuration nslcd-configuration
|
||||||
|
(nss-pam-ldapd
|
||||||
|
(package nss-pam-ldapd)
|
||||||
|
"The NSS-PAM-LDAPD package to use.")
|
||||||
|
|
||||||
|
;; Runtime options
|
||||||
|
(threads
|
||||||
|
(maybe-number 'disabled)
|
||||||
|
"The number of threads to start that can handle requests and perform LDAP
|
||||||
|
queries. Each thread opens a separate connection to the LDAP server. The
|
||||||
|
default is to start 5 threads.")
|
||||||
|
(uid
|
||||||
|
(string "nslcd")
|
||||||
|
"This specifies the user id with which the daemon should be run.")
|
||||||
|
(gid
|
||||||
|
(string "nslcd")
|
||||||
|
"This specifies the group id with which the daemon should be run.")
|
||||||
|
(log
|
||||||
|
(log-option '("/var/log/nslcd" info))
|
||||||
|
"This option controls the way logging is done via a list containing SCHEME
|
||||||
|
and LEVEL. The SCHEME argument may either be the symbols \"none\" or
|
||||||
|
\"syslog\", or an absolute file name. The LEVEL argument is optional and
|
||||||
|
specifies the log level. The log level may be one of the following symbols:
|
||||||
|
\"crit\", \"error\", \"warning\", \"notice\", \"info\" or \"debug\". All
|
||||||
|
messages with the specified log level or higher are logged.")
|
||||||
|
|
||||||
|
;; LDAP connection settings
|
||||||
|
(uri
|
||||||
|
(list '("ldap://localhost:389/"))
|
||||||
|
"The list of LDAP server URIs. Normally, only the first server will be
|
||||||
|
used with the following servers as fall-back.")
|
||||||
|
(ldap-version
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"The version of the LDAP protocol to use. The default is to use the
|
||||||
|
maximum version supported by the LDAP library.")
|
||||||
|
(binddn
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the distinguished name with which to bind to the directory
|
||||||
|
server for lookups. The default is to bind anonymously.")
|
||||||
|
(bindpw
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the credentials with which to bind. This option is only
|
||||||
|
applicable when used with binddn.")
|
||||||
|
(rootpwmoddn
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the distinguished name to use when the root user tries to modify
|
||||||
|
a user's password using the PAM module.")
|
||||||
|
(rootpwmodpw
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the credentials with which to bind if the root user tries to
|
||||||
|
change a user's password. This option is only applicable when used with
|
||||||
|
rootpwmoddn")
|
||||||
|
|
||||||
|
;; SASL authentication options
|
||||||
|
(sasl-mech
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the SASL mechanism to be used when performing SASL
|
||||||
|
authentication.")
|
||||||
|
(sasl-realm
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the SASL realm to be used when performing SASL authentication.")
|
||||||
|
(sasl-authcid
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the authentication identity to be used when performing SASL
|
||||||
|
authentication.")
|
||||||
|
(sasl-authzid
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the authorization identity to be used when performing SASL
|
||||||
|
authentication.")
|
||||||
|
(sasl-canonicalize?
|
||||||
|
(maybe-boolean 'disabled)
|
||||||
|
"Determines whether the LDAP server host name should be canonicalised. If
|
||||||
|
this is enabled the LDAP library will do a reverse host name lookup. By
|
||||||
|
default, it is left up to the LDAP library whether this check is performed or
|
||||||
|
not.")
|
||||||
|
|
||||||
|
;; Kerberos authentication options
|
||||||
|
(krb5-ccname
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Set the name for the GSS-API Kerberos credentials cache.")
|
||||||
|
|
||||||
|
;; Search / mapping options
|
||||||
|
(base
|
||||||
|
(string "dc=example,dc=com")
|
||||||
|
"The directory search base.")
|
||||||
|
(scope
|
||||||
|
(scope-option '(subtree))
|
||||||
|
"Specifies the search scope (subtree, onelevel, base or children). The
|
||||||
|
default scope is subtree; base scope is almost never useful for name service
|
||||||
|
lookups; children scope is not supported on all servers.")
|
||||||
|
(deref
|
||||||
|
(maybe-deref-option 'disabled)
|
||||||
|
"Specifies the policy for dereferencing aliases. The default policy is to
|
||||||
|
never dereference aliases.")
|
||||||
|
(referrals
|
||||||
|
(maybe-boolean 'disabled)
|
||||||
|
"Specifies whether automatic referral chasing should be enabled. The
|
||||||
|
default behaviour is to chase referrals.")
|
||||||
|
(maps
|
||||||
|
(list-of-map-entries '())
|
||||||
|
"This option allows for custom attributes to be looked up instead of the
|
||||||
|
default RFC 2307 attributes. It is a list of maps, each consisting of the
|
||||||
|
name of a map, the RFC 2307 attribute to match and the query expression for
|
||||||
|
the attribute as it is available in the directory.")
|
||||||
|
(filters
|
||||||
|
(list-of-filter-entries '())
|
||||||
|
"A list of filters consisting of the name of a map to which the filter
|
||||||
|
applies and an LDAP search filter expression.")
|
||||||
|
|
||||||
|
;; Timing / reconnect options
|
||||||
|
(bind-timelimit
|
||||||
|
(maybe-number 'disabled)
|
||||||
|
"Specifies the time limit in seconds to use when connecting to the
|
||||||
|
directory server. The default value is 10 seconds.")
|
||||||
|
(timelimit
|
||||||
|
(maybe-number 'disabled)
|
||||||
|
"Specifies the time limit (in seconds) to wait for a response from the LDAP
|
||||||
|
server. A value of zero, which is the default, is to wait indefinitely for
|
||||||
|
searches to be completed.")
|
||||||
|
(idle-timelimit
|
||||||
|
(maybe-number 'disabled)
|
||||||
|
"Specifies the period if inactivity (in seconds) after which the con‐
|
||||||
|
nection to the LDAP server will be closed. The default is not to time out
|
||||||
|
connections.")
|
||||||
|
(reconnect-sleeptime
|
||||||
|
(maybe-number 'disabled)
|
||||||
|
"Specifies the number of seconds to sleep when connecting to all LDAP
|
||||||
|
servers fails. By default one second is waited between the first failure and
|
||||||
|
the first retry.")
|
||||||
|
(reconnect-retrytime
|
||||||
|
(maybe-number 'disabled)
|
||||||
|
"Specifies the time after which the LDAP server is considered to be
|
||||||
|
permanently unavailable. Once this time is reached retries will be done only
|
||||||
|
once per this time period. The default value is 10 seconds.")
|
||||||
|
|
||||||
|
;; TLS options
|
||||||
|
(ssl
|
||||||
|
(maybe-ssl-option 'disabled)
|
||||||
|
"Specifies whether to use SSL/TLS or not (the default is not to). If
|
||||||
|
'start-tls is specified then StartTLS is used rather than raw LDAP over SSL.")
|
||||||
|
(tls-reqcert
|
||||||
|
(maybe-tls-reqcert-option 'disabled)
|
||||||
|
"Specifies what checks to perform on a server-supplied certificate.
|
||||||
|
The meaning of the values is described in the ldap.conf(5) manual page.")
|
||||||
|
(tls-cacertdir
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the directory containing X.509 certificates for peer authen‐
|
||||||
|
tication. This parameter is ignored when using GnuTLS.")
|
||||||
|
(tls-cacertfile
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the path to the X.509 certificate for peer authentication.")
|
||||||
|
(tls-randfile
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the path to an entropy source. This parameter is ignored when
|
||||||
|
using GnuTLS.")
|
||||||
|
(tls-ciphers
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the ciphers to use for TLS as a string.")
|
||||||
|
(tls-cert
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the path to the file containing the local certificate for client
|
||||||
|
TLS authentication.")
|
||||||
|
(tls-key
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"Specifies the path to the file containing the private key for client TLS
|
||||||
|
authentication.")
|
||||||
|
|
||||||
|
;; Other options
|
||||||
|
(pagesize
|
||||||
|
(maybe-number 'disabled)
|
||||||
|
"Set this to a number greater than 0 to request paged results from the LDAP
|
||||||
|
server in accordance with RFC2696. The default (0) is to not request paged
|
||||||
|
results.")
|
||||||
|
(nss-initgroups-ignoreusers
|
||||||
|
(maybe-ignore-users-option 'disabled)
|
||||||
|
"This option prevents group membership lookups through LDAP for the
|
||||||
|
specified users. Alternatively, the value 'all-local may be used. With that
|
||||||
|
value nslcd builds a full list of non-LDAP users on startup.")
|
||||||
|
(nss-min-uid
|
||||||
|
(maybe-number 'disabled)
|
||||||
|
"This option ensures that LDAP users with a numeric user id lower than the
|
||||||
|
specified value are ignored.")
|
||||||
|
(nss-uid-offset
|
||||||
|
(maybe-number 'disabled)
|
||||||
|
"This option specifies an offset that is added to all LDAP numeric user
|
||||||
|
ids. This can be used to avoid user id collisions with local users.")
|
||||||
|
(nss-gid-offset
|
||||||
|
(maybe-number 'disabled)
|
||||||
|
"This option specifies an offset that is added to all LDAP numeric group
|
||||||
|
ids. This can be used to avoid user id collisions with local groups.")
|
||||||
|
(nss-nested-groups
|
||||||
|
(maybe-boolean 'disabled)
|
||||||
|
"If this option is set, the member attribute of a group may point to
|
||||||
|
another group. Members of nested groups are also returned in the higher level
|
||||||
|
group and parent groups are returned when finding groups for a specific user.
|
||||||
|
The default is not to perform extra searches for nested groups.")
|
||||||
|
(nss-getgrent-skipmembers
|
||||||
|
(maybe-boolean 'disabled)
|
||||||
|
"If this option is set, the group member list is not retrieved when looking
|
||||||
|
up groups. Lookups for finding which groups a user belongs to will remain
|
||||||
|
functional so the user will likely still get the correct groups assigned on
|
||||||
|
login.")
|
||||||
|
(nss-disable-enumeration
|
||||||
|
(maybe-boolean 'disabled)
|
||||||
|
"If this option is set, functions which cause all user/group entries to be
|
||||||
|
loaded from the directory will not succeed in doing so. This can dramatically
|
||||||
|
reduce LDAP server load in situations where there are a great number of users
|
||||||
|
and/or groups. This option is not recommended for most configurations.")
|
||||||
|
(validnames
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"This option can be used to specify how user and group names are verified
|
||||||
|
within the system. This pattern is used to check all user and group names
|
||||||
|
that are requested and returned from LDAP.")
|
||||||
|
(ignorecase
|
||||||
|
(maybe-boolean 'disabled)
|
||||||
|
"This specifies whether or not to perform searches using case-insensitive
|
||||||
|
matching. Enabling this could open up the system to authorization bypass
|
||||||
|
vulnerabilities and introduce nscd cache poisoning vulnerabilities which allow
|
||||||
|
denial of service.")
|
||||||
|
(pam-authc-ppolicy
|
||||||
|
(maybe-boolean 'disabled)
|
||||||
|
"This option specifies whether password policy controls are requested and
|
||||||
|
handled from the LDAP server when performing user authentication.")
|
||||||
|
(pam-authc-search
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"By default nslcd performs an LDAP search with the user's credentials after
|
||||||
|
BIND (authentication) to ensure that the BIND operation was successful. The
|
||||||
|
default search is a simple check to see if the user's DN exists. A search
|
||||||
|
filter can be specified that will be used instead. It should return at least
|
||||||
|
one entry.")
|
||||||
|
(pam-authz-search
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"This option allows flexible fine tuning of the authorisation check that
|
||||||
|
should be performed. The search filter specified is executed and if any
|
||||||
|
entries match, access is granted, otherwise access is denied.")
|
||||||
|
(pam-password-prohibit-message
|
||||||
|
(maybe-string 'disabled)
|
||||||
|
"If this option is set password modification using pam_ldap will be denied
|
||||||
|
and the specified message will be presented to the user instead. The message
|
||||||
|
can be used to direct the user to an alternative means of changing their
|
||||||
|
password.")
|
||||||
|
|
||||||
|
;; Options for extension of pam-root-service-type.
|
||||||
|
(pam-services
|
||||||
|
(list '())
|
||||||
|
"List of pam service names for which LDAP authentication should suffice."))
|
||||||
|
|
||||||
|
(define %nslcd-accounts
|
||||||
|
(list (user-group
|
||||||
|
(name "nslcd")
|
||||||
|
(system? #t))
|
||||||
|
(user-account
|
||||||
|
(name "nslcd")
|
||||||
|
(group "nslcd")
|
||||||
|
(comment "NSLCD service account")
|
||||||
|
(home-directory "/var/empty")
|
||||||
|
(shell (file-append shadow "/sbin/nologin"))
|
||||||
|
(system? #t))))
|
||||||
|
|
||||||
|
(define (nslcd-config-file config)
|
||||||
|
"Return an NSLCD configuration file."
|
||||||
|
(plain-file "nslcd.conf"
|
||||||
|
(with-output-to-string
|
||||||
|
(lambda ()
|
||||||
|
(serialize-configuration config nslcd-configuration-fields)
|
||||||
|
;; The file must end with a newline character.
|
||||||
|
(format #t "\n")))))
|
||||||
|
|
||||||
|
;; XXX: The file should only be readable by root if it contains a "bindpw"
|
||||||
|
;; declaration. Unfortunately, this etc-service-type extension does not
|
||||||
|
;; support setting file modes, so we do this in the activation service.
|
||||||
|
(define (nslcd-etc-service config)
|
||||||
|
`(("nslcd.conf" ,(nslcd-config-file config))))
|
||||||
|
|
||||||
|
(define (nslcd-shepherd-service config)
|
||||||
|
(list (shepherd-service
|
||||||
|
(documentation "Run the nslcd service for resolving names from LDAP.")
|
||||||
|
(provision '(nslcd))
|
||||||
|
(requirement '(networking user-processes))
|
||||||
|
(start #~(make-forkexec-constructor
|
||||||
|
(list (string-append #$(nslcd-configuration-nss-pam-ldapd config)
|
||||||
|
"/sbin/nslcd")
|
||||||
|
"--nofork")
|
||||||
|
#:pid-file "/var/run/nslcd/nslcd.pid"
|
||||||
|
#:environment-variables
|
||||||
|
(list (string-append "LD_LIBRARY_PATH="
|
||||||
|
#$(nslcd-configuration-nss-pam-ldapd config)
|
||||||
|
"/lib"))))
|
||||||
|
(stop #~(make-kill-destructor)))))
|
||||||
|
|
||||||
|
(define (pam-ldap-pam-service config)
|
||||||
|
"Return a PAM service for LDAP authentication."
|
||||||
|
(define pam-ldap-module
|
||||||
|
#~(string-append #$(nslcd-configuration-nss-pam-ldapd config)
|
||||||
|
"/lib/security/pam_ldap.so"))
|
||||||
|
(lambda (pam)
|
||||||
|
(if (member (pam-service-name pam)
|
||||||
|
(nslcd-configuration-pam-services config))
|
||||||
|
(let ((sufficient
|
||||||
|
(pam-entry
|
||||||
|
(control "sufficient")
|
||||||
|
(module pam-ldap-module))))
|
||||||
|
(pam-service
|
||||||
|
(inherit pam)
|
||||||
|
(auth (cons sufficient (pam-service-auth pam)))
|
||||||
|
(session (cons sufficient (pam-service-session pam)))
|
||||||
|
(account (cons sufficient (pam-service-account pam)))))
|
||||||
|
pam)))
|
||||||
|
|
||||||
|
(define (pam-ldap-pam-services config)
|
||||||
|
(list (pam-ldap-pam-service config)))
|
||||||
|
|
||||||
|
(define nslcd-service-type
|
||||||
|
(service-type
|
||||||
|
(name 'nslcd)
|
||||||
|
(description "Run the NSLCD service for looking up names from LDAP.")
|
||||||
|
(extensions
|
||||||
|
(list (service-extension account-service-type
|
||||||
|
(const %nslcd-accounts))
|
||||||
|
(service-extension etc-service-type
|
||||||
|
nslcd-etc-service)
|
||||||
|
(service-extension activation-service-type
|
||||||
|
(const #~(begin
|
||||||
|
(use-modules (guix build utils))
|
||||||
|
(let ((rundir "/var/run/nslcd")
|
||||||
|
(user (getpwnam "nslcd")))
|
||||||
|
(mkdir-p rundir)
|
||||||
|
(chown rundir (passwd:uid user) (passwd:gid user))
|
||||||
|
(chmod rundir #o755)
|
||||||
|
(when (file-exists? "/etc/nslcd.conf")
|
||||||
|
(chmod "/etc/nslcd.conf" #o400))))))
|
||||||
|
(service-extension pam-root-service-type
|
||||||
|
pam-ldap-pam-services)
|
||||||
|
(service-extension nscd-service-type
|
||||||
|
(const (list nss-pam-ldapd)))
|
||||||
|
(service-extension shepherd-root-service-type
|
||||||
|
nslcd-shepherd-service)))
|
||||||
|
(default-value (nslcd-configuration))))
|
||||||
|
|
||||||
|
(define (generate-nslcd-documentation)
|
||||||
|
(generate-documentation
|
||||||
|
`((nslcd-configuration ,nslcd-configuration-fields))
|
||||||
|
'nslcd-configuration))
|
||||||
|
|
160
gnu/tests/ldap.scm
Normal file
160
gnu/tests/ldap.scm
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
|
;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
|
||||||
|
;;;
|
||||||
|
;;; This file is part of GNU Guix.
|
||||||
|
;;;
|
||||||
|
;;; GNU Guix is free software; you can redistribute it and/or modify it
|
||||||
|
;;; under the terms of the GNU General Public License as published by
|
||||||
|
;;; the Free Software Foundation; either version 3 of the License, or (at
|
||||||
|
;;; your option) any later version.
|
||||||
|
;;;
|
||||||
|
;;; GNU Guix is distributed in the hope that it will be useful, but
|
||||||
|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;;; GNU General Public License for more details.
|
||||||
|
;;;
|
||||||
|
;;; You should have received a copy of the GNU General Public License
|
||||||
|
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
(define-module (gnu tests ldap)
|
||||||
|
#:use-module (gnu tests)
|
||||||
|
#:use-module (gnu system)
|
||||||
|
#:use-module (gnu system nss)
|
||||||
|
#:use-module (gnu system vm)
|
||||||
|
#:use-module (gnu services)
|
||||||
|
#:use-module (gnu services authentication)
|
||||||
|
#:use-module (gnu services networking)
|
||||||
|
#:use-module (gnu packages base)
|
||||||
|
#:use-module (gnu packages openldap)
|
||||||
|
#:use-module (guix gexp)
|
||||||
|
#:use-module (guix store)
|
||||||
|
#:export (%test-ldap))
|
||||||
|
|
||||||
|
(define %ldap-os
|
||||||
|
(let ((simple
|
||||||
|
(simple-operating-system
|
||||||
|
(service dhcp-client-service-type)
|
||||||
|
(service nslcd-service-type))))
|
||||||
|
(operating-system
|
||||||
|
(inherit simple)
|
||||||
|
(name-service-switch
|
||||||
|
(let ((services (list (name-service (name "db"))
|
||||||
|
(name-service (name "files"))
|
||||||
|
(name-service (name "ldap")))))
|
||||||
|
(name-service-switch
|
||||||
|
(inherit %mdns-host-lookup-nss)
|
||||||
|
(password services)
|
||||||
|
(shadow services)
|
||||||
|
(group services)
|
||||||
|
(netgroup services)
|
||||||
|
(gshadow services)))))))
|
||||||
|
|
||||||
|
(define (run-ldap-test)
|
||||||
|
"Run tests in %LDAP-OS."
|
||||||
|
(define os
|
||||||
|
(marionette-operating-system
|
||||||
|
%ldap-os
|
||||||
|
#:imported-modules '((gnu services herd)
|
||||||
|
(guix combinators))))
|
||||||
|
|
||||||
|
(define vm
|
||||||
|
(virtual-machine os))
|
||||||
|
|
||||||
|
(define test
|
||||||
|
(with-imported-modules '((gnu build marionette))
|
||||||
|
#~(begin
|
||||||
|
(use-modules (srfi srfi-11) (srfi srfi-64)
|
||||||
|
(gnu build marionette))
|
||||||
|
|
||||||
|
(define marionette
|
||||||
|
(make-marionette (list #$vm)))
|
||||||
|
|
||||||
|
(mkdir #$output)
|
||||||
|
(chdir #$output)
|
||||||
|
|
||||||
|
(test-begin "ldap")
|
||||||
|
|
||||||
|
;; Set up LDAP directory server
|
||||||
|
(test-assert "LDAP server instance running"
|
||||||
|
(marionette-eval
|
||||||
|
'(begin
|
||||||
|
(with-output-to-file "instance.inf"
|
||||||
|
(lambda ()
|
||||||
|
(display "[general]
|
||||||
|
config_version = 2
|
||||||
|
|
||||||
|
\n[slapd]
|
||||||
|
root_password = SECRET
|
||||||
|
user = root
|
||||||
|
group = root
|
||||||
|
|
||||||
|
\n[backend-userroot]
|
||||||
|
sample_entries = yes
|
||||||
|
suffix = dc=example,dc=com")))
|
||||||
|
(and
|
||||||
|
;; Create instance
|
||||||
|
(zero? (system* #$(file-append 389-ds-base "/sbin/dscreate")
|
||||||
|
"-v" "from-file" "instance.inf"))
|
||||||
|
;; Start instance
|
||||||
|
(zero? (system* #$(file-append 389-ds-base "/sbin/dsctl")
|
||||||
|
"localhost" "start"))
|
||||||
|
;; Create user account
|
||||||
|
(zero? (system* #$(file-append 389-ds-base "/sbin/dsidm")
|
||||||
|
"-b" "dc=example,dc=com"
|
||||||
|
"localhost" "user" "create"
|
||||||
|
"--uid" "eva" "--cn" "Eva Lu Ator"
|
||||||
|
"--displayName" "Eva Lu Ator"
|
||||||
|
"--uidNumber" "1234" "--gidNumber" "2345"
|
||||||
|
"--homeDirectory" "/home/eva"))))
|
||||||
|
marionette))
|
||||||
|
|
||||||
|
(test-assert "Manager can bind to LDAP server instance"
|
||||||
|
(marionette-eval
|
||||||
|
'(zero? (system* #$(file-append openldap "/bin/ldapwhoami")
|
||||||
|
"-H" "ldap://localhost" "-D"
|
||||||
|
"cn=Directory Manager" "-w" "SECRET"))
|
||||||
|
marionette))
|
||||||
|
|
||||||
|
;; Wait for nslcd to be up and running.
|
||||||
|
(test-assert "nslcd service running"
|
||||||
|
(marionette-eval
|
||||||
|
'(begin
|
||||||
|
(use-modules (gnu services herd))
|
||||||
|
(match (start-service 'nslcd)
|
||||||
|
(#f #f)
|
||||||
|
(('service response-parts ...)
|
||||||
|
(match (assq-ref response-parts 'running)
|
||||||
|
((pid) (number? pid))))))
|
||||||
|
marionette))
|
||||||
|
|
||||||
|
(test-assert "nslcd produces a log file"
|
||||||
|
(marionette-eval
|
||||||
|
'(file-exists? "/var/log/nslcd")
|
||||||
|
marionette))
|
||||||
|
|
||||||
|
(test-assert "Can query LDAP user accounts"
|
||||||
|
(marionette-eval
|
||||||
|
'(begin
|
||||||
|
;; TODO: This shouldn't be necessary, but unfortunately it
|
||||||
|
;; really is needed to discover LDAP accounts with "id".
|
||||||
|
(setenv "LD_LIBRARY_PATH"
|
||||||
|
#$(file-append nss-pam-ldapd "/lib"))
|
||||||
|
(zero? (system* #$(file-append coreutils "/bin/id") "eva")))
|
||||||
|
marionette))
|
||||||
|
|
||||||
|
(test-assert "Can become LDAP user"
|
||||||
|
(marionette-eval
|
||||||
|
'(zero? (system* "/run/setuid-programs/su" "eva" "-c"
|
||||||
|
#$(file-append coreutils "/bin/true")))
|
||||||
|
marionette))
|
||||||
|
|
||||||
|
(test-end)
|
||||||
|
(exit (= (test-runner-fail-count (test-runner-current)) 0)))))
|
||||||
|
|
||||||
|
(gexp->derivation "ldap-test" test))
|
||||||
|
|
||||||
|
(define %test-ldap
|
||||||
|
(system-test
|
||||||
|
(name "ldap")
|
||||||
|
(description "Run an LDAP directory server and authenticate against it.")
|
||||||
|
(value (run-ldap-test))))
|
Loading…
Reference in a new issue