From a8bbc5198faa16201b42f83f638a46fa19814b19 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Thu, 8 Aug 2013 17:32:18 -0400 Subject: Handle binds to compat entries without "uid"s Use a dummy user name if the one we get passed is NULL, which happens when the bind target entry doesn't contain a "uid" attribute. Try to avoid a timing attack by calling into PAM anyway. Switch to just logging the detailed error information, and telling the client nothing. --- src/back-sch-pam.c | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) (limited to 'src/back-sch-pam.c') diff --git a/src/back-sch-pam.c b/src/back-sch-pam.c index 9e9b085..84f982b 100644 --- a/src/back-sch-pam.c +++ b/src/back-sch-pam.c @@ -57,6 +57,8 @@ #include +#include "plugin.h" + /* for third arg to pam_start */ struct conv_data { Slapi_PBlock *pb; @@ -147,8 +149,13 @@ map_pam_error(Slapi_PBlock *pb, const char *user, const char *binddn, int rc, int pw_response_requested, pam_handle_t *pamh, char **errmsg, int *retcode) { - *errmsg = PR_smprintf("PAM error for user \"%s\" (bind DN \"%s\"): %s", - user, binddn, pam_strerror(pamh, rc)); + if (user != NULL) { + *errmsg = PR_smprintf("PAM error for user \"%s\" (bind DN \"%s\"): %s", + user, binddn, pam_strerror(pamh, rc)); + } else { + *errmsg = PR_smprintf("PAM error for invalid user (bind DN \"%s\"): %s", + binddn, pam_strerror(pamh, rc)); + } switch (rc) { case PAM_USER_UNKNOWN: *retcode = LDAP_NO_SUCH_OBJECT; @@ -199,7 +206,9 @@ backend_sch_do_pam_auth(Slapi_PBlock *pb, const char *username) struct pam_conv conv; int pw_response_requested = 0; char *errmsg = NULL; + struct plugin_state *state; + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); slapi_pblock_get(pb, SLAPI_PWPOLICY, &pw_response_requested); slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &bindsdn); if (NULL == bindsdn) { @@ -211,12 +220,16 @@ backend_sch_do_pam_auth(Slapi_PBlock *pb, const char *username) memset(&conv_data, 0, sizeof(conv_data)); conv_data.pb = pb; - conv_data.user = username; + if ((username == NULL) || (strlen(username) == 0)) { + conv_data.user = "(schema compat plugin invalid bind uid)"; + } else { + conv_data.user = username; + } memset(&conv, 0, sizeof(conv)); conv.conv = &converse; conv.appdata_ptr = &conv_data; - rc = pam_start(DEFAULT_PAM_SERVICE, username, &conv, &pamh); + rc = pam_start(DEFAULT_PAM_SERVICE, conv_data.user, &conv, &pamh); if (rc == PAM_SUCCESS) { rc = pam_authenticate(pamh, PAM_SILENT); if (rc != PAM_SUCCESS) { @@ -237,19 +250,30 @@ backend_sch_do_pam_auth(Slapi_PBlock *pb, const char *username) done: if ((retcode == LDAP_SUCCESS) && (rc != PAM_SUCCESS)) { - errmsg = PR_smprintf("PAM error for user \"%s\" " - "(bind DN \"%s\"): %s", - username, binddn, pam_strerror(pamh, rc)); + if (username != NULL) { + errmsg = PR_smprintf("PAM error for user \"%s\" " + "(bind DN \"%s\"): %s", + username, binddn, pam_strerror(pamh, rc)); + } else { + errmsg = PR_smprintf("PAM error for invalid user " + "(bind DN \"%s\"): %s", + binddn, pam_strerror(pamh, rc)); + } retcode = LDAP_OPERATIONS_ERROR; } - if (retcode != LDAP_SUCCESS) { - slapi_send_ldap_result(pb, retcode, NULL, errmsg, 0, NULL); - } - + /* Log the diagnostic information for the administrator. */ + slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id, + "%s\n", errmsg); if (errmsg != NULL) { PR_smprintf_free(errmsg); } + /* The client gets a less useful error. */ + if (retcode != LDAP_SUCCESS) { + slapi_send_ldap_result(pb, retcode, NULL, NULL, 0, NULL); + } + + return retcode; } -- cgit