diff options
Diffstat (limited to 'source4/dsdb/schema')
-rw-r--r-- | source4/dsdb/schema/schema_convert_to_ol.c | 12 | ||||
-rw-r--r-- | source4/dsdb/schema/schema_query.c | 143 |
2 files changed, 122 insertions, 33 deletions
diff --git a/source4/dsdb/schema/schema_convert_to_ol.c b/source4/dsdb/schema/schema_convert_to_ol.c index ebcb7ade59..c0ab5c2af8 100644 --- a/source4/dsdb/schema/schema_convert_to_ol.c +++ b/source4/dsdb/schema/schema_convert_to_ol.c @@ -56,9 +56,11 @@ static char *print_schema_recursive(char *append_to_string, struct dsdb_schema * const char **must; const char **may; char *schema_entry = NULL; - const char *objectclass_name_as_list[] = { - objectclass->lDAPDisplayName, - NULL + struct ldb_val objectclass_name_as_ldb_val = data_blob_string_const(objectclass->lDAPDisplayName); + struct ldb_message_element objectclass_name_as_el = { + .name = "objectClass", + .num_values = 1, + .values = &objectclass_name_as_ldb_val }; int j; int attr_idx; @@ -89,7 +91,7 @@ static char *print_schema_recursive(char *append_to_string, struct dsdb_schema * } } - may = dsdb_full_attribute_list(mem_ctx, schema, objectclass_name_as_list, DSDB_SCHEMA_ALL_MAY); + may = dsdb_full_attribute_list(mem_ctx, schema, &objectclass_name_as_el, DSDB_SCHEMA_ALL_MAY); for (j=0; may && may[j]; j++) { /* We might have been asked to remap this name, due to a conflict */ @@ -101,7 +103,7 @@ static char *print_schema_recursive(char *append_to_string, struct dsdb_schema * } } - must = dsdb_full_attribute_list(mem_ctx, schema, objectclass_name_as_list, DSDB_SCHEMA_ALL_MUST); + must = dsdb_full_attribute_list(mem_ctx, schema, &objectclass_name_as_el, DSDB_SCHEMA_ALL_MUST); for (j=0; must && must[j]; j++) { /* We might have been asked to remap this name, due to a conflict */ diff --git a/source4/dsdb/schema/schema_query.c b/source4/dsdb/schema/schema_query.c index f894ef5b1e..0e5efa9004 100644 --- a/source4/dsdb/schema/schema_query.c +++ b/source4/dsdb/schema/schema_query.c @@ -51,11 +51,24 @@ } } while (0) +static const char **dsdb_full_attribute_list_internal(TALLOC_CTX *mem_ctx, + const struct dsdb_schema *schema, + const char **class_list, + enum dsdb_attr_list_query query); + static int uint32_cmp(uint32_t c1, uint32_t c2) { return c1 - c2; } +static int strcasecmp_with_ldb_val(const struct ldb_val *target, const char *str) +{ + int ret = strncasecmp((const char *)target->data, str, target->length); + if (ret == 0) { + return (target->length - strlen(str)); + } + return ret; +} const struct dsdb_attribute *dsdb_attribute_by_attributeID_id(const struct dsdb_schema *schema, uint32_t id) @@ -143,6 +156,16 @@ const struct dsdb_class *dsdb_class_by_lDAPDisplayName(const struct dsdb_schema return c; } +const struct dsdb_class *dsdb_class_by_lDAPDisplayName_ldb_val(const struct dsdb_schema *schema, + struct ldb_val *name) +{ + struct dsdb_class *c; + if (!name) return NULL; + BINARY_ARRAY_SEARCH(schema->classes_by_lDAPDisplayName, + schema->num_classes, lDAPDisplayName, name, strcasecmp_with_ldb_val, c); + return c; +} + const struct dsdb_class *dsdb_class_by_cn(const struct dsdb_schema *schema, const char *cn) { @@ -153,6 +176,16 @@ const struct dsdb_class *dsdb_class_by_cn(const struct dsdb_schema *schema, return c; } +const struct dsdb_class *dsdb_class_by_cn_ldb_val(const struct dsdb_schema *schema, + struct ldb_val *cn) +{ + struct dsdb_class *c; + if (!cn) return NULL; + BINARY_ARRAY_SEARCH(schema->classes_by_cn, + schema->num_classes, cn, cn, strcasecmp_with_ldb_val, c); + return c; +} + const char *dsdb_lDAPDisplayName_by_id(const struct dsdb_schema *schema, uint32_t id) { @@ -268,48 +301,86 @@ const char **dsdb_attribute_list(TALLOC_CTX *mem_ctx, const struct dsdb_class *s return attr_list; } +static const char **attribute_list_from_class(TALLOC_CTX *mem_ctx, + const struct dsdb_schema *schema, + const struct dsdb_class *sclass, + enum dsdb_attr_list_query query) +{ + const char **this_class_list; + const char **system_recursive_list; + const char **recursive_list; + const char **attr_list; + + this_class_list = dsdb_attribute_list(mem_ctx, sclass, query); + + recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema, + sclass->systemAuxiliaryClass, + query); + + system_recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema, + sclass->auxiliaryClass, + query); + + attr_list = this_class_list; + attr_list = merge_attr_list(mem_ctx, attr_list, recursive_list); + attr_list = merge_attr_list(mem_ctx, attr_list, system_recursive_list); + return attr_list; +} + +/* Return a full attribute list for a given class list (as a ldb_message_element) + + Via attribute_list_from_class() this calls itself when recursing on auxiliary classes + */ static const char **dsdb_full_attribute_list_internal(TALLOC_CTX *mem_ctx, - const struct dsdb_schema *schema, - const char **class_list, - enum dsdb_attr_list_query query) + const struct dsdb_schema *schema, + const char **class_list, + enum dsdb_attr_list_query query) { int i; - const struct dsdb_class *sclass; - const char **attr_list = NULL; - const char **this_class_list; - const char **recursive_list; for (i=0; class_list && class_list[i]; i++) { - sclass = dsdb_class_by_lDAPDisplayName(schema, class_list[i]); - - this_class_list = dsdb_attribute_list(mem_ctx, sclass, query); - attr_list = merge_attr_list(mem_ctx, attr_list, this_class_list); + const char **sclass_list + = attribute_list_from_class(mem_ctx, schema, + dsdb_class_by_lDAPDisplayName(schema, class_list[i]), + query); - recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema, - sclass->systemAuxiliaryClass, - query); - - attr_list = merge_attr_list(mem_ctx, attr_list, recursive_list); - - recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema, - sclass->auxiliaryClass, - query); - - attr_list = merge_attr_list(mem_ctx, attr_list, recursive_list); + attr_list = merge_attr_list(mem_ctx, attr_list, sclass_list); + } + return attr_list; +} + +/* Return a full attribute list for a given class list (as a ldb_message_element) + + Using the ldb_message_element ensures we do length-limited + comparisons, rather than casting the possibly-unterminated string + + Via attribute_list_from_class() this calls + dsdb_full_attribute_list_internal() when recursing on auxiliary classes + */ +static const char **dsdb_full_attribute_list_internal_el(TALLOC_CTX *mem_ctx, + const struct dsdb_schema *schema, + const struct ldb_message_element *el, + enum dsdb_attr_list_query query) +{ + int i; + const char **attr_list = NULL; + + for (i=0; i < el->num_values; i++) { + const char **sclass_list + = attribute_list_from_class(mem_ctx, schema, + dsdb_class_by_lDAPDisplayName_ldb_val(schema, &el->values[i]), + query); + attr_list = merge_attr_list(mem_ctx, attr_list, sclass_list); } return attr_list; } -const char **dsdb_full_attribute_list(TALLOC_CTX *mem_ctx, - const struct dsdb_schema *schema, - const char **class_list, - enum dsdb_attr_list_query query) +/* Helper function to remove duplicates from the attribute list to be returned */ +static const char **dedup_attr_list(const char **attr_list) { - const char **attr_list = dsdb_full_attribute_list_internal(mem_ctx, schema, class_list, query); size_t new_len = str_list_length(attr_list); - /* Remove duplicates */ if (new_len > 1) { int i; @@ -329,3 +400,19 @@ const char **dsdb_full_attribute_list(TALLOC_CTX *mem_ctx, } return attr_list; } + +/* Return a full attribute list for a given class list (as a ldb_message_element) + + Using the ldb_message_element ensures we do length-limited + comparisons, rather than casting the possibly-unterminated string + + The result contains only unique values + */ +const char **dsdb_full_attribute_list(TALLOC_CTX *mem_ctx, + const struct dsdb_schema *schema, + const struct ldb_message_element *class_list, + enum dsdb_attr_list_query query) +{ + const char **attr_list = dsdb_full_attribute_list_internal_el(mem_ctx, schema, class_list, query); + return dedup_attr_list(attr_list); +} |