static int get_parsed_dns(struct ldb_module *module, TALLOC_CTX *mem_ctx,
			  struct ldb_message_element *el, struct parsed_dn **pdn,
			  const char *ldap_oid, struct ldb_request *parent)
{
	unsigned int i;
	bool values_are_sorted = true;
	struct ldb_context *ldb = ldb_module_get_ctx(module);

	if (el == NULL) {
		*pdn = NULL;
		return LDB_SUCCESS;
	}

	(*pdn) = talloc_array(mem_ctx, struct parsed_dn, el->num_values);
	if (!*pdn) {
		ldb_module_oom(module);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	for (i=0; i<el->num_values; i++) {
		struct ldb_val *v = &el->values[i];
		NTSTATUS status;
		struct ldb_dn *dn;
		struct parsed_dn *p;

		p = &(*pdn)[i];

		p->dsdb_dn = dsdb_dn_parse(*pdn, ldb, v, ldap_oid);
		if (p->dsdb_dn == NULL) {
			return LDB_ERR_INVALID_DN_SYNTAX;
		}

		dn = p->dsdb_dn->dn;

		status = dsdb_get_extended_dn_guid(dn, &p->guid, "GUID");
		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
		    unlikely(GUID_all_zero(&p->guid))) {
			/* we got a DN without a GUID - go find the GUID */
			int ret = dsdb_module_guid_by_dn(module, dn, &p->guid, parent);
			if (ret != LDB_SUCCESS) {
				char *dn_str = NULL;
				dn_str = ldb_dn_get_extended_linearized(mem_ctx,
									(dn), 1);
				ldb_asprintf_errstring(ldb,
						"Unable to find GUID for DN %s\n",
						dn_str);
				if (ret == LDB_ERR_NO_SUCH_OBJECT &&
				    LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE &&
				    ldb_attr_cmp(el->name, "member") == 0) {
					return LDB_ERR_UNWILLING_TO_PERFORM;
				}
				return ret;
			}
			ret = dsdb_set_extended_dn_guid(dn, &p->guid, "GUID");
			if (ret != LDB_SUCCESS) {
				return ret;
			}
		} else if (!NT_STATUS_IS_OK(status)) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
		if (i > 0 && values_are_sorted) {
			int cmp = parsed_dn_compare(p, &(*pdn)[i - 1]);
			if (cmp < 0) {
				values_are_sorted = false;
			}
		}
		/* keep a pointer to the original ldb_val */
		p->v = v;
	}
	if (! values_are_sorted) {
		TYPESAFE_QSORT(*pdn, el->num_values, parsed_dn_compare);
	}
	return LDB_SUCCESS;
}
static int get_parsed_dns(struct ldb_module *module, TALLOC_CTX *mem_ctx,
			  struct ldb_message_element *el, struct parsed_dn **pdn,
			  const char *ldap_oid, struct ldb_request *parent)
{
	unsigned int i;
	bool values_are_sorted = true;
	struct ldb_context *ldb = ldb_module_get_ctx(module);

	if (el == NULL) {
		*pdn = NULL;
		return LDB_SUCCESS;
	}

	(*pdn) = talloc_array(mem_ctx, struct parsed_dn, el->num_values);
	if (!*pdn) {
		ldb_module_oom(module);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	for (i=0; i<el->num_values; i++) {
		struct ldb_val *v = &el->values[i];
		NTSTATUS status;
		struct ldb_dn *dn;
		struct parsed_dn *p;

		p = &(*pdn)[i];

		p->dsdb_dn = dsdb_dn_parse(*pdn, ldb, v, ldap_oid);
		if (p->dsdb_dn == NULL) {
			return LDB_ERR_INVALID_DN_SYNTAX;
		}

		dn = p->dsdb_dn->dn;

		status = dsdb_get_extended_dn_guid(dn, &p->guid, "GUID");
		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
		    unlikely(GUID_all_zero(&p->guid))) {
			 
			int ret = dsdb_module_guid_by_dn(module, dn, &p->guid, parent);
			if (ret != LDB_SUCCESS) {
				char *dn_str = NULL;
				dn_str = ldb_dn_get_extended_linearized(mem_ctx,
									(dn), 1);
				ldb_asprintf_errstring(ldb,
						"Unable to find GUID for DN %s\n",
						dn_str);
				if (ret == LDB_ERR_NO_SUCH_OBJECT &&
				    LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE &&
				    ldb_attr_cmp(el->name, "member") == 0) {
					return LDB_ERR_UNWILLING_TO_PERFORM;
				}
				return ret;
			}
			ret = dsdb_set_extended_dn_guid(dn, &p->guid, "GUID");
			if (ret != LDB_SUCCESS) {
				return ret;
			}
		} else if (!NT_STATUS_IS_OK(status)) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
		if (i > 0 && values_are_sorted) {
			int cmp = parsed_dn_compare(p, &(*pdn)[i - 1]);
			if (cmp < 0) {
				values_are_sorted = false;
			}
		}
		 
		p->v = v;
	}
	if (! values_are_sorted) {
		TYPESAFE_QSORT(*pdn, el->num_values, parsed_dn_compare);
	}
	return LDB_SUCCESS;
}