From 1154075220da592e160ab357f2669eb4e1266217 Mon Sep 17 00:00:00 2001 From: Kamen Mazdrashki Date: Tue, 28 Oct 2014 06:10:56 +0100 Subject: [PATCH] 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 Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam --- source4/dsdb/samdb/ldb_modules/util.c | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) 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; +} -- 2.11.4.GIT