summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb/ldb_modules/util.c
diff options
context:
space:
mode:
authorKamen Mazdrashki <kamenim@samba.org>2014-10-28 06:10:56 +0100
committerAndrew Bartlett <abartlet@samba.org>2015-02-03 05:02:11 +0100
commit1154075220da592e160ab357f2669eb4e1266217 (patch)
treed122c96b6a1d320af82623df7e5984154d1c2bbe /source4/dsdb/samdb/ldb_modules/util.c
parent5921bb84ab54123d68691e63154f22ed124f6be4 (diff)
downloadsamba-1154075220da592e160ab357f2669eb4e1266217.tar.gz
s4-dsdb: Make most specific objectCategory for an object
This is lightweight implementation and should be used on objects with already verified objectClass attribute value - eg. valid classes, sorted properly, etc. Checkout objectclass.c module for heavy weight implementation. Change-Id: Ifa7880d26246f67e2f982496fcc6c77e6648d56f Signed-off-by: Kamen Mazdrashki <kamenim@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules/util.c')
-rw-r--r--source4/dsdb/samdb/ldb_modules/util.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c
index a71c49b042c..4c81a1dd328 100644
--- a/source4/dsdb/samdb/ldb_modules/util.c
+++ b/source4/dsdb/samdb/ldb_modules/util.c
@@ -1445,3 +1445,70 @@ int dsdb_fix_dn_rdncase(struct ldb_context *ldb, struct ldb_dn *dn)
}
return LDB_SUCCESS;
}
+
+/**
+ * Make most specific objectCategory for the objectClass of passed object
+ * NOTE: In this implementation we count that it is called on already
+ * verified objectClass attribute value. See objectclass.c thorough
+ * implementation for all the magic that involves
+ *
+ * @param ldb ldb context
+ * @param schema cached schema for ldb. We may get it, but it is very time consuming.
+ * Hence leave the responsibility to the caller.
+ * @param obj AD object to determint objectCategory for
+ * @param mem_ctx Memory context - usually it is obj actually
+ * @param pobjectcategory location to store found objectCategory
+ *
+ * @return LDB_SUCCESS or error including out of memory error
+ */
+int dsdb_make_object_category(struct ldb_context *ldb, const struct dsdb_schema *schema,
+ struct ldb_message *obj,
+ TALLOC_CTX *mem_ctx, const char **pobjectcategory)
+{
+ const struct dsdb_class *objectclass;
+ struct ldb_message_element *objectclass_element;
+ struct dsdb_extended_dn_store_format *dn_format;
+
+ objectclass_element = ldb_msg_find_element(obj, "objectClass");
+ if (!objectclass_element) {
+ ldb_asprintf_errstring(ldb, "dsdb: Cannot add %s, no objectclass specified!",
+ ldb_dn_get_linearized(obj->dn));
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
+ }
+ if (objectclass_element->num_values == 0) {
+ ldb_asprintf_errstring(ldb, "dsdb: Cannot add %s, at least one (structural) objectclass has to be specified!",
+ ldb_dn_get_linearized(obj->dn));
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+
+ /*
+ * Get the new top-most structural object class and check for
+ * unrelated structural classes
+ */
+ objectclass = dsdb_get_last_structural_class(schema,
+ objectclass_element);
+ if (objectclass == NULL) {
+ ldb_asprintf_errstring(ldb,
+ "Failed to find a structural class for %s",
+ ldb_dn_get_linearized(obj->dn));
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+
+ dn_format = talloc_get_type(ldb_get_opaque(ldb, DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME),
+ struct dsdb_extended_dn_store_format);
+ if (dn_format && dn_format->store_extended_dn_in_ldb == false) {
+ /* Strip off extended components */
+ struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb,
+ objectclass->defaultObjectCategory);
+ *pobjectcategory = ldb_dn_alloc_linearized(mem_ctx, dn);
+ talloc_free(dn);
+ } else {
+ *pobjectcategory = talloc_strdup(mem_ctx, objectclass->defaultObjectCategory);
+ }
+
+ if (*pobjectcategory == NULL) {
+ return ldb_oom(ldb);
+ }
+
+ return LDB_SUCCESS;
+}