summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/dsdb/samdb/ldb_modules/entryUUID.c185
1 files changed, 182 insertions, 3 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/entryUUID.c b/source4/dsdb/samdb/ldb_modules/entryUUID.c
index acc8067fa7..c2c422185f 100644
--- a/source4/dsdb/samdb/ldb_modules/entryUUID.c
+++ b/source4/dsdb/samdb/ldb_modules/entryUUID.c
@@ -36,6 +36,10 @@
#include "librpc/gen_ndr/ndr_misc.h"
#include "librpc/ndr/libndr.h"
+struct entryUUID_private {
+ struct ldb_result *objectclass_res;
+};
+
static struct ldb_val encode_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
{
struct GUID guid;
@@ -76,7 +80,7 @@ static struct ldb_val decode_guid(struct ldb_module *module, TALLOC_CTX *ctx, co
}
/* The backend holds binary sids, so just copy them back */
-static struct ldb_val sid_copy(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+static struct ldb_val val_copy(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
{
struct ldb_val out = data_blob(NULL, 0);
ldb_handler_copy(module->ldb, ctx, val, &out);
@@ -97,6 +101,75 @@ static struct ldb_val sid_always_binary(struct ldb_module *module, TALLOC_CTX *c
return out;
}
+static struct ldb_val objectCategory_always_dn(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+{
+ int i;
+ struct map_private *map_private;
+ struct entryUUID_private *entryUUID_private;
+ struct ldb_result *list;
+
+ if (ldb_dn_explode(ctx, val->data)) {
+ return *val;
+ }
+ map_private = talloc_get_type(module->private_data, struct map_private);
+
+ entryUUID_private = talloc_get_type(map_private->caller_private, struct entryUUID_private);
+ list = entryUUID_private->objectclass_res;
+
+ for (i=0; i < list->count; i++) {
+ if (ldb_attr_cmp(val->data, ldb_msg_find_attr_as_string(list->msgs[i], "lDAPDisplayName", NULL)) == 0) {
+ char *dn = ldb_dn_linearize(ctx, list->msgs[i]->dn);
+ return data_blob_string_const(dn);
+ }
+ }
+ return *val;
+}
+
+static struct ldb_val class_to_oid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+{
+ int i;
+ struct map_private *map_private;
+ struct entryUUID_private *entryUUID_private;
+ struct ldb_result *list;
+
+ map_private = talloc_get_type(module->private_data, struct map_private);
+
+ entryUUID_private = talloc_get_type(map_private->caller_private, struct entryUUID_private);
+ list = entryUUID_private->objectclass_res;
+
+ for (i=0; i < list->count; i++) {
+ if (ldb_attr_cmp(val->data, ldb_msg_find_attr_as_string(list->msgs[i], "lDAPDisplayName", NULL)) == 0) {
+ const char *oid = ldb_msg_find_attr_as_string(list->msgs[i], "governsID", NULL);
+ return data_blob_string_const(oid);
+ }
+ }
+ return *val;
+}
+
+static struct ldb_val class_from_oid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+{
+ int i;
+ struct map_private *map_private;
+ struct entryUUID_private *entryUUID_private;
+ struct ldb_result *list;
+
+ map_private = talloc_get_type(module->private_data, struct map_private);
+
+ entryUUID_private = talloc_get_type(map_private->caller_private, struct entryUUID_private);
+ list = entryUUID_private->objectclass_res;
+
+ for (i=0; i < list->count; i++) {
+ if (ldb_attr_cmp(val->data, ldb_msg_find_attr_as_string(list->msgs[i], "governsID", NULL)) == 0) {
+ const char *oc = ldb_msg_find_attr_as_string(list->msgs[i], "lDAPDisplayName", NULL);
+ return data_blob_string_const(oc);
+ }
+ }
+ return *val;
+}
+
+
+
+
const struct ldb_map_attribute entryUUID_attributes[] =
{
/* objectGUID */
@@ -119,7 +192,7 @@ const struct ldb_map_attribute entryUUID_attributes[] =
.convert = {
.remote_name = "objectSid",
.convert_local = sid_always_binary,
- .convert_remote = sid_copy,
+ .convert_remote = val_copy,
},
},
},
@@ -142,6 +215,28 @@ const struct ldb_map_attribute entryUUID_attributes[] =
}
},
{
+ .local_name = "allowedChildClassesEffective",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "allowedChildClassesEffective",
+ .convert_local = class_to_oid,
+ .convert_remote = class_from_oid,
+ },
+ },
+ },
+ {
+ .local_name = "objectCategory",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "objectCategory",
+ .convert_local = objectCategory_always_dn,
+ .convert_remote = val_copy,
+ },
+ },
+ },
+ {
.local_name = "distinguishedName",
.type = MAP_RENAME,
.u = {
@@ -159,16 +254,100 @@ const struct ldb_map_attribute entryUUID_attributes[] =
}
};
+static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
+{
+ const char *rootdse_attrs[] = {"schemaNamingContext", NULL};
+ struct ldb_dn *schemadn;
+ struct ldb_dn *basedn = ldb_dn_explode(mem_ctx, "");
+ struct ldb_result *rootdse_res;
+ int ldb_ret;
+ if (!basedn) {
+ return NULL;
+ }
+
+ /* Search for rootdse */
+ ldb_ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, NULL, rootdse_attrs, &rootdse_res);
+ if (ldb_ret != LDB_SUCCESS) {
+ printf("Search failed: %s\n", ldb_errstring(ldb));
+ return NULL;
+ }
+
+ talloc_steal(mem_ctx, rootdse_res);
+
+ if (rootdse_res->count != 1) {
+ printf("Failed to find rootDSE");
+ return NULL;
+ }
+
+ /* Locate schema */
+ schemadn = ldb_msg_find_attr_as_dn(mem_ctx, rootdse_res->msgs[0], "schemaNamingContext");
+ if (!schemadn) {
+ return NULL;
+ }
+
+ talloc_free(rootdse_res);
+ return schemadn;
+}
+
+static int fetch_objectclass_schema(struct ldb_context *ldb, struct ldb_dn *schemadn,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_result **objectclass_res)
+{
+ TALLOC_CTX *local_ctx = talloc_new(mem_ctx);
+ int ret;
+ const char *attrs[] = {
+ "lDAPDisplayName",
+ "governsID",
+ NULL
+ };
+
+ if (!local_ctx) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* Downlaod schema */
+ ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
+ "objectClass=classSchema",
+ attrs, objectclass_res);
+ if (ret != LDB_SUCCESS) {
+ printf("Search failed: %s\n", ldb_errstring(ldb));
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ return ret;
+}
+
/* the context init function */
static int entryUUID_init(struct ldb_module *module)
{
int ret;
+ struct map_private *map_private;
+ struct entryUUID_private *entryUUID_private;
+ struct ldb_dn *schema_dn;
ret = ldb_map_init(module, entryUUID_attributes, NULL, NULL);
if (ret != LDB_SUCCESS)
return ret;
- return ldb_next_init(module);
+ map_private = talloc_get_type(module->private_data, struct map_private);
+
+ entryUUID_private = talloc(map_private, struct entryUUID_private);
+ map_private->caller_private = entryUUID_private;
+
+ schema_dn = find_schema_dn(module->ldb, map_private);
+ if (!schema_dn) {
+ printf("Failed to find schema DN: %s\n", ldb_errstring(module->ldb));
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = fetch_objectclass_schema(module->ldb, schema_dn, entryUUID_private, &entryUUID_private->objectclass_res);
+ if (ret != LDB_SUCCESS) {
+ printf("Failed to fetch objectClass schema elements: %s\n", ldb_errstring(module->ldb));
+ return ret;
+ }
+
+
+ return ldb_next_init(module);
}
static struct ldb_module_ops entryUUID_ops = {