The branch, master has been updated via 8d3fc23... s4-dsdb: also mark the relax control non-critical when done via 558a386... s4-dsdb: it is a better pattern to mark a control as done than remove it via 41e403a... s4-dsdb: when the SD_FLAGS control is set, don't remove nTSecurityDescriptor via 934bb28... s4-dsdb: don't actually remove the sd_flags control, just mark it non-critical via 9955756... s4-ldb: show the OID of any unhandled critical controls via f8320b3... s4-ldb: fixed a transaction error on prepare_commit via e14c728... s4-ldb: added --show-deactivated-link command line option via f9302f9... ldap: give a debug error when we don't know a control via 6c21255... s4-dsdb: added dsdb_get_deleted_objects_dn() via 3c1f18c... s4-dsdb: added dsdb_find_nc_root() via 7d0fdca... s4-dsdb: added dsdb_wellknown_dn() via b7a74ac... libds: added GUIDs for wellknown AD objects via 8a74633... s4-dsdb: added a dsdb_module_rename() call via 9fa1f96... s4-dsdb: added dsdb_module_modify() via 4b970c0... s4-dsdb: fixed dsdb_module_dn_by_guid() via cd4574f... s4-dsdb: dsdb_flags should be unsigned via 57b10b6... s4-dsdb: rename dsdb_module_search_handle_flags to dsdb_request_add_controls via 9515926... s4-dsdb: added dsdb_module_dn_by_guid() via 32995e8... s4-dsdb: use dsdb_dn_is_deleted_val() via 152f415... s4-dsdb: added dsdb_dn_is_deleted_val() via d31b636... s4-ntvfs: try to fix bug 6989 from e22e336... s4:drsuapi/getncchanges.c - Update the list of operational attributes
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 8d3fc23157376af5657a09324509abace3c5ee4f Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 20:45:40 2009 +1100 s4-dsdb: also mark the relax control non-critical when done commit 558a38671af5ea05d9ee1d815f0c1c2dab41a80c Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 20:45:02 2009 +1100 s4-dsdb: it is a better pattern to mark a control as done than remove it removing a control means it can't be seen by any other modules, which is usually not what is wanted. Better to just mark it non-critical, which means anyone else who wants to look at it can, but if nobody does its not an error. commit 41e403adb0fa76c8d15d5d1ef38b195a6da2265c Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 20:39:55 2009 +1100 s4-dsdb: when the SD_FLAGS control is set, don't remove nTSecurityDescriptor commit 934bb28ef3cc9c6589cbb8b75c2a9f8435cc88a3 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 20:39:18 2009 +1100 s4-dsdb: don't actually remove the sd_flags control, just mark it non-critical For controls that need to be seen by more than one module, it is best to just mark them non-critical when handled, instead of removing them. Otherwise lower modules can't see them. In this case we want the operational module to see the SD_FLAGS control commit 99557563141a3776b05bebba0436c56e72f9e20f Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 17:13:19 2009 +1100 s4-ldb: show the OID of any unhandled critical controls It isn't very useful just saying that a control is not supported, without saying which one is the problem Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit f8320b3559956b06d3b54e7707986d03aa5084f3 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 17:12:28 2009 +1100 s4-ldb: fixed a transaction error on prepare_commit when a prepare commit fails, we need to give a cancel to all modules, not a commit! Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit e14c72877fa87e0e6ba0f637dd3367160f8d52b1 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 14:58:35 2009 +1100 s4-ldb: added --show-deactivated-link command line option this adds the SHOW_DEACTIVATED_LINK control commit f9302f9e08d68f6fd974e02668c2bae273981688 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 14:57:32 2009 +1100 ldap: give a debug error when we don't know a control This interface should really have a proper error interface, but at least a DEBUG() gives the user a chance of finding the error Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 6c2125572cfbcd1878dfe99893ddae37f95d1f6e Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 13:41:21 2009 +1100 s4-dsdb: added dsdb_get_deleted_objects_dn() This is based on the code from Eduardo Lima <eduard...@gmail.com>, but uses the new helper functions added in the last couple of commits Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 3c1f18c5e2c3f56d512aa9a8cfab2f5698bafbb0 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 13:36:17 2009 +1100 s4-dsdb: added dsdb_find_nc_root() This is based on the function of the same name from Eduardo Lima <eduard...@gmail.com>, but using ldb_dn_compare, to give us comparisons consistent with what the rest of the code uses. We will use this function in combination with dsdb_wellknown_dn() to find the Deleted Objects container for any object. Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 7d0fdcae1e68f24a642e1b0fb0069ec54502fbb9 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 13:18:44 2009 +1100 s4-dsdb: added dsdb_wellknown_dn() This finds a wellknown object given its GUID Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit b7a74aca5e27213d1ff20b584c67a5bda407ce89 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 13:18:10 2009 +1100 libds: added GUIDs for wellknown AD objects Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 8a74633eaa9404ac43788a38c8bf3178b1101b1c Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 12:01:16 2009 +1100 s4-dsdb: added a dsdb_module_rename() call This will be used by the replmd_delete() code Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 9fa1f96172ffd2552a0e6b385b63e7d7dca024e7 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 11:32:57 2009 +1100 s4-dsdb: added dsdb_module_modify() This is used to do a sync modify in a module Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 4b970c00ae5a0b89dca4664725ab1fa1650490f0 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 11:31:30 2009 +1100 s4-dsdb: fixed dsdb_module_dn_by_guid() needs to ask for the DN in storage format, plus fix compilation errors commit cd4574ff847439ffe287187971d63a0c31bdc531 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 11:30:03 2009 +1100 s4-dsdb: dsdb_flags should be unsigned Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 57b10b664b49546234b8edc7efb64369460766ff Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 11:28:50 2009 +1100 s4-dsdb: rename dsdb_module_search_handle_flags to dsdb_request_add_controls This function will be used for non-search controls, like relax commit 951592687a29e15304d8e203b2b892aa40d7576f Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 10:27:32 2009 +1100 s4-dsdb: added dsdb_module_dn_by_guid() This finds a DN given a GUID, searching below the current module in the module stack. Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 32995e84a2c28d8781a0386906df58b9754af24a Author: Andrew Tridgell <tri...@samba.org> Date: Tue Dec 15 11:01:18 2009 +1100 s4-dsdb: use dsdb_dn_is_deleted_val() This also moves the check to before we parse the DN, which saves some unnecessary work Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 152f415ba8c289f85981f672b163816df9d4ad9f Author: Andrew Tridgell <tri...@samba.org> Date: Tue Dec 15 11:00:30 2009 +1100 s4-dsdb: added dsdb_dn_is_deleted_val() This is used to determine if a extedned DN has the 'DELETED=1' component Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit d31b6360d64eb821da07f4342093d1323db7b4dd Author: Andrew Tridgell <tri...@samba.org> Date: Wed Dec 16 09:32:10 2009 +1100 s4-ntvfs: try to fix bug 6989 bug 6989 is a rare crash that has occurred in production. My best guess as to the cause is the talloc_free() not being specific enough as to which parent needs to be freed. ----------------------------------------------------------------------- Summary of changes: libcli/ldap/ldap_message.c | 2 + libds/common/flags.h | 13 ++ source4/dsdb/common/util.c | 132 ++++++++++++++++++ source4/dsdb/samdb/ldb_modules/descriptor.c | 24 ++-- source4/dsdb/samdb/ldb_modules/extended_dn_out.c | 65 ++++------ source4/dsdb/samdb/ldb_modules/extended_dn_store.c | 4 +- source4/dsdb/samdb/ldb_modules/lazy_commit.c | 3 +- source4/dsdb/samdb/ldb_modules/operational.c | 29 +++-- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 8 +- source4/dsdb/samdb/ldb_modules/samldb.c | 2 +- source4/dsdb/samdb/ldb_modules/show_deleted.c | 7 +- source4/dsdb/samdb/ldb_modules/util.c | 140 +++++++++++++++++++- source4/lib/ldb/common/ldb.c | 4 +- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 13 ++- source4/lib/ldb/tools/cmdline.c | 9 +- source4/ntvfs/posix/pvfs_wait.c | 4 +- 16 files changed, 368 insertions(+), 91 deletions(-) Changeset truncated at 500 lines: diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c index 8b0f8a2..1e44214 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -668,6 +668,8 @@ _PUBLIC_ bool ldap_encode(struct ldap_message *msg, if (!ldap_encode_control(mem_ctx, data, control_handlers, msg->controls[i])) { + DEBUG(1,("Unable to encode control %s\n", + msg->controls[i]->oid)); return false; } } diff --git a/libds/common/flags.h b/libds/common/flags.h index 46d0372..40e40c3 100644 --- a/libds/common/flags.h +++ b/libds/common/flags.h @@ -190,3 +190,16 @@ #define DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL 0x00000004 #define DS_NTDSDSA_OPT_DISABLE_NTDSCONN_XLATE 0x00000008 #define DS_NTDSDSA_OPT_DISABLE_SPN_REGISTRATION 0x00000010 + +/* wellknown GUID strings for AD objects. See MS-ADTS 7.1.1.4 */ +#define DS_GUID_COMPUTERS_CONTAINER "AA312825768811D1ADED00C04FD8D5CD" +#define DS_GUID_DELETED_OBJECTS_CONTAINER "18E2EA80684F11D2B9AA00C04F79F805" +#define DS_GUID_DOMAIN_CONTROLLERS_CONTAINER "A361B2FFFFD211D1AA4B00C04FD7D83A" +#define DS_GUID_FOREIGNSECURITYPRINCIPALS_CONTAINER "22B70C67D56E4EFB91E9300FCA3DC1AA" +#define DS_GUID_INFRASTRUCTURE_CONTAINER "2FBAC1870ADE11D297C400C04FD8D5CD" +#define DS_GUID_LOSTANDFOUND_CONTAINER "AB8153B7768811D1ADED00C04FD8D5CD" +#define DS_GUID_MICROSOFT_PROGRAM_DATA_CONTAINER "F4BE92A4C777485E878E9421D53087DB" +#define DS_GUID_NTDS_QUOTAS_CONTAINER "6227F0AF1FC2410D8E3BB10615BB5B0F" +#define DS_GUID_PROGRAM_DATA_CONTAINER "09460C08AE1E4A4EA0F64AEE7DAA1E5A" +#define DS_GUID_SYSTEMS_CONTAINER "AB1D30F3768811D1ADED00C04FD8D5CD" +#define DS_GUID_USERS_CONTAINER "A9D1CA15768811D1ADED00C04FD8D5CD" diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 5b8365a..b437d08 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -2736,3 +2736,135 @@ NTSTATUS dsdb_get_extended_dn_guid(struct ldb_dn *dn, struct GUID *guid) return GUID_from_ndr_blob(v, guid); } + +/* + return true if a ldb_val containing a DN in storage form is deleted + */ +bool dsdb_dn_is_deleted_val(struct ldb_val *val) +{ + /* this relies on the sort order and exact format of + linearized extended DNs */ + if (val->length >= 12 && + strncmp((const char *)val->data, "<DELETED=1>;", 12) == 0) { + return true; + } + return false; +} + +/* + return a DN for a wellknown GUID + */ +int dsdb_wellknown_dn(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, + struct ldb_dn *nc_root, const char *wk_guid, + struct ldb_dn **wkguid_dn) +{ + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + const char *attrs[] = { NULL }; + int ret; + struct ldb_dn *dn; + struct ldb_result *res; + + /* construct the magic WKGUID DN */ + dn = ldb_dn_new_fmt(tmp_ctx, samdb, "<WKGUID=%s,%s>", + wk_guid, ldb_dn_get_linearized(nc_root)); + if (!wkguid_dn) { + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = dsdb_search_dn_with_deleted(samdb, tmp_ctx, &res, dn, attrs); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + (*wkguid_dn) = talloc_steal(mem_ctx, res->msgs[0]->dn); + talloc_free(tmp_ctx); + return LDB_SUCCESS; +} + + +/* + find a NC root given a DN within the NC + */ +int dsdb_find_nc_root(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn, + struct ldb_dn **nc_root) +{ + const char *root_attrs[] = { "namingContexts", NULL }; + TALLOC_CTX *tmp_ctx; + int ret; + struct ldb_message_element *el; + struct ldb_result *root_res; + int i; + struct ldb_dn **nc_dns; + + tmp_ctx = talloc_new(samdb); + if (tmp_ctx == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_search(samdb, tmp_ctx, &root_res, + ldb_dn_new(tmp_ctx, samdb, ""), LDB_SCOPE_BASE, root_attrs, NULL); + if (ret) { + DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(samdb))); + talloc_free(tmp_ctx); + return ret; + } + + el = ldb_msg_find_element(root_res->msgs[0], "namingContexts"); + if (!el) { + DEBUG(1,("Finding namingContexts element in root_res failed: %s\n", + ldb_errstring(samdb))); + talloc_free(tmp_ctx); + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + + nc_dns = talloc_array(tmp_ctx, struct ldb_dn *, el->num_values); + if (!nc_dns) { + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i=0; i<el->num_values; i++) { + nc_dns[i] = ldb_dn_from_ldb_val(nc_dns, samdb, &el->values[i]); + if (nc_dns[i] == NULL) { + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + qsort(nc_dns, el->num_values, sizeof(nc_dns[0]), (comparison_fn_t)ldb_dn_compare); + + for (i=0; i<el->num_values; i++) { + if (ldb_dn_compare_base(nc_dns[i], dn) == 0) { + (*nc_root) = talloc_steal(mem_ctx, nc_dns[i]); + talloc_free(tmp_ctx); + return LDB_SUCCESS; + } + } + + talloc_free(tmp_ctx); + return LDB_ERR_NO_SUCH_OBJECT; +} + + +/* + find the deleted objects DN for any object, by looking for the NC + root, then looking up the wellknown GUID + */ +int dsdb_get_deleted_objects_dn(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, struct ldb_dn *obj_dn, + struct ldb_dn **do_dn) +{ + struct ldb_dn *nc_root; + int ret; + + ret = dsdb_find_nc_root(ldb, mem_ctx, obj_dn, &nc_root); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = dsdb_wellknown_dn(ldb, mem_ctx, nc_root, DS_GUID_DELETED_OBJECTS_CONTAINER, do_dn); + talloc_free(nc_root); + return ret; +} diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c index 03cb1ff..7622f96 100644 --- a/source4/dsdb/samdb/ldb_modules/descriptor.c +++ b/source4/dsdb/samdb/ldb_modules/descriptor.c @@ -536,6 +536,11 @@ static int descriptor_search_callback(struct ldb_request *req, struct ldb_reply sd_flags = sdctr->secinfo_flags; /* we only care for the last 4 bits */ sd_flags = sd_flags & 0x0000000F; + if (sd_flags == 0) { + /* MS-ADTS 3.1.1.3.4.1.11 says that no bits + equals all 4 bits */ + sd_flags = 0xF; + } } switch (ares->type) { @@ -589,7 +594,6 @@ static int descriptor_do_mod(struct descriptor_context *ac) struct ldb_message *msg; struct ldb_control *sd_control; struct ldb_control *sd_control2; - struct ldb_control **saved_controls; int flags = 0; uint32_t sd_flags = 0; @@ -646,13 +650,10 @@ static int descriptor_do_mod(struct descriptor_context *ac) if (ret != LDB_SUCCESS) { return ret; } - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ + /* mark it non-critical, so we don't get an error from the + backend, but mark that we've handled it */ if (sd_control) { - if (!save_controls(sd_control, mod_req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } + sd_control->critical = 0; } return ldb_next_request(ac->module, mod_req); @@ -836,7 +837,6 @@ static int descriptor_search(struct ldb_module *module, struct ldb_request *req) int ret; struct ldb_context *ldb; struct ldb_control *sd_control; - struct ldb_control **saved_controls; struct ldb_request *down_req; struct descriptor_context *ac; @@ -862,13 +862,9 @@ static int descriptor_search(struct ldb_module *module, struct ldb_request *req) if (ret != LDB_SUCCESS) { return ret; } - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ + /* mark it as handled */ if (sd_control) { - if (!save_controls(sd_control, down_req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } + sd_control->critical = 0; } return ldb_next_request(ac->module, down_req); diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c index 987a3b3..2d0ee6a 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c @@ -434,6 +434,28 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares, struct ldb_dn *dn; struct dsdb_dn *dsdb_dn = NULL; struct ldb_val *plain_dn = &msg->elements[i].values[j]; + + if (!checked_reveal_control) { + have_reveal_control = + ldb_request_get_control(req, LDB_CONTROL_REVEAL_INTERNALS) != NULL; + checked_reveal_control = true; + } + + /* this is a fast method for detecting deleted + linked attributes, working on the unparsed + ldb_val */ + 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--; + continue; + } + + dsdb_dn = dsdb_dn_parse(msg, ldb, plain_dn, attribute->syntax->ldap_oid); if (!dsdb_dn || !ldb_dn_validate(dsdb_dn->dn)) { @@ -447,31 +469,6 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares, } dn = dsdb_dn->dn; - if (!checked_reveal_control) { - have_reveal_control = - ldb_request_get_control(req, LDB_CONTROL_REVEAL_INTERNALS) != NULL; - checked_reveal_control = true; - } - - /* this is a fast method for detecting deleted - linked attributes. It relies on the - linearization of extended DNs sorting by name, - and "DELETED" being the first name */ - if (plain_dn->length >= 12 && - strncmp((const char *)plain_dn->data, "<DELETED=1>;", 12) == 0) { - if (!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--; - continue; - } - } - /* don't let users see the internal extended GUID components */ if (!have_reveal_control) { @@ -556,7 +553,6 @@ static int extended_dn_out_search(struct ldb_module *module, struct ldb_request struct ldb_control *control; struct ldb_control *storage_format_control; struct ldb_extended_dn_control *extended_ctrl = NULL; - struct ldb_control **saved_controls; struct extended_search_context *ac; struct ldb_request *down_req; char **new_attrs; @@ -655,24 +651,13 @@ static int extended_dn_out_search(struct ldb_module *module, struct ldb_request return ret; } - /* Remove extended DN and storage format controls */ - + /* mark extended DN and storage format controls as done */ if (control) { - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ - if (!save_controls(control, down_req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } + control->critical = 0; } if (storage_format_control) { - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ - if (!save_controls(storage_format_control, down_req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } + storage_format_control->critical = 0; } /* Add in dereference control, if we were asked to, we are diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c index 3a531c0..0b9a105 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c @@ -275,8 +275,8 @@ static int extended_store_replace(struct extended_dn_context *ac, return ret; } - ret = dsdb_module_search_handle_flags(ac->module, os->search_req, - DSDB_SEARCH_SHOW_DELETED|DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT); + ret = dsdb_request_add_controls(ac->module, os->search_req, + DSDB_SEARCH_SHOW_DELETED|DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT); if (ret != LDB_SUCCESS) { talloc_free(os); return ret; diff --git a/source4/dsdb/samdb/ldb_modules/lazy_commit.c b/source4/dsdb/samdb/ldb_modules/lazy_commit.c index 69ac99e..0502b2e 100644 --- a/source4/dsdb/samdb/ldb_modules/lazy_commit.c +++ b/source4/dsdb/samdb/ldb_modules/lazy_commit.c @@ -33,7 +33,6 @@ static int unlazy_op(struct ldb_module *module, struct ldb_request *req) { int ret; struct ldb_request *new_req; - struct ldb_control **saved_controls; struct ldb_control *control = ldb_request_get_control(req, LDB_CONTROL_SERVER_LAZY_COMMIT); if (!control) { return ldb_next_request(module, req); @@ -99,7 +98,7 @@ static int unlazy_op(struct ldb_module *module, struct ldb_request *req) return ret; } - save_controls(control, req, &saved_controls); + control->critical = 0; return ldb_next_request(module, new_req); } diff --git a/source4/dsdb/samdb/ldb_modules/operational.c b/source4/dsdb/samdb/ldb_modules/operational.c index 0ea4b79..3b1b13f 100644 --- a/source4/dsdb/samdb/ldb_modules/operational.c +++ b/source4/dsdb/samdb/ldb_modules/operational.c @@ -214,7 +214,8 @@ static const struct { enum op_remove { OPERATIONAL_REMOVE_ALWAYS, /* remove always */ - OPERATIONAL_REMOVE_UNASKED /* remove if not requested */ + OPERATIONAL_REMOVE_UNASKED,/* remove if not requested */ + OPERATIONAL_SD_FLAGS /* show if SD_FLAGS_OID set, or asked for */ }; /* @@ -225,7 +226,7 @@ static const struct { const char *attr; enum op_remove op; } operational_remove[] = { - { "nTSecurityDescriptor", OPERATIONAL_REMOVE_UNASKED }, + { "nTSecurityDescriptor", OPERATIONAL_SD_FLAGS }, { "parentGUID", OPERATIONAL_REMOVE_ALWAYS }, { "replPropertyMetaData", OPERATIONAL_REMOVE_UNASKED }, { "unicodePwd", OPERATIONAL_REMOVE_UNASKED }, @@ -244,7 +245,8 @@ static const struct { */ static int operational_search_post_process(struct ldb_module *module, struct ldb_message *msg, - const char * const *attrs) + const char * const *attrs, + bool sd_flags_set) { struct ldb_context *ldb; int i, a=0; @@ -253,18 +255,20 @@ static int operational_search_post_process(struct ldb_module *module, /* removed any attrs that should not be shown to the user */ for (i=0; i<ARRAY_SIZE(operational_remove); i++) { - struct ldb_message_element *el; - switch (operational_remove[i].op) { case OPERATIONAL_REMOVE_UNASKED: if (ldb_attr_in_list(attrs, operational_remove[i].attr)) { continue; } case OPERATIONAL_REMOVE_ALWAYS: - el = ldb_msg_find_element(msg, operational_remove[i].attr); - if (el) { - ldb_msg_remove_element(msg, el); + ldb_msg_remove_attr(msg, operational_remove[i].attr); + break; + case OPERATIONAL_SD_FLAGS: + if (sd_flags_set || + ldb_attr_in_list(attrs, operational_remove[i].attr)) { + continue; } + ldb_msg_remove_attr(msg, operational_remove[i].attr); break; } } @@ -321,6 +325,7 @@ struct operational_context { struct ldb_request *req; const char * const *attrs; + bool sd_flags_set; }; static int operational_callback(struct ldb_request *req, struct ldb_reply *ares) @@ -344,8 +349,9 @@ static int operational_callback(struct ldb_request *req, struct ldb_reply *ares) /* for each record returned post-process to add any derived attributes that have been asked for */ ret = operational_search_post_process(ac->module, - ares->message, - ac->attrs); + ares->message, + ac->attrs, + ac->sd_flags_set); if (ret != 0) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); @@ -432,6 +438,9 @@ static int operational_search(struct ldb_module *module, struct ldb_request *req } } + /* remember if the SD_FLAGS_OID was set */ + ac->sd_flags_set = (ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID) != NULL); + ret = ldb_build_search_req_ex(&down_req, ldb, ac, req->op.search.base, req->op.search.scope, diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 27e4ce0..3ae165c 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -405,7 +405,6 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; struct ldb_control *control; - struct ldb_control **saved_controls; struct replmd_replicated_request *ac; enum ndr_err_code ndr_err; struct ldb_request *down_req; @@ -639,10 +638,9 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) return ret; } - /* if a control is there remove if from the modified request */ - if (control && !save_controls(control, down_req, &saved_controls)) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; + /* mark the control done */ + if (control) { + control->critical = 0; } /* go on with the call chain */ diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index e49b493..fc286c4 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -1010,7 +1010,7 @@ static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac) if (ret != LDB_SUCCESS) { return ret; } - ret = dsdb_module_search_handle_flags(ac->module, req, DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT); -- Samba Shared Repository