]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ldb: add support for LDB_CONTROL_DIRSYNC_EX
authorStefan Metzmacher <metze@samba.org>
Tue, 26 Jan 2016 08:36:56 +0000 (09:36 +0100)
committerGarming Sam <garming@samba.org>
Wed, 17 Feb 2016 02:43:23 +0000 (03:43 +0100)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/ldb/common/ldb_controls.c
lib/ldb/include/ldb.h
lib/ldb/tools/cmdline.c

index 73463266e4c880bfa6d84532e314301c515b31b7..af056d09a5ace940f9baf891dd93c35f7691b8c0 100644 (file)
@@ -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;
index dc0ce42595d6f7cd82383cb9720fde06488994b9..e715b92626a4663bfa6f049b512d95ada4439387 100644 (file)
@@ -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"
 
 
 /**
index a06445fc0f4b1f7d65e72fbb8871d7676d6b4272..6d0a40643df82b737e5519822dc30212c8a2a25f 100644 (file)
@@ -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);