From 4811057a37549a6ef3a2b04f8bcce8b64d44f581 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 28 Nov 2012 14:16:52 +0100 Subject: Enable libldap debugging --- src/providers/ldap/sdap_async.c | 13 +++++ src/providers/ldap/sdap_async_connection.c | 10 ++++ src/util/debug.c | 52 +++++++++++++++++++ src/util/sss_ldap.c | 82 ++++++++++++++++++++++++++++++ src/util/sss_ldap.h | 3 ++ src/util/util.h | 3 ++ 6 files changed, 163 insertions(+) diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c index 84497b75e..ae1611524 100644 --- a/src/providers/ldap/sdap_async.c +++ b/src/providers/ldap/sdap_async.c @@ -1111,6 +1111,7 @@ struct sdap_get_generic_ext_state { void *cb_data; bool allow_paging; + int old_ldap_debug; }; static errno_t sdap_get_generic_ext_step(struct tevent_req *req); @@ -1274,6 +1275,13 @@ static errno_t sdap_get_generic_ext_step(struct tevent_req *req) state->serverctrls[state->nserverctrls+1] = NULL; } + ret = sss_ldap_set_debug(&state->old_ldap_debug); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Could not set extra LDAP debugging\n")); + /* Not fatal, carry on */ + } + lret = ldap_search_ext(state->sh->ldap, state->search_base, state->scope, state->filter, discard_const(state->attrs), @@ -1314,6 +1322,9 @@ static errno_t sdap_get_generic_ext_step(struct tevent_req *req) } done: + if (ret != EOK) { + sss_ldap_reset_debug(state->old_ldap_debug); + } return ret; } @@ -1333,6 +1344,8 @@ static void sdap_get_generic_ext_done(struct sdap_op *op, LDAPControl **returned_controls = NULL; LDAPControl *page_control; + sss_ldap_reset_debug(state->old_ldap_debug); + if (error) { tevent_req_error(req, error); return; diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c index 20f282e3d..0dfcfc637 100644 --- a/src/providers/ldap/sdap_async_connection.c +++ b/src/providers/ldap/sdap_async_connection.c @@ -70,6 +70,7 @@ struct sdap_connect_state { struct sdap_msg *reply; int result; + int old_ldap_debug; }; static void sdap_sys_connect_done(struct tevent_req *subreq); @@ -129,6 +130,13 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx, goto fail; } + ret = sss_ldap_set_debug(&state->old_ldap_debug); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Could not set extra LDAP debugging\n")); + /* Not fatal, carry on */ + } + tevent_req_set_callback(subreq, sdap_sys_connect_done, req); return req; @@ -425,6 +433,8 @@ int sdap_connect_recv(struct tevent_req *req, struct sdap_connect_state *state = tevent_req_data(req, struct sdap_connect_state); + sss_ldap_reset_debug(state->old_ldap_debug); + TEVENT_REQ_RETURN_ON_ERROR(req); *sh = talloc_steal(memctx, state->sh); diff --git a/src/util/debug.c b/src/util/debug.c index 54fb8011b..305799bdc 100644 --- a/src/util/debug.c +++ b/src/util/debug.c @@ -274,3 +274,55 @@ void talloc_log_fn(const char *message) { DEBUG(SSSDBG_FATAL_FAILURE, (message)); } + +int reopen_stderr_for_libldap(const char *filename) +{ + int ret; + char *logpath; + const char *log_file; + FILE *new_stderr; + TALLOC_CTX *tmp_ctx; + + if (!debug_to_file) return EOK; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) return ENOMEM; + + log_file = filename ? filename : debug_log_file; + + logpath = talloc_asprintf(tmp_ctx, "%s/%s.log", LOG_PATH, log_file); + if (logpath == NULL) { + ret = ENOMEM; + goto done; + } + + fclose(stderr); + new_stderr = freopen(logpath, "a", stderr); + if (!new_stderr) { + ret = errno; + DEBUG(SSSDBG_OP_FAILURE, ("Couldn't reopen stderr to logfile\n")); + goto done; + } + + ret = EOK; +done: + talloc_free(tmp_ctx); + return ret; +} + +int reopen_stderr_after_libldap(void) +{ + FILE *new_stderr; + int ret; + + if (!debug_to_file) return EOK; + + new_stderr = freopen("/dev/null", "a", stderr); + if (!new_stderr) { + ret = errno; + DEBUG(SSSDBG_OP_FAILURE, ("Couldn't reopen stderr to logfile\n")); + return ret; + } + + return EOK; +} diff --git a/src/util/sss_ldap.c b/src/util/sss_ldap.c index 060aacf9e..878ed4a63 100644 --- a/src/util/sss_ldap.c +++ b/src/util/sss_ldap.c @@ -590,3 +590,85 @@ done: talloc_free(filter); return ret; } + +int sss_ldap_set_debug(int *old_debug) +{ + const char *dbg; + static const char dbg_var[] = "SSSD_DEBUG_LDAP_SEARCH"; + int ret; + int new_debug; + int ldap_old_debug; + char *endptr; + + dbg = getenv(dbg_var); + if (!dbg){ + DEBUG(SSSDBG_TRACE_LIBS, ("No extra LDAP debugging set\n")); + return EOK; + } + + errno = 0; + new_debug = strtol(dbg, &endptr, 0); + if (errno != 0) { + ret = errno; + DEBUG(SSSDBG_OP_FAILURE, + ("strtol failed on [%s]: [%d][%s].\n", dbg, ret, strerror(ret))); + return ret; + } + + if (*endptr != '\0') { + DEBUG(SSSDBG_OP_FAILURE, + ("Found additional characters [%s] in debug level [%s].\n", + endptr, dbg)); + return EINVAL; + } + + ret = reopen_stderr_for_libldap(NULL); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not redirect stderr to log file\n")); + return ret; + } + + ret = ldap_get_option(NULL, LDAP_OPT_DEBUG_LEVEL, + &ldap_old_debug); + if (ret != LDAP_OPT_SUCCESS) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not save old LDAP debug level\n")); + return EIO; + } + + DEBUG(8, ("LDAP debug level was %#X setting to %#X\n", + ldap_old_debug, new_debug)); + + ret = ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, + &new_debug); + if (ret != LDAP_OPT_SUCCESS) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set LDAP debugging\n")); + return EIO; + } + + if (old_debug) *old_debug = ldap_old_debug; + + return EOK; +} + +int sss_ldap_reset_debug(int ldap_old_debug) +{ + int ret; + + ret = reopen_stderr_after_libldap(); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + ("Could not redirect stderr back to /dev/null\n")); + return ret; + } + + ret = ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, + &ldap_old_debug); + if (ret != LDAP_SUCCESS) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not reset LDAP debugging\n")); + return EIO; + } + + DEBUG(SSSDBG_TRACE_LIBS, + ("Resetting LDAP debug level to %#X\n", ldap_old_debug)); + return EOK; +} diff --git a/src/util/sss_ldap.h b/src/util/sss_ldap.h index 46829259a..de1cf6a48 100644 --- a/src/util/sss_ldap.h +++ b/src/util/sss_ldap.h @@ -76,4 +76,7 @@ bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx, struct sdap_search_base **search_bases, char **_filter); +int sss_ldap_set_debug(int *old_debug); +int sss_ldap_reset_debug(int ldap_old_debug); + #endif /* __SSS_LDAP_H__ */ diff --git a/src/util/util.h b/src/util/util.h index df1ee3b08..1f269e595 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -67,6 +67,9 @@ int debug_get_level(int old_level); int debug_convert_old_level(int old_level); errno_t set_debug_file_from_fd(const int fd); +int reopen_stderr_for_libldap(const char *filename); +int reopen_stderr_after_libldap(void); + #define SSSDBG_FATAL_FAILURE 0x0010 /* level 0 */ #define SSSDBG_CRIT_FAILURE 0x0020 /* level 1 */ #define SSSDBG_OP_FAILURE 0x0040 /* level 2 */ -- cgit