aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-05-18 18:22:52 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-05-18 18:22:52 +0300
commit29916f8fc75612a821251e35f627d53ea60f8e57 (patch)
tree97385f014df95c92d067050c33e6899f2711cb08
parent8c3fca619ba1cd369f60121b9d74c2bdc9a64d5a (diff)
downloadpam-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.texi9
-rw-r--r--pam_ldaphome/pam_ldaphome.c46
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:

Return to:

Send suggestions and report system problems to the System administrator.