summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/common
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/ldb/common')
-rw-r--r--source4/lib/ldb/common/attrib_handlers.c61
-rw-r--r--source4/lib/ldb/common/ldb_modules.c10
-rw-r--r--source4/lib/ldb/common/ldb_msg.c27
3 files changed, 82 insertions, 16 deletions
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;
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c
index e79f072d50..3b8934702a 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;
@@ -601,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;
}
@@ -824,8 +829,7 @@ int ldb_module_done(struct ldb_request *req,
ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE);
}
- req->callback(req, ares);
- return error;
+ return req->callback(req, ares);
}
/* to be used *only* in modules init functions.
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
@@ -832,6 +832,33 @@ time_t ldb_string_to_time(const char *s)
}
/*
+ 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
*/
char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t)