>From a564a6ce59a1fc7c2a1bd21b4c2cce738a60bba0 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 9 Aug 2011 14:13:14 +0200 Subject: [PATCH] Allow more libldap debugging When the user exports an openldap-compatible debug level in the SSSD_DEBUG_LDAP_SEARCH environment variable, it would be used for the duration of ldap_search_ext call and reset afterwards. --- src/providers/ldap/sdap_async.c | 12 ++++++ src/util/debug.c | 52 ++++++++++++++++++++++++ src/util/sss_ldap.c | 84 ++++++++++++++++++++++++++++++++++++++- src/util/sss_ldap.h | 2 + src/util/util.h | 3 + 5 files changed, 152 insertions(+), 1 deletions(-) diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c index ebd8d48..30aa588 100644 --- a/src/providers/ldap/sdap_async.c +++ b/src/providers/ldap/sdap_async.c @@ -755,6 +755,8 @@ struct sdap_get_generic_state { size_t reply_max; size_t reply_count; struct sysdb_attrs **reply; + + int old_ldap_debug; }; static errno_t add_to_reply(struct sdap_get_generic_state *state, @@ -800,6 +802,7 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, state->reply_max = 0; state->reply_count = 0; state->reply = NULL; + state->old_ldap_debug = 0; DEBUG(6, ("calling ldap_search_ext with [%s][%s].\n", state->filter, state->search_base)); @@ -813,6 +816,12 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, } } + ret = sss_ldap_set_debug(&state->old_ldap_debug); + if (ret != EOK) { + DEBUG(2, ("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), @@ -853,6 +862,7 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, return req; fail: + sss_ldap_reset_debug(state->old_ldap_debug); tevent_req_error(req, ret); tevent_req_post(req, ev); return req; @@ -871,6 +881,8 @@ static void sdap_get_generic_done(struct sdap_op *op, int result; int ret; + sss_ldap_reset_debug(state->old_ldap_debug); + if (error) { tevent_req_error(req, error); return; diff --git a/src/util/debug.c b/src/util/debug.c index 1b78eba..156a93e 100644 --- a/src/util/debug.c +++ b/src/util/debug.c @@ -194,3 +194,55 @@ int rotate_debug_files(void) return open_debug_file(); } + +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; + } + + new_stderr = freopen(logpath, "a", stderr); + if (!new_stderr) { + ret = errno; + DEBUG(1, ("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(1, ("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 f098e7d..a232eb2 100644 --- a/src/util/sss_ldap.c +++ b/src/util/sss_ldap.c @@ -22,7 +22,7 @@ #include "config.h" #include "util/sss_ldap.h" - +#include "util/util.h" int sss_ldap_control_create(const char *oid, int iscritical, struct berval *value, int dupval, @@ -68,3 +68,85 @@ int sss_ldap_control_create(const char *oid, int iscritical, return LDAP_SUCCESS; #endif } + +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 || *dbg == '\0'){ + DEBUG(7, ("No extra LDAP debugging set\n")); + return EOK; + } + + errno = 0; + new_debug = strtol(dbg, &endptr, 16); + if (errno != 0) { + ret = errno; + DEBUG(1, ("strtol failed on [%s]: [%d][%s].\n", dbg, + ret, strerror(ret))); + return ret; + } + + if (*endptr != '\0') { + DEBUG(1, ("Found additional characters [%s] in debug level" + "[%s].\n", endptr, dbg)); + return EINVAL; + } + + ret = reopen_stderr_for_libldap(NULL); + if (ret != EOK) { + DEBUG(4, ("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(3, ("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(3, ("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(4, ("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(3, ("Could not reset LDAP debugging\n")); + return EIO; + } + + DEBUG(8, ("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 14747df..3ed9005 100644 --- a/src/util/sss_ldap.h +++ b/src/util/sss_ldap.h @@ -26,5 +26,7 @@ int sss_ldap_control_create(const char *oid, int iscritical, struct berval *value, int dupval, LDAPControl **ctrlp); +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 61fe7f6..5a7caed 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -240,6 +240,9 @@ void ldb_debug_messages(void *context, enum ldb_debug_level level, int open_debug_file_ex(const char *filename, FILE **filep); int open_debug_file(void); int rotate_debug_files(void); +int reopen_stderr_for_libldap(const char *filename); +int reopen_stderr_after_libldap(void); + /* From sss_log.c */ #define SSS_LOG_EMERG 0 /* system is unusable */ -- 1.7.6