[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Tue Feb 14 05:15:02 UTC 2017
The branch, master has been updated
via 4f558c9 repl_meta_data: Remove the correct forward link for dn+binary attributes
via 056b6b8 repl_meta_data: Add comment with some future improvements
via 75d523f repl_meta_data: Always sort the links when upgrading them
via 6ee0ace repl_meta_data: Bring replmd_check_upgrade_links() into get_parsed_dns_trusted()
via b6902fd python/tests: Add test for generated and duplicate mAPIIDs
via ec11d65 samldb: Allow automatic generation of mAPIIDs
via 1c16e8a torture/drs: Add a test for dn+binary linked attributes
via bfe423a torture/drs: run repl_schema in vampire_2000_dc environment as well
via 1983d07 selftest: add vampire_2000_dc environment
via 305cdce python/tests: add test for generated and duplicate linkIDs
via 373bd43 torture/drs: generate linkID for test rather than specifying
via 35be7ee samldb: Allow automatic generation of linkIDs and prevent duplicates
from 85d5b43 waf: Do not install the unit test binary for krb5samba
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 4f558c9ad6f9b8a947e33207473579655708eed0
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Oct 12 15:51:37 2015 +1300
repl_meta_data: Remove the correct forward link for dn+binary attributes
The previous code assumed that only plain DNs could be linked attributes.
We need to look over the list of attribute values and find the value
that causes this particular backlink to exist, so we can remove it.
We do not know (until we search) of the binary portion, so we must
search over all the attribute values at this layer, using the
parsed_dn_find() routine used elsewhere in this code.
Found attempting to demote an RODC in a clone of a Windows 2012R2
domain, due to the msDS-RevealedUsers attribute.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11139
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Tue Feb 14 06:14:35 CET 2017 on sn-devel-144
commit 056b6b8e5c5203d642cc2c9cbe2e9c36dff6bc56
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue Feb 14 12:11:19 2017 +1300
repl_meta_data: Add comment with some future improvements
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
commit 75d523f5792275b8aa357d0f266b0bc9b7a1c935
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue Feb 14 12:08:35 2017 +1300
repl_meta_data: Always sort the links when upgrading them
This allows us to know that the output of get_parsed_dns_trusted() is sorted, as an
upgraded attribute of FL2000 links would not otherwise be sorted in the DB
This allows us to delete linked objects that have a forward link from a
FL2000 style linked attribute once the DN+Binary patches land.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
commit 6ee0aceae17991d3eb665e9f19399be1a03b1ace
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue Feb 14 11:59:13 2017 +1300
repl_meta_data: Bring replmd_check_upgrade_links() into get_parsed_dns_trusted()
This eliminates a lot of duplicate code and allows us to know that we will
have a set of FL2003 style links in the parsed DNs to operate on
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
commit b6902fd637f22f2740d1ae1eb5ac73aadc9a0f30
Author: Bob Campbell <bobcampbell at catalyst.net.nz>
Date: Wed Feb 8 11:55:32 2017 +1300
python/tests: Add test for generated and duplicate mAPIIDs
Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit ec11d65bef7aaea155fb40e87a74210166eca7dd
Author: Bob Campbell <bobcampbell at catalyst.net.nz>
Date: Wed Feb 8 11:40:32 2017 +1300
samldb: Allow automatic generation of mAPIIDs
This allows us to conform to MS-ADTS 3.1.1.2.3.2, where the OID
1.2.840.113556.1.2.49 can be specified as the mAPIID of a new attribute
in the schema in order to automatically assign it an unused mAPIID.
Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 1c16e8abd28fd05ab169b7a6bc11f102264def3e
Author: Bob Campbell <bobcampbell at catalyst.net.nz>
Date: Fri Feb 3 10:34:14 2017 +1300
torture/drs: Add a test for dn+binary linked attributes
Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11139
commit bfe423a6607e2b80d1fd946bcaf303c0be2b757b
Author: Bob Campbell <bobcampbell at catalyst.net.nz>
Date: Fri Feb 3 10:33:54 2017 +1300
torture/drs: run repl_schema in vampire_2000_dc environment as well
This will be necessary as linked attributes are handled differently in
Windows 2000.
We also only check msDS-IntId if we have a functional level of > Windows
2000, as this attribute is not present on lower domain function levels.
Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11139
commit 1983d078f62d1e4f6597ef549f576e72285b25a5
Author: Bob Campbell <bobcampbell at catalyst.net.nz>
Date: Wed Feb 8 09:16:41 2017 +1300
selftest: add vampire_2000_dc environment
This is the equivalent of vampire_dc, but using a domain functional
level of DS_DOMAIN_FUNCTION_2000.
Using this functional level is useful for tests involving replication
and linked attributes, as they behave differently at it.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11139
Pair-programmed-with: Bob Campbell <bobcampbell at catalyst.net.nz>
commit 305cdcea8851d389aa7c6b9da69441c2aacee432
Author: Bob Campbell <bobcampbell at catalyst.net.nz>
Date: Thu Feb 2 09:46:26 2017 +1300
python/tests: add test for generated and duplicate linkIDs
Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11139
commit 373bd435425f85a0f24f9f14c36f76c51243a077
Author: Bob Campbell <bobcampbell at catalyst.net.nz>
Date: Tue Feb 7 15:42:29 2017 +1300
torture/drs: generate linkID for test rather than specifying
Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11139
commit 35be7ee8a49f000282859661fc6522c9d6c05020
Author: Bob Campbell <bobcampbell at catalyst.net.nz>
Date: Wed Feb 1 11:54:40 2017 +1300
samldb: Allow automatic generation of linkIDs and prevent duplicates
As per MS-ADTS 3.1.1.2.3.1, this allows specifying the OID
1.2.840.113556.1.2.50 as the linkID of a new linked attribute in the
schema in order to automatically assign it an unused even linkID.
Specifying the attributeID or ldapDisplayName of an existing forward
link will now also add the new linked attribute as the backlink of that
existing link.
This also prevents adding duplicate linkIDs. Previously, we could run
into issues when trying to delete backlinks with duplicate linkIDs.
Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11139
-----------------------------------------------------------------------
Summary of changes:
selftest/selftest.pl | 7 +
selftest/target/Samba.pm | 1 +
selftest/target/Samba4.pm | 46 ++-
source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 257 +++++++++++------
source4/dsdb/samdb/ldb_modules/samldb.c | 290 ++++++++++++++++++-
source4/dsdb/tests/python/ldap_schema.py | 361 ++++++++++++++++++++++++
source4/selftest/tests.py | 11 +-
source4/torture/drs/python/repl_schema.py | 91 +++++-
source4/torture/drs/rpc/msds_intid.c | 2 +-
9 files changed, 944 insertions(+), 122 deletions(-)
Changeset truncated at 500 lines:
diff --git a/selftest/selftest.pl b/selftest/selftest.pl
index bfc8d7f..45e0ae0 100755
--- a/selftest/selftest.pl
+++ b/selftest/selftest.pl
@@ -811,6 +811,13 @@ my @exported_envvars = (
"VAMPIRE_DC_NETBIOSNAME",
"VAMPIRE_DC_NETBIOSALIAS",
+ # domain controller stuff for FL 2000 Vampired DC
+ "VAMPIRE_2000_DC_SERVER",
+ "VAMPIRE_2000_DC_SERVER_IP",
+ "VAMPIRE_2000_DC_SERVER_IPV6",
+ "VAMPIRE_2000_DC_NETBIOSNAME",
+ "VAMPIRE_2000_DC_NETBIOSALIAS",
+
"PROMOTED_DC_SERVER",
"PROMOTED_DC_SERVER_IP",
"PROMOTED_DC_SERVER_IPV6",
diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
index 24484c9..e5c7f93 100644
--- a/selftest/target/Samba.pm
+++ b/selftest/target/Samba.pm
@@ -308,6 +308,7 @@ sub get_interface($)
$interfaces{"fakednsforwarder1"} = 36;
$interfaces{"fakednsforwarder2"} = 37;
$interfaces{"s4member_dflt"} = 38;
+ $interfaces{"vampire2000dc"} = 39;
# update lib/socket_wrapper/socket_wrapper.c
# #define MAX_WRAPPED_INTERFACES 40
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index dacdab4..8b5e699 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1246,15 +1246,20 @@ sub provision_promoted_dc($$$)
sub provision_vampire_dc($$$)
{
- my ($self, $prefix, $dcvars) = @_;
- print "PROVISIONING VAMPIRE DC...\n";
+ my ($self, $prefix, $dcvars, $fl) = @_;
+ print "PROVISIONING VAMPIRE DC @ FL $fl...\n";
+ my $name = "localvampiredc";
+
+ if ($fl == "2000") {
+ $name = "vampire2000dc";
+ }
# We do this so that we don't run the provision. That's the job of 'net vampire'.
my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
- "localvampiredc",
- "SAMBADOMAIN",
- "samba.example.com",
- "2008",
+ $name,
+ $dcvars->{DOMAIN},
+ $dcvars->{REALM},
+ $fl,
$dcvars->{PASSWORD},
$dcvars->{SERVER_IP},
$dcvars->{SERVER_IPV6});
@@ -1299,11 +1304,17 @@ sub provision_vampire_dc($$$)
return undef;
}
- $ret->{VAMPIRE_DC_SERVER} = $ret->{SERVER};
- $ret->{VAMPIRE_DC_SERVER_IP} = $ret->{SERVER_IP};
- $ret->{VAMPIRE_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
- $ret->{VAMPIRE_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
-
+ if ($fl == "2000") {
+ $ret->{VAMPIRE_2000_DC_SERVER} = $ret->{SERVER};
+ $ret->{VAMPIRE_2000_DC_SERVER_IP} = $ret->{SERVER_IP};
+ $ret->{VAMPIRE_2000_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
+ $ret->{VAMPIRE_2000_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
+ } else {
+ $ret->{VAMPIRE_DC_SERVER} = $ret->{SERVER};
+ $ret->{VAMPIRE_DC_SERVER_IP} = $ret->{SERVER_IP};
+ $ret->{VAMPIRE_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
+ $ret->{VAMPIRE_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
+ }
$ret->{DC_SERVER} = $dcvars->{DC_SERVER};
$ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
$ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
@@ -2002,6 +2013,11 @@ sub setup_env($$$)
return $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
} elsif ($envname eq "fl2000dc") {
return $self->setup_fl2000dc("$path/fl2000dc");
+ } elsif ($envname eq "vampire_2000_dc") {
+ if (not defined($self->{vars}->{fl2000dc})) {
+ $self->setup_fl2000dc("$path/fl2000dc");
+ }
+ return $self->setup_vampire_dc("$path/vampire_2000_dc", $self->{vars}->{fl2000dc}, "2000");
} elsif ($envname eq "fl2003dc") {
if (not defined($self->{vars}->{ad_dc})) {
$self->setup_ad_dc("$path/ad_dc");
@@ -2021,7 +2037,7 @@ sub setup_env($$$)
if (not defined($self->{vars}->{ad_dc_ntvfs})) {
$self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
}
- return $self->setup_vampire_dc("$path/vampire_dc", $self->{vars}->{ad_dc_ntvfs});
+ return $self->setup_vampire_dc("$path/vampire_dc", $self->{vars}->{ad_dc_ntvfs}, "2008");
} elsif ($envname eq "promoted_dc") {
if (not defined($self->{vars}->{ad_dc_ntvfs})) {
$self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
@@ -2211,11 +2227,11 @@ sub setup_fl2008r2dc($$$)
return $env;
}
-sub setup_vampire_dc($$$)
+sub setup_vampire_dc($$$$)
{
- my ($self, $path, $dc_vars) = @_;
+ my ($self, $path, $dc_vars, $fl) = @_;
- my $env = $self->provision_vampire_dc($path, $dc_vars);
+ my $env = $self->provision_vampire_dc($path, $dc_vars, $fl);
if (defined $env) {
if (not defined($self->check_or_start($env, "single"))) {
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 6e041c7..e3bf032 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -101,8 +101,18 @@ struct replmd_replicated_request {
bool isDeleted;
};
+struct parsed_dn {
+ struct dsdb_dn *dsdb_dn;
+ struct GUID guid;
+ struct ldb_val *v;
+};
+
static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar);
static int replmd_delete_internals(struct ldb_module *module, struct ldb_request *req, bool re_delete);
+static int replmd_check_upgrade_links(struct ldb_context *ldb,
+ struct parsed_dn *dns, uint32_t count,
+ struct ldb_message_element *el,
+ const char *ldap_oid);
enum urgent_situation {
REPL_URGENT_ON_CREATE = 1,
@@ -862,12 +872,6 @@ static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct ds
const struct GUID *invocation_id, uint64_t seq_num,
uint64_t local_usn, NTTIME nttime, uint32_t version, bool deleted);
-struct parsed_dn {
- struct dsdb_dn *dsdb_dn;
- struct GUID guid;
- struct ldb_val *v;
-};
-
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);
@@ -2073,6 +2077,9 @@ static int get_parsed_dns(struct ldb_module *module, TALLOC_CTX *mem_ctx,
* GUID, even though the GUIDs might not be known. That works because we trust
* the database to give us the elements like that if the
* replmd_private->sorted_links flag is set.
+ *
+ * We also ensure that the links are in the Functional Level 2003
+ * linked attributes format.
*/
static int get_parsed_dns_trusted(struct ldb_module *module,
struct replmd_private *replmd_private,
@@ -2083,7 +2090,7 @@ static int get_parsed_dns_trusted(struct ldb_module *module,
struct ldb_request *parent)
{
unsigned int i;
-
+ int ret;
if (el == NULL) {
*pdn = NULL;
return LDB_SUCCESS;
@@ -2093,19 +2100,41 @@ static int get_parsed_dns_trusted(struct ldb_module *module,
/* We need to sort the list. This is the slow old path we want
to avoid.
*/
- return get_parsed_dns(module, mem_ctx, el, pdn, ldap_oid,
+ ret = get_parsed_dns(module, mem_ctx, el, pdn, ldap_oid,
parent);
- }
- /* Here we get a list of 'struct parsed_dns' without the parsing */
- *pdn = talloc_zero_array(mem_ctx, struct parsed_dn,
- el->num_values);
- if (!*pdn) {
- ldb_module_oom(module);
- return LDB_ERR_OPERATIONS_ERROR;
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ } else {
+ /* Here we get a list of 'struct parsed_dns' without the parsing */
+ *pdn = talloc_zero_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++) {
+ (*pdn)[i].v = &el->values[i];
+ }
}
- for (i = 0; i < el->num_values; i++) {
- (*pdn)[i].v = &el->values[i];
+ /*
+ * This upgrades links to FL2003 style, and sorts the result
+ * if that was needed.
+ *
+ * TODO: Add a database feature that asserts we have no FL2000
+ * style links to avoid this check or add a feature that
+ * uses a similar check to find sorted/unsorted links
+ * for an on-the-fly upgrade.
+ */
+
+ ret = replmd_check_upgrade_links(ldb_module_get_ctx(module),
+ *pdn, el->num_values,
+ el,
+ ldap_oid);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
return LDB_SUCCESS;
@@ -2208,10 +2237,10 @@ static int replmd_update_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct d
static int replmd_check_upgrade_links(struct ldb_context *ldb,
struct parsed_dn *dns, uint32_t count,
struct ldb_message_element *el,
- const struct GUID *invocation_id,
const char *ldap_oid)
{
uint32_t i;
+ const struct GUID *invocation_id = NULL;
for (i=0; i<count; i++) {
NTSTATUS status;
uint32_t version;
@@ -2243,6 +2272,14 @@ static int replmd_check_upgrade_links(struct ldb_context *ldb,
continue;
}
+ if (invocation_id == NULL) {
+ invocation_id = samdb_ntds_invocation_id(ldb);
+ if (invocation_id == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ }
+
+
/* it's an old one that needs upgrading */
ret = replmd_update_la_val(el->values, dns[i].v,
dns[i].dsdb_dn, dns[i].dsdb_dn,
@@ -2251,6 +2288,19 @@ static int replmd_check_upgrade_links(struct ldb_context *ldb,
return ret;
}
}
+
+ /*
+ * This sort() is critical for the operation of
+ * get_parsed_dns_trusted() because callers of this function
+ * expect a sorted list, and FL2000 style links are not
+ * sorted. In particular, as well as the upgrade case,
+ * get_parsed_dns_trusted() is called from
+ * replmd_delete_remove_link() even in FL2000 mode
+ *
+ * We do not normally pay the cost of the qsort() due to the
+ * early return in the RMD_VERSION found case.
+ */
+ TYPESAFE_QSORT(dns, count, parsed_dn_compare);
return LDB_SUCCESS;
}
@@ -2381,9 +2431,14 @@ static int replmd_modify_la_add(struct ldb_module *module,
const struct GUID *invocation_id;
struct ldb_context *ldb = ldb_module_get_ctx(module);
NTTIME now;
-
unix_to_nt_time(&now, t);
+ invocation_id = samdb_ntds_invocation_id(ldb);
+ if (!invocation_id) {
+ talloc_free(tmp_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
/* get the DNs to be added, fully parsed.
*
* We need full parsing because they came off the wire and we don't
@@ -2407,20 +2462,6 @@ static int replmd_modify_la_add(struct ldb_module *module,
return ret;
}
- invocation_id = samdb_ntds_invocation_id(ldb);
- if (!invocation_id) {
- talloc_free(tmp_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ret = replmd_check_upgrade_links(ldb, old_dns, old_num_values,
- old_el, invocation_id,
- schema_attr->syntax->ldap_oid);
- if (ret != LDB_SUCCESS) {
- talloc_free(tmp_ctx);
- return ret;
- }
-
max_num_values = old_num_values + el->num_values;
if (max_num_values < old_num_values) {
DEBUG(0, ("we seem to have overflow in replmd_modify_la_add. "
@@ -2597,16 +2638,21 @@ static int replmd_modify_la_delete(struct ldb_module *module,
struct parsed_dn *dns, *old_dns;
TALLOC_CTX *tmp_ctx = NULL;
int ret;
- const struct GUID *invocation_id;
struct ldb_context *ldb = ldb_module_get_ctx(module);
struct ldb_control *vanish_links_ctrl = NULL;
bool vanish_links = false;
unsigned int num_to_delete = el->num_values;
uint32_t rmd_flags;
+ const struct GUID *invocation_id;
NTTIME now;
unix_to_nt_time(&now, t);
+ invocation_id = samdb_ntds_invocation_id(ldb);
+ if (!invocation_id) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
if (old_el == NULL || old_el->num_values == 0) {
/* there is nothing to delete... */
if (num_to_delete == 0) {
@@ -2637,20 +2683,6 @@ static int replmd_modify_la_delete(struct ldb_module *module,
return ret;
}
- invocation_id = samdb_ntds_invocation_id(ldb);
- if (!invocation_id) {
- talloc_free(tmp_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ret = replmd_check_upgrade_links(ldb, old_dns, old_el->num_values,
- old_el, invocation_id,
- schema_attr->syntax->ldap_oid);
- if (ret != LDB_SUCCESS) {
- talloc_free(tmp_ctx);
- return ret;
- }
-
if (parent) {
vanish_links_ctrl = ldb_request_get_control(parent, DSDB_CONTROL_REPLMD_VANISH_LINKS);
if (vanish_links_ctrl) {
@@ -2863,6 +2895,11 @@ static int replmd_modify_la_replace(struct ldb_module *module,
unix_to_nt_time(&now, t);
+ invocation_id = samdb_ntds_invocation_id(ldb);
+ if (!invocation_id) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
/*
* The replace operation is unlike the replace and delete cases in that
* we need to look at every existing link to see whether it is being
@@ -2908,13 +2945,8 @@ static int replmd_modify_la_replace(struct ldb_module *module,
return ret;
}
- invocation_id = samdb_ntds_invocation_id(ldb);
- if (!invocation_id) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
ret = replmd_check_upgrade_links(ldb, old_dns, old_num_values,
- old_el, invocation_id, ldap_oid);
+ old_el, ldap_oid);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ret;
@@ -3625,7 +3657,9 @@ static int replmd_rename_callback(struct ldb_request *req, struct ldb_reply *are
*/
static int replmd_delete_remove_link(struct ldb_module *module,
const struct dsdb_schema *schema,
+ struct replmd_private *replmd_private,
struct ldb_dn *dn,
+ struct GUID *guid,
struct ldb_message_element *el,
const struct dsdb_attribute *sa,
struct ldb_request *parent)
@@ -3636,14 +3670,19 @@ static int replmd_delete_remove_link(struct ldb_module *module,
for (i=0; i<el->num_values; i++) {
struct dsdb_dn *dsdb_dn;
- NTSTATUS status;
int ret;
- struct GUID guid2;
struct ldb_message *msg;
const struct dsdb_attribute *target_attr;
struct ldb_message_element *el2;
+ const char *dn_str;
struct ldb_val dn_val;
uint32_t dsdb_flags = 0;
+ const char *attrs[] = { NULL, NULL };
+ struct ldb_result *link_res;
+ struct ldb_message *link_msg;
+ struct ldb_message_element *link_el;
+ struct parsed_dn *link_dns;
+ struct parsed_dn *p = NULL, *unused = NULL;
if (dsdb_dn_is_deleted_val(&el->values[i])) {
continue;
@@ -3655,12 +3694,6 @@ static int replmd_delete_remove_link(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
- status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &guid2, "GUID");
- if (!NT_STATUS_IS_OK(status)) {
- talloc_free(tmp_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
/* remove the link */
msg = ldb_msg_new(tmp_ctx);
if (!msg) {
@@ -3676,14 +3709,74 @@ static int replmd_delete_remove_link(struct ldb_module *module,
if (target_attr == NULL) {
continue;
}
+ attrs[0] = target_attr->lDAPDisplayName;
- ret = ldb_msg_add_empty(msg, target_attr->lDAPDisplayName, LDB_FLAG_MOD_DELETE, &el2);
+ ret = ldb_msg_add_empty(msg, target_attr->lDAPDisplayName,
+ LDB_FLAG_MOD_DELETE, &el2);
if (ret != LDB_SUCCESS) {
ldb_module_oom(module);
talloc_free(tmp_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
- dn_val = data_blob_string_const(ldb_dn_get_linearized(dn));
+
+ ret = dsdb_module_search_dn(module, tmp_ctx, &link_res,
+ msg->dn, attrs,
+ DSDB_FLAG_NEXT_MODULE |
+ DSDB_SEARCH_SHOW_EXTENDED_DN,
+ parent);
+
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ link_msg = link_res->msgs[0];
+ link_el = ldb_msg_find_element(link_msg,
+ target_attr->lDAPDisplayName);
+ if (link_el == NULL) {
+ talloc_free(tmp_ctx);
+ return LDB_ERR_NO_SUCH_ATTRIBUTE;
+ }
+
+ /*
+ * This call 'upgrades' the links in link_dns, but we
+ * do not commit the result back into the database, so
+ * this is safe to call in FL2000 or on databases that
+ * have been run at that level in the past.
+ */
+ ret = get_parsed_dns_trusted(module, replmd_private, tmp_ctx,
+ link_el, &link_dns,
+ target_attr->syntax->ldap_oid, parent);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ ret = parsed_dn_find(ldb, link_dns, link_el->num_values,
+ guid, dn, &p, &unused,
+ target_attr->syntax->ldap_oid);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ if (p == NULL) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(module),
+ "Failed to find forward link on %s "
+ "as %s to remove backlink %s on %s",
+ ldb_dn_get_linearized(msg->dn),
+ target_attr->lDAPDisplayName,
+ sa->lDAPDisplayName,
+ ldb_dn_get_linearized(dn));
+ talloc_free(tmp_ctx);
+ return LDB_ERR_NO_SUCH_ATTRIBUTE;
+ }
+
+
+ /* This needs to get the Binary DN, by first searching */
+ dn_str = dsdb_dn_get_linearized(tmp_ctx,
+ p->dsdb_dn);
--
Samba Shared Repository
More information about the samba-cvs
mailing list