nslcd.conf(5)
β¨ nslcd.conf(5) β¨ β the glow-up guide to your LDAP nameservice daemon config π
okay bestie, listen up, this is from the System Manager's Manual and it's literally the manual page for nslcd.conf(5), and it's giving essential reading, fr fr.
πΈ NAME πΈ
nslcd.conf β the configuration file for the LDAP nameservice daemon π§
π DESCRIPTION π
so the nss-pam-ldapd package lets LDAP directory servers be your primary source of name service information. (and like, name service info is normally users, hosts, groups, and all that other data that historically lived in flat files or NIS, iykyk.)
the file nslcd.conf holds all the configuration info for running nslcd (go peek at nslcd(8) if you want). it's got options, one on each line, and they define the way NSS lookups and PAM actions get mapped to LDAP lookups. slay. π
π OPTIONS π
π RUNTIME OPTIONS π
threads NUMβ tells it how many threads to start, and those threads handle requests and do the LDAP queries. lowkey important: each thread opens a separate connection to the LDAP server. the default is to start 5 threads. π«uid UIDβ the user id the daemon should run as. can be a numerical id or a symbolic value. if you don't specify a uid, no attempt to change the user gets made, periodt. heads up tho: use values that don't need LDAP to resolve. π«Άgid GIDβ the group id the daemon should run as. also can be a numerical id or a symbolic value. if no gid is specified, no attempt to change the group happens. same note as above: use values that don't need LDAP to resolve. πlog SCHEME [LEVEL]β controls how logging gets done. theSCHEMEargument can benone,syslog, or an absolute file name. theLEVELargument is optional and sets the log level. the log level can be one of:crit,error,warning,notice,infoordebug. the default log level isinfo. all messages at the specified loglevel or higher get logged. you can supply this option multiple times. if you omit it entirely,syslog infois assumed. β¨
π¦ GENERAL CONNECTION OPTIONS π¦
uri URI ...β the LDAP URI of the server to connect to. the URI scheme can beldap,ldapiorldaps, which specify LDAP over TCP, ICP or SSL respectively (if your LDAP library supports it, that is).
alternatively, the value DNS can be used to try looking up the server using DNS SRV records. by default the current domain is used, but you can query another domain with the DNS:DOMAIN syntax. to convert SRV records for port 389 into an ldaps:// URI, DNSLDAPS can be used.
when you're using the ldapi scheme, %2f should be used to escape slashes (like ldapi://%2fvar%2frun%2fslapd%2fldapi/), although most of the time this shouldn't be needed.
this option may be specified multiple times and/or with more URIs on the line, separated by spaces. normally, only the first server gets used, with the following servers as fall-back (see bind_timelimit below π).
if LDAP lookups are used for host name resolution, any host names should be specified as an IP address or a name that can be resolved without using LDAP. no cap, this matters. π¨
ldap_version VERSIONβ the version of the LDAP protocol to use. the default is to use the maximum version supported by the LDAP library. π₯binddn DNβ the distinguished name to bind to the directory server with for lookups. the default is to bind anonymously. πbindpw PASSWORDβ the credentials to bind with. only applicable when used withbinddnabove. if you set this one, you should consider changing the permissions of thenslcd.conffile to only grant access to the root user. πrootpwmoddn DNβ the distinguished name to use when the root user tries to modify a user's password using the PAM module.
note that currently this DN needs to exist as a real entry in the LDAP directory. it's not a vibe-only situation.
rootpwmodpw PASSWORDβ the credentials to bind with if the root user tries to change a user's password. only applicable when used withrootpwmoddnabove. if you don't specify this option, the PAM module prompts the user for this password instead. and if you do set it, you should consider changing the permissions of thenslcd.conffile to only grant access to the root user. π
π SASL AUTHENTICATION OPTIONS π
sasl_mech MECHANISMβ the SASL mechanism to use when performing SASL authentication.sasl_realm REALMβ the SASL realm to use when performing SASL authentication.sasl_authcid AUTHCIDβ the authentication identity to use when performing SASL authentication.sasl_authzid AUTHZIDβ the authorization identity to use when performing SASL authentication. must be specified in one of the formats:dn:<distinguished name>oru:<username>. don't freestyle this one bestie. βοΈsasl_secprops PROPERTIESβ the Cyrus SASL security properties. all the allowed values are described in theldap.conf(5)manual page, go check it.sasl_canonicalize yes|noβ decides whether the LDAP server host name should be canonicalised. if this is set toyes, the LDAP library will do a reverse host name lookup. by default, it's left up to the LDAP library whether this check is performed or not. main character energy: deferred. β¨
π KERBEROS AUTHENTICATION OPTIONS π
krb5_ccname NAMEβ sets the name for the GSS-API Kerberos credentials cache.
π SEARCH/MAPPING OPTIONS π
base [MAP] DNβ the distinguished name (DN) to use as the search base. you can supply this option multiple times and all the specified bases will be searched. π
you can specify a global search base or a MAP-specific one. if no MAP-specific search bases are defined, the global ones get used.
if, instead of a DN, you specify the value DOMAIN, the host's DNS domain is used to construct a search base. a value of "" can be used to indicate an empty search base (quotes are not otherwise supported for base values, and not all LDAP server configurations support this either).
if this value isn't defined, an attempt is made to look it up in the configured LDAP server. and if the LDAP server is unavailable during start-up, nslcd will not start. π
scope [MAP] sub[tree]|one[level]|base|childrenβ the search scope (subtree,onelevel,baseorchildren). the default scope issubtree;basescope is almost never useful for name service lookups;childrenscope is not supported on all servers.deref never|searching|finding|alwaysβ the policy for dereferencing aliases. the default policy is to never dereference aliases.referrals yes|noβ whether automatic referral chasing should be enabled. the default behaviour is to chase referrals.filter MAP FILTERβ theFILTERis an LDAP search filter to use for a specific map. the default filter is a basic search on theobjectClassfor the map (like(objectClass=posixAccount)).map MAP ATTRIBUTE NEWATTRIBUTEβ this one lets you look up custom attributes instead of the default RFC 2307 attributes. theMAPcan be one of the supported maps listed below. theATTRIBUTEis the one used in RFC 2307 (likeuserPassword,ipProtocolNumber,macAddress, etc.).
the NEWATTRIBUTE can be the name of any attribute as it's available in the directory.
if the NEWATTRIBUTE is quoted (") as "EXPRESSION", it's treated as an expression that gets evaluated to build up the actual value used. see the section on attribute mapping expressions below for more details. π§
only some attributes for group, passwd and shadow entries can be mapped with an expression (because other attributes may be used in search filters). for group entries, only the userPassword attribute may be mapped with an expression. for passwd entries, these attributes may be mapped with an expression: userPassword, gidNumber, gecos, homeDirectory and loginShell. for shadow entries, these may be mapped with an expression: userPassword, shadowLastChange, shadowMin, shadowMax, shadowWarning, shadowInactive, shadowExpire and shadowFlag.
the uidNumber and gidNumber attributes in the passwd and group maps may be mapped to the objectSid followed by the domain SID, to derive numeric user and group ids from the SID (like objectSid:S-1-5-21-3623811015-3361044348-30300820).
by default, alluserPasswordattributes are mapped to the unmatchable password ("*") to avoid accidentally leaking password information. we love a security queen. π
β° TIMING/RECONNECT OPTIONS β°
bind_timelimit SECONDSβ the time limit (in seconds) to use when connecting to the directory server. this is distinct from the time limit specified intimelimit, and it only affects the set-up of the connection. note that not all LDAP client libraries support setting the connection time out. the defaultbind_timelimitis 10 seconds.timelimit SECONDSβ the time limit (in seconds) to wait for a response from the LDAP server. a value of zero (0), which is the default, means wait indefinitely for searches to be completed. no rush, no stress. πidle_timelimit SECONDSβ the period of inactivity (in seconds) after which the connection to the LDAP server gets closed. the default is not to time out connections.reconnect_sleeptime SECONDSβ the number of seconds to sleep when connecting to all LDAP servers fails. by default, 1 second is waited between the first failure and the first retry.reconnect_retrytime SECONDSβ the time after which the LDAP server is considered to be permanently unavailable. once this time is reached, retries are only done once per this time period. the default value is 10 seconds.
note that the reconnect logic described above is the mechanism used between nslcd and the LDAP server. the mechanism between the NSS and PAM client libraries on one end and nslcd on the other is simpler, with a fixed compiled-in time out of 10 seconds for writing to nslcd and a time out of 60 seconds for reading answers. nslcd itself has a read time out of 0.5 seconds and a write time out of 60 seconds. β¨ (yes bestie, the numbers are exact, don't round them π
)
π SSL/TLS OPTIONS π
okay bestie, this is the section where we make your LDAP connection stop being naked on the wire. very important, no cap.
ssl on|off|start_tlsβ says whether we're doing SSL/TLS or not (and ngl, the default is not doing it). If you saystart_tlsthen StartTLS gets used instead of raw LDAP-over-SSL. Heads up though: not all LDAP client libraries support both SSL, StartTLS and all the related config options, so like, know your lib.tls_reqcert never|allow|try|demand|hardβ tells nslcd what checks to run on the certificate the server hands you. The vibes of each value are explained over in theldap.conf(5)manual page. π If peer verification is enabled, you need at least one oftls_cacertdirandtls_cacertfile, fr fr.tls_cacertdir PATHβ the directory holding X.509 certificates for peer authentication. β οΈ This parameter is ignored when using GnuTLS β and on Debian, OpenLDAP is linked against GnuTLS, so yeah. πtls_cacertfile PATHβ the path to the X.509 certificate used for peer authentication. β¨tls_randfile PATHβ the path to an entropy source. Also ignored when using GnuTLS, and on Debian OpenLDAP is linked against GnuTLS. πtls_ciphers CIPHERSβ the ciphers to use for TLS. Go read your TLS implementation's documentation for the details, that's a whole other rabbit hole bestie.tls_cert PATHβ the path to the file with the local certificate for client TLS authentication. πtls_key PATHβ the path to the file with the private key for client TLS authentication. Keep this one safe, obviously. πtls_reqsan never|allow|try|demand|hardβ how the server's Subject Alternative Name (SAN) gets checked in the server-supplied certificate. The values mean the same thing they mean in theldap.conf(5)manual page. πtls_crlcheck none|peer|allβ whether the CA's Certificate Revocation List (CRL) should be used to verify that the server certificates haven't been revoked. Values explained inldap.conf(5), same deal. π¦tls_crlfile PATHβ the path to the file containing a Certificate Revocation List, used to verify the server certificates. And again, the meaning of the values is described in theldap.conf(5)manual page. πΈ
π OTHER OPTIONS π
pagesize NUMBERβ set this to a number greater than0to request paged results from the LDAP server in accordance withRFC2696. The default (0) is to not request paged results.
This is a lifesaver for LDAP servers holding a LOT of entries (like, more than 500) that cap how many entries come back in one request. For OpenLDAP servers you may need to set sizelimit size.prtotal=unlimited so more entries can be returned across multiple pages. β¨
nss_initgroups_ignoreusers user1,user2,...β stops group membership lookups through LDAP for the users you list. Super useful when the LDAP server is justβ¦ not available. π This option may be specified multiple times.
Alternatively you can pass the value ALLLOCAL, and with that, nslcd builds a full list of non-LDAP users on startup. π«Ά
nss_min_uid UIDβ LDAP users with a numeric user id lower than the value you give here get ignored. Also, requests for users with a lower user id get ignored. π«nss_uid_offset NUMBERβ an offset that gets added to all LDAP numeric user ids. Handy for dodging user id collisions with local users, or for compatibility reasons when you're usingobjectSidattributes.
The value from the nss_min_uid option is evaluated after applying the offset. Important order of operations bestie. π
nss_gid_offset NUMBERβ an offset added to all LDAP numeric group ids. Same deal as above: avoids group id collisions with local groups, or helps for compatibility reasons when usingobjectSidattributes. πnss_nested_groups yes|noβ if this is set, thememberattribute of a group may point to another group. Members of nested groups also come back in the higher level group, and parent groups get returned when finding groups for a specific user. The default is to not do extra searches for nested groups. πΈnss_getgrent_skipmembers yes|noβ if this is set, the group member list is not retrieved when looking up groups. Lookups for finding which groups a user belongs to still work, so the user will likely still get the correct groups assigned on login.
It can speed things up on systems with very large groups. But the downside is it returns inconsistent information about group membership, which may confuse some applications. > This option is not recommended for most configurations. π¬
nss_disable_enumeration yes|noβ if this is set, functions that cause all user/group entries to be loaded (getpwent(),getgrent(),setspent()) from the directory will not succeed in doing so. Applications that depend on being able to sequentially read all users and/or groups may fail to operate correctly.
This can dramatically reduce LDAP server load when there are a great number of users and/or groups. It's typically used where user/program access to enumerate the entire directory is undesirable, and changing the behavior of the user/program isn't possible. > This option is not recommended for most configurations. π
validnames REGEXβ use this to specify how user and group names are verified within the system. The pattern is used to check all user and group names that are requested and returned from LDAP.
The regular expression should be specified as a POSIX extended regular expression. The expression itself needs to be separated by slash (/) characters, and the i flag may be appended at the end to indicate the match should be case-insensitive. The default value is /^[a-z0-9._@$()]([a-z0-9._@$() \\~-]*[a-z0-9._@$()~-])?$/i β¨
ignorecase yes|noβ whether or not to perform searches for group, netgroup, passwd, protocols, rpc, services and shadow maps using case-insensitive matching. β οΈ Setting this toyescould open up the system to authorisation bypass vulnerabilities and introduce nscd cache poisoning vulnerabilities which allow denial of service. The default is to perform case-sensitive filtering of LDAP search results for the maps listed above. So likeβ¦ be careful bestie. π¨pam_authc_ppolicy yes|noβ whether password policy controls are requested and handled from the LDAP server when performing user authentication. By default the controls are requested and handled if available. πpam_authc_search FILTERβ by default nslcd performs an LDAP search with the user's credentials after BIND (authentication) to make sure the BIND operation actually succeeded. The default search is a simple check to see if the user's DN exists.
You can specify a search filter that gets used instead. The same substitutions as with the pam_authz_search option are performed, and the search should at least return one entry.
The value BASE may be used to force the default search for the user DN.
The value NONE may be used to indicate that no search should be performed after BIND. > Note that some LDAP servers do not always return a correct error code as a result of a failed BIND operation (e.g. when an empty password is supplied). π
pam_authz_search FILTERβ lets you flexibly fine tune the authorisation check that should be performed. The search filter you specify is executed, and if any entries match, access is granted β otherwise access is denied. π₯
The search filter can contain these variable references: $username, $service, $ruser, $rhost, $tty, $hostname, $fqdn, $domain, $dn, and $uid. These references are substituted in the search filter using the same syntax as described in the section on attribute mapping expressions below.
For example, to check that the user has a proper authorizedService value if the attribute is present (this almost emulates the pam_check_service_attr option in PADL's pam_ldap):
(&(objectClass=posixAccount)(uid=$username)(|(authorizedService=$service)(!(authorizedService=*))))
The pam_check_host_attr option can be emulated with:
(&(objectClass=posixAccount)(uid=$username)(|(host=$hostname)(host=$fqdn)(host=\*)))
This option may be specified multiple times, and all specified searches should at least return one entry for access to be granted. π
pam_password_prohibit_message "MESSAGE"β if this is set, password modification usingpam_ldapwill be denied and the message you specify gets presented to the user instead. Perfect for pointing your users at some other way of changing their password. πreconnect_invalidate DB,DB,...β if set, nslcd will try to flush the specified external caches on start-up and whenever a connection to the LDAP server is re-established after an error. π§Ή
DB can refer to one of the nsswitch maps, in which case nscd is contacted to flush its cache for the specified database. If DB is nfsidmap, nfsidmap is contacted to clear its cache.
Using this option ensures external caches get cleared of incorrect information (typically the absence of users) that may be hanging around because the LDAP server was unavailable. π
cache CACHE TIME [TIME]β configures the time entries are kept in the specified internal cache. β°
The first TIME value specifies how long to keep found entries in the cache. The second TIME value specifies how long to remember that a particular entry was not found. If the second parameter is absent, it's assumed to be the same as the first.
Time values are written as a number followed by an s for seconds, m for minutes, h for hours or d for days. Use 0 or off to disable the cache. β¨
Currently, the only cache that's supported is the dn2uid cache β it's the one that remembers DN-to-username lookups, which is exactly what gets used when the member attribute comes into play. Default time value for this cache? 15m. slay. β±οΈβ¨
πΊοΈ SUPPORTED MAPS π
okay so these are the maps that are supported, bestie. up in the options we just went through, they get referred to as MAP. here's the whole roster:
alias[es]β mail aliases. β οΈ heads up though: most mail servers do not use the NSS interface when they want mail aliases β they just go read/etc/aliasesthemselves. not their problem, ig.ether[s]β ethernet numbers, aka mac addresses. π¦groupβ posix groups. πhost[s]β host names. πΈnetgroupβ host and user groups, used for access control. πnetwork[s]β network numbers. πpasswdβ posix users. πprotocol[s]β protocol definitions, same vibe as what's in/etc/protocols. π§rpcβ remote procedure call names and numbers. β¨service[s]β network service names and numbers. πshadowβ shadow user password information. π€«
β¨ ATTRIBUTE MAPPING EXPRESSIONS β¨
so for some attributes you can use a mapping expression to build the resulting value. currently this is only possible for attributes that don't need to be used in search filters β no cap. the expressions are a subset of the double quoted string expressions from the Bourne (POSIX) shell. but instead of variable substitution, what happens is attribute lookups on the current entry, and then the attribute value gets substituted in. here's everything that's supported:
"${attr}"(or"$attr"for short) β will substitute the value of the attribute. π"${attr:-word}"β (use default) will substitute the value of the attribute, or, if the attribute is not set or is empty, substitute word instead."${attr:+word}"β (use alternative) will substitute word if the attribute is set, otherwise it substitutes the empty string."${attr:offset:length}"β will substitutelengthcharacters (actually bytes, fr) starting from positionoffset(and offset is counted starting at zero). the substituted string gets truncated if it's too long; in particular it can be of length zero (iflengthis zero, or ifoffsetfalls out of the original string). π"${attr#word}"β remove the shortest possible match of word from the left of the attribute value."${attr##word}"β remove the longest possible match of word from the left of the attribute value (pynslcd only)."${attr%word}"β remove the shortest possible match of word from the right of the attribute value (pynslcd only)."${attr%%word}"β remove the longest possible match of word from the right of the attribute value (pynslcd only).
lowkey important: only the#matching expression is supported innslcd, and only with the?wildcard symbol. thepynslcdimplementation supports full matching. π
Quote ("), dollar ($) and backslash (\) characters should be escaped with a backslash (\). π«Ά
The expressions get inspected so the appropriate attributes can be automatically fetched from LDAP. and now some examples to demonstrate how these expressions may be used in attribute mapping:
map shadow shadowFlag "${shadowFlag:-0}"
use the shadowFlag attribute, using the value 0 as default.
map passd homeDirectory "${homeDirectory:-/home/$uid}"
use the uid attribute to build a homeDirectory value if that attribute is missing.
map shadow shadowExpire "${isDisabled:+100}"
if the isDisabled attribute is set, return 100, otherwise leave the value empty.
map shadow userPassword "${userPassword#{crypt\}}"
strip the {crypt} prefix from the userPassword attribute, returning the raw hash value. π
π FILES π
/etc/nslcd.confβ the main configuration file. this is the one. π/etc/nsswitch.confβ Name Service Switch configuration file.
π SEE ALSO π
π AUTHOR π
This manual was written by Arthur de Jong <arthur@arthurdejong.org> and is based on the nss_ldap(5) manual developed by PADL Software Pty Ltd. iconic honestly π«Ά
and that's a wrap bestie!! π this was Version 0.9.13, dated Feb 2025, and the page is nslcd.conf(5). go configure ur LDAP, u got this. slay β¨πππ¦πΈπ
π¦ where this page comes from
- arch rolling: nss-pam-ldapd 0.9.13-1 Β· LGPL2.1
- debian trixie: nslcd 0.9.13-1
- debian trixie: pynslcd 0.9.13-1
- nixos 26.05: nss-pam-ldapd 0.9.13
- nixpkgs unstable: nss-pam-ldapd 0.9.13
- ubuntu questing: nslcd 0.9.13-1
- ubuntu questing: nslcd 0.9.13-1ubuntu0.1
- ubuntu questing: pynslcd 0.9.13-1
- ubuntu questing: pynslcd 0.9.13-1ubuntu0.1
- ubuntu resolute: nslcd 0.9.13-2ubuntu2
- ubuntu resolute: pynslcd 0.9.13-2ubuntu2
- ubuntu stonking: nslcd 0.9.13-2ubuntu2
- ubuntu stonking: pynslcd 0.9.13-2ubuntu2
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms