# Sort the array, except for the last element. This strange
# construction, creating a new list, due to bugs in samba's
# array handling in IDL generated objects.
- ctr.array = sorted(ctr.array[:-1], key=lambda o: o.attid) + [ctr.array[-1]]
+ ctr.array = sorted(ctr.array[:], key=lambda o: o.attid)
# Now walk it in reverse, so we see the low (and so incorrect,
# the correct values are above 0x80000000) values first and
# remove the 'second' value we see.
fix = True
o.attid = correct_attid
if fix:
- # Sort the array, except for the last element (we changed
- # the value so must re-sort)
- new_list[:-1] = sorted(new_list[:-1], key=lambda o: o.attid)
+ # Sort the array, (we changed the value so must re-sort)
+ new_list[:] = sorted(new_list[:], key=lambda o: o.attid)
# If we did not already need to fix it, then ask about sorting
if not fix:
if len(set_attrs_from_md) < len(list_attid_from_md) \
or len(wrong_attids) > 0 \
- or sorted(list_attid_from_md[:-1]) != list_attid_from_md[:-1]:
+ or sorted(list_attid_from_md) != list_attid_from_md:
error_count +=1
self.err_replmetadata_incorrect_attid(dn, attrname, obj[attrname], wrong_attids)
# Here we check that the first attid is 0
# (objectClass) and that the last on is the RDN
# from the DN.
- rdn_attid = self.samdb_schema.get_attid_from_lDAPDisplayName(dn.get_rdn_name())
- if list_attid_from_md[-1] != rdn_attid:
- error_count += 1
- self.report("ERROR: Not fixing incorrect final attributeID in '%s' on '%s', it should match the RDN %s" %
- (attrname, str(dn), dn.get_rdn_name()))
-
if list_attid_from_md[0] != 0:
error_count += 1
self.report("ERROR: Not fixing incorrect inital attributeID in '%s' on '%s', it should be objectClass" %
return 0;
}
- /*
- * the rdn attribute should be at the end!
- * so we need to return a value greater than zero
- * which means m1 is greater than m2
- */
- if (attid_1 == *rdn_attid) {
- return 1;
- }
-
- /*
- * the rdn attribute should be at the end!
- * so we need to return a value less than zero
- * which means m2 is greater than m1
- */
- if (attid_2 == *rdn_attid) {
- return -1;
- }
-
/*
* See above regarding this being an unsigned comparison.
* Otherwise when the high bit is set on non-standard
static int replmd_replPropertyMetaDataCtr1_verify(struct ldb_context *ldb,
struct replPropertyMetaDataCtr1 *ctr1,
- const struct dsdb_attribute *rdn_sa,
struct ldb_dn *dn)
{
if (ctr1->count == 0) {
static int replmd_replPropertyMetaDataCtr1_sort_and_verify(struct ldb_context *ldb,
struct replPropertyMetaDataCtr1 *ctr1,
- const struct dsdb_schema *schema,
struct ldb_dn *dn)
{
- const char *rdn_name;
- const struct dsdb_attribute *rdn_sa;
-
- rdn_name = ldb_dn_get_rdn_name(dn);
- if (!rdn_name) {
- ldb_debug_set(ldb, LDB_DEBUG_FATAL,
- __location__ ": No rDN for %s?\n",
- ldb_dn_get_linearized(dn));
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
-
- rdn_sa = dsdb_attribute_by_lDAPDisplayName(schema, rdn_name);
- if (rdn_sa == NULL) {
- ldb_debug_set(ldb, LDB_DEBUG_FATAL,
- __location__ ": No sa found for rDN %s for %s\n",
- rdn_name, ldb_dn_get_linearized(dn));
- return LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE;
- }
-
- DEBUG(6,("Sorting rpmd with attid exception %u rDN=%s DN=%s\n",
- rdn_sa->attributeID_id, rdn_name, ldb_dn_get_linearized(dn)));
-
- LDB_TYPESAFE_QSORT(ctr1->array, ctr1->count, &rdn_sa->attributeID_id,
+ /* Note this is O(n^2) for the almost-sorted case, which this is */
+ LDB_TYPESAFE_QSORT(ctr1->array, ctr1->count, NULL,
replmd_replPropertyMetaData1_attid_sort);
- return replmd_replPropertyMetaDataCtr1_verify(ldb, ctr1, rdn_sa, dn);
+ return replmd_replPropertyMetaDataCtr1_verify(ldb, ctr1, dn);
}
static int replmd_ldb_message_element_attid_sort(const struct ldb_message_element *e1,
/*
* sort meta data array, and move the rdn attribute entry to the end
*/
- ret = replmd_replPropertyMetaDataCtr1_sort_and_verify(ldb, &nmd.ctr.ctr1, ac->schema, msg->dn);
+ ret = replmd_replPropertyMetaDataCtr1_sort_and_verify(ldb, &nmd.ctr.ctr1, msg->dn);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb, "%s: error during direct ADD: %s", __func__, ldb_errstring(ldb));
talloc_free(ac);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = replmd_replPropertyMetaDataCtr1_sort_and_verify(ldb, &omd.ctr.ctr1, schema, msg->dn);
+ ret = replmd_replPropertyMetaDataCtr1_sort_and_verify(ldb, &omd.ctr.ctr1, msg->dn);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb, "%s: %s", __func__, ldb_errstring(ldb));
return ret;
unsigned int i;
int ret;
bool remote_isDeleted = false;
- const struct dsdb_attribute *rdn_sa;
- const char *rdn_name;
ldb = ldb_module_get_ctx(ar->module);
msg = ar->objs->objects[ar->index_current].msg;
"isDeleted", false);
/*
- * the meta data array is already sorted by the caller
+ * the meta data array is already sorted by the caller, except
+ * for the RDN, which needs to be put in the right spot.
*/
- rdn_name = ldb_dn_get_rdn_name(msg->dn);
- if (rdn_name == NULL) {
- ldb_asprintf_errstring(ldb, __location__ ": No rDN for %s?\n", ldb_dn_get_linearized(msg->dn));
- return replmd_replicated_request_error(ar, LDB_ERR_INVALID_DN_SYNTAX);
- }
-
- rdn_sa = dsdb_attribute_by_lDAPDisplayName(ar->schema, rdn_name);
- if (rdn_sa == NULL) {
- ldb_asprintf_errstring(ldb, ": No schema attribute found for rDN %s for %s\n",
- rdn_name, ldb_dn_get_linearized(msg->dn));
- return replmd_replicated_request_error(ar, LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE);
- }
- ret = replmd_replPropertyMetaDataCtr1_verify(ldb, &md->ctr.ctr1, rdn_sa, msg->dn);
+ ret = replmd_replPropertyMetaDataCtr1_sort_and_verify(ldb, &md->ctr.ctr1, msg->dn);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb, "%s: error during DRS repl ADD: %s", __func__, ldb_errstring(ldb));
return replmd_replicated_request_error(ar, ret);
* 'cn' for most objects is the last entry in the meta data array
* we have stored
*
- * sort the new meta data array
+ * sort the new meta data array so it is slotted into the right place
*/
- ret = replmd_replPropertyMetaDataCtr1_sort_and_verify(ldb, &nmd.ctr.ctr1, ar->schema, msg->dn);
+ ret = replmd_replPropertyMetaDataCtr1_sort_and_verify(ldb, &nmd.ctr.ctr1, msg->dn);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb, "%s: error during DRS repl merge: %s", __func__, ldb_errstring(ldb));
return ret;