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
479
doc/guix.texi
479
doc/guix.texi
|
@ -11139,6 +11139,7 @@ declaration.
|
|||
* Telephony Services:: Telephony services.
|
||||
* Monitoring Services:: Monitoring services.
|
||||
* Kerberos Services:: Kerberos services.
|
||||
* LDAP Services:: LDAP services.
|
||||
* Web Services:: Web servers.
|
||||
* Certificate Services:: TLS certificates via Let's Encrypt.
|
||||
* DNS Services:: DNS daemons.
|
||||
|
@ -17685,6 +17686,484 @@ Local accounts with lower values will silently fail to authenticate.
|
|||
@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
|
||||
@subsection Web Services
|
||||
|
||||
|
|
|
@ -569,6 +569,7 @@ GNU_SYSTEM_MODULES = \
|
|||
%D%/tests/monitoring.scm \
|
||||
%D%/tests/nfs.scm \
|
||||
%D%/tests/install.scm \
|
||||
%D%/tests/ldap.scm \
|
||||
%D%/tests/mail.scm \
|
||||
%D%/tests/messaging.scm \
|
||||
%D%/tests/networking.scm \
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2018 Danny Milosavljevic <dannym@scratchpost.org>
|
||||
;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
|
@ -18,13 +19,28 @@
|
|||
|
||||
(define-module (gnu services authentication)
|
||||
#:use-module (gnu services)
|
||||
#:use-module (gnu services base)
|
||||
#:use-module (gnu services configuration)
|
||||
#: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 openldap)
|
||||
#:use-module (guix gexp)
|
||||
#: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
|
||||
fprintd-configuration?
|
||||
fprintd-service-type))
|
||||
fprintd-service-type
|
||||
|
||||
nslcd-configuration
|
||||
nslcd-configuration?
|
||||
nslcd-service-type))
|
||||
|
||||
(define-record-type* <fprintd-configuration>
|
||||
fprintd-configuration make-fprintd-configuration
|
||||
|
@ -39,3 +55,496 @@
|
|||
list)))
|
||||
(description
|
||||
"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))
|
||||
|
|
|
@ -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 New Issue