s4-dsdb: rename dsdb_module_search_handle_flags to dsdb_request_add_controls
[kai/samba-autobuild/.git] / source4 / dsdb / samdb / ldb_modules / util.c
index 372cad62e21202567d50e0eeace406a83b0fa102..ebc2d9476a80621499c010a0faa2f1828ef2cd6f 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include "includes.h"
 #include "ldb.h"
 #include "ldb_module.h"
+#include "dsdb/samdb/ldb_modules/util.h"
+#include "dsdb/samdb/samdb.h"
+
+/*
+  add a set of controls to a ldb_request structure based on a set of
+  flags. See util.h for a list of available flags
+ */
+int dsdb_request_add_controls(struct ldb_module *module, struct ldb_request *req, uint32_t dsdb_flags)
+{
+       int ret;
+       if (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) {
+               struct ldb_search_options_control *options;
+               /* Using the phantom root control allows us to search all partitions */
+               options = talloc(req, struct ldb_search_options_control);
+               if (options == NULL) {
+                       ldb_module_oom(module);
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+               options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT;
+               
+               ret = ldb_request_add_control(req,
+                                             LDB_CONTROL_SEARCH_OPTIONS_OID,
+                                             true, options);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+       }
+
+       if (dsdb_flags & DSDB_SEARCH_SHOW_DELETED) {
+               ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+       }
+
+       if (dsdb_flags & DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT) {
+               ret = ldb_request_add_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID, true, NULL);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+       }
+
+       if (dsdb_flags & DSDB_SEARCH_SHOW_EXTENDED_DN) {
+               struct ldb_extended_dn_control *extended_ctrl = talloc(req, struct ldb_extended_dn_control);
+               if (!extended_ctrl) {
+                       ldb_module_oom(module);
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+               extended_ctrl->type = 1;
+               
+               ret = ldb_request_add_control(req, LDB_CONTROL_EXTENDED_DN_OID, true, extended_ctrl);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+       }
+
+       if (dsdb_flags & DSDB_SEARCH_REVEAL_INTERNALS) {
+               ret = ldb_request_add_control(req, LDB_CONTROL_REVEAL_INTERNALS, false, NULL);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+       }
+
+       return LDB_SUCCESS;
+}
 
 /*
   search for attrs on one DN, in the modules below
@@ -29,7 +95,8 @@ int dsdb_module_search_dn(struct ldb_module *module,
                          TALLOC_CTX *mem_ctx,
                          struct ldb_result **_res,
                          struct ldb_dn *basedn,
-                         const char * const *attrs)
+                         const char * const *attrs,
+                         int dsdb_flags)
 {
        int ret;
        struct ldb_request *req;
@@ -57,6 +124,12 @@ int dsdb_module_search_dn(struct ldb_module *module,
                return ret;
        }
 
+       ret = dsdb_request_add_controls(module, req, dsdb_flags);
+       if (ret != LDB_SUCCESS) {
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+
        ret = ldb_next_request(module, req);
        if (ret == LDB_SUCCESS) {
                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
@@ -88,6 +161,7 @@ int dsdb_module_search(struct ldb_module *module,
                       struct ldb_result **_res,
                       struct ldb_dn *basedn, enum ldb_scope scope, 
                       const char * const *attrs,
+                      int dsdb_flags, 
                       const char *expression)
 {
        int ret;
@@ -116,6 +190,12 @@ int dsdb_module_search(struct ldb_module *module,
                return ret;
        }
 
+       ret = dsdb_request_add_controls(module, req, dsdb_flags);
+       if (ret != LDB_SUCCESS) {
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+
        ret = ldb_next_request(module, req);
        if (ret == LDB_SUCCESS) {
                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
@@ -129,3 +209,44 @@ int dsdb_module_search(struct ldb_module *module,
        return ret;
 }
 
+/*
+  find a DN given a GUID. This searches across all partitions
+ */
+int dsdb_module_dn_by_guid(struct ldb_module *module, TALLOC_CTX *mem_ctx,
+                          const struct GUID *guid, struct ldb_dn **dn)
+{
+       struct ldb_result *res;
+       const char *attrs[] = { NULL };
+       char *expression;
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+       int ret;
+
+       expression = talloc_asprintf(tmp_ctx, "objectGUID=%s", GUID_string(tmp_ctx, guid));
+       if (!expression) {
+               ldb_module_oom(module);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       ret = dsdb_module_search(module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
+                                attrs, DSDB_SEARCH_SHOW_DELETED | DSDB_SEARCH_SEARCH_ALL_PARTITIONS,
+                                expression);
+       if (ret != LDB_SUCCESS) {
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+       if (ret->count == 0) {
+               talloc_free(tmp_ctx);
+               return LDB_ERR_NO_SUCH_OBJECT;
+       }
+       if (res->count != 1) {
+               ldb_asprintf_errstring(ldb_module_get_ctx(module), "More than one object found matching %s\n",
+                                      expression);
+               talloc_free(tmp_ctx);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       *dn = talloc_steal(mem_ctx, res->msgs[0].dn);
+
+       talloc_free(tmp_ctx);
+       return LDB_SUCCESS;
+}