diff options
Diffstat (limited to 'source4')
| -rw-r--r-- | source4/dsdb/samdb/ldb_modules/kludge_acl.c | 18 | ||||
| -rw-r--r-- | source4/dsdb/samdb/ldb_modules/objectclass.c | 5 | ||||
| -rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_fsmo.c | 3 | ||||
| -rw-r--r-- | source4/dsdb/schema/schema_convert_to_ol.c | 12 | ||||
| -rw-r--r-- | source4/dsdb/schema/schema_query.c | 143 | 
5 files changed, 129 insertions, 52 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c index 5bed28b00c..15db491171 100644 --- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c +++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c @@ -93,7 +93,7 @@ static int kludge_acl_allowedAttributes(struct ldb_context *ldb, struct ldb_mess  	struct ldb_message_element *allowedAttributes;  	const struct dsdb_schema *schema = dsdb_get_schema(ldb);  	TALLOC_CTX *mem_ctx; -	const char **objectclass_list, **attr_list; +	const char **attr_list;  	int i, ret;   	/* If we don't have a schema yet, we can't do anything... */ @@ -118,19 +118,7 @@ static int kludge_acl_allowedAttributes(struct ldb_context *ldb, struct ldb_mess  	   we alter the element array in ldb_msg_add_empty() */  	oc_el = ldb_msg_find_element(msg, "objectClass"); -	objectclass_list = talloc_array(mem_ctx, const char *, oc_el->num_values + 1); -	if (!objectclass_list) { -		ldb_oom(ldb); -		talloc_free(mem_ctx); -		return LDB_ERR_OPERATIONS_ERROR; -	} - -	for (i=0; oc_el && i < oc_el->num_values; i++) { -		objectclass_list[i] = (const char *)oc_el->values[i].data; -	} -	objectclass_list[i] = NULL; - -	attr_list = dsdb_full_attribute_list(mem_ctx, schema, objectclass_list, DSDB_SCHEMA_ALL); +	attr_list = dsdb_full_attribute_list(mem_ctx, schema, oc_el, DSDB_SCHEMA_ALL);  	if (!attr_list) {  		ldb_asprintf_errstring(ldb, "kludge_acl: Failed to get list of attributes create %s attribute", attrName);  		talloc_free(mem_ctx); @@ -172,7 +160,7 @@ static int kludge_acl_childClasses(struct ldb_context *ldb, struct ldb_message *  	oc_el = ldb_msg_find_element(msg, "objectClass");  	for (i=0; oc_el && i < oc_el->num_values; i++) { -		sclass = dsdb_class_by_lDAPDisplayName(schema, (const char *)oc_el->values[i].data); +		sclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &oc_el->values[i]);  		if (!sclass) {  			/* We don't know this class?  what is going on? */  			continue; diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 7883bccfe7..4f013709b2 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -134,9 +134,10 @@ static int objectclass_sort(struct ldb_module *module,  			ldb_oom(ldb);  			return LDB_ERR_OPERATIONS_ERROR;  		} -		current->objectclass = dsdb_class_by_lDAPDisplayName(schema, (const char *)objectclass_element->values[i].data); +		current->objectclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &objectclass_element->values[i]);  		if (!current->objectclass) { -			ldb_asprintf_errstring(ldb, "objectclass %s is not a valid objectClass in schema", (const char *)objectclass_element->values[i].data); +			ldb_asprintf_errstring(ldb, "objectclass %.*s is not a valid objectClass in schema",  +					       (int)objectclass_element->values[i].length, (const char *)objectclass_element->values[i].data);  			return LDB_ERR_OBJECT_CLASS_VIOLATION;  		} diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c index 1b8f786c35..290232bdb9 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c @@ -417,9 +417,8 @@ static int generate_possibleInferiors(struct ldb_context *ldb, struct ldb_messag  	}  	first_component_val = ldb_dn_get_component_val(dn, 0); -	class_name = (const char *)first_component_val->data; -	schema_class = dsdb_class_by_cn(schema, class_name); +	schema_class = dsdb_class_by_cn_ldb_val(schema, first_component_val);  	if (schema_class == NULL) {  		return LDB_SUCCESS;  	} 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); +}  | 
