diff options
Diffstat (limited to 'lib/ldb')
-rw-r--r-- | lib/ldb/common/ldb_controls.c | 65 | ||||
-rw-r--r-- | lib/ldb/include/ldb.h | 2 | ||||
-rw-r--r-- | lib/ldb/tools/cmdline.c | 33 |
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); |