diff options
author | Douglas Bagnall <douglas.bagnall@catalyst.net.nz> | 2019-04-11 13:14:24 +1200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2019-05-10 01:15:18 +0000 |
commit | 9c254572dd42147d1e215ef5144c6c7583b1f835 (patch) | |
tree | 249628de2c3db3d7e3439c096d0f8867c243df8d | |
parent | 06a02cb88c88c0ba9af5a2eeba722c0b5878cccd (diff) | |
download | samba-9c254572dd42147d1e215ef5144c6c7583b1f835.tar.gz |
dsdb/mod/extended_dn_out: use faster removal filters
When filtering out multiple elements, we end up memmove()ing the same
elements many times over. It is simpler to not do that by keeping track
of how many elements we are keeping.
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/extended_dn_out.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c index 4228a2ab69d..7fc0a6cffd8 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c @@ -396,7 +396,7 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares, struct ldb_control *control; struct dsdb_openldap_dereference_result_control *dereference_control = NULL; int ret; - unsigned int i, j; + unsigned int i, j, k; struct ldb_message *msg; struct extended_dn_out_private *p; struct ldb_context *ldb; @@ -521,11 +521,11 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares, make_extended_dn = (strcmp(attribute->syntax->ldap_oid, DSDB_SYNTAX_OR_NAME) != 0); } - for (j = 0; j < msg->elements[i].num_values; j++) { + for (k = 0, j = 0; j < msg->elements[i].num_values; j++) { const char *dn_str; struct ldb_dn *dn; struct dsdb_dn *dsdb_dn = NULL; - struct ldb_val *plain_dn = &msg->elements[i].values[j]; + struct ldb_val *plain_dn = &msg->elements[i].values[j]; bool is_deleted_objects = false; /* this is a fast method for detecting deleted @@ -534,11 +534,7 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares, if (dsdb_dn_is_deleted_val(plain_dn) && !have_reveal_control) { /* it's a deleted linked attribute, and we don't have the reveal control */ - memmove(&msg->elements[i].values[j], - &msg->elements[i].values[j+1], - (msg->elements[i].num_values-(j+1))*sizeof(struct ldb_val)); - msg->elements[i].num_values--; - j--; + /* we won't keep this one, so not incrementing k */ continue; } @@ -546,8 +542,8 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares, dsdb_dn = dsdb_dn_parse_trusted(msg, ldb, plain_dn, attribute->syntax->ldap_oid); if (!dsdb_dn) { - ldb_asprintf_errstring(ldb, - "could not parse %.*s in %s on %s as a %s DN", + ldb_asprintf_errstring(ldb, + "could not parse %.*s in %s on %s as a %s DN", (int)plain_dn->length, plain_dn->data, msg->elements[i].name, ldb_dn_get_linearized(msg->dn), attribute->syntax->ldap_oid); @@ -574,7 +570,7 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares, return ldb_module_done(ac->req, NULL, NULL, ret); } } - + /* If we are running in dereference mode (such * as against OpenLDAP) then the DN in the msg * above does not contain the extended values, @@ -611,11 +607,7 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares, /* we show these with REVEAL to allow dbcheck to find and cleanup these orphaned links */ - memmove(&msg->elements[i].values[j], - &msg->elements[i].values[j+1], - (msg->elements[i].num_values-(j+1))*sizeof(struct ldb_val)); - msg->elements[i].num_values--; - j--; + /* we won't keep this one, so not incrementing k */ continue; } } @@ -639,23 +631,27 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares, dn_str = dsdb_dn_get_extended_linearized(msg->elements[i].values, dsdb_dn, ac->extended_type); } else { - dn_str = dsdb_dn_get_linearized(msg->elements[i].values, + dn_str = dsdb_dn_get_linearized(msg->elements[i].values, dsdb_dn); } - + if (!dn_str) { ldb_oom(ldb); talloc_free(dsdb_dn); return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } - msg->elements[i].values[j] = data_blob_string_const(dn_str); + msg->elements[i].values[k] = data_blob_string_const(dn_str); talloc_free(dsdb_dn); + k++; } - if (msg->elements[i].num_values == 0) { + + if (k == 0) { /* we've deleted all of the values from this * element - remove the element */ ldb_msg_remove_element(msg, &msg->elements[i]); i--; + } else { + msg->elements[i].num_values = k; } } return ldb_module_send_entry(ac->req, msg, ares->controls); |