From e1ffcfc7832768429e2f84ae048476ac0ff8dbba Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 21 Dec 2009 21:03:11 +1100 Subject: s4-ldb: added ldb_module_get_ops() This is needed to support DSDB_FLAG_OWN_MODULE Pair-Programmed-With: Andrew Bartlett --- source4/lib/ldb/common/ldb_modules.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/lib/ldb/common') diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index e79f072d50..e49d46a987 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -527,6 +527,11 @@ struct ldb_context *ldb_module_get_ctx(struct ldb_module *module) return module->ldb; } +const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module) +{ + return module->ops; +} + void *ldb_module_get_private(struct ldb_module *module) { return module->private_data; -- cgit From baae6ef9d24a59f794a8cbc9aa0ccdbbeb2ed369 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 29 Dec 2009 11:36:37 +1100 Subject: s4-ldb: added ldb_val_to_time() This is intended as a replacement for ldb_string_to_time() for ldb_val inputs. This ensures it is length limited and includes additional validity checks --- source4/lib/ldb/common/ldb_msg.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'source4/lib/ldb/common') diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index fbf49fbb23..9b33d7e351 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -831,6 +831,33 @@ time_t ldb_string_to_time(const char *s) return timegm(&tm); } +/* + convert a LDAP GeneralizedTime string in ldb_val format to a + time_t. +*/ +int ldb_val_to_time(const struct ldb_val *v, time_t *t) +{ + struct tm tm; + + if (v == NULL || !v->data || v->length < 14) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + memset(&tm, 0, sizeof(tm)); + + if (sscanf((char *)v->data, "%04u%02u%02u%02u%02u%02u", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + *t = timegm(&tm); + + return LDB_SUCCESS; +} + /* return a LDAP formatted UTCTime string */ -- cgit From 53e86ac5b27e7e5d13ab671b8ce202bb97b80d3e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 29 Dec 2009 11:38:49 +1100 Subject: s4-ldb: use safe length limited conversions for int64 and time --- source4/lib/ldb/common/attrib_handlers.c | 61 +++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 13 deletions(-) (limited to 'source4/lib/ldb/common') diff --git a/source4/lib/ldb/common/attrib_handlers.c b/source4/lib/ldb/common/attrib_handlers.c index 1c08741f7d..464707530e 100644 --- a/source4/lib/ldb/common/attrib_handlers.c +++ b/source4/lib/ldb/common/attrib_handlers.c @@ -100,6 +100,27 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, return 0; } +/* length limited conversion of a ldb_val to a int32_t */ +static int val_to_int64(const struct ldb_val *in, int64_t *v) +{ + char *end; + char buf[64]; + + /* make sure we don't read past the end of the data */ + if (in->length > sizeof(buf)-1) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + strncpy(buf, (char *)in->data, in->length); + buf[in->length] = 0; + + /* We've to use "strtoll" here to have the intended overflows. + * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ + *v = (int64_t) strtoll(buf, &end, 0); + if (*end != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + return LDB_SUCCESS; +} /* @@ -109,14 +130,17 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { - char *end; - long long i = strtoll((char *)in->data, &end, 0); - if (*end != 0) { - return -1; + int64_t i; + int ret; + + ret = val_to_int64(in, &i); + if (ret != LDB_SUCCESS) { + return ret; } - out->data = (uint8_t *)talloc_asprintf(mem_ctx, "%lld", i); + out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i); if (out->data == NULL) { - return -1; + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; } out->length = strlen((char *)out->data); return 0; @@ -128,7 +152,11 @@ static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx, static int ldb_comparison_Integer(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2) { - return strtoll((char *)v1->data, NULL, 0) - strtoll((char *)v2->data, NULL, 0); + int64_t i1=0, i2=0; + val_to_int64(v1, &i1); + val_to_int64(v2, &i2); + if (i1 == i2) return 0; + return i1 > i2? 1 : -1; } /* @@ -338,10 +366,11 @@ static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx, static int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *v1, const struct ldb_val *v2) { - time_t t1, t2; - t1 = ldb_string_to_time((char *)v1->data); - t2 = ldb_string_to_time((char *)v2->data); - return (int)t2 - (int)t1; + time_t t1=0, t2=0; + ldb_val_to_time(v1, &t1); + ldb_val_to_time(v2, &t2); + if (t1 == t2) return 0; + return t1 > t2? 1 : -1; } /* @@ -350,10 +379,16 @@ static int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx, static int ldb_canonicalise_utctime(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { - time_t t = ldb_string_to_time((char *)in->data); + time_t t; + int ret; + ret = ldb_val_to_time(in, &t); + if (ret != LDB_SUCCESS) { + return ret; + } out->data = (uint8_t *)ldb_timestring(mem_ctx, t); if (out->data == NULL) { - return -1; + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; } out->length = strlen((char *)out->data); return 0; -- cgit From 81e8a18181d3f24ac837ae0295fc2fca927a7ddf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 29 Dec 2009 11:40:30 +1100 Subject: s4-ldb: allow modules to override error return values The samldb module overrides the error code for some returns when handling primaryGroupID. We need to take the error from the async callback to allow this to work reliably --- source4/lib/ldb/common/ldb_modules.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/lib/ldb/common') diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index e49d46a987..5e9d0e6e98 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -606,7 +606,7 @@ int ldb_next_request(struct ldb_module *module, struct ldb_request *request) * all our modules, and leaves us one less sharp * corner for module developers to cut themselves on */ - ldb_module_done(request, NULL, NULL, ret); + ret = ldb_module_done(request, NULL, NULL, ret); } return ret; } @@ -830,7 +830,9 @@ int ldb_module_done(struct ldb_request *req, } req->callback(req, ares); - return error; + /* returning ares->error here allows the callback routines in + modules to override the error code */ + return ares->error; } /* to be used *only* in modules init functions. -- cgit From 335af02218fbee7b02cbd1e4e6b40acff288465f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 30 Dec 2009 21:36:31 +1100 Subject: s4-ldb: fixed valgrind error: ares can be freed by callback --- source4/lib/ldb/common/ldb_modules.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/lib/ldb/common') diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index 5e9d0e6e98..3b8934702a 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -829,10 +829,7 @@ int ldb_module_done(struct ldb_request *req, ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); } - req->callback(req, ares); - /* returning ares->error here allows the callback routines in - modules to override the error code */ - return ares->error; + return req->callback(req, ares); } /* to be used *only* in modules init functions. -- cgit