summaryrefslogtreecommitdiff
path: root/lib/ldb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ldb')
-rw-r--r--lib/ldb/common/ldb_controls.c65
-rw-r--r--lib/ldb/include/ldb.h2
-rw-r--r--lib/ldb/tools/cmdline.c33
3 files changed, 100 insertions, 0 deletions
diff --git a/lib/ldb/common/ldb_controls.c b/lib/ldb/common/ldb_controls.c
index 73463266e4c..af056d09a5a 100644
--- a/lib/ldb/common/ldb_controls.c
+++ b/lib/ldb/common/ldb_controls.c
@@ -367,6 +367,26 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr
talloc_free(cookie);
return res;
}
+ if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_EX_OID) == 0) {
+ char *cookie;
+ struct ldb_dirsync_control *rep_control = talloc_get_type(control->data,
+ struct ldb_dirsync_control);
+
+ cookie = ldb_base64_encode(mem_ctx, rep_control->cookie,
+ rep_control->cookie_len);
+ if (cookie == NULL) {
+ return NULL;
+ }
+ res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s",
+ LDB_CONTROL_DIRSYNC_EX_NAME,
+ control->critical,
+ rep_control->flags,
+ rep_control->max_attributes,
+ cookie);
+
+ talloc_free(cookie);
+ return res;
+ }
if (strcmp(control->oid, LDB_CONTROL_VERIFY_NAME_OID) == 0) {
struct ldb_verify_name_control *rep_control = talloc_get_type(control->data, struct ldb_verify_name_control);
@@ -525,6 +545,51 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
return ctrl;
}
+ if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_EX_NAME) == 0) {
+ struct ldb_dirsync_control *control;
+ const char *p;
+ char cookie[1024];
+ int crit, max_attrs, ret;
+ uint32_t flags;
+
+ cookie[0] = '\0';
+ p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_EX_NAME)]);
+ ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
+
+ if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) {
+ error_string = talloc_asprintf(mem_ctx, "invalid %s control syntax\n",
+ LDB_CONTROL_DIRSYNC_EX_NAME);
+ error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n");
+ error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number, o = b64 binary blob");
+ ldb_set_errstring(ldb, error_string);
+ talloc_free(error_string);
+ talloc_free(ctrl);
+ return NULL;
+ }
+
+ /* w2k3 seems to ignore the parameter,
+ * but w2k sends a wrong cookie when this value is to small
+ * this would cause looping forever, while getting
+ * the same data and same cookie forever
+ */
+ if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
+
+ ctrl->oid = LDB_CONTROL_DIRSYNC_EX_OID;
+ ctrl->critical = crit;
+ control = talloc(ctrl, struct ldb_dirsync_control);
+ control->flags = flags;
+ control->max_attributes = max_attrs;
+ if (*cookie) {
+ control->cookie_len = ldb_base64_decode(cookie);
+ control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
+ } else {
+ control->cookie = NULL;
+ control->cookie_len = 0;
+ }
+ ctrl->data = control;
+
+ return ctrl;
+ }
if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) {
struct ldb_asq_control *control;
diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h
index dc0ce42595d..e715b92626a 100644
--- a/lib/ldb/include/ldb.h
+++ b/lib/ldb/include/ldb.h
@@ -657,6 +657,8 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
*/
#define LDB_CONTROL_DIRSYNC_OID "1.2.840.113556.1.4.841"
#define LDB_CONTROL_DIRSYNC_NAME "dirsync"
+#define LDB_CONTROL_DIRSYNC_EX_OID "1.2.840.113556.1.4.2090"
+#define LDB_CONTROL_DIRSYNC_EX_NAME "dirsync_ex"
/**
diff --git a/lib/ldb/tools/cmdline.c b/lib/ldb/tools/cmdline.c
index a06445fc0f4..6d0a40643df 100644
--- a/lib/ldb/tools/cmdline.c
+++ b/lib/ldb/tools/cmdline.c
@@ -459,6 +459,39 @@ int handle_controls_reply(struct ldb_control **reply, struct ldb_control **reque
continue;
}
+ if (strcmp(LDB_CONTROL_DIRSYNC_EX_OID, reply[i]->oid) == 0) {
+ struct ldb_dirsync_control *rep_control, *req_control;
+ char *cookie;
+
+ rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control);
+ if (rep_control->cookie_len == 0) /* we are done */
+ break;
+
+ /* more processing required */
+ /* let's fill in the request control with the new cookie */
+
+ for (j = 0; request[j]; j++) {
+ if (strcmp(LDB_CONTROL_DIRSYNC_EX_OID, request[j]->oid) == 0)
+ break;
+ }
+ /* if there's a reply control we must find a request
+ * control matching it */
+ if (! request[j]) return -1;
+
+ req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control);
+
+ if (req_control->cookie)
+ talloc_free(req_control->cookie);
+ req_control->cookie = (char *)talloc_memdup(
+ req_control, rep_control->cookie,
+ rep_control->cookie_len);
+ req_control->cookie_len = rep_control->cookie_len;
+
+ cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len);
+ printf("# DIRSYNC_EX cookie returned was:\n# %s\n", cookie);
+
+ continue;
+ }
/* no controls matched, throw a warning */
fprintf(stderr, "Unknown reply control oid: %s\n", reply[i]->oid);