diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2009-03-20 01:30:36 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2009-03-20 01:30:36 +0100 |
commit | 5fe2b28f45289dc5578cdd536600f0d30a14d820 (patch) | |
tree | 4bdf36d0d4d8bdddcb3d618b4b01839370ed57c3 /source4/lib/ldb | |
parent | ec9aeeab00584f4d3dfe9afb83dc1a77b8463b81 (diff) | |
parent | 3a4638db0351368d3b148bf547546f28fa0b1479 (diff) | |
download | samba-5fe2b28f45289dc5578cdd536600f0d30a14d820.tar.gz samba-5fe2b28f45289dc5578cdd536600f0d30a14d820.tar.bz2 samba-5fe2b28f45289dc5578cdd536600f0d30a14d820.zip |
Merge branch 'master' of git://git.samba.org/samba into minschema
Diffstat (limited to 'source4/lib/ldb')
-rw-r--r-- | source4/lib/ldb/common/ldb.c | 37 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_index.c | 2 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_search.c | 6 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.c | 55 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.h | 7 | ||||
-rwxr-xr-x | source4/lib/ldb/tests/python/ldap.py | 30 | ||||
-rw-r--r-- | source4/lib/ldb/tools/cmdline.h | 1 |
7 files changed, 126 insertions, 12 deletions
diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index f1b28b6819..86ce2069a5 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -32,6 +32,7 @@ * Author: Andrew Tridgell */ +#define TEVENT_DEPRECATED 1 #include "ldb_private.h" static int ldb_context_destructor(void *ptr) @@ -48,6 +49,40 @@ static int ldb_context_destructor(void *ptr) } /* + this is used to catch debug messages from events +*/ +static void ldb_tevent_debug(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); + +static void ldb_tevent_debug(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) +{ + struct ldb_context *ldb = talloc_get_type(context, struct ldb_context); + enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL; + char *s = NULL; + + switch (level) { + case TEVENT_DEBUG_FATAL: + ldb_level = LDB_DEBUG_FATAL; + break; + case TEVENT_DEBUG_ERROR: + ldb_level = LDB_DEBUG_ERROR; + break; + case TEVENT_DEBUG_WARNING: + ldb_level = LDB_DEBUG_WARNING; + break; + case TEVENT_DEBUG_TRACE: + ldb_level = LDB_DEBUG_TRACE; + break; + }; + + vasprintf(&s, fmt, ap); + if (!s) return; + ldb_debug(ldb, ldb_level, "tevent: %s", s); + free(s); +} + +/* initialise a ldb context The mem_ctx is required The event_ctx is required @@ -62,6 +97,8 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) * until we have them all converted */ if (ev_ctx == NULL) { ev_ctx = tevent_context_init(talloc_autofree_context()); + tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb); + tevent_loop_allow_nesting(ev_ctx); } ret = ldb_setup_wellknown_attributes(ldb); diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index ad27c9a9a9..c99c2936d8 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -1055,7 +1055,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list, ret = ldb_module_send_entry(ac->req, msg, NULL); if (ret != LDB_SUCCESS) { - ac->callback_failed = true; + ac->request_terminated = true; return ret; } } diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 0f595267fc..d395c28f28 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -424,10 +424,10 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi ret = ldb_module_send_entry(ac->req, msg, NULL); if (ret != LDB_SUCCESS) { - ac->callback_failed = true; + ac->request_terminated = true; /* the callback failed, abort the operation */ return -1; - } + } return 0; } @@ -544,7 +544,7 @@ int ltdb_search(struct ltdb_context *ctx) /* Check if we got just a normal error. * In that case proceed to a full search unless we got a * callback error */ - if ( ! ctx->callback_failed && ret != LDB_SUCCESS) { + if ( ! ctx->request_terminated && ret != LDB_SUCCESS) { /* Not indexed, so we need to do a full scan */ ret = ltdb_search_full(ctx); if (ret != LDB_SUCCESS) { diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 24ec06ea32..9df62be936 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1019,7 +1019,16 @@ static void ltdb_timeout(struct tevent_context *ev, struct ltdb_context *ctx; ctx = talloc_get_type(private_data, struct ltdb_context); - ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); + if (!ctx->request_terminated) { + /* request is done now */ + ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); + } + + if (!ctx->request_terminated) { + /* neutralize the spy */ + ctx->spy->ctx = NULL; + } + talloc_free(ctx); } static void ltdb_request_extended_done(struct ltdb_context *ctx, @@ -1078,6 +1087,10 @@ static void ltdb_callback(struct tevent_context *ev, ctx = talloc_get_type(private_data, struct ltdb_context); + if (ctx->request_terminated) { + goto done; + } + switch (ctx->req->operation) { case LDB_SEARCH: ret = ltdb_search(ctx); @@ -1096,17 +1109,34 @@ static void ltdb_callback(struct tevent_context *ev, break; case LDB_EXTENDED: ltdb_handle_extended(ctx); - return; + goto done; default: /* no other op supported */ ret = LDB_ERR_UNWILLING_TO_PERFORM; } - if (!ctx->callback_failed) { - /* Once we are done, we do not need timeout events */ - talloc_free(ctx->timeout_event); + if (!ctx->request_terminated) { + /* request is done now */ ltdb_request_done(ctx, ret); } + +done: + if (!ctx->request_terminated) { + /* neutralize the spy */ + ctx->spy->ctx = NULL; + } + talloc_free(ctx); +} + +static int ltdb_request_destructor(void *ptr) +{ + struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy); + + if (spy->ctx != NULL) { + spy->ctx->request_terminated = true; + } + + return 0; } static int ltdb_handle_request(struct ldb_module *module, @@ -1131,7 +1161,7 @@ static int ltdb_handle_request(struct ldb_module *module, ev = ldb_get_event_context(ldb); - ac = talloc_zero(req, struct ltdb_context); + ac = talloc_zero(ldb, struct ltdb_context); if (ac == NULL) { ldb_set_errstring(ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; @@ -1144,15 +1174,28 @@ static int ltdb_handle_request(struct ldb_module *module, tv.tv_usec = 0; te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac); if (NULL == te) { + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } tv.tv_sec = req->starttime + req->timeout; ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac); if (NULL == ac->timeout_event) { + talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } + /* set a spy so that we do not try to use the request context + * if it is freed before ltdb_callback fires */ + ac->spy = talloc(req, struct ltdb_req_spy); + if (NULL == ac->spy) { + talloc_free(ac); + return LDB_ERR_OPERATIONS_ERROR; + } + ac->spy->ctx = ac; + + talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor); + return LDB_SUCCESS; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 0a06cdb1b0..5a1c8fee2d 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -36,11 +36,16 @@ struct ltdb_private { the async local context holds also internal search state during a full db search */ +struct ltdb_req_spy { + struct ltdb_context *ctx; +}; + struct ltdb_context { struct ldb_module *module; struct ldb_request *req; - bool callback_failed; + bool request_terminated; + struct ltdb_req_spy *spy; /* search stuff */ const struct ldb_parse_tree *tree; diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py index a30273fc66..7d2c7d0547 100755 --- a/source4/lib/ldb/tests/python/ldap.py +++ b/source4/lib/ldb/tests/python/ldap.py @@ -90,6 +90,36 @@ class BasicTests(unittest.TestCase): except LdbError, (num, _): self.assertEquals(num, ERR_NO_SUCH_OBJECT) + def test_parentGUID(self): + """Test parentGUID behaviour""" + print "Testing parentGUID behaviour\n" + + self.ldb.add({ + "dn": "cn=parentguidtest,cn=users," + self.base_dn, + "objectclass":"user", + "samaccountname":"parentguidtest"}); + res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE, + attrs=["parentGUID"]); + res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE, + attrs=["objectGUID"]); + self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]); + + """Test parentGUID behaviour""" + print "Testing parentGUID behaviour on rename\n" + + self.ldb.add({ + "dn": "cn=testotherusers," + self.base_dn, + "objectclass":"container"}); + res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE, + attrs=["objectGUID"]); + ldb.rename("cn=parentguidtest,cn=users," + self.base_dn, + "cn=parentguidtest,cn=testotherusers," + self.base_dn); + res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn, + scope=SCOPE_BASE, + attrs=["parentGUID"]); + self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]); + + def test_all(self): """Basic tests""" diff --git a/source4/lib/ldb/tools/cmdline.h b/source4/lib/ldb/tools/cmdline.h index 3473d62a16..45619ce496 100644 --- a/source4/lib/ldb/tools/cmdline.h +++ b/source4/lib/ldb/tools/cmdline.h @@ -50,5 +50,4 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const void (*usage)(void)); -struct ldb_control **parse_controls(void *mem_ctx, char **control_strings); int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request); |