diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c index 6b2babbbf0..d2e9f621b4 100644 --- a/servers/slapd/ldapsync.c +++ b/servers/slapd/ldapsync.c @@ -166,6 +166,68 @@ slap_parse_csn_sids( BerVarray csns, int numcsns, void *memctx ) return ret; } +static slap_mr_match_func sidsort_cmp; + +static const MatchingRule sidsort_mr = { + {}, + NULL, + {}, + {}, + 0, + NULL, NULL, NULL, sidsort_cmp +}; +static const AttributeType sidsort_at = { + {}, + {}, + NULL, NULL, (MatchingRule *)&sidsort_mr, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, SLAP_AT_SORTED_VAL +}; +static const AttributeDescription sidsort_ad = { + NULL, + (AttributeType *)&sidsort_at +}; + +static int +sidsort_cmp( + int *matchp, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *b1, + void *v2 ) +{ + struct berval *b2 = v2; + *matchp = b1->bv_len - b2->bv_len; + return LDAP_SUCCESS; +} + +/* sort CSNs by SID. Use a fake Attribute with our own + * syntax and matching rule, which sorts the nvals by + * bv_len order. Stuff our sids into the bv_len. + */ +int +slap_sort_csn_sids( BerVarray csns, int *sids, int numcsns, void *memctx ) +{ + Attribute a; + const char *text; + int i, rc; + + a.a_desc = (AttributeDescription *)&sidsort_ad; + a.a_nvals = slap_sl_malloc( numcsns * sizeof(struct berval), memctx ); + for ( i=0; inumcsns ) { cookie->sids = slap_parse_csn_sids( cookie->ctxcsn, cookie->numcsns, memctx ); + if ( cookie->numcsns > 1 ) + slap_sort_csn_sids( cookie->ctxcsn, cookie->sids, cookie->numcsns, memctx ); } return 0; } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index d44a03e41f..4c1a540d9d 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -1177,6 +1177,8 @@ LDAP_SLAPD_F (int) slap_parse_csn_sid LDAP_P(( struct berval * )); LDAP_SLAPD_F (int *) slap_parse_csn_sids LDAP_P(( BerVarray, int, void *memctx )); +LDAP_SLAPD_F (int) slap_sort_csn_sids LDAP_P(( + BerVarray, int *, int, void *memctx )); LDAP_SLAPD_F (int) slap_parse_sync_cookie LDAP_P(( struct sync_cookie *, void *memctx )); LDAP_SLAPD_F (int) slap_init_sync_cookie_ctxcsn LDAP_P((