Arthur de Jong <adej...@debian.org> writes: > This sounds like a good idea. I would welcome a patch for that. Thanks a > lot for working on this.
Here is the changelog, patch based on latest svn (revno:1161): * debian/nslcd.templates: Add nslcd/ldap-auth-type and SASL templates. * debian/nslcd.config: Manage SASL questions, bindpw is shared between binddn and sasl, it's asked just after binddn or authcid, this complexify a little the switch case. * debian/nslcd.postinst: Manage SASL options, binddn and SASL disable each other. Use 2 functions simple_auth and sasl_auth to simplify the configuration. NB: I added an SASL auto mechanism but I'm not sure if it's useful, feel free to remove it, it's the default mech in the template. Regards. -- Daniel Dehennin Récupérer ma clef GPG: gpg --keyserver pgp.mit.edu --recv-keys 0x6A2540D1
=== modified file 'debian/nslcd.config' --- debian/nslcd.config 2010-07-03 14:18:17 +0000 +++ debian/nslcd.config 2010-07-14 11:19:53 +0000 @@ -98,12 +98,35 @@ searchbase=`sed -n 's/^base[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile" | tail -n 1` [ -n "$searchbase" ] && db_set nslcd/ldap-base "$searchbase" fi - # find binddn - db_get nslcd/ldap-binddn - if [ -z "$RET" ] + # find authentication type + # first none, second binddn, last SASL + db_get nslcd/ldap-auth-type + authtype="$RET" + if [ -z "$authtype" ] then - binddn=`sed -n 's/^binddn[[:space:]]*//ip' "$cfgfile" | tail -n 1` - db_set nslcd/ldap-binddn "$binddn" + db_set nslcd/ldap-auth-type "none" + # find binddn + db_get nslcd/ldap-binddn + if [ -z "$RET" ] + then + binddn=`sed -n 's/^binddn[[:space:]]*//ip' "$cfgfile" | tail -n 1` + if [ -n "$binddn" ] + then + db_set nslcd/ldap-auth-type "simple" + db_set nslcd/ldap-binddn "$binddn" + fi + fi + # check SASL mechanism + db_get nslcd/ldap-sasl-mech + if [ -z "$RET" ] + then + saslmech=`sed -n 's/^SASL_MECH[[:space:]]*\([^//[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile"` + if [ -n "$saslmech" ] + then + db_set nslcd/ldap-auth-type "SASL" + db_set nslcd/ldap-sasl-mech "$saslmech" + fi + fi fi # find bindpw db_get nslcd/ldap-bindpw @@ -133,6 +156,34 @@ reqcert=`echo "$reqcert" | tr 'A-Z' 'a-z' | sed 's/^no$/never/;s/^yes$/demand/'` [ -n "$reqcert" ] && db_set nslcd/ldap-reqcert "$reqcert" fi + # check SASL realm + db_get nslcd/ldap-sasl-realm + if [ -z "$RET" ] + then + saslrealm=`sed -n 's/^SASL_REALM[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile"` + [ -n "$saslrealm" ] && db_set nslcd/ldap-sasl-realm "$saslrealm" + fi + # check SASL authentication ID + db_get nslcd/ldap-sasl-authcid + if [ -z "$RET" ] + then + saslauthcid=`sed -n 's/^SASL_AUTHCID[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile"` + [ -n "$saslauthcid" ] && db_set nslcd/ldap-sasl-authcid "$saslauthcid" + fi + # check SASL authorization ID + db_get nslcd/ldap-sasl-authzid + if [ -z "$RET" ] + then + saslauthzid=`sed -n 's/^SASL_AUTHZID[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile"` + [ -n "$saslauthzid" ] && db_set nslcd/ldap-sasl-authzid "$saslauthzid" + fi + # check SASL security properties + db_get nslcd/ldap-sasl-secprops + if [ -z "$RET" ] + then + saslsecprops=`sed -n 's/^SASL_SECPROPS[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile"` + [ -n "$saslsecprops" ] && db_set nslcd/ldap-sasl-secprops "$saslsecprops" + fi # we're done return 0 } @@ -144,9 +195,19 @@ # clear settings to pick up valus from configfile db_set nslcd/ldap-uris "" db_set nslcd/ldap-base "" - db_set nslcd/ldap-binddn "" db_set nslcd/ldap-bindpw "" db_set nslcd/ldap-starttls "" + + # Do not clear the following settings + # they are manage based on auth-type + # db_set nslcd/ldap-auth-type "" + # db_set nslcd/ldap-binddn "" + # db_set nslcd/ldap-sasl-mech "" + # db_set nslcd/ldap-sasl-realm "" + # db_set nslcd/ldap-sasl-authcid "" + # db_set nslcd/ldap-sasl-authzid "" + # db_set nslcd/ldap-sasl-secprops "" + # parse current configuration parsecfg "$CONFFILE" else @@ -167,6 +228,14 @@ db_get nslcd/ldap-starttls [ -z "$RET" ] && db_set nslcd/ldap-starttls "false" +# fallback for krb5_keytab +db_get nslcd/ldap-sasl-krb5-keytab +[ -z "$RET" ] && db_set nslcd/ldap-sasl-krb5-keytab "/etc/krb5.keytab" + +# fallback for krb5_ccname +db_get nslcd/ldap-sasl-krb5-ccname +[ -z "$RET" ] && db_set nslcd/ldap-sasl-krb5-ccname "/var/run/nslcd/nslcd.tkt" + # # This is the second part of the script. In this part the configurable # settings will be presented to the user for approval. The postinst @@ -182,31 +251,122 @@ db_input high nslcd/ldap-uris || true db_input high nslcd/ldap-base || true # ask the questions, go to the next question or exit - state="binddn" + state="authtype" db_go || exit 1 # TODO: add error checking on options ;; + authtype) + # ask for authentication type + db_input medium nslcd/ldap-auth-type || true + # ask the question, go to the next question or back + if ! db_go + then + state="server" + else + db_get nslcd/ldap-auth-type + case "$RET" in + none) + state="starttls" + ;; + simple) + state="binddn" + ;; + SASL) + state="saslmech" + ;; + *) + exit 1 + ;; + esac + fi + ;; binddn) # ask for login information db_input medium nslcd/ldap-binddn || true # ask the question, go to the next question or back state="bindpw" - db_go || state="server" + if ! db_go + then + state="authtype" + else + # null binddn is not allowed + db_get nslcd/ldap-binddn + [ -z "$RET" ] && state="binddn" + fi + ;; + saslmech) + db_input medium nslcd/ldap-sasl-mech || true + # ask the question, go to the next question or back + state="saslrealm" + db_go || state="authtype" + ;; + saslrealm) + db_input medium nslcd/ldap-sasl-realm || true + # ask the question, go to the next question or back + state="saslauthcid" + db_go || state="saslmech" + ;; + saslauthcid) + db_get nslcd/ldap-sasl-mech + if [ "$RET" != "GSSAPI" ] + then + db_input medium nslcd/ldap-sasl-authcid || true + # ask the question, go to the next question or back + state="bindpw" + db_go || state="saslrealm" + else + # ask the question, go to the next question or back + state="saslauthzid" + fi + ;; + saslauthzid) + db_input medium nslcd/ldap-sasl-authzid || true + # ask the question, go to the next question or back + state="saslsecprops" + db_get nslcd/ldap-sasl-mech + if [ "$RET" != "GSSAPI" ] + then + prev="saslauthcid" + else + prev="saslrealm" + fi + db_go || state="$prev" + ;; + saslsecprops) + db_input medium nslcd/ldap-sasl-secprops || true + # ask the question, go to the next question or back + state="starttls" + db_go || state="saslauthzid" ;; bindpw) - # only ask question if we have a binddn - db_get nslcd/ldap-binddn - if [ -n "$RET" ] + # check if password is required + db_get nslcd/ldap-auth-type + authtype="$RET" + if [ -n "$authtype" ] || [ "$authtype" != "none" ] then - # ask for login information + # ask for password information db_input medium nslcd/ldap-bindpw || true - else - # clear password - db_set nslcd/ldap-bindpw "" fi # ask the question, go to the next question or back - state="starttls" - db_go || state="binddn" + case "$authtype" in + none) + state="starttls" + prev="authtype" + ;; + simple) + state="starttls" + prev="binddn" + ;; + SASL) + state="saslauthzid" + prev="saslauthcid" + ;; + *) + state="starttls" + prev="authtype" + ;; + esac + db_go || state="$prev" ;; starttls) # check if ldaps:// URL's are used @@ -222,7 +382,21 @@ fi # ask the question, go to the next question or back state="reqcert" - db_go || state="bindpw" + # Check authentication type + db_get nslcd/ldap-auth-type + authtype="$RET" + case "$authtype" in + none) + prev="authtype" + ;; + simple|SASL) + prev="bindpw" + ;; + *) + prev="authtype" + ;; + esac + db_go || state="$prev" ;; reqcert) # check if ldaps:// URL's are used @@ -237,8 +411,38 @@ db_input high nslcd/ldap-reqcert || true fi # ask the question, go to the next question or back + state="krb5keytab" + db_go || state="starttls" + ;; + krb5keytab) + # Check authentication type + db_get nslcd/ldap-auth-type + authtype="$RET" + # check if SASL mechanism is GSSAPI + db_get nslcd/ldap-sasl-mech + saslmech="$RET" + if [ "$authtype" = "SASL" ] && [ "$saslmech" = "GSSAPI" ] + then + db_input low nslcd/ldap-sasl-krb5-keytab || true + fi + # ask the question, go to the next question or back + state="krb5ccname" + db_go || state="reqcert" + ;; + krb5ccname) + # Check authentication type + db_get nslcd/ldap-auth-type + authtype="$RET" + # check if SASL mechanism is GSSAPI + db_get nslcd/ldap-sasl-mech + saslmech="$RET" + if [ "$authtype" = "SASL" ] && [ "$saslmech" = "GSSAPI" ] + then + db_input low nslcd/ldap-sasl-krb5-ccname || true + fi + # ask the question, go to the next question or back state="done" - db_go || state="bindpw" + db_go || state="krb5keytab" ;; esac done === modified file 'debian/nslcd.postinst' --- debian/nslcd.postinst 2010-05-09 09:39:45 +0000 +++ debian/nslcd.postinst 2010-07-14 11:08:13 +0000 @@ -4,6 +4,7 @@ CONFFILE="/etc/nslcd.conf" OCONFFILE="/etc/nss-ldapd.conf" +DEFAULCONFFILE="/etc/default/nslcd" # set an option in the configuration file to the specified value cfg_set() @@ -135,6 +136,158 @@ return 0 } +simple_auth() +{ + case "$1" in + enable) + # set bind dn/pw + db_get nslcd/ldap-binddn + if [ -n "$RET" ] + then + cfg_set binddn "$RET" + db_get nslcd/ldap-bindpw + if [ -n "$RET" ] + then + cfg_set bindpw "$RET" + else + # no bindpw set + if grep -i -q "^bindpw " $CONFFILE + then + cfg_set bindpw "*removed*" + cfg_disable bindpw + cfg_disable binddn + fi + fi + else + # no binddn/pw, disable options + cfg_disable binddn + if grep -i -q "^bindpw " $CONFFILE + then + cfg_set bindpw "*removed*" + cfg_disable bindpw + fi + fi + ;; + disable) + # Password must be hidden + cfg_set bindpw "*removed*" + for simpleitem in binddn bindpw + do + if grep -qi "^$simpleitem" $CONFFILE + then + cfg_disable $simpleitem + fi + done + ;; + *) + # Should not happen + exit 1 + ;; + esac +} + +sasl_auth() +{ + case "$1" in + enable) + # set SASL options + db_get nslcd/ldap-sasl-mech + if [ -n "$RET" ] + then + saslmech="$RET" + # RFC4313 if SASL, binddn should be disabled + cfg_disable binddn + cfg_set sasl_mech "$saslmech" + db_get nslcd/ldap-sasl-realm + if [ -n "$RET" ] + then + cfg_set sasl_realm "$RET" + else + cfg_disable sasl_realm + fi + db_get nslcd/ldap-sasl-authzid + if [ -n "$RET" ] + then + cfg_set sasl_authzid "$RET" + else + cfg_disable sasl_authzid + fi + db_get nslcd/ldap-sasl-secprops + if [ -n "$RET" ] + then + cfg_set sasl_secprops "$RET" + else + cfg_disable sasl_secprops + fi + + # Disable krb5_ccname, we don't know what was the mech before + grep -qi "^krb5_ccname" $CONFFILE && cfg_disable krb5_ccname + # mech specific setup + case "$saslmech" in + GSSAPI) + # TODO handle nslcd/ldap-sasl-krb5-keytab in /etc/default/nslcd + # Set kerberos credential cache name + db_get nslcd/ldap-sasl-krb5-ccname + if [ -n "$RET" ] + then + cfg_set krb5_ccname "$RET" + else + # default value + cfg_set krb5_ccname "/var/run/nslcd/nslcd.tkt" + fi + ;; + LOGIN|PLAIN|CRAM-MD5|DIGEST-MD5) + # FIXME login/password only for those? + # authcid must be set + db_get nslcd/ldap-sasl-authcid + saslauthcid="$RET" + if [ -n "$saslauthcid" ] + then + # bindpw must be set + db_get nslcd/ldap-bindpw + bindpw="$RET" + if [ -n "$bindpw" ] + then + cfg_set sasl_authcid "$saslauthcid" + cfg_set bindpw "$bindpw" + else + cfg_disable sasl_authcid "$saslauthcid" + cfg_set bindpw "*removed*" + cfg_disable bindpw "$bindpw" + fi + fi + ;; + esac + else + # Password must be hidden + cfg_set bindpw "*removed*" + for saslitem in sasl_mech sasl_realm sasl_authcid sasl_authzid sasl_secprops krb5_ccname + do + if grep -qi "^$saslitem" $CONFFILE + then + cfg_disable $saslitem + fi + done + fi + ;; + disable) + # Password must be hidden + cfg_set bindpw "*removed*" + for saslitem in bindpw sasl_mech sasl_realm sasl_authcid sasl_authzid sasl_secprops krb5_ccname + do + if grep -qi "^$saslitem" $CONFFILE + then + cfg_disable $saslitem + fi + done + ;; + *) + # Should not happen + exit 1 + ;; + esac +} + # real functions begin here if [ "$1" = "configure" ] then @@ -173,34 +326,24 @@ else cfg_disable base fi - # set bind dn/pw - db_get nslcd/ldap-binddn - if [ -n "$RET" ] - then - cfg_set binddn "$RET" - db_get nslcd/ldap-bindpw - if [ -n "$RET" ] - then - cfg_set bindpw "$RET" - else - # no bindpw set - if grep -i -q "^bindpw " $CONFFILE - then - cfg_set bindpw "*removed*" - cfg_disable bindpw - fi - fi - else - # no binddn/pw, disable options - cfg_disable binddn - if grep -i -q "^bindpw " $CONFFILE - then - cfg_set bindpw "*removed*" - cfg_disable bindpw - fi - fi - # remove password from database - db_set nslcd/ldap-bindpw "" + # authentication + db_get nslcd/ldap-auth-type + authtype="$RET" + case "$authtype" in + simple) + sasl_auth disable + simple_auth enable + ;; + SASL) + simple_auth disable + sasl_auth enable + ;; + none) + sasl_auth disable + simple_auth disable + ;; + esac + # set ssl option db_get nslcd/ldap-starttls if [ "$RET" = "true" ] @@ -221,6 +364,8 @@ # clear debconf value so that this option is only set if the question is asked db_set nslcd/ldap-reqcert "" fi + # remove password from database + db_set nslcd/ldap-bindpw "" # we're done db_stop # rename reconnect_maxsleeptime to reconnect_retrytime === modified file 'debian/nslcd.templates' --- debian/nslcd.templates 2009-08-31 20:46:01 +0000 +++ debian/nslcd.templates 2010-07-14 10:54:13 +0000 @@ -25,11 +25,15 @@ the account that will be used here. Leave it empty otherwise. . This value should be specified as a DN (distinguished name). + . + Leave empty for Simple Authentication and Security Layer (SASL) + authentication. Template: nslcd/ldap-bindpw Type: password _Description: LDAP user password: - Enter the password that will be used to log in to the LDAP database. + Enter the password that will be used to log in to the LDAP database + with simple binddn or SASL authentications. Template: nslcd/ldap-starttls Type: boolean @@ -52,3 +56,130 @@ * demand: a certificate will be requested, required, and checked. If certificate checking is enabled, at least one of the tls_cacertdir or tls_cacertfile options must be put in /etc/nslcd.conf. + +Template: nslcd/ldap-auth-type +Type: select +__Choices: none, simple, SASL +_Default: none +_Description: LDAP authentication to use: + LDAP bind can be performed anonymously or authenticated with either a + simple binddn/password or the Simple Authentication and Security Layer. + . + You can choose in the following list: + * none: no authentication. + * simple: simple clear text binddn/password. + * SASL: one of the Simple Authentication and Security Layer + mechanisms. + . + Clear text authentication methods should be use with Transport Layer + security (TLS) enabled. + +Template: nslcd/ldap-sasl-mech +Type: select +__Choices: auto, LOGIN, PLAIN, NTLM, CRAM-MD5, DIGEST-MD5, GSSAPI, OTP +Default: auto +_Description: SASL mechanism to use: + Simple Authentication and Security Layer is a challange based + protocol. + . + You can choose in the following list: + * auto: autonegociation, you can restrict autonegociation with + security properties. + * LOGIN: a simple cleartext password mechanism (need SASL SECPROPS + none or noanonymous). + * PLAIN: a simple cleartext password mechanism. PLAIN obsoleted the + LOGIN mechanism (need SASL SECPROPS none or noanonymous). + * NTLM: an NT LAN Manager authentication mechanism. + * CRAM-MD5: a simple challenge-response scheme based on HMAC-MD5 + (need SASL SECPROPS minssf=0). + * DIGEST-MD5: HTTP Digest compatible challenge-response scheme based + upon MD5. DIGEST-MD5 offers a data security layer. + * GSSAPI: Generic Security Services Application Program Interface + (Kerberos, needs libsasl2-modules-gssapi-mit or + libsasl2-modules-gssapi-heimdal) + * OTP: a One Time Password mechanism. OTP obsoleted the SKEY + mechanism (untested, needs libsasl2-modules-otp). + . + Clear text authentication methods should be use with Transport Layer + security (TLS) enabled. + +Template: nslcd/ldap-sasl-realm +Type: string +_Description: SASL realm: + Simple Authentication and Security Layer realm to use for LDAP + authentication. + . + If empty, the GSSAPI mechanism will use informations from the kerberos + credential cache. Others may need @<REALM> suffixing sasl_authcid and + sasl_authzid. + . + The realm is appended to authentication and authorisation identities. + +Template: nslcd/ldap-sasl-authcid +Type: string +_Description: SASL authentication identity: + Simple Authentication and Security Layer identity. + . + This is the login used in LOGIN, PLAIN, CRAM-MD5 and DIGEST-MD5 mechanisms. + +Template: nslcd/ldap-sasl-authzid +Type: string +_Description: SASL proxy authorisation identity: + Simple Authentication and Security Layer proxy authorisation + identity. + . + This is the object in the name of witch the LDAP request are + done. They should have a DN syntax. + +Template: nslcd/ldap-sasl-secprops +Type: string +_Description: Cyrus SASL security properties: + The Cyrus Simple Authentication and Security Layer library provides + the following security properties: + * none: (without any other properties) causes the properties + defaults ("noanonymous,noplain") to be cleared. + Use it to enable ANONYMOUS and LOGIN and PLAIN. + * noplain: disables mechanisms susceptible to simple passive + attacks. Use it to enable ANONYMOUS. + * noactive: disables mechanisms susceptible to active attacks. + * nodict: disables mechanisms susceptible to passive dictionary + attacks. + * noanonymous: disables mechanisms which support anonymous login, + can be used to enable LOGIN and PLAIN. + * forwardsec: requires forward secrecy between sessions. + * passcred: requires mechanisms which pass client credentials (and + allows mechanisms which can pass credentials to do so). + * minssf=<factor>: specifies the minimum acceptable security strength + factor as an integer approximating the effective + key length used for encryption. 0 (zero) implies + no protection, 1 implies integrity protection + only, 56 allows DES or other weak ciphers, 112 + allows triple DES and other strong ciphers, 128 + allows RC4, Blowfish and other modern strong + ciphers. The default is 0. + * maxssf=<factor>: specifies the maximum acceptable security + strength factor as an integer (see minssf + description). The default is INT_MAX. + * maxbufsize=<factor>: specifies the maximum security layer receive + buffer size allowed. 0 disables security + layers. The default is 65536. + +Template: nslcd/ldap-sasl-krb5-keytab +Type: string +Default: /etc/krb5.keytab +_Description: Kerberos keytab file path: + The GSSAPI/Kerberos authentication mechanism needs a keytab file. + . + The keytab file is used by k5start to create the credential cache + file. + . + This option is not used for now, edit /etc/default/nslcd directly. + +Template: nslcd/ldap-sasl-krb5-ccname +Type: string +Default: /var/run/nslcd/nslcd.tkt +_Description: Kerberos credential cache file path: + The GSSAPI/Kerberos authentication mechanism needs a credential cache + file. + . + The cache file is initialised and maintained by k5start.
pgpvROnz7JvBK.pgp
Description: PGP signature