|
|
//+----------------------------------------------------------------------------
//
// Copyright (C) 1996, Microsoft Corporation
//
// File: dfsipc.c
//
// Contents: Code to communicate with the Dfs driver. The Dfs driver
// sends messages to the user level to resolve a name to either a domain or
// computer based Dfs name.
//
// Classes: None
//
// History: Feb 1, 1996 Milans Created
//
//-----------------------------------------------------------------------------
#include <ntos.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <dfsfsctl.h>
#include <windows.h>
#include <dfsstr.h>
#include <nodetype.h>
#include <libsup.h>
#include <dfsmrshl.h>
#include <upkt.h>
#include <ntlsa.h>
#include <dfsmsrv.h>
#include <lm.h>
#include <dsrole.h>
#include <crypt.h>
#include <samrpc.h>
#include <logonmsv.h>
#include <dsgetdc.h>
#include <ntdsapi.h>
#include <winldap.h>
#include "dominfo.h"
#include "dfsipc.h"
#include "svcwml.h"
DWORD DfsLoadSiteTableFromDs( PLDAP pLDAP, LPWSTR wszFtDfsName, ULONG Count, PUNICODE_STRING pustr);
DWORD DfsCreateSpcArg( LPWSTR DomainName, ULONG Timeout, ULONG Flags, ULONG TrustDirection, ULONG TrustType, LONG NameCount, PUNICODE_STRING pustrDCNames, PDFS_CREATE_SPECIAL_INFO_ARG *ppSpcArg, PULONG pSize);
DWORD DfsCreateSiteArg( LPWSTR ServerName, ULONG SiteCount, PUNICODE_STRING pustrSiteNames, PDFS_CREATE_SITE_INFO_ARG *ppSiteArg, PULONG pSize);
DWORD DfsGetFtServersFromDs( PLDAP pLdap, LPWSTR wszDomainName, LPWSTR wszDfsName, LPWSTR **List);
//
// Event logging and debugging globals
//
extern ULONG DfsSvcVerbose; extern ULONG DfsEventLog;
extern DFS_DOMAIN_INFO DfsDomainInfo; extern DSROLE_MACHINE_ROLE DfsMachineRole;
extern WCHAR MachineName[MAX_PATH]; extern WCHAR DomainName[MAX_PATH]; extern WCHAR DomainNameDns[MAX_PATH]; extern WCHAR LastMachineName[MAX_PATH]; extern WCHAR LastDomainName[MAX_PATH]; extern WCHAR SiteName[MAX_PATH];
extern PLDAP pLdap;
extern CRITICAL_SECTION DomListCritSection;
BOOLEAN DfsGetNextDomainName( LPWSTR DomName, ULONG Size);
NTSTATUS DfsInitOurDomainDCs(VOID) {
DWORD dwErr; LPWSTR OurSite; NTSTATUS status; HANDLE dfsHandle = NULL; IO_STATUS_BLOCK ioStatus; ULONG cDom; PDFS_CREATE_SPECIAL_INFO_ARG pSpcArg; ULONG Size;
#if DBG
if (DfsSvcVerbose) DbgPrint("DfsInitOurDomainDCs()\n"); #endif
dwErr = DsGetSiteName( NULL, &OurSite);
RtlZeroMemory(SiteName, MAX_PATH * sizeof(WCHAR));
if (dwErr == NO_ERROR) {
wcscpy(SiteName, OurSite);
NetApiBufferFree(OurSite);
}
status = DfsOpen(&dfsHandle, NULL);
if (NT_SUCCESS(status)) {
#if DBG
if (DfsSvcVerbose) DbgPrint("Domain %ws/%ws\n", DomainName, DomainNameDns); #endif
status = DfsCreateSpcArg( DomainName, 0, DFS_SPECIAL_INFO_NETBIOS, TRUST_DIRECTION_BIDIRECTIONAL, TRUST_TYPE_UPLEVEL, -1, NULL, &pSpcArg, &Size);
if (status == ERROR_SUCCESS) {
status = NtFsControlFile( dfsHandle, NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&ioStatus, FSCTL_DFS_CREATE_SPECIAL_INFO, pSpcArg, Size, NULL, 0);
free(pSpcArg);
}
status = DfsCreateSpcArg( DomainNameDns, 0, 0, TRUST_DIRECTION_BIDIRECTIONAL, TRUST_TYPE_UPLEVEL, -1, NULL, &pSpcArg, &Size);
if (status == ERROR_SUCCESS) {
status = NtFsControlFile( dfsHandle, NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&ioStatus, FSCTL_DFS_CREATE_SPECIAL_INFO, pSpcArg, Size, NULL, 0);
#if DBG
if (DfsSvcVerbose) DbgPrint("NtFsControlFile(FSCTL_DFS_CREATE_SPECIAL_INFO) returned 0x%x\n", status); #endif
free(pSpcArg);
}
}
if (dfsHandle != NULL) { NtClose( dfsHandle); }
#if DBG
if (DfsSvcVerbose) DbgPrint("DfsInitOurDomainDCs returning 0x%x\n", status); #endif
DFSSVC_TRACE_LOW(DEFAULT, DfsInitOurDomainDCs_Exit, LOGSTATUS(status)); return( status );
}
NTSTATUS DfsInitRemainingDomainDCs(VOID) { NTSTATUS status; HANDLE dfsHandle = NULL; IO_STATUS_BLOCK ioStatus; ULONG cDom; PDFS_CREATE_SPECIAL_INFO_ARG pSpcArg; ULONG Size;
#if DBG
if (DfsSvcVerbose) DbgPrint("DfsInitRemainingDomainDCs()\n"); #endif
if (DfsDomainInfo.cDomains == 0) {
return STATUS_SUCCESS;
}
status = DfsOpen(&dfsHandle, NULL);
if (NT_SUCCESS(status)) {
for (cDom = 0; cDom < DfsDomainInfo.cDomains; cDom++) {
#if DBG
if (DfsSvcVerbose) DbgPrint("Trusted domain %ws/%ws\n", DfsDomainInfo.rgustrDomains[cDom].DnsName.Buffer, DfsDomainInfo.rgustrDomains[cDom].FlatName.Buffer); #endif
status = DfsCreateSpcArg( DfsDomainInfo.rgustrDomains[cDom].FlatName.Buffer, 0, DFS_SPECIAL_INFO_NETBIOS, DfsDomainInfo.rgustrDomains[cDom].TrustDirection, DfsDomainInfo.rgustrDomains[cDom].TrustType, -1, NULL, &pSpcArg, &Size);
if (status == ERROR_SUCCESS) {
status = NtFsControlFile( dfsHandle, NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&ioStatus, FSCTL_DFS_CREATE_SPECIAL_INFO, pSpcArg, Size, NULL, 0);
DFSSVC_TRACE_ERROR_HIGH(status, ALL_ERROR, DfsInitRemainingDomainDCs_Error_NtFsControlFile, LOGSTATUS(status)); free(pSpcArg);
}
status = DfsCreateSpcArg( DfsDomainInfo.rgustrDomains[cDom].DnsName.Buffer, 0, 0, DfsDomainInfo.rgustrDomains[cDom].TrustDirection, DfsDomainInfo.rgustrDomains[cDom].TrustType, -1, NULL, &pSpcArg, &Size);
if (status == ERROR_SUCCESS) {
status = NtFsControlFile( dfsHandle, NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&ioStatus, FSCTL_DFS_CREATE_SPECIAL_INFO, pSpcArg, Size, NULL, 0);
DFSSVC_TRACE_ERROR_HIGH(status, ALL_ERROR, DfsInitRemainingDomainDCs_Error_NtFsControlFile2, LOGSTATUS(status));
free(pSpcArg);
}
}
}
if (dfsHandle != NULL) { NtClose( dfsHandle); }
#if DBG
if (DfsSvcVerbose) DbgPrint("DfsInitRemainingDomainDCs returning 0x%x\n", status); #endif
return( status );
}
NTSTATUS _DfsGetTrustedDomainDCs( LPWSTR LpcDomainName, ULONG Flags) { NTSTATUS status; DWORD dwErr; HANDLE dfsHandle = NULL; HANDLE hDs = NULL; IO_STATUS_BLOCK ioStatus; ULONG i, j; PDFS_CREATE_SPECIAL_INFO_ARG pSpcArg; ULONG NameCount = 0; ULONG NT5Count = 0; ULONG Size; ULONG Timeout = 10 * 60; ULONG TrustDirection; ULONG TrustType; ULONG cDom; PDS_DOMAIN_CONTROLLER_INFO_1 pDsDomainControllerInfo1 = NULL; PUNICODE_STRING pustrDCNames = NULL; UNICODE_STRING ustrSiteName; PDFS_CREATE_SITE_INFO_ARG pSiteArg; LPWSTR Name = NULL; WCHAR DnsDomName[MAX_PATH]; UNICODE_STRING uDomainName; UNICODE_STRING uDomainNameDns; UNICODE_STRING uLpcDomainName;
#if DBG
if (DfsSvcVerbose) DbgPrint("DfsGetTrustedDomainDCs(%ws)\n", LpcDomainName); #endif
EnterCriticalSection(&DomListCritSection);
RtlInitUnicodeString(&uDomainName, DomainName); RtlInitUnicodeString(&uDomainNameDns, DomainNameDns); RtlInitUnicodeString(&uLpcDomainName, LpcDomainName);
#if DBG
if (DfsSvcVerbose) DbgPrint("Comparing [%wZ/%wZ] to [%wZ]\n", &uDomainName, &uDomainNameDns, &uLpcDomainName); #endif
if (RtlCompareUnicodeString(&uDomainName, &uLpcDomainName, TRUE) == 0 || RtlCompareUnicodeString(&uDomainNameDns, &uLpcDomainName, TRUE) == 0 ) {
if (wcslen(DomainNameDns) <= MAX_PATH) {
wcscpy(DnsDomName, DomainNameDns); TrustDirection = TRUST_DIRECTION_BIDIRECTIONAL; TrustType = TRUST_TYPE_UPLEVEL;
} else {
status = ERROR_NOT_ENOUGH_MEMORY; LeaveCriticalSection(&DomListCritSection); goto exit_with_status;
}
} else {
for (cDom = 0; cDom < DfsDomainInfo.cDomains; cDom++) {
RtlInitUnicodeString(&uLpcDomainName, LpcDomainName);
#if DBG
if (DfsSvcVerbose) DbgPrint("Comparing [%wZ/%wZ] to [%wZ]\n", &DfsDomainInfo.rgustrDomains[cDom].FlatName, &DfsDomainInfo.rgustrDomains[cDom].DnsName, &uLpcDomainName); #endif
if (RtlCompareUnicodeString( &DfsDomainInfo.rgustrDomains[cDom].FlatName, &uLpcDomainName, TRUE) == 0 || RtlCompareUnicodeString( &DfsDomainInfo.rgustrDomains[cDom].DnsName, &uLpcDomainName, TRUE) == 0 ) {
break;
}
}
if (cDom >= DfsDomainInfo.cDomains) {
status = STATUS_OBJECT_NAME_NOT_FOUND; LeaveCriticalSection(&DomListCritSection); goto exit_with_status;
}
if (DfsDomainInfo.rgustrDomains[cDom].DnsName.Length/sizeof(WCHAR) <= MAX_PATH) {
wcscpy(DnsDomName, DfsDomainInfo.rgustrDomains[cDom].DnsName.Buffer); TrustDirection = DfsDomainInfo.rgustrDomains[cDom].TrustDirection; TrustType = DfsDomainInfo.rgustrDomains[cDom].TrustType;
} else {
status = ERROR_NOT_ENOUGH_MEMORY; LeaveCriticalSection(&DomListCritSection); goto exit_with_status;
}
}
LeaveCriticalSection(&DomListCritSection);
status = DfsOpen(&dfsHandle, NULL);
if (NT_SUCCESS(status)) {
dwErr = DsBind(NULL, DnsDomName, &hDs);
if (dwErr == NO_ERROR) {
//
// get DC list for that domain
//
dwErr = DsGetDomainControllerInfo( hDs, DnsDomName, 1, &NameCount, &pDsDomainControllerInfo1);
#if DBG
if (DfsSvcVerbose) DbgPrint("DsGetDomainControllerInfo(%ws) returned %d\n", DnsDomName, dwErr); #endif
if (dwErr == NO_ERROR && pDsDomainControllerInfo1 != NULL) {
//
// Load Site info
//
#if DBG
if (DfsSvcVerbose) DbgPrint("NameCount=%d\n", NameCount); #endif
for (i = 0; i < NameCount; i++) {
Name = (Flags & DFS_SPECIAL_INFO_NETBIOS) != 0 ? pDsDomainControllerInfo1[i].NetbiosName : pDsDomainControllerInfo1[i].DnsHostName;
if (pDsDomainControllerInfo1[i].fDsEnabled == TRUE && Name != NULL && pDsDomainControllerInfo1[i].SiteName != NULL) {
RtlInitUnicodeString( &ustrSiteName, pDsDomainControllerInfo1[i].SiteName); #if DBG
if (DfsSvcVerbose) DbgPrint("%ws is in site %ws\n", Name, pDsDomainControllerInfo1[i].SiteName); #endif
dwErr = DfsCreateSiteArg( Name, 1, &ustrSiteName, &pSiteArg, &Size);
if ( dwErr != NO_ERROR) {
status = ERROR_NOT_ENOUGH_MEMORY; goto exit_with_status;
}
NtFsControlFile( dfsHandle, NULL, NULL, NULL, &ioStatus, FSCTL_DFS_CREATE_SITE_INFO, pSiteArg, Size, NULL, 0);
free(pSiteArg);
}
}
//
// Convert to an array of UNICODE_STRINGS, taking only the NT5 DC's
//
for (i = NT5Count = 0; i < NameCount; i++) {
if (pDsDomainControllerInfo1[i].fDsEnabled == TRUE) {
NT5Count++;
}
}
if (NT5Count > 0) {
pustrDCNames = malloc(sizeof(UNICODE_STRING) * NT5Count);
if (pustrDCNames == NULL) {
status = ERROR_NOT_ENOUGH_MEMORY; goto exit_with_status;
}
for (i = j = 0; i < NameCount; i++) {
Name = (Flags & DFS_SPECIAL_INFO_NETBIOS) != 0 ? pDsDomainControllerInfo1[i].NetbiosName : pDsDomainControllerInfo1[i].DnsHostName;
if (pDsDomainControllerInfo1[i].fDsEnabled == TRUE && Name != NULL) { RtlInitUnicodeString( &pustrDCNames[j], Name); j++;
}
}
}
#if DBG
if (DfsSvcVerbose) { DbgPrint("DFSINIT:%ws=", LpcDomainName);
for (i = 0; i < j; i++) {
DbgPrint("%wZ ", &pustrDCNames[i]);
}
DbgPrint("\n"); DbgPrint("Our domain has %d DC's\n", j);
} #endif
status = DfsCreateSpcArg( LpcDomainName, Timeout, Flags, TrustDirection, TrustType, j, pustrDCNames, &pSpcArg, &Size);
if (status == ERROR_SUCCESS) {
status = NtFsControlFile( dfsHandle, NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&ioStatus, FSCTL_DFS_CREATE_SPECIAL_INFO, pSpcArg, Size, NULL, 0);
free(pSpcArg);
}
if (pustrDCNames != NULL) {
free(pustrDCNames); pustrDCNames = NULL;
}
}
} else {
status = STATUS_DS_UNAVAILABLE;
}
}
exit_with_status:
if (dfsHandle != NULL) { NtClose( dfsHandle); }
if (pDsDomainControllerInfo1 != NULL) { DsFreeDomainControllerInfo( 1, NameCount, pDsDomainControllerInfo1); }
if (pustrDCNames != NULL) { free(pustrDCNames); }
if (hDs != NULL) { DsUnBind(&hDs); }
#if DBG
if (DfsSvcVerbose) DbgPrint("DfsGetTrustedDomainDCs returning 0x%x\n", status); #endif
return( status );
}
#define MAX_SPC_LONG_NAME_SIZE 2048
NTSTATUS DfsGetTrustedDomainDCs( LPWSTR LpcDomainName, ULONG Flags) { LPWSTR NewDomainName = NULL; NTSTATUS Status = STATUS_SUCCESS;
if ((LpcDomainName != NULL) && (*LpcDomainName != 0)) { return _DfsGetTrustedDomainDCs(LpcDomainName, Flags); }
NewDomainName = malloc(MAX_SPC_LONG_NAME_SIZE); if (NewDomainName == NULL) { return STATUS_INSUFFICIENT_RESOURCES; }
while (DfsGetNextDomainName(NewDomainName, MAX_SPC_LONG_NAME_SIZE) == TRUE) { Status = _DfsGetTrustedDomainDCs(NewDomainName, Flags); }
free(NewDomainName);
return Status; }
DWORD DfsCreateSpcArg( LPWSTR SpecialName, ULONG Timeout, ULONG Flags, ULONG TrustDirection, ULONG TrustType, LONG NameCount, PUNICODE_STRING pustrDCNames, PDFS_CREATE_SPECIAL_INFO_ARG *ppSpcArg, PULONG pSize) { ULONG Size; PDFS_CREATE_SPECIAL_INFO_ARG pSpcArg; PUNICODE_STRING ustrp; WCHAR *wCp; LONG i; LONG j; DWORD status = STATUS_SUCCESS; UNICODE_STRING ComputerNetbiosName; UNICODE_STRING ComputerDnsName; ULONG ComputerNameSize; BOOL bStatus; WCHAR NetBIOSBuffer[MAX_COMPUTERNAME_LENGTH + 1];
RtlInitUnicodeString(&ComputerNetbiosName, NULL); RtlInitUnicodeString(&ComputerDnsName, NULL);
ComputerNetbiosName.Buffer = NetBIOSBuffer; ComputerNetbiosName.MaximumLength = (MAX_COMPUTERNAME_LENGTH + 1) * sizeof(WCHAR);
ComputerNameSize = MAX_COMPUTERNAME_LENGTH + 1; if (GetComputerNameEx(ComputerNameNetBIOS, ComputerNetbiosName.Buffer, &ComputerNameSize)) { ComputerNetbiosName.Length = (USHORT)(ComputerNameSize - 1) * sizeof(WCHAR); }
ComputerNameSize = 0;
while( TRUE ) {
bStatus = GetComputerNameEx( ComputerNameDnsFullyQualified, ComputerDnsName.Buffer, &ComputerNameSize );
if( bStatus == TRUE ) {
ComputerDnsName.Length = (USHORT)(ComputerNameSize - 1) * sizeof(WCHAR); break; }
if( GetLastError() == ERROR_MORE_DATA ) {
if( ComputerDnsName.Buffer != NULL ) {
free( ComputerDnsName.Buffer ); }
ComputerDnsName.Buffer = malloc( ComputerNameSize * sizeof(WCHAR) );
if( ComputerDnsName.Buffer == NULL ) {
ComputerDnsName.MaximumLength = 0; break; }
ComputerDnsName.MaximumLength = (USHORT)ComputerNameSize * sizeof(WCHAR);
} else {
break; } }
#if DBG
if (DfsSvcVerbose) { DbgPrint("DfsCreateSpcArg(SpecialName=%ws,Timeout=%d,Flags=0x%x,NameCount=%d)\n", SpecialName, Timeout, Flags, NameCount);
for (i = 0; i < NameCount; i++) { DbgPrint(" Name[%d]:%wZ\n", i, &pustrDCNames[i]); }
} #endif
//
// Size the buffer
//
if (NameCount > 0) {
Size = FIELD_OFFSET(DFS_CREATE_SPECIAL_INFO_ARG,Name[NameCount]) + wcslen(SpecialName) * sizeof(WCHAR);
for (i = 0; i < NameCount; i++) {
Size += pustrDCNames[i].Length;
}
} else {
Size = sizeof(DFS_CREATE_SPECIAL_INFO_ARG) + wcslen(SpecialName) * sizeof(WCHAR);
}
pSpcArg = malloc(Size);
if (pSpcArg != NULL) {
ZeroMemory(pSpcArg, Size);
// Marshall the info in
pSpcArg->NameCount = NameCount; pSpcArg->Flags = Flags; pSpcArg->TrustDirection = TrustDirection; pSpcArg->TrustType = TrustType; pSpcArg->Timeout = Timeout;
wCp = (WCHAR *) &pSpcArg->Name[NameCount < 0 ? 0 : NameCount];
ustrp = &pSpcArg->SpecialName; ustrp->Buffer = wCp; ustrp->Length = ustrp->MaximumLength = wcslen(SpecialName) * sizeof(WCHAR); RtlCopyMemory(ustrp->Buffer, SpecialName, ustrp->Length); wCp += ustrp->Length / sizeof(WCHAR);
for (i = 0; i < NameCount; i++) { BOOLEAN foundDc = FALSE;
ustrp = &pSpcArg->Name[i]; ustrp->Buffer = wCp; ustrp->Length = ustrp->MaximumLength = pustrDCNames[i].Length; RtlCopyMemory(ustrp->Buffer, pustrDCNames[i].Buffer, ustrp->Length); wCp += ustrp->Length / sizeof(WCHAR); if (!foundDc) { if ((ComputerNetbiosName.Length != 0) && (RtlCompareUnicodeString(&ComputerNetbiosName, &pustrDCNames[i], TRUE) == 0)) { foundDc = TRUE; } else if ((ComputerDnsName.Length != 0) && (RtlCompareUnicodeString(&ComputerDnsName, &pustrDCNames[i], TRUE) == 0)) { foundDc = TRUE; } if ((foundDc == TRUE) && (i != 0)) { UNICODE_STRING Tmp;
Tmp = *ustrp; *ustrp = pSpcArg->Name[0]; pSpcArg->Name[0] = Tmp; } } }
POINTER_TO_OFFSET(pSpcArg->SpecialName.Buffer, pSpcArg); for (i = 0; i < NameCount; i++) { POINTER_TO_OFFSET(pSpcArg->Name[i].Buffer, pSpcArg); }
*ppSpcArg = pSpcArg; *pSize = Size;
} else {
status = ERROR_NOT_ENOUGH_MEMORY;
}
if( ComputerDnsName.Buffer != NULL ) {
free( ComputerDnsName.Buffer ); }
return status;
}
DWORD DfsCreateSiteArg( LPWSTR ServerName, ULONG SiteCount, PUNICODE_STRING pustrSiteNames, PDFS_CREATE_SITE_INFO_ARG *ppSiteArg, PULONG pSize) { ULONG i; ULONG Size; WCHAR *wCp; PUNICODE_STRING ustrp; PDFS_CREATE_SITE_INFO_ARG pSiteArg; DWORD status = STATUS_SUCCESS;
DFSSVC_TRACE_NORM(DEFAULT, DfsCreateSiteArg_Entry, LOGWSTR_CHK(ServerName) LOGULONG(SiteCount) LOGUSTR(*pustrSiteNames)); // Size the buffer
Size = FIELD_OFFSET(DFS_CREATE_SITE_INFO_ARG,SiteName[SiteCount]) + wcslen(ServerName) * sizeof(WCHAR);
for (i = 0; i < SiteCount; i++) Size += pustrSiteNames[i].Length;
pSiteArg = malloc(Size);
if (pSiteArg != NULL) {
// Marshall the info in
pSiteArg->SiteCount = SiteCount;
wCp = (WCHAR *) &pSiteArg->SiteName[SiteCount];
ustrp = &pSiteArg->ServerName; ustrp->Buffer = wCp; ustrp->Length = ustrp->MaximumLength = wcslen(ServerName) * sizeof(WCHAR); RtlCopyMemory(ustrp->Buffer,ServerName,ustrp->Length); wCp += ustrp->Length / sizeof(WCHAR);
for (i = 0; i < SiteCount; i++) {
ustrp = &pSiteArg->SiteName[i]; ustrp->Buffer = wCp; ustrp->Length = ustrp->MaximumLength = pustrSiteNames[i].Length; RtlCopyMemory(ustrp->Buffer,pustrSiteNames[i].Buffer,ustrp->Length); wCp += ustrp->Length / sizeof(WCHAR);
}
POINTER_TO_OFFSET(pSiteArg->ServerName.Buffer, pSiteArg); for (i = 0; i < SiteCount; i++) { POINTER_TO_OFFSET(pSiteArg->SiteName[i].Buffer, pSiteArg); }
*ppSiteArg = pSiteArg; *pSize = Size;
} else {
status = ERROR_NOT_ENOUGH_MEMORY;
}
DFSSVC_TRACE_NORM(DEFAULT, DfsCreateSiteArg_Exit, LOGSTATUS(status) LOGWSTR_CHK(ServerName) LOGULONG(SiteCount) LOGUSTR(*pustrSiteNames));
return status;
}
NTSTATUS DfsDomainReferral( LPWSTR wszDomain, LPWSTR wszShare) { NTSTATUS Status; DWORD dwErr; LPWSTR *List = NULL; PUNICODE_STRING pustr; HANDLE dfsHandle; IO_STATUS_BLOCK ioStatus; ULONG Count; ULONG Size; PDFS_CREATE_SPECIAL_INFO_ARG pSpcArg; ULONG i;
DFSSVC_TRACE_HIGH(DEFAULT,DfsDomainReferral_Entry, LOGWSTR_CHK(wszDomain) LOGWSTR_CHK(wszShare)); #if DBG
if (DfsSvcVerbose) { DbgPrint("DfsDomainReferral()\n", 0); DbgPrint("\twszDomain:%ws\n", wszDomain); DbgPrint("\twszShare:%ws\n", wszShare); } #endif
dwErr = DfsGetFtServersFromDs(pLdap, wszDomain, wszShare, &List);
if (dwErr != NO_ERROR || List == NULL) {
Status = STATUS_OBJECT_NAME_NOT_FOUND;
} else {
for (Count = 0; List[Count]; Count++) /* NOTHING */;
pustr = malloc(sizeof(UNICODE_STRING) * Count);
if (pustr != NULL) {
for (i = 0; i < Count; i++) {
RtlInitUnicodeString(&pustr[i], List[i]);
if (pustr[i].Buffer[0] == L'\\') {
pustr[i].Buffer++; pustr[i].Length -= sizeof(WCHAR); pustr[i].MaximumLength -= sizeof(WCHAR);
}
}
Status = DfsCreateSpcArg( wszShare, 60 * 15, // 15 min
DFS_SPECIAL_INFO_PRIMARY, 0, 0, Count, pustr, &pSpcArg, &Size);
if (Status == ERROR_SUCCESS) {
Status = DfsOpen(&dfsHandle, NULL);
if (NT_SUCCESS(Status)) {
NtFsControlFile( dfsHandle, NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&ioStatus, FSCTL_DFS_CREATE_FTDFS_INFO, pSpcArg, Size, NULL, 0);
NtClose( dfsHandle);
}
//
// Rummage through the DS, loading the site info for the
// machines we found.
//
if (NT_SUCCESS(Status)) {
DfsLoadSiteTableFromDs( pLdap, wszShare, Count, pustr);
}
free(pSpcArg);
}
free(pustr);
}
NetApiBufferFree(List);
}
#if DBG
if (DfsSvcVerbose) DbgPrint("DfsDomainReferral exit 0x%x\n", Status); #endif
return Status;
}
BOOLEAN DfsGetNextDomainName( LPWSTR DomName, ULONG Size) { HANDLE dfsHandle; IO_STATUS_BLOCK ioStatus; NTSTATUS Status;
Status = DfsOpen(&dfsHandle, NULL);
if (NT_SUCCESS(Status)) {
Status = NtFsControlFile( dfsHandle, NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&ioStatus, FSCTL_DFS_GET_NEXT_LONG_DOMAIN_NAME, NULL, 0, DomName, Size);
NtClose( dfsHandle); }
return (Status == STATUS_SUCCESS) ? TRUE : FALSE;
}
|