diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-05-18 18:22:52 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-05-18 18:22:52 +0300 |
commit | 29916f8fc75612a821251e35f627d53ea60f8e57 (patch) | |
tree | 97385f014df95c92d067050c33e6899f2711cb08 | |
parent | 8c3fca619ba1cd369f60121b9d74c2bdc9a64d5a (diff) | |
download | pam-modules-29916f8fc75612a821251e35f627d53ea60f8e57.tar.gz pam-modules-29916f8fc75612a821251e35f627d53ea60f8e57.tar.bz2 |
Enable fine-grained control over TLS.
* doc/pam-modules.texi: Document new tls values.
* pam_ldaphome/pam_ldaphome.c (ldap_connect): The tls
keyword is tri-state. Allowed values are: "yes", "no"
and "only".
-rw-r--r-- | doc/pam-modules.texi | 9 | ||||
-rw-r--r-- | pam_ldaphome/pam_ldaphome.c | 46 |
2 files changed, 45 insertions, 10 deletions
diff --git a/doc/pam-modules.texi b/doc/pam-modules.texi index 27e05ba..cf29180 100644 --- a/doc/pam-modules.texi +++ b/doc/pam-modules.texi @@ -1214,8 +1214,13 @@ If @code{binddn} statement is used, this statement supplies the password for simple authentication. @end deffn -@deffn {pam_ldaphome config} tls bool -If @var{bool} is @samp{yes}, enables TLS. +@deffn {pam_ldaphome config} tls val +Controls whether TLS is desired or required. If @var{val} is +@samp{no} (the default), TLS will not be used. If it is @samp{yes}, +the module will issue the @samp{StartTLS} command, but will continue +anyway if it fails. Finally, if @var{val} is @samp{only}, TLS is +mandatory, and the module will not establish LDAP connection unless +@samp{StartTLS} succeeds. @end deffn @deffn {pam_ldaphome config} min-uid n diff --git a/pam_ldaphome/pam_ldaphome.c b/pam_ldaphome/pam_ldaphome.c index 0b9fe7a..2a0a19b 100644 --- a/pam_ldaphome/pam_ldaphome.c +++ b/pam_ldaphome/pam_ldaphome.c @@ -298,6 +298,8 @@ parse_ldap_uri(const char *uri) return ldapuri; } +static void ldap_unbind(LDAP *ld); + static LDAP * ldap_connect(struct gray_env *env) { @@ -346,17 +348,45 @@ ldap_connect(struct gray_env *env) val = gray_env_get(env, "tls"); - if (val && gray_boolean_true_p(val)) { - rc = ldap_start_tls_s(ld, NULL, NULL); - if (rc != LDAP_SUCCESS) { + if (val) { + enum { tls_no, tls_yes, tls_only } tls; + + if (strcmp(val, "yes") == 0) + tls = tls_yes; + else if (strcmp(val, "no") == 0) + tls = tls_no; + else if (strcmp(val, "only") == 0) + tls = tls_only; + else { _pam_log(LOG_ERR, - "ldap_start_tls failed: %s", - ldap_err2string(rc)); - /* try to continue anyway, to avoid memory - leek (ld not being freed) */ + "wrong value for tls statement, " + "assuming \"no\""); + tls = tls_no; } - } + if (tls != tls_no) { + rc = ldap_start_tls_s(ld, NULL, NULL); + if (rc != LDAP_SUCCESS) { + char *msg = NULL; + ldap_get_option(ld, + LDAP_OPT_DIAGNOSTIC_MESSAGE, + (void*)&msg); + _pam_log(LOG_ERR, + "ldap_start_tls failed: %s", + ldap_err2string(rc)); + _pam_log(LOG_ERR, + "TLS diagnostics: %s", msg); + ldap_memfree(msg); + + if (tls == tls_only) { + ldap_unbind(ld); + return NULL; + } + /* try to continue anyway */ + } + } + } + if (get_intval(env, "ldap-version", 10, &lval) == 0) { switch (lval) { case 2: |