[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Fri Aug 18 08:06:04 UTC 2017
The branch, master has been updated
via cd813f7 s3:gse_krb5: make use of precalculated krb5 keys in fill_mem_keytab_from_secrets()
via 37e49a2 s3:secrets: allow secrets_fetch_or_upgrade_domain_info() on an AD DC
via 0bb4d28 getncchanges.py: Add test for GET_ANC and linked attributes
via 9f0ae6e getncchanges.py: Add GET_ANC replication test case
via 4cfc296 getncchanges.py: Add a new test for replication
via fae5df8 replmd: Try to add forward-link for unknown cross-partition links
via 89cf5c3 replmd: Don't fail cycle if we get link for deleted object with GET_TGT
via ab12aed replmd: Avoid dropping links if link target is deleted
via 18ea167 replmd: Move where we store linked attributes
via f812c29 drs_utils: Add GET_TGT support to 'samba-tool drs replicate --local'
via f87332e replmd: Set GET_ANC if Windows sends a link with unknown source object
via cc201c2 drepl: Support GET_TGT on periodic replication client
via 67617d4 drs: Check target object is known after applying objects
via f69596c drs: Fail replication transaction instead of dropping links
via 04ce638 replmd: Split checking link attr target into new function
via d13e7b9 werror: Add WERR_DS_DRA_RECYCLED_TARGET
from 9fb2562 libcli/smb: debug an error if smb1cli_req_writev_submit() is called for SMB2/3
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit cd813f7fd9ee8e9d82a6bf6c98621c437f6974b2
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Aug 17 17:45:21 2017 +0200
s3:gse_krb5: make use of precalculated krb5 keys in fill_mem_keytab_from_secrets()
This avoids a lot of cpu cycles, which were wasted for each single smb
connection, even if the client didn't use kerberos.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12973
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Fri Aug 18 10:04:57 CEST 2017 on sn-devel-144
commit 37e49a2af5bb1c40c17eab18ff9412f2ce79ef71
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Aug 17 21:42:34 2017 +0200
s3:secrets: allow secrets_fetch_or_upgrade_domain_info() on an AD DC
The reason for the check is for write access as secrets.ldb is the
master database.
But secrets_fetch_or_upgrade_domain_info() just syncs the values
we got from if they got overwritten by secrets_store_machine_pw_sync().
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12973
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 0bb4d28272914736a46dc5cdb0bef766ba7a4ab8
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed Jul 12 10:16:00 2017 +1200
getncchanges.py: Add test for GET_ANC and linked attributes
Add a basic test that when we use GET_ANC and the parents have linked
attributes, then we receive all the expected links and all the expected
objects by the end of the test.
This extends the test code to track what linked attributes get received
and check whether they match what's present on the DC.
Also made some minor cleanups to store the received objects/links each
time we successfully receive a GETNCChanges response (this saves the
test case having to repeat this code every time).
Note that although this test involves linked attributes, it shouldn't
exercise the GET_TGT case at all.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit 9f0ae6e44d0f6def6be7c44067c7fcfdf0d42db2
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Tue Jun 6 18:21:40 2017 +1200
getncchanges.py: Add GET_ANC replication test case
This test:
- creates blocks of parent/child objects
- modifies the parents, so the child gets received first in the
replication (which means the client has to use GET_ANC)
- checks that we always receive the parent before the child (if not, it
either retries with GET_ANC, or asserts if GET_ANC is already set)
- modifies the parent objects to change their USN while the
replication is in progress
- checks that all expected objects are received by the end of the
test
I've added a repl_get_next() function to help simulate a client's
behaviour - if it encounters an object it doesn't know the parent of,
then it retries with GET_ANC.
Also added some debug to drs_base.py that developers can turn on to make
it easier to see what objects we're actually receiving in the
responses.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit 4cfc29688584ca69c43abb770d1e721d1eab1480
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Tue Jun 6 18:06:22 2017 +1200
getncchanges.py: Add a new test for replication
This adds a new test to check that if objects are modified during a
replication, then those objects don't wind up missing from the
replication data.
Note that when this scenario occurs, samba returns the objects in a
different order to Windows. This test doesn't care what order the
replicated objects get returned in, so long as they all have been
received by the end of the test.
As part of this, I've refactored _check_replication() in drs_base.py so
it can be reused in new tests. In these cases, the objects are split up
over multiple different chunks. So asserting that the objects are returned
in a specific order makes it difficult to run the same test on both Samba
and Windows.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit fae5df891c11f642cbede9e4e3d845c49c5f86b8
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Mon Jul 24 16:20:58 2017 +1200
replmd: Try to add forward-link for unknown cross-partition links
Previously Samba would just drop cross-partition links where the link
target object is unknown. Instead, what we want to do is try to add the
forward link for the GUID specified. We can't add the backlink because
we don't know the target, however, dbcheck should be able to fix any
missing backlinks.
The new behaviour should now mean dbcheck will detect the problem and be
able to fix it. It's still not ideal, but it's better than dropping the
link completely.
I've updated the log so that it has higher severity and tells the user
what they need to do to fix it.
These changes now mean that the selftests now detect an error - instead
of completely dropping the serverReference, we now have a missing
backlink. I've updated the selftests to fix up any missing
serverReference backlinks before running dbcheck.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit 89cf5c3f76e214fbd06ce461470eb64b338c5144
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Thu Jul 20 11:14:27 2017 +1200
replmd: Don't fail cycle if we get link for deleted object with GET_TGT
We are going to end up supporting 2 different server schemes:
A. the old/default behaviour of sending all the linked attributes last,
at the end of the replication cycle.
B. the new/Microsoft way of sending the linked attributes interleaved
with the source/target objects.
Normally if we're talking to a server using the old scheme-A, we won't
ever use the GET_TGT flag. However, there are a couple of cases where
it can happen:
- A link to a new object was added during the replication cycle.
- An object was deleted while the replication was in progress (and
the linked attribute got queued before the object was deleted).
Talking to an Samba DC running the old scheme will just cause it to
start the replication cycle from scratch again, which is fairly
harmless. However, there is a chance that the same thing can happen
again, in which case the replication cycle will fail (because GET_TGT
was already set).
Even if we're using the new scheme (B), we could still potentially hit
this case, as we can still queue up linked attributes between requests
(group memberships can be larger than what can fit into a single
replication chunk).
If GET_TGT is set in the GetNcChanges request, then the local copy of
the target object should always be up-to-date when we process the linked
attribute. So if we still think the target object is deleted/recycled at
this point, then it's safe to ignore the linked attribute (because we
know our local copy is up-to-date). This logic matches the MS spec logic
in ProcessLinkValue().
Not failing the replication cycle may be beneficial if we're trying to
do a full-sync of a large database. Otherwise it might be time-consuming
and frustrating to repeat the sync unnecessarily.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit ab12aed7e13a9c9663ba04b6dd4f02acb7bff380
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed Jul 19 16:18:20 2017 +1200
replmd: Avoid dropping links if link target is deleted
The server-side can potentially send the linked attribute before the
target-object. This happens on Microsoft, and will happen on Samba once
server-side GET_TGT support is added. In these cases there is a hole
where the Samba client can silently drop the linked attribute.
If the old copy of the target object was deleted/recycled, then the
client can receive the new linked attribute before it realizes the target
has now been reincarnated. It silently ignores the linked attribute,
thinking its receiving out of date information, when really it's the
client's copy of the target object that's out of date.
In this case we want to retry with the GET_TGT flag set, which will
force the updated version of the target object to be sent along with the
linked attribute. This deleted/recycled target case is the main reason
that Windows added the GET_TGT flag.
If the server sends all the links at the end, instead of along with the
source object, then this case can still be hit. If so, it will cause the
server to restart the replication from the beginning again. This is
probably preferential to silently dropping links.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit 18ea167adef59b80982f13135947e58cb56a4f16
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Thu Jun 22 10:43:31 2017 +1200
replmd: Move where we store linked attributes
There was a bug in my previous patch where the code would verify
*all* links in the list, rather than just the ones that are new. And it
would do this for every replication chunk it received, regardless of
whether there were actually any links in that chunk.
The problem is by the time we want to verify the attributes, we don't
actually know which attributes are new. We can fix this by moving where
we store the linked attributes from the start of processing the
replication chunk to the end of processing the chunk. We can then verify
the new linked attributes at the same time we store them.
Longer-term we may want to try to apply the linked attribute at this
point. This would save looking up the source/target objects twice, but
it makes things a bit more complicated (attributes will usually apply at
this point *most* of the time, but not *all* the time).
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit f812c29d4000ef35fa5d7f6007606ca53c5ed37a
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Fri Jun 16 12:54:32 2017 +1200
drs_utils: Add GET_TGT support to 'samba-tool drs replicate --local'
Update drs_Replicate.replicate() so it handles being passed the GET_TGT
flag (more_flags). To do this, we need to always use a v10 GetNCChanges
request (v8 and v10 are essentially the same except for the more_flags).
If the replicate_chunk() call into the C bindings throws an error, check
to see whether the error could be fixed by setting the GET_TGT flag, and
re-send the request if so.
Unfortunately because WERR_DS_DRA_RECYCLED_TARGET isn't documented with
the other AD error codes, I've left it hardcoded for now (Microsoft
should be fixing up their Docs).
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit f87332eb35638cc38f83c580d4623ab978088601
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Fri Jun 16 09:49:16 2017 +1200
replmd: Set GET_ANC if Windows sends a link with unknown source object
Windows replication can send the linked attribute before it sends the
source object. The MS-DRSR spec says that in this case the client should
resend the GetNCChanges request with the GET_ANC flag set. In my testing
this resolves the problem - Windows will include the source object for the
linked attribute in the same replication chunk.
This problem doesn't happen with Samba-to-Samba replication, because the
source object for the linked attribute is guaranteed to have already been
sent.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit cc201c2c4f5d2dfd18f68143d001c5ba02c00b32
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Thu Jun 15 16:52:33 2017 +1200
drepl: Support GET_TGT on periodic replication client
- Update IDL comments to include Microsoft reference doc
- Add support for sending v10 GetNCChanges request (needed for the
GET_TGT flag, which is in the new 'more_flags' field)
- Update to also set the GET_TGT flag in the same place we were setting
GET_ANC (I split this logic out into a separate function).
- The state struct now needs to hold a 'more_flags' field as well (this
flag is different to the GET_ANC replica flag)
Note that using the GET_TGT when replicating from a Windows DC could be
highly inefficient. Because Samba keeps the GET_TGT flag set throughout
the replication cycle, it will basically receive a repeated object from
Windows for every single linked attribute that it receives.
I believe Windows behaviour only expects the client to set the GET_TGT
flag when it actually needs to (i.e. when it receives a target object it
doesn't know about), rather than throughout the replication cycle.
However, this approach won't work with Samba-to-Samba replication,
because when the server receives the GET_TGT flag it restarts the
replication cycle from scratch. So if we only set the GET_TGT flag when
the client encountered an unknown target then Samba-to-Samba could
potentially get into an endless replication loop.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit 67617d470028b45c722c598944a17591cab1e6ba
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Thu Jun 15 14:09:27 2017 +1200
drs: Check target object is known after applying objects
Currently we only check that the target object is known at the end of
the transaction (i.e. the .prepare_commit hook). It's too late at this
point to resend the request with GET_TGT. Move this processing earlier
on, after we've applied all the objects (i.e. off the .extended hook).
In reality, we need to perform the checks at both points. I've
split the common code that gets the source/target details out of the
la_entry into a helper function. It's not the greatest function ever,
but seemed to make more sense than duplicating the code.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit f69596cd21d8106afdf494f39d1fcebea2b0f5dd
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed Jun 14 11:35:36 2017 +1200
drs: Fail replication transaction instead of dropping links
If the DRS client received a linked attribute that it couldn't resolve
the target for, then it would just ignore that link and keep going. That
link would then be lost forever (although a full-sync would resolve
this). Instead of silently ignoring the link, fail the transaction.
This *can* happen on Samba, but it is unusual. The target object and
linked-attribute would need to be added while a replication is still in
progress. It can also happen fairly easily when talking to a Windows DC.
There are two import exceptions to this:
1). Linked attributes that span partitions. We can never guarantee that
we will have received the target object, because it may be in a partition
we haven't replicated yet. Samba doesn't have a great way of handling
this currently, but we shouldn't fail the replication (because that breaks
basic join tests). Just skip that linked attribute and hope that a
subsequent full-sync will fix it.
(I queried Microsoft and they said resolving cross-partition linked
attributes is a implementation-specific problem to solve. GET_TGT won't
resolve it)
2). When the replication involves a subset of objects, e.g.
critical-only. In these cases, we don't increase the highwater-mark, so
it is probably not such a dire problem if we don't add the link. In the
case of critical-only, we will do a subsequent full sync which will then
add the links.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit 04ce638a1f7166b3fe75b52efd0a522248196fd4
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed Jun 14 10:51:59 2017 +1200
replmd: Split checking link attr target into new function
We want to re-use this code to check that the linked attribute's target
object exists *before* we try to commit the transaction. This will allow
us to re-request the block with the GET_TGT flag set.
This splits checking the target object exists into a separate function.
Minor changes of note:
- the 'parent' argument was passed to replmd_process_linked_attribute()
as NULL, so I've just replaced where it was used in the refactored code
with NULL.
- I've tweaked the "Failed to find GUID" error message slightly to display
the attribute ID rather than the attribute name (saves repeating
lookups and/or passing extra arguments).
- Tweaked the replmd_deletion_state() logic - it only made sense to call
it in the code block where we actually found the target
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
commit d13e7b92f85e5623c5cf1309f13d59141dc7d888
Author: Tim Beale <timbeale at catalyst.net.nz>
Date: Tue May 30 15:08:44 2017 +1200
werror: Add WERR_DS_DRA_RECYCLED_TARGET
When the DRS client encounters a linked attribute with an unknown target
object, it should return a RECYCLED_TARGET error, which should result in
the client resending the GETNCChanges request with the GET_TGT flag set.
This error code is currently documented by Microsoft under System Error
Codes (8200-8999). I contacted them and they will also add it to the
MS-ERREF doc in future.
Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
-----------------------------------------------------------------------
Summary of changes:
libcli/util/werror.h | 1 +
librpc/idl/drsuapi.idl | 4 +-
python/samba/drs_utils.py | 101 +++--
source3/librpc/crypto/gse_krb5.c | 180 ++++----
source3/passdb/machine_account_secrets.c | 15 +-
source4/dsdb/repl/drepl_out_helpers.c | 105 ++++-
source4/dsdb/repl/drepl_out_pull.c | 1 +
source4/dsdb/repl/drepl_service.h | 2 +
source4/dsdb/repl/replicated_objects.c | 11 +-
source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 558 +++++++++++++++++-------
source4/dsdb/samdb/samdb.h | 3 +-
source4/libnet/libnet_vampire.c | 5 +
source4/selftest/tests.py | 10 +
source4/torture/drs/python/drs_base.py | 141 ++++--
source4/torture/drs/python/getncchanges.py | 428 ++++++++++++++++++
testprogs/blackbox/dbcheck.sh | 8 +
16 files changed, 1233 insertions(+), 340 deletions(-)
create mode 100644 source4/torture/drs/python/getncchanges.py
Changeset truncated at 500 lines:
diff --git a/libcli/util/werror.h b/libcli/util/werror.h
index d3d3327..0370a06 100644
--- a/libcli/util/werror.h
+++ b/libcli/util/werror.h
@@ -100,6 +100,7 @@ typedef uint32_t WERROR;
#define WERR_INVALID_PRIMARY_GROUP W_ERROR(0x0000051C)
#define WERR_DS_DRA_SECRETS_DENIED W_ERROR(0x000021B6)
+#define WERR_DS_DRA_RECYCLED_TARGET W_ERROR(0x000021BF)
#define WERR_DNS_ERROR_KEYMASTER_REQUIRED W_ERROR(0x0000238D)
#define WERR_DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE W_ERROR(0x0000238E)
diff --git a/librpc/idl/drsuapi.idl b/librpc/idl/drsuapi.idl
index 2eb1d65..51ef567 100644
--- a/librpc/idl/drsuapi.idl
+++ b/librpc/idl/drsuapi.idl
@@ -70,7 +70,9 @@ interface drsuapi
} drsuapi_DrsUpdate;
/*****************/
- /* Function 0x00 */
+ /* Function 0x00 drsuapi_DsBind() */
+
+ /* MS-DRSR 5.39 DRS_EXTENSIONS_INT */
typedef [bitmap32bit] bitmap {
DRSUAPI_SUPPORTED_EXTENSION_BASE = 0x00000001,
DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION = 0x00000002,
diff --git a/python/samba/drs_utils.py b/python/samba/drs_utils.py
index b9ed059..bed8817 100644
--- a/python/samba/drs_utils.py
+++ b/python/samba/drs_utils.py
@@ -21,6 +21,8 @@ from samba.dcerpc import drsuapi, misc, drsblobs
from samba.net import Net
from samba.ndr import ndr_unpack
from samba import dsdb
+from samba import werror
+from samba import WERRORError
import samba, ldb
@@ -198,18 +200,37 @@ class drs_Replicate(object):
raise RuntimeError("Must not set GUID 00000000-0000-0000-0000-000000000000 as invocation_id")
self.replication_state = self.net.replicate_init(self.samdb, lp, self.drs, invocation_id)
+ def _should_retry_with_get_tgt(self, error_code, req):
+
+ # If the error indicates we fail to resolve a target object for a
+ # linked attribute, then we should retry the request with GET_TGT
+ # (if we support it and haven't already tried that)
+
+ # TODO fix up the below line when we next update werror_err_table.txt
+ # and pull in the new error-code
+ # return (error_code == werror.WERR_DS_DRA_RECYCLED_TARGET and
+ return (error_code == 0x21bf and
+ (req.more_flags & drsuapi.DRSUAPI_DRS_GET_TGT) == 0 and
+ self.supported_extensions & drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10)
+
def replicate(self, dn, source_dsa_invocation_id, destination_dsa_guid,
schema=False, exop=drsuapi.DRSUAPI_EXOP_NONE, rodc=False,
- replica_flags=None, full_sync=True, sync_forced=False):
+ replica_flags=None, full_sync=True, sync_forced=False, more_flags=0):
'''replicate a single DN'''
# setup for a GetNCChanges call
- req8 = drsuapi.DsGetNCChangesRequest8()
+ if self.supported_extensions & drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10:
+ req = drsuapi.DsGetNCChangesRequest10()
+ req.more_flags = more_flags
+ req_level = 10
+ else:
+ req_level = 8
+ req = drsuapi.DsGetNCChangesRequest8()
- req8.destination_dsa_guid = destination_dsa_guid
- req8.source_dsa_invocation_id = source_dsa_invocation_id
- req8.naming_context = drsuapi.DsReplicaObjectIdentifier()
- req8.naming_context.dn = dn
+ req.destination_dsa_guid = destination_dsa_guid
+ req.source_dsa_invocation_id = source_dsa_invocation_id
+ req.naming_context = drsuapi.DsReplicaObjectIdentifier()
+ req.naming_context.dn = dn
# Default to a full replication if we don't find an upToDatenessVector
udv = None
@@ -244,49 +265,46 @@ class drs_Replicate(object):
udv.cursors = cursors_v1
udv.count = len(cursors_v1)
- req8.highwatermark = hwm
- req8.uptodateness_vector = udv
+ req.highwatermark = hwm
+ req.uptodateness_vector = udv
if replica_flags is not None:
- req8.replica_flags = replica_flags
+ req.replica_flags = replica_flags
elif exop == drsuapi.DRSUAPI_EXOP_REPL_SECRET:
- req8.replica_flags = 0
+ req.replica_flags = 0
else:
- req8.replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC |
- drsuapi.DRSUAPI_DRS_PER_SYNC |
- drsuapi.DRSUAPI_DRS_GET_ANC |
- drsuapi.DRSUAPI_DRS_NEVER_SYNCED |
- drsuapi.DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP)
+ req.replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC |
+ drsuapi.DRSUAPI_DRS_PER_SYNC |
+ drsuapi.DRSUAPI_DRS_GET_ANC |
+ drsuapi.DRSUAPI_DRS_NEVER_SYNCED |
+ drsuapi.DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP)
if rodc:
- req8.replica_flags |= (
- drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING)
+ req.replica_flags |= (
+ drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING)
else:
- req8.replica_flags |= drsuapi.DRSUAPI_DRS_WRIT_REP
+ req.replica_flags |= drsuapi.DRSUAPI_DRS_WRIT_REP
if sync_forced:
- req8.replica_flags |= drsuapi.DRSUAPI_DRS_SYNC_FORCED
+ req.replica_flags |= drsuapi.DRSUAPI_DRS_SYNC_FORCED
- req8.max_object_count = 402
- req8.max_ndr_size = 402116
- req8.extended_op = exop
- req8.fsmo_info = 0
- req8.partial_attribute_set = None
- req8.partial_attribute_set_ex = None
- req8.mapping_ctr.num_mappings = 0
- req8.mapping_ctr.mappings = None
+ req.max_object_count = 402
+ req.max_ndr_size = 402116
+ req.extended_op = exop
+ req.fsmo_info = 0
+ req.partial_attribute_set = None
+ req.partial_attribute_set_ex = None
+ req.mapping_ctr.num_mappings = 0
+ req.mapping_ctr.mappings = None
if not schema and rodc:
- req8.partial_attribute_set = drs_get_rodc_partial_attribute_set(self.samdb)
+ req.partial_attribute_set = drs_get_rodc_partial_attribute_set(self.samdb)
- if self.supported_extensions & drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8:
- req_level = 8
- req = req8
- else:
+ if not self.supported_extensions & drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8:
req_level = 5
req5 = drsuapi.DsGetNCChangesRequest5()
for a in dir(req5):
if a[0] != '_':
- setattr(req5, a, getattr(req8, a))
+ setattr(req5, a, getattr(req, a))
req = req5
num_objects = 0
@@ -295,8 +313,21 @@ class drs_Replicate(object):
(level, ctr) = self.drs.DsGetNCChanges(self.drs_handle, req_level, req)
if ctr.first_object is None and ctr.object_count != 0:
raise RuntimeError("DsGetNCChanges: NULL first_object with object_count=%u" % (ctr.object_count))
- self.net.replicate_chunk(self.replication_state, level, ctr,
- schema=schema, req_level=req_level, req=req)
+
+ try:
+ self.net.replicate_chunk(self.replication_state, level, ctr,
+ schema=schema, req_level=req_level, req=req)
+ except WERRORError as e:
+ # Check if retrying with the GET_TGT flag set might resolve this error
+ if self._should_retry_with_get_tgt(e[0], req):
+
+ print("Missing target object - retrying with DRS_GET_TGT")
+ req.more_flags |= drsuapi.DRSUAPI_DRS_GET_TGT
+
+ # try sending the request again
+ continue
+ else:
+ raise e
num_objects += ctr.object_count
diff --git a/source3/librpc/crypto/gse_krb5.c b/source3/librpc/crypto/gse_krb5.c
index 2c9fc03..cc8cb90 100644
--- a/source3/librpc/crypto/gse_krb5.c
+++ b/source3/librpc/crypto/gse_krb5.c
@@ -20,6 +20,7 @@
#include "includes.h"
#include "smb_krb5.h"
#include "secrets.h"
+#include "librpc/gen_ndr/secrets.h"
#include "gse_krb5.h"
#include "lib/param/loadparm.h"
#include "libads/kerberos_proto.h"
@@ -85,45 +86,15 @@ out:
return ret;
}
-static krb5_error_code get_host_principal(krb5_context krbctx,
- krb5_principal *host_princ)
-{
- krb5_error_code ret;
- char *host_princ_s = NULL;
- int err;
-
- err = asprintf(&host_princ_s, "%s$@%s", lp_netbios_name(), lp_realm());
- if (err == -1) {
- return -1;
- }
-
- if (!strlower_m(host_princ_s)) {
- SAFE_FREE(host_princ_s);
- return -1;
- }
- ret = smb_krb5_parse_name(krbctx, host_princ_s, host_princ);
- if (ret) {
- DEBUG(1, (__location__ ": smb_krb5_parse_name(%s) "
- "failed (%s)\n",
- host_princ_s, error_message(ret)));
- }
-
- SAFE_FREE(host_princ_s);
- return ret;
-}
-
static krb5_error_code fill_keytab_from_password(krb5_context krbctx,
krb5_keytab keytab,
krb5_principal princ,
krb5_kvno vno,
- krb5_data *password)
+ struct secrets_domain_info1_password *pw)
{
krb5_error_code ret;
krb5_enctype *enctypes;
- krb5_keytab_entry kt_entry;
- unsigned int i;
- krb5_principal salt_princ = NULL;
- char *salt_princ_s = NULL;
+ uint16_t i;
ret = smb_krb5_get_allowed_etypes(krbctx, &enctypes);
if (ret) {
@@ -132,61 +103,47 @@ static krb5_error_code fill_keytab_from_password(krb5_context krbctx,
return ret;
}
- salt_princ_s = kerberos_secrets_fetch_salt_princ();
- if (salt_princ_s == NULL) {
- ret = ENOMEM;
- goto out;
- }
- ret = krb5_parse_name(krbctx, salt_princ_s, &salt_princ);
- SAFE_FREE(salt_princ_s);
- if (ret != 0) {
- goto out;
- }
-
- for (i = 0; enctypes[i]; i++) {
+ for (i = 0; i < pw->num_keys; i++) {
+ krb5_keytab_entry kt_entry;
krb5_keyblock *key = NULL;
- int rc;
+ unsigned int ei;
+ bool found_etype = false;
- if (!(key = SMB_MALLOC_P(krb5_keyblock))) {
- ret = ENOMEM;
- goto out;
+ for (ei=0; enctypes[ei] != 0; ei++) {
+ if ((uint32_t)enctypes[ei] != pw->keys[i].keytype) {
+ continue;
+ }
+
+ found_etype = true;
+ break;
}
- rc = create_kerberos_key_from_string(krbctx,
- princ,
- salt_princ,
- password,
- key,
- enctypes[i],
- false);
- if (rc != 0) {
- DEBUG(10, ("Failed to create key for enctype %d "
- "(error: %s)\n",
- enctypes[i], error_message(ret)));
- SAFE_FREE(key);
+ if (!found_etype) {
continue;
}
+ ZERO_STRUCT(kt_entry);
kt_entry.principal = princ;
kt_entry.vno = vno;
- *(KRB5_KT_KEY(&kt_entry)) = *key;
+
+ key = KRB5_KT_KEY(&kt_entry);
+ KRB5_KEY_TYPE(key) = pw->keys[i].keytype;
+ KRB5_KEY_DATA(key) = pw->keys[i].value.data;
+ KRB5_KEY_LENGTH(key) = pw->keys[i].value.length;
ret = krb5_kt_add_entry(krbctx, keytab, &kt_entry);
if (ret) {
DEBUG(1, (__location__ ": Failed to add entry to "
"keytab for enctype %d (error: %s)\n",
- enctypes[i], error_message(ret)));
- krb5_free_keyblock(krbctx, key);
+ (unsigned)pw->keys[i].keytype,
+ error_message(ret)));
goto out;
}
-
- krb5_free_keyblock(krbctx, key);
}
ret = 0;
out:
- krb5_free_principal(krbctx, salt_princ);
SAFE_FREE(enctypes);
return ret;
}
@@ -197,27 +154,43 @@ out:
static krb5_error_code fill_mem_keytab_from_secrets(krb5_context krbctx,
krb5_keytab *keytab)
{
+ TALLOC_CTX *frame = talloc_stackframe();
krb5_error_code ret;
- char *pwd = NULL;
- size_t pwd_len;
+ const char *domain = lp_workgroup();
+ struct secrets_domain_info1 *info = NULL;
+ const char *realm = NULL;
+ const DATA_BLOB *ct = NULL;
krb5_kt_cursor kt_cursor;
krb5_keytab_entry kt_entry;
- krb5_data password;
krb5_principal princ = NULL;
krb5_kvno kvno = 0; /* FIXME: fetch current vno from KDC ? */
- char *pwd_old = NULL;
+ NTSTATUS status;
if (!secrets_init()) {
DEBUG(1, (__location__ ": secrets_init failed\n"));
+ TALLOC_FREE(frame);
return KRB5_CONFIG_CANTOPEN;
}
- pwd = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
- if (!pwd) {
- DEBUG(2, (__location__ ": failed to fetch machine password\n"));
+ status = secrets_fetch_or_upgrade_domain_info(domain,
+ frame,
+ &info);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_WARNING("secrets_fetch_or_upgrade_domain_info(%s) - %s\n",
+ domain, nt_errstr(status));
+ TALLOC_FREE(frame);
return KRB5_LIBOS_CANTREADPWD;
}
- pwd_len = strlen(pwd);
+ ct = &info->password->cleartext_blob;
+
+ if (info->domain_info.dns_domain.string != NULL) {
+ realm = strupper_talloc(frame,
+ info->domain_info.dns_domain.string);
+ if (realm == NULL) {
+ TALLOC_FREE(frame);
+ return ENOMEM;
+ }
+ }
ZERO_STRUCT(kt_entry);
ZERO_STRUCT(kt_cursor);
@@ -249,9 +222,9 @@ static krb5_error_code fill_mem_keytab_from_secrets(krb5_context krbctx,
/* found private entry,
* check if keytab is up to date */
- if ((pwd_len == KRB5_KEY_LENGTH(KRB5_KT_KEY(&kt_entry))) &&
+ if ((ct->length == KRB5_KEY_LENGTH(KRB5_KT_KEY(&kt_entry))) &&
(memcmp(KRB5_KEY_DATA(KRB5_KT_KEY(&kt_entry)),
- pwd, pwd_len) == 0)) {
+ ct->data, ct->length) == 0)) {
/* keytab is already up to date, return */
smb_krb5_kt_free_entry(krbctx, &kt_entry);
goto out;
@@ -277,32 +250,51 @@ static krb5_error_code fill_mem_keytab_from_secrets(krb5_context krbctx,
/* keytab is not up to date, fill it up */
- ret = get_host_principal(krbctx, &princ);
+ ret = smb_krb5_make_principal(krbctx, &princ, realm,
+ info->account_name, NULL);
if (ret) {
DEBUG(1, (__location__ ": Failed to get host principal!\n"));
goto out;
}
- password.data = pwd;
- password.length = pwd_len;
ret = fill_keytab_from_password(krbctx, *keytab,
- princ, kvno, &password);
+ princ, kvno,
+ info->password);
if (ret) {
- DEBUG(1, (__location__ ": Failed to fill memory keytab!\n"));
+ DBG_WARNING("fill_keytab_from_password() failed for "
+ "info->password.\n.");
goto out;
}
- pwd_old = secrets_fetch_prev_machine_password(lp_workgroup());
- if (!pwd_old) {
- DEBUG(10, (__location__ ": no prev machine password\n"));
- } else {
- password.data = pwd_old;
- password.length = strlen(pwd_old);
+ if (info->old_password != NULL) {
+ ret = fill_keytab_from_password(krbctx, *keytab,
+ princ, kvno - 1,
+ info->old_password);
+ if (ret) {
+ DBG_WARNING("fill_keytab_from_password() failed for "
+ "info->old_password.\n.");
+ goto out;
+ }
+ }
+
+ if (info->older_password != NULL) {
ret = fill_keytab_from_password(krbctx, *keytab,
- princ, kvno -1, &password);
+ princ, kvno - 2,
+ info->older_password);
if (ret) {
- DEBUG(1, (__location__
- ": Failed to fill memory keytab!\n"));
+ DBG_WARNING("fill_keytab_from_password() failed for "
+ "info->older_password.\n.");
+ goto out;
+ }
+ }
+
+ if (info->next_change != NULL) {
+ ret = fill_keytab_from_password(krbctx, *keytab,
+ princ, kvno - 3,
+ info->next_change->password);
+ if (ret) {
+ DBG_WARNING("fill_keytab_from_password() failed for "
+ "info->next_change->password.\n.");
goto out;
}
}
@@ -314,8 +306,8 @@ static krb5_error_code fill_mem_keytab_from_secrets(krb5_context krbctx,
kt_entry.vno = 0;
KRB5_KEY_TYPE(KRB5_KT_KEY(&kt_entry)) = CLEARTEXT_PRIV_ENCTYPE;
- KRB5_KEY_LENGTH(KRB5_KT_KEY(&kt_entry)) = pwd_len;
- KRB5_KEY_DATA(KRB5_KT_KEY(&kt_entry)) = (uint8_t *)pwd;
+ KRB5_KEY_LENGTH(KRB5_KT_KEY(&kt_entry)) = ct->length;
+ KRB5_KEY_DATA(KRB5_KT_KEY(&kt_entry)) = ct->data;
ret = krb5_kt_add_entry(krbctx, *keytab, &kt_entry);
if (ret) {
@@ -328,9 +320,6 @@ static krb5_error_code fill_mem_keytab_from_secrets(krb5_context krbctx,
ret = 0;
out:
- SAFE_FREE(pwd);
- SAFE_FREE(pwd_old);
-
if (!all_zero((uint8_t *)&kt_cursor, sizeof(kt_cursor)) && *keytab) {
krb5_kt_end_seq_get(krbctx, *keytab, &kt_cursor);
}
@@ -339,6 +328,7 @@ out:
krb5_free_principal(krbctx, princ);
}
+ TALLOC_FREE(frame);
return ret;
}
diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c
index 3d1cb5b..5a0f7a8 100644
--- a/source3/passdb/machine_account_secrets.c
+++ b/source3/passdb/machine_account_secrets.c
@@ -832,7 +832,8 @@ static NTSTATUS secrets_store_domain_info1_by_key(const char *key,
return NT_STATUS_OK;
}
-static NTSTATUS secrets_store_domain_info(const struct secrets_domain_info1 *info)
+static NTSTATUS secrets_store_domain_info(const struct secrets_domain_info1 *info,
+ bool upgrade)
{
TALLOC_CTX *frame = talloc_stackframe();
const char *domain = info->domain_info.name.string;
@@ -853,7 +854,7 @@ static NTSTATUS secrets_store_domain_info(const struct secrets_domain_info1 *inf
switch (info->secure_channel_type) {
case SEC_CHAN_WKSTA:
--
Samba Shared Repository
More information about the samba-cvs
mailing list