[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Fri Oct 20 06:02:02 UTC 2017


The branch, master has been updated
       via  da8af83 selftest: Print link meta-data when developer debugging is used
       via  9b3b09c replmd: Remove unnecessary replmd_build_la_val() param
       via  cd936a7 replmd: Get rid of duplicated replmd_build_la_val() code
       via  4cb260f replmd: Fix RMD_VERSION inital value to match Windows
       via  cef17ce replmd: Remove static values passed to replmd_build_la_val()
       via  499fa6b selftest: Add test for initial link attribute RMD_VERSION value
       via  8319536 replmd: Small refactor to replmd_check_singleval_la_conflict()
       via  c83dffc replmd: Change replmd_check_singleval_la_conflict() logic flow
       via  841e724 replmd: Move link conflict handling into separate function
       via  82b56e6 replmd: Handle single-valued conflicts for an existing link
       via  f36b2bb replmd: Mark link conflicts as inactive correctly
       via  7649652 replmd: Use replmd_set_la_val() when adding new links
       via  f183dcf replmd: Fix talloc inconsistency in replmd_set_la_val()
       via  a607a3e replmd: Make replmd_set_la_val() closer to replmd_build_la_val()
       via  f196897 replmd: Handle conflicts for single-valued link attributes better
       via  70d532a replmd: Partial fix for single-valued link conflict
       via  20c0f3e selftest: Add conflict test where the single-valued link already exists
       via  77abba5 selftest: Add test for deleted single-valued link conflict
       via  9c54e74 selftest: Make sure single-link conflict retains the deleted link
       via  c9ea47e replmd: Remove unused originating_usn variable
       via  21179fe replmd: Refactor logic to check if replicated link is newer
       via  91951d8 replmd: Refactor adding the backlink in replmd_process_linked_attribute()
       via  593dacd replace: Link to -lbsd when building replace.c by hand
       via  9c207ad s3:cli_netlogon: let rpccli_connect_netlogon() retry once after NT_STATUS_NETWORK_ACCESS_DENIED
       via  90d57ec s3:cli_netlogon: make sure rpccli_connect_netlogon only returns NT_STATUS_OK on success
      from  1d1e1da s3:tests: Fix the smblcient utimes test in Europe

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit da8af833cfd2f3368d386621a0dd4e68dccb7a90
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Wed Sep 27 11:21:48 2017 +1300

    selftest: Print link meta-data when developer debugging is used
    
    For Windows, DRS is the only way to see the RMD_VERSION of a link, or to
    tell what inactive links the DC. Add some debug to display this
    information. By default, this debug is turned off.
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Fri Oct 20 08:01:35 CEST 2017 on sn-devel-144

commit 9b3b09ce41b2ef4989656e4b6304e62be5f3095f
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 16:13:05 2017 +1300

    replmd: Remove unnecessary replmd_build_la_val() param
    
    replmd_build_la_val() is creating a new link attribute. In this case,
    the RMD_ORIGINATING_USN and RMD_LOCAL_USN are always going to be the
    same thing, so we don't need to pass them in as 2 separate parameters.
    
    This isn't required for any bug fix, but is just a general code
    tidy-up.
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit cd936a725cb7f651fef99dac59569947a31aaa70
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 15:48:58 2017 +1300

    replmd: Get rid of duplicated replmd_build_la_val() code
    
    replmd_build_la_val() and replmd_set_la_val() are pretty much identical.
    Keep the replmd_build_la_val() API (as it makes it clearer we're
    creating a new linked attribute), but replace the code with a call to
    replmd_set_la_val().
    
    This isn't required for any bug fix, but is just a general tidy-up to
    avoid code duplication.
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4cb260f8c06edd3ab1f9a52867fc4d8124ebb0b5
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 15:09:34 2017 +1300

    replmd: Fix RMD_VERSION inital value to match Windows
    
    The initial value for RMD_VERSION is one on Windows. The MS-DRSR spec
    states the following in section 5.11 AttributeStamp:
    
      dwVersion: A 32-bit integer. Set to 1 when a value for the attribute is
      set for the first time. On each subsequent originating update, if the
      current value of dwVersion is less than 0xFFFFFFFF, then increment it
      by 1; otherwise set it to 0
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13059
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit cef17ce4f04bacb50193cb7e7a2cfd53fdf61110
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 15:01:21 2017 +1300

    replmd: Remove static values passed to replmd_build_la_val()
    
    replmd_build_la_val() is used to populate a new link attribute value
    from scratch. The version parameter is always passed in as the initial
    value (zero), and deleted is always passed in as false.
    
    For cases (like replication) where we want to set version/deleted to
    something other than the defaults, we can use replmd_set_la_val()
    instead.
    
    This patch changes these 2 parameters to variables instead.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13059
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 499fa6b4a68f93f20df00dc776637fc93ae4c37b
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 14:42:08 2017 +1300

    selftest: Add test for initial link attribute RMD_VERSION value
    
    While testing link conflicts I noticed that links on Windows start from
    a different RMD_VERSION compared to Samba. This adds a simple test to
    highlight the problem.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13059
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 831953656590c1d4725d2d798d3d6cdee8499513
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 12:10:11 2017 +1300

    replmd: Small refactor to replmd_check_singleval_la_conflict()
    
    Now that the code is all in one place we can refactor it to make it
    slightly more readable.
    
    - added more code comments
    - tweaked the 'no conflict' return logic to try to make what it's checking
      for more obvious
    - removed conflict_pdn (we can just use active_pdn instead)
    - added a placeholder variable and tweaked a parameter name
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c83dffc6f1cc30be4cad404c4b5f5c3213d27b9f
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 12:01:34 2017 +1300

    replmd: Change replmd_check_singleval_la_conflict() logic flow
    
    Return immediately if there's no conflict, which reduces nesting.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 841e724e29be6c97a6bc2cfd8a97778b02aa77ca
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 10:22:55 2017 +1300

    replmd: Move link conflict handling into separate function
    
    Link conflict handling is a corner-case. The logic in
    replmd_process_linked_attribute() is already reasonably busy/complex.
    Split out the handling of link conflicts into a separate function so
    that it doesn't detract from the core replmd_process_linked_attribute()
    logic too much.
    
    This refactor should not alter functionality.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 82b56e63b5cb7e19a580a7cdeaf1caa8608852bc
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 09:42:14 2017 +1300

    replmd: Handle single-valued conflicts for an existing link
    
    Currently the code only handles the case where the received link
    attribute is a new link (i.e. pdn == NULL). As well as this, we need to
    handle the case where the conflicting link already exists, i.e. it's a
    deleted link that has been re-added on another DC.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f36b2bb126ccdc9a68b3b51b999f59090c7d8b82
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Wed Sep 27 16:37:59 2017 +1300

    replmd: Mark link conflicts as inactive correctly
    
    The previous patch to handle link conflicts was simply overriding the
    received information and marking the link as deleted. We should be doing
    this as a separate operation to make it clear what has happened, and so
    that the new (i.e. inactive) link details get replicated out.
    
    This patch changes it so that when a conflict occurs, we immediately
    overwrite the received information to mark it as deleted, and to update
    the version/USN/timestamp/originating_invocation_id to make it clear
    that this is a new change.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7649652b636fcc6997377a94ee7b4bc8fec4ffbb
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Wed Sep 27 16:23:29 2017 +1300

    replmd: Use replmd_set_la_val() when adding new links
    
    replmd_set_la_val() and replmd_build_la_val() are almost identical. When
    we were processing the replicated link attributes we were calling one
    function if the link was new, and a different one if the link existed.
    I think we should be able to get away with using replmd_set_la_val() in
    both cases.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f183dcfad56c7eb9b188dcfbf4d4b7a2598ef08c
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 16:19:29 2017 +1300

    replmd: Fix talloc inconsistency in replmd_set_la_val()
    
    All the other talloc_asprintf()s in this function use the mem_ctx, but
    for some reason the vstring was using the dsdb_dn->dn. This probably
    isn't a big deal, but might have unintentional side-effects.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a607a3e83e1f355b73057af235f385c6db98f5c4
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Thu Sep 28 15:58:16 2017 +1300

    replmd: Make replmd_set_la_val() closer to replmd_build_la_val()
    
    These two functions are almost identical. The main difference between
    them is the RMD_ADDTIME. replmd_set_la_val() tries to use the
    RMD_ADDTIME of the old_dsdb_dn. Whereas replmd_build_la_val() always
    uses the time passed in.
    
    Change replmd_set_la_val() so it can accept a NULL old_dsdb_dn (i.e. if
    it's a new linked attribute that's being set). If so, it'll end up using
    the nttime parameter passed in, same as replmd_build_la_val() does.
    
    Also update replmd_process_linked_attribute (which used to use
    replmd_build_la_val()) to now pass in a NULL old_dsdb_dn. There
    shouldn't be a difference in behaviour either way, but this exercises
    the code change.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f196897bc822f7133627477e77a4bcd98b8ceda6
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Wed Sep 27 13:44:29 2017 +1300

    replmd: Handle conflicts for single-valued link attributes better
    
    If 2 DCs independently set a single-valued linked attribute to differing
    values, Samba should be able to resolve this problem when replication
    occurs.
    
    If the received information is better, then we want to set the existing
    link attribute in our DB as inactive.
    
    If our own information is better, then we still want to add the received
    link attribute, but mark it as inactive so that it doesn't clobber our
    own link.
    
    This still isn't a complete solution. When we add the received attribute
    as inactive, we really should be incrementing the version, updating the
    USN, etc. Also this only deals with the case where the received link is
    completely new (i.e. a received link conflicting with an existing
    inactive link isn't handled).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 70d532a5c79dc386bf55db1d32865044872a6905
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Tue Sep 19 11:59:58 2017 +1200

    replmd: Partial fix for single-valued link conflict
    
    This is the first part of the fix for resolving a single-valued link
    conflict.
    
    When processing the replication data for a linked attribute, if we don't
    find a match for the link target value, check if the link is a
    single-valued attribute and it currently has an active link. If so, then
    use the active link instead.
    
    This change means we delete the existing active link (and backlink)
    before adding the new link. This prevents the failure in the subsequent
    dsdb_check_single_valued_link() check that was happening previously
    (because the link would end up with 2 active values).
    
    This is only a partial fix. It stops replication from failing completely
    if we ever hit this situation (which means the test is no longer
    hitting an assertion when replicating). However, ideally the existing
    active link should be retained and just marked as deleted (with this
    change, the existing link is overwritten completely).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 20c0f3e1e91baac2a359d02ee617c17cbbc32072
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Wed Sep 27 14:43:53 2017 +1300

    selftest: Add conflict test where the single-valued link already exists
    
    As well as testing scenarios where both variants of the link are new, we
    should also check the case where the received link already exists on the
    DC as an inactive (i.e. previously deleted) link.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 77abba58802d25094b269370cf974704f42ebdf9
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Tue Sep 26 13:55:11 2017 +1300

    selftest: Add test for deleted single-valued link conflict
    
    Currently we're only testing the case where the links have been modified
    independently on 2 different DCs and both the links are active. We also
    want to test the case where one link is active and the other is deleted.
    
    Technically, this isn't really a conflict - the links involve different
    target DNs, and the end result is still only one active link.
    
    It's still probably worth having these tests to prove that fixing bug
    13055 doesn't break anything.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 9c54e7484f703176d9ffd72371e353deb30f7108
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Tue Sep 19 13:41:02 2017 +1200

    selftest: Make sure single-link conflict retains the deleted link
    
    There should only ever be one active value for a single-valued link
    attribute. When a conflict occurs the 'losing' value should still be
    present, but should be marked as deleted.
    
    This change is just making the test criteria stricter to make sure that
    we fix the bug correctly.
    
    Note that the only way to query the deleted link attributes present
    is to send a DRS request.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c9ea47ec6bf2d0cb868e94a594c108ee02b1aa34
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Mon Sep 18 16:39:44 2017 +1200

    replmd: Remove unused originating_usn variable
    
    The previous refactor makes it obvious that we aren't actually using
    this variable for anything.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 21179febe8f9dca478404c9e43203755f42f8bcf
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Mon Sep 18 16:33:30 2017 +1200

    replmd: Refactor logic to check if replicated link is newer
    
    This is precursor work for supporting single-link conflicts.
    
    Split out the code to check if the link update is newer. It's now safe
    to call this from the main codepath. This also means we can combine the 2
    calls to get the seqnum into a single common call.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 91951d869f8a2e06869577f36e0fb5af806ffa99
Author: Tim Beale <timbeale at catalyst.net.nz>
Date:   Mon Sep 18 13:47:56 2017 +1200

    replmd: Refactor adding the backlink in replmd_process_linked_attribute()
    
    The code to add the backlink is the same in both the 'if' and the 'else'
    case, so move it outside the if-else block.
    
    (We're going to rework this block of code quite a bit in order to
    support single-value linked attribute conflicts, aka bug #13055).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055
    
    Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 593dacd274a22583cac4e091a08bf2ded0ae9703
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Oct 14 22:38:18 2017 +1300

    replace: Link to -lbsd when building replace.c by hand
    
    This ensures that we correctly detect HAVE_IFACE_GETIFADDRS
    et al, which are based on a "build the source" style test.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13087
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 9c207adbe9cf2487231956dedfbd338820cf4027
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Oct 18 13:36:59 2017 +0200

    s3:cli_netlogon: let rpccli_connect_netlogon() retry once after NT_STATUS_NETWORK_ACCESS_DENIED
    
    Otherwise we could easily endup with an endless loop.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 90d57ec08c7af7b678b753b9d17bf7c4ac1d6dd0
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Oct 18 13:36:59 2017 +0200

    s3:cli_netlogon: make sure rpccli_connect_netlogon only returns NT_STATUS_OK on success
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/replace/wscript                             |  12 +-
 selftest/knownfail.d/link_conflicts             |   4 -
 source3/rpc_client/cli_netlogon.c               |  15 +-
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 481 ++++++++++++++++--------
 source4/torture/drs/python/drs_base.py          |  18 +-
 source4/torture/drs/python/link_conflicts.py    | 243 +++++++++++-
 6 files changed, 596 insertions(+), 177 deletions(-)
 delete mode 100644 selftest/knownfail.d/link_conflicts


Changeset truncated at 500 lines:

diff --git a/lib/replace/wscript b/lib/replace/wscript
index 9526632..7436a90 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -263,10 +263,13 @@ def configure(conf):
 
     conf.CHECK_FUNCS('prctl dirname basename')
 
+    strlcpy_in_bsd = False
+
     # libbsd on some platforms provides strlcpy and strlcat
     if not conf.CHECK_FUNCS('strlcpy strlcat'):
-        conf.CHECK_FUNCS_IN('strlcpy strlcat', 'bsd', headers='bsd/string.h',
-                checklibc=True)
+        if conf.CHECK_FUNCS_IN('strlcpy strlcat', 'bsd', headers='bsd/string.h',
+                               checklibc=True):
+            strlcpy_in_bsd = True
     if not conf.CHECK_FUNCS('getpeereid'):
         conf.CHECK_FUNCS_IN('getpeereid', 'bsd', headers='sys/types.h bsd/unistd.h')
     if not conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h'):
@@ -625,6 +628,9 @@ removeea setea
 
     # look for a method of finding the list of network interfaces
     for method in ['HAVE_IFACE_GETIFADDRS', 'HAVE_IFACE_AIX', 'HAVE_IFACE_IFCONF', 'HAVE_IFACE_IFREQ']:
+        bsd_for_strlcpy = ''
+        if strlcpy_in_bsd:
+            bsd_for_strlcpy = ' bsd'
         if conf.CHECK_CODE('''
                            #define %s 1
                            #define NO_CONFIG_H 1
@@ -637,7 +643,7 @@ removeea setea
                            #include "test/getifaddrs.c"
                            ''' % method,
                            method,
-                           lib='nsl socket',
+                           lib='nsl socket' + bsd_for_strlcpy,
                            addmain=False,
                            execute=True):
             break
diff --git a/selftest/knownfail.d/link_conflicts b/selftest/knownfail.d/link_conflicts
deleted file mode 100644
index e0c1ded..0000000
--- a/selftest/knownfail.d/link_conflicts
+++ /dev/null
@@ -1,4 +0,0 @@
-# Currently Samba can't resolve a conflict for a single-valued link attribute
-samba4.drs.link_conflicts.python\(vampire_dc\).link_conflicts.DrsReplicaLinkConflictTestCase.test_conflict_single_valued_link\(vampire_dc\)
-samba4.drs.link_conflicts.python\(promoted_dc\).link_conflicts.DrsReplicaLinkConflictTestCase.test_conflict_single_valued_link\(promoted_dc\)
-
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index 616523e..a7676ef 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -292,6 +292,7 @@ NTSTATUS rpccli_connect_netlogon(
 	bool do_serverauth;
 	struct rpc_pipe_client *rpccli;
 	NTSTATUS status;
+	bool retry = false;
 
 again:
 
@@ -354,15 +355,17 @@ again:
 		status = cli_rpc_pipe_open_bind_schannel(
 			cli, &ndr_table_netlogon, transport, creds_ctx,
 			&rpccli);
-		if (!NT_STATUS_IS_OK(status)) {
-			DBG_DEBUG("cli_rpc_pipe_open_bind_schannel "
-				  "failed: %s\n", nt_errstr(status));
-		}
-		if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
+		if (!retry && NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
 			DBG_DEBUG("Retrying with serverauthenticate\n");
 			TALLOC_FREE(lck);
+			retry = true;
 			goto again;
 		}
+		if (!NT_STATUS_IS_OK(status)) {
+			DBG_DEBUG("cli_rpc_pipe_open_bind_schannel "
+				  "failed: %s\n", nt_errstr(status));
+			goto fail;
+		}
 		goto done;
 	}
 
@@ -399,6 +402,7 @@ again:
 		if (!NT_STATUS_IS_OK(status)) {
 			DBG_DEBUG("cli_rpc_pipe_open_noauth_transport "
 				  "failed: %s\n", nt_errstr(status));
+			goto fail;
 		}
 		goto done;
 	}
@@ -434,6 +438,7 @@ again:
 		if (!NT_STATUS_IS_OK(status)) {
 			DBG_DEBUG("cli_rpc_pipe_open_noauth_transport "
 				  "failed: %s\n", nt_errstr(status));
+			goto fail;
 		}
 		goto done;
 	}
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 2e0f705..1901ee1 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -54,6 +54,9 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS            DBGC_DRS_REPL
 
+/* the RMD_VERSION for linked attributes starts from 1 */
+#define RMD_VERSION_INITIAL   1
+
 /*
  * It's 29/12/9999 at 23:59:59 UTC as specified in MS-ADTS 7.1.1.4.2
  * Deleted Objects Container
@@ -119,6 +122,10 @@ static int replmd_check_upgrade_links(struct ldb_context *ldb,
 				      const char *ldap_oid);
 static int replmd_verify_linked_attribute(struct replmd_replicated_request *ar,
 					  struct la_entry *la);
+static int replmd_set_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb_dn *dsdb_dn,
+			     struct dsdb_dn *old_dsdb_dn, const struct GUID *invocation_id,
+			     uint64_t usn, uint64_t local_usn, NTTIME nttime,
+			     uint32_t version, bool deleted);
 
 enum urgent_situation {
 	REPL_URGENT_ON_CREATE = 1,
@@ -922,8 +929,8 @@ static void replmd_ldb_message_sort(struct ldb_message *msg,
 }
 
 static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb_dn *dsdb_dn,
-			       const struct GUID *invocation_id, uint64_t seq_num,
-			       uint64_t local_usn, NTTIME nttime, uint32_t version, bool deleted);
+			       const struct GUID *invocation_id,
+			       uint64_t local_usn, NTTIME nttime);
 
 static int parsed_dn_compare(struct parsed_dn *pdn1, struct parsed_dn *pdn2);
 
@@ -994,7 +1001,7 @@ static int replmd_add_fix_la(struct ldb_module *module, TALLOC_CTX *mem_ctx,
 		}
 		ret = replmd_build_la_val(el->values, p->v, p->dsdb_dn,
 					  &ac->our_invocation_id,
-					  ac->seq_num, ac->seq_num, now, 0, false);
+					  ac->seq_num, now);
 		if (ret != LDB_SUCCESS) {
 			talloc_free(tmp_ctx);
 			return ret;
@@ -2136,79 +2143,14 @@ static int get_parsed_dns_trusted(struct ldb_module *module,
   RMD_LOCAL_USN       = local_usn
   RMD_VERSION         = version
  */
-static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb_dn *dsdb_dn,
-			       const struct GUID *invocation_id, uint64_t seq_num,
-			       uint64_t local_usn, NTTIME nttime, uint32_t version, bool deleted)
+static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v,
+			       struct dsdb_dn *dsdb_dn,
+			       const struct GUID *invocation_id,
+			       uint64_t local_usn, NTTIME nttime)
 {
-	struct ldb_dn *dn = dsdb_dn->dn;
-	const char *tstring, *usn_string, *flags_string;
-	struct ldb_val tval;
-	struct ldb_val iid;
-	struct ldb_val usnv, local_usnv;
-	struct ldb_val vers, flagsv;
-	NTSTATUS status;
-	int ret;
-	const char *dnstring;
-	char *vstring;
-	uint32_t rmd_flags = deleted?DSDB_RMD_FLAG_DELETED:0;
-
-	tstring = talloc_asprintf(mem_ctx, "%llu", (unsigned long long)nttime);
-	if (!tstring) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	tval = data_blob_string_const(tstring);
-
-	usn_string = talloc_asprintf(mem_ctx, "%llu", (unsigned long long)seq_num);
-	if (!usn_string) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	usnv = data_blob_string_const(usn_string);
-
-	usn_string = talloc_asprintf(mem_ctx, "%llu", (unsigned long long)local_usn);
-	if (!usn_string) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	local_usnv = data_blob_string_const(usn_string);
-
-	vstring = talloc_asprintf(mem_ctx, "%lu", (unsigned long)version);
-	if (!vstring) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	vers = data_blob_string_const(vstring);
-
-	status = GUID_to_ndr_blob(invocation_id, dn, &iid);
-	if (!NT_STATUS_IS_OK(status)) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	flags_string = talloc_asprintf(mem_ctx, "%u", rmd_flags);
-	if (!flags_string) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	flagsv = data_blob_string_const(flags_string);
-
-	ret = ldb_dn_set_extended_component(dn, "RMD_FLAGS", &flagsv);
-	if (ret != LDB_SUCCESS) return ret;
-	ret = ldb_dn_set_extended_component(dn, "RMD_ADDTIME", &tval);
-	if (ret != LDB_SUCCESS) return ret;
-	ret = ldb_dn_set_extended_component(dn, "RMD_INVOCID", &iid);
-	if (ret != LDB_SUCCESS) return ret;
-	ret = ldb_dn_set_extended_component(dn, "RMD_CHANGETIME", &tval);
-	if (ret != LDB_SUCCESS) return ret;
-	ret = ldb_dn_set_extended_component(dn, "RMD_LOCAL_USN", &local_usnv);
-	if (ret != LDB_SUCCESS) return ret;
-	ret = ldb_dn_set_extended_component(dn, "RMD_ORIGINATING_USN", &usnv);
-	if (ret != LDB_SUCCESS) return ret;
-	ret = ldb_dn_set_extended_component(dn, "RMD_VERSION", &vers);
-	if (ret != LDB_SUCCESS) return ret;
-
-	dnstring = dsdb_dn_get_extended_linearized(mem_ctx, dsdb_dn, 1);
-	if (dnstring == NULL) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	*v = data_blob_string_const(dnstring);
-
-	return LDB_SUCCESS;
+	return replmd_set_la_val(mem_ctx, v, dsdb_dn, NULL, invocation_id,
+				 local_usn, local_usn, nttime,
+				 RMD_VERSION_INITIAL, false);
 }
 
 static int replmd_update_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb_dn *dsdb_dn,
@@ -2305,7 +2247,7 @@ static int replmd_set_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb
 	struct ldb_val iid;
 	struct ldb_val usnv, local_usnv;
 	struct ldb_val vers, flagsv;
-	const struct ldb_val *old_addtime;
+	const struct ldb_val *old_addtime = NULL;
 	NTSTATUS status;
 	int ret;
 	const char *dnstring;
@@ -2345,7 +2287,10 @@ static int replmd_set_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb
 	if (ret != LDB_SUCCESS) return ret;
 
 	/* get the ADDTIME from the original */
-	old_addtime = ldb_dn_get_extended_component(old_dsdb_dn->dn, "RMD_ADDTIME");
+	if (old_dsdb_dn != NULL) {
+		old_addtime = ldb_dn_get_extended_component(old_dsdb_dn->dn,
+							    "RMD_ADDTIME");
+	}
 	if (old_addtime == NULL) {
 		old_addtime = &tval;
 	}
@@ -2370,7 +2315,7 @@ static int replmd_set_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct dsdb
 	ret = ldb_dn_set_extended_component(dn, "RMD_LOCAL_USN", &local_usnv);
 	if (ret != LDB_SUCCESS) return ret;
 
-	vstring = talloc_asprintf(dn, "%lu", (unsigned long)version);
+	vstring = talloc_asprintf(mem_ctx, "%lu", (unsigned long)version);
 	vers = data_blob_string_const(vstring);
 	ret = ldb_dn_set_extended_component(dn, "RMD_VERSION", &vers);
 	if (ret != LDB_SUCCESS) return ret;
@@ -2393,7 +2338,7 @@ static int replmd_update_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct d
 				bool deleted)
 {
 	uint32_t old_version;
-	uint32_t version = 0;
+	uint32_t version = RMD_VERSION_INITIAL;
 	NTSTATUS status;
 
 	/*
@@ -2597,8 +2542,7 @@ static int replmd_modify_la_add(struct ldb_module *module,
 		/* Make the new linked attribute ldb_val. */
 		ret = replmd_build_la_val(new_values, &new_values[num_values],
 					  dns[i].dsdb_dn, invocation_id,
-					  seq_num, seq_num,
-					  now, 0, false);
+					  seq_num, now);
 		if (ret != LDB_SUCCESS) {
 			talloc_free(tmp_ctx);
 			return ret;
@@ -3080,8 +3024,7 @@ static int replmd_modify_la_replace(struct ldb_module *module,
 						  new_p->v,
 						  new_p->dsdb_dn,
 						  invocation_id,
-						  seq_num, seq_num,
-						  now, 0, false);
+						  seq_num, now);
 			if (ret != LDB_SUCCESS) {
 				talloc_free(tmp_ctx);
 				return ret;
@@ -7142,6 +7085,236 @@ static int replmd_verify_linked_attribute(struct replmd_replicated_request *ar,
 	return ret;
 }
 
+/**
+ * Finds the current active Parsed-DN value for a single-valued linked
+ * attribute, if one exists.
+ * @param ret_pdn assigned the active Parsed-DN, or NULL if none was found
+ * @returns LDB_SUCCESS (regardless of whether a match was found), unless
+ * an error occurred
+ */
+static int replmd_get_active_singleval_link(struct ldb_module *module,
+					    TALLOC_CTX *mem_ctx,
+					    struct parsed_dn pdn_list[],
+					    unsigned int count,
+					    const struct dsdb_attribute *attr,
+					    struct parsed_dn **ret_pdn)
+{
+	unsigned int i;
+
+	*ret_pdn = NULL;
+
+	if (!(attr->ldb_schema_attribute->flags & LDB_ATTR_FLAG_SINGLE_VALUE)) {
+
+		/* nothing to do for multi-valued linked attributes */
+		return LDB_SUCCESS;
+	}
+
+	for (i = 0; i < count; i++) {
+		int ret = LDB_SUCCESS;
+		struct parsed_dn *pdn = &pdn_list[i];
+
+		/* skip any inactive links */
+		if (dsdb_dn_is_deleted_val(pdn->v)) {
+			continue;
+		}
+
+		/* we've found an active value for this attribute */
+		*ret_pdn = pdn;
+
+		if (pdn->dsdb_dn == NULL) {
+			struct ldb_context *ldb = ldb_module_get_ctx(module);
+
+			ret = really_parse_trusted_dn(mem_ctx, ldb, pdn,
+						      attr->syntax->ldap_oid);
+		}
+
+		return ret;
+	}
+
+	/* no active link found */
+	return LDB_SUCCESS;
+}
+
+/**
+ * @returns true if the replication linked attribute info is newer than we
+ * already have in our DB
+ * @param pdn the existing linked attribute info in our DB
+ * @param la the new linked attribute info received during replication
+ */
+static bool replmd_link_update_is_newer(struct parsed_dn *pdn,
+					struct drsuapi_DsReplicaLinkedAttribute *la)
+{
+	/* see if this update is newer than what we have already */
+	struct GUID invocation_id = GUID_zero();
+	uint32_t version = 0;
+	NTTIME change_time = 0;
+
+	if (pdn == NULL) {
+
+		/* no existing info so update is newer */
+		return true;
+	}
+
+	dsdb_get_extended_dn_guid(pdn->dsdb_dn->dn, &invocation_id, "RMD_INVOCID");
+	dsdb_get_extended_dn_uint32(pdn->dsdb_dn->dn, &version, "RMD_VERSION");
+	dsdb_get_extended_dn_nttime(pdn->dsdb_dn->dn, &change_time, "RMD_CHANGETIME");
+
+	return replmd_update_is_newer(&invocation_id,
+				      &la->meta_data.originating_invocation_id,
+				      version,
+				      la->meta_data.version,
+				      change_time,
+				      la->meta_data.originating_change_time);
+}
+
+/**
+ * Marks an existing linked attribute value as deleted in the DB
+ * @param pdn the parsed-DN of the target-value to delete
+ */
+static int replmd_delete_link_value(struct ldb_module *module,
+				    struct replmd_private *replmd_private,
+				    TALLOC_CTX *mem_ctx,
+				    struct ldb_dn *src_obj_dn,
+				    const struct dsdb_schema *schema,
+				    const struct dsdb_attribute *attr,
+				    uint64_t seq_num,
+				    bool is_active,
+				    struct GUID *target_guid,
+				    struct dsdb_dn *target_dsdb_dn,
+				    struct ldb_val *output_val)
+{
+	struct ldb_context *ldb = ldb_module_get_ctx(module);
+	time_t t;
+	NTTIME now;
+	const struct GUID *invocation_id = NULL;
+	int ret;
+
+	t = time(NULL);
+	unix_to_nt_time(&now, t);
+
+	invocation_id = samdb_ntds_invocation_id(ldb);
+	if (invocation_id == NULL) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	/* if the existing link is active, remove its backlink */
+	if (is_active) {
+
+		ret = replmd_add_backlink(module, replmd_private, schema,
+					  src_obj_dn, target_guid, false,
+					  attr, NULL);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
+	/* mark the existing value as deleted */
+	ret = replmd_update_la_val(mem_ctx, output_val, target_dsdb_dn,
+				   target_dsdb_dn, invocation_id, seq_num,
+				   seq_num, now, true);
+	return ret;
+}
+
+/**
+ * Checks for a conflict in single-valued link attributes, and tries to
+ * resolve the problem if possible.
+ *
+ * Single-valued links should only ever have one active value. If we already
+ * have an active link value, and during replication we receive an active link
+ * value for a different target DN, then we need to resolve this inconsistency
+ * and determine which value should be active. If the received info is better/
+ * newer than the existing link attribute, then we need to set our existing
+ * link as deleted. If the received info is worse/older, then we should continue
+ * to add it, but set it as an inactive link.
+ *
+ * Note that this is a corner-case that is unlikely to happen (but if it does
+ * happen, we don't want it to break replication completely).
+ *
+ * @param pdn_being_modified the parsed DN corresponding to the received link
+ * target (note this is NULL if the link does not already exist in our DB)
+ * @param pdn_list all the source object's Parsed-DNs for this attribute, i.e.
+ * any existing active or inactive values for the attribute in our DB.
+ * @param dsdb_dn the target DN for the received link attribute
+ * @param add_as_inactive gets set to true if the received link is worse than
+ * the existing link - it should still be added, but as an inactive link.
+ */
+static int replmd_check_singleval_la_conflict(struct ldb_module *module,
+					      struct replmd_private *replmd_private,
+					      TALLOC_CTX *mem_ctx,
+					      struct ldb_dn *src_obj_dn,
+					      struct drsuapi_DsReplicaLinkedAttribute *la,
+					      struct dsdb_dn *dsdb_dn,
+					      struct parsed_dn *pdn_being_modified,
+					      struct parsed_dn *pdn_list,
+					      struct ldb_message_element *old_el,
+					      const struct dsdb_schema *schema,
+					      const struct dsdb_attribute *attr,
+					      uint64_t seq_num,
+					      bool *add_as_inactive)
+{
+	struct parsed_dn *active_pdn = NULL;
+	bool update_is_newer = false;
+	int ret;
+
+	/*
+	 * check if there's a conflict for single-valued links, i.e. an active
+	 * linked attribute already exists, but it has a different target value
+	 */
+	ret = replmd_get_active_singleval_link(module, mem_ctx, pdn_list,
+					       old_el->num_values, attr,
+					       &active_pdn);
+
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	/*
+	 * If no active value exists (or the received info is for the currently
+	 * active value), then no conflict exists
+	 */
+	if (active_pdn == NULL || active_pdn == pdn_being_modified) {
+		return LDB_SUCCESS;
+	}
+
+	DBG_WARNING("Link conflict for %s attribute on %s\n",
+		    attr->lDAPDisplayName, ldb_dn_get_linearized(src_obj_dn));
+
+	/* Work out how to resolve the conflict based on which info is better */
+	update_is_newer = replmd_link_update_is_newer(active_pdn, la);
+
+	if (update_is_newer) {
+		DBG_WARNING("Using received value %s, over existing target %s\n",
+			    ldb_dn_get_linearized(dsdb_dn->dn),
+			    ldb_dn_get_linearized(active_pdn->dsdb_dn->dn));
+
+		/*
+		 * Delete our existing active link. The received info will then
+		 * be added (through normal link processing) as the active value


-- 
Samba Shared Repository



More information about the samba-cvs mailing list