This commit is contained in:
MichaelGrafnetter 2016-04-30 11:19:32 +02:00
parent 5ac020b4ce
commit 15db6eba0d
4 changed files with 40 additions and 15 deletions

View File

@ -1,5 +1,6 @@
Version 2.14
- Added support for Windows Server 2016 ntds.dit encryption.
- Added support for replication with renamed domains.
- Added support for reading security descriptors (ACLs) from both ntds.dit files and DRS-R.
- Added support for the AdminCount attribute.
- Updated the forked ManagedEsent source codes to version 1.9.3.3.

View File

@ -115,6 +115,7 @@ PrivateData = @{
# ReleaseNotes of this module
ReleaseNotes = @"
- Added support for Windows Server 2016 ntds.dit encryption.
- Added support for replication with renamed domains.
- Added support for reading security descriptors (ACLs) from both ntds.dit files and DRS-R.
- Added support for the AdminCount attribute.
"@

View File

@ -24,24 +24,19 @@ namespace DSInternals
: SafeHandleZeroOrMinusOneIsInvalid(true)
{
this->_clientDsa = clientDsa;
this->_serverReplEpoch = DrsConnection::defaultReplEpoch;
// Register the RetrieveSessionKey as RCP security callback. Mind the delegate lifecycle.
this->_securityCallback = gcnew SecurityCallback(this, &DrsConnection::RetrieveSessionKey);
RPC_STATUS status1 = RpcBindingSetOption(rpcHandle.ToPointer(), RPC_C_OPT_SECURITY_CALLBACK, (ULONG_PTR)Marshal::GetFunctionPointerForDelegate(this->_securityCallback).ToPointer());
RPC_STATUS status = RpcBindingSetOption(rpcHandle.ToPointer(), RPC_C_OPT_SECURITY_CALLBACK, (ULONG_PTR)Marshal::GetFunctionPointerForDelegate(this->_securityCallback).ToPointer());
UUID clientDsaUuid = RpcTypeConverter::ToUUID(clientDsa);
auto clientInfo = CreateClientInfo();
DRS_EXTENSIONS *genericServerInfo = nullptr;
DRS_HANDLE drsHandle = nullptr;
ULONG result = IDL_DRSBind_NoSEH(rpcHandle.ToPointer(), &clientDsaUuid, (DRS_EXTENSIONS*)clientInfo.get(), &genericServerInfo, &drsHandle);
Validator::AssertSuccess((Win32ErrorCode)result);
// Store the DRS handle
this->SetHandle((IntPtr)drsHandle);
// Prevent memory leak by storing the genericServerInfo in midl_ptr
auto genericServerInfoSafePtr = midl_ptr<DRS_EXTENSIONS>(genericServerInfo);
// TODO: Parse the server info
DRS_EXTENSIONS_INT serverInfo = DRS_EXTENSIONS_INT(genericServerInfo);
this->_serverSiteObjectGuid = RpcTypeConverter::ToGuid(serverInfo.siteObjGuid);
this->Bind(rpcHandle);
if (this->_serverReplEpoch != DrsConnection::defaultReplEpoch)
{
// The domain must have been renamed, so we need to rebind with the proper dwReplEpoch.
this->ReleaseHandle();
this->Bind(rpcHandle);
}
}
DrsConnection::DrsConnection(IntPtr preexistingDrssHandle, bool ownsHandle)
@ -55,6 +50,30 @@ namespace DSInternals
{
}
void DrsConnection::Bind(IntPtr rpcHandle)
{
// Init binding parameters
UUID clientDsaUuid = RpcTypeConverter::ToUUID(this->_clientDsa);
auto clientInfo = this->CreateClientInfo();
DRS_EXTENSIONS *genericServerInfo = nullptr;
DRS_HANDLE drsHandle = nullptr;
// Bind
ULONG result = IDL_DRSBind_NoSEH(rpcHandle.ToPointer(), &clientDsaUuid, (DRS_EXTENSIONS*)clientInfo.get(), &genericServerInfo, &drsHandle);
Validator::AssertSuccess((Win32ErrorCode)result);
// Prevent memory leak by storing the genericServerInfo in midl_ptr
auto genericServerInfoSafePtr = midl_ptr<DRS_EXTENSIONS>(genericServerInfo);
// Store the DRS handle
this->SetHandle((IntPtr)drsHandle);
// Parse the server info
DRS_EXTENSIONS_INT serverInfo = DRS_EXTENSIONS_INT(genericServerInfo);
this->_serverSiteObjectGuid = RpcTypeConverter::ToGuid(serverInfo.siteObjGuid);
this->_serverReplEpoch = serverInfo.dwReplEpoch;
}
array<byte>^ DrsConnection::SessionKey::get()
{
return this->_sessionKey;
@ -70,6 +89,7 @@ namespace DSInternals
clientInfo->dwFlags = DRS_EXT::ALL_EXT;
clientInfo->dwFlagsExt = DRS_EXT2::DRS_EXT_LH_BETA2;
clientInfo->dwExtCaps = DRS_EXT2::DRS_EXT_LH_BETA2 | DRS_EXT2::DRS_EXT_RECYCLE_BIN;
clientInfo->dwReplEpoch = this->_serverReplEpoch;
return clientInfo;
}

View File

@ -24,10 +24,12 @@ namespace DSInternals
array<byte>^ _sessionKey;
Guid _clientDsa;
Guid _serverSiteObjectGuid;
DWORD _serverReplEpoch;
SecurityCallback^ _securityCallback;
static const size_t defaultMaxObjects = 1000;
// 8MB
static const size_t defaultMaxBytes = 8 * 1024 * 1024;
static const DWORD defaultReplEpoch = 0;
public:
DrsConnection(IntPtr rpcHandle, Guid clientDsa);
DrsConnection(IntPtr preexistingDrssHandle, bool ownsHandle);
@ -51,17 +53,18 @@ namespace DSInternals
virtual bool ReleaseHandle() override;
private:
DrsConnection();
void Bind(IntPtr rpcHandle);
midl_ptr<DRS_MSG_GETCHGREPLY_V6> GetNCChanges(midl_ptr<DRS_MSG_GETCHGREQ_V8> &&request);
midl_ptr<DRS_MSG_CRACKREPLY_V1> CrackNames(midl_ptr<DRS_MSG_CRACKREQ_V1> &&request);
String^ ResolveName(String^ name, DS_NAME_FORMAT formatOffered, DS_NAME_FORMAT formatDesired);
String^ ResolveName(midl_ptr<DRS_MSG_CRACKREQ_V1> &&request);
midl_ptr<DRS_EXTENSIONS_INT> CreateClientInfo();
midl_ptr<DRS_MSG_GETCHGREQ_V8> CreateReplicateAllRequest(ReplicationCookie^ cookie, array<ATTRTYP>^ partialAttributeSet, ULONG maxBytes, ULONG maxObjects);
midl_ptr<DRS_MSG_GETCHGREQ_V8> CreateReplicateSingleRequest(String^ distinguishedName, array<ATTRTYP>^ partialAttributeSet);
midl_ptr<DRS_MSG_GETCHGREQ_V8> CreateReplicateSingleRequest(Guid objectGuid, array<ATTRTYP>^ partialAttributeSet);
midl_ptr<DRS_MSG_GETCHGREQ_V8> CreateGenericReplicateRequest(midl_ptr<DSNAME> &&dsName, array<ATTRTYP>^ partialAttributeSet, ULONG maxBytes, ULONG maxObjects);
void RetrieveSessionKey(void* rpcContext);
static midl_ptr<PARTIAL_ATTR_VECTOR_V1_EXT> CreateNativePas(array<ATTRTYP>^ partialAttributeSet);
static midl_ptr<DRS_EXTENSIONS_INT> CreateClientInfo();
static array<byte>^ ReadValue(const ATTRVAL &value);
static array<array<byte>^>^ ReadValues(const ATTRVALBLOCK &values);
static ReplicaAttribute^ ReadAttribute(const ATTR &attribute);