[SSSD] [PATCH] Allow more libldap debugging
Jakub Hrozek
jhrozek at redhat.com
Wed Aug 10 09:28:13 UTC 2011
On Wed, Aug 10, 2011 at 10:14:14AM +0200, Jan Zelený wrote:
> > This patch should not be pushed to master, but I would like to get it
> > reviewed anyway.
> >
> > It should be used to provide a custom build for users experiencing cases
> > where ldap_search_ext would block (c.f.
> > https://bugzilla.redhat.com/show_bug.cgi?id=728343)
> >
> > For example:
> > export SSSD_DEBUG_LDAP_SEARCH="0xffff"
> > would set LDAP_DEBUG_ANY
> >
> > The attached patch applies cleanly on the RHEL6.1 branch. I also have a
> > version that applies on master/1.5 if needed.
>
> I have three things:
> On line 98 you close the original stderr - this is not a problem, but it is
> redundant
>
> On line 162 you are using strtol and testing that it did not fail. Please
> consider two possibilities that you haven't considered in your patch:
> - the function did not fail, but non-zero value remains in errno from previous
> program run
> - the env. variable SSSD_DEBUG_LDAP_SEARCH contains empty string (I'm not sure
> whether it is possible)
>
> Other than that the patch looks fine.
>
> Jan
Thanks, a new patch is attached.
-------------- next part --------------
>From a564a6ce59a1fc7c2a1bd21b4c2cce738a60bba0 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
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
More information about the sssd-devel
mailing list