windows-nt/Source/XPSP1/NT/ds/netapi/svcdlls/wkssvc/server/dominfo.c
2020-09-26 16:20:57 +08:00

454 lines
10 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//+----------------------------------------------------------------------------
//
// Copyright (C) 1996, Microsoft Corporation
//
// File: dominfo.h
//
// Contents: Code to figure out domain dfs addresses
//
// Classes: None
//
// Functions:
//
// History: Feb 7, 1996 Milans created
//
//-----------------------------------------------------------------------------
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <dfsfsctl.h>
#include <windows.h>
#include <dsgetdc.h>
#include <dsrole.h>
#include <wsutil.h>
#include "dominfo.h"
#define MUP_EVENT_NAME TEXT("wkssvc: MUP finished initializing event")
HANDLE
CreateMupEvent(void);
NTSTATUS
DfsGetDomainNameInfo(void);
HANDLE hMupEvent = NULL;
BOOLEAN MupEventSignaled = FALSE;
BOOLEAN GotDomainNameInfo = FALSE;
ULONG DfsDebug = 0;
//
// Commonly used strings and characters
//
#define UNICODE_PATH_SEP_STR L"\\"
#define UNICODE_PATH_SEP L'\\'
#define DNS_PATH_SEP L'.'
//+----------------------------------------------------------------------------
//
// Function: DfsGetDCName
//
// Synopsis: Gets the name of a DC we can use for expanded name referrals
// It will stick this into the driver.
//
// Arguments: [Flags] -- TBD
//
// Returns: [STATUS_SUCCESS] -- Successfully created domain pkt entry.
//
// [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory condition.
//
// [STATUS_OBJECT_NAME_NOT_FOUND] -- wszDomain is not a trusted
// domain.
//
// [STATUS_UNEXPECTED_NETWORK_ERROR] -- Unable to get DC for
// domain.
//
//-----------------------------------------------------------------------------
NTSTATUS
DfsGetDCName(
IN ULONG Flags,
BOOLEAN *DcNameFailed)
{
NTSTATUS Status;
HANDLE hDfs;
ULONG cbSize;
WCHAR *DCName;
ULONG dwErr;
ULONG Len;
PDOMAIN_CONTROLLER_INFO pDomainControllerInfo;
*DcNameFailed = TRUE;
#if DBG
if (DfsDebug)
DbgPrint("DfsGetDCName(%d)\n", Flags);
#endif
if( WsInAWorkgroup() == TRUE ) {
//
// We are in a workgroup. We will never find a DC!
//
#if DBG
if (DfsDebug)
DbgPrint("DfsGetDCName exit STATUS_NO_SUCH_DOMAIN\n");
#endif
return STATUS_NO_SUCH_DOMAIN;
}
if (hMupEvent == NULL) {
hMupEvent = CreateMupEvent();
}
dwErr = DsGetDcName(
NULL, // Computername
NULL, // DomainName
NULL, // DomainGuid
NULL, // SiteGuid
Flags | DS_DIRECTORY_SERVICE_REQUIRED,
&pDomainControllerInfo);
//
// If DsGetDcName succeeded, try to get the NetBios & Dns domain names.
//
if (dwErr != NO_ERROR) {
if (MupEventSignaled == FALSE) {
#if DBG
if (DfsDebug)
DbgPrint("Signaling mup event\n");
#endif
SetEvent(hMupEvent);
MupEventSignaled = TRUE;
}
switch (dwErr) {
case ERROR_NOT_ENOUGH_MEMORY:
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
case ERROR_NETWORK_UNREACHABLE:
Status = STATUS_NETWORK_UNREACHABLE;
break;
default:
Status = STATUS_UNEXPECTED_NETWORK_ERROR;
break;
}
#if DBG
if (DfsDebug)
DbgPrint("DfsGetDCName(1) exit 0x%x\n", Status);
#endif
return (Status);
} else {
if (pDomainControllerInfo == NULL) {
DbgBreakPoint();
}
}
*DcNameFailed = FALSE;
DfsGetDomainNameInfo();
//
// Remove leading '\'s
//
DCName = pDomainControllerInfo->DomainControllerName;
while (*DCName == UNICODE_PATH_SEP && *DCName != UNICODE_NULL)
DCName++;
//
// Remove trailing '.', if present
//
Len = wcslen(DCName);
if (Len >= 1 && DCName[Len-1] == DNS_PATH_SEP) {
DCName[Len-1] = UNICODE_NULL;
}
if (wcslen(DCName) <= 0) {
NetApiBufferFree(pDomainControllerInfo);
#if DBG
if (DfsDebug)
DbgPrint("DfsGetDCName exit STATUS_UNEXPECTED_NETWORK_ERROR\n");
#endif
return (STATUS_UNEXPECTED_NETWORK_ERROR);
}
Status = DfsOpen( &hDfs, NULL );
if (!NT_SUCCESS(Status)) {
NetApiBufferFree(pDomainControllerInfo);
#if DBG
if (DfsDebug)
DbgPrint("DfsGetDCName(2) exit 0x%x\n", Status);
#endif
return (Status);
}
//
// Take the name and fscontrol it down to the driver
//
cbSize = wcslen(DCName) * sizeof(WCHAR) + sizeof(WCHAR);
Status = DfsFsctl(
hDfs,
FSCTL_DFS_PKT_SET_DC_NAME,
DCName,
cbSize,
NULL,
0L);
NetApiBufferFree(pDomainControllerInfo);
//
// Inform anyone waiting that the mup is ready.
//
if (MupEventSignaled == FALSE) {
#if DBG
if (DfsDebug)
DbgPrint("Signaling mup event\n");
#endif
SetEvent(hMupEvent);
MupEventSignaled = TRUE;
}
NtClose( hDfs );
#if DBG
if (DfsDebug)
DbgPrint("DfsGetDCName(3) exit 0x%x\n", Status);
#endif
return (Status);
}
//+----------------------------------------------------------------------------
//
// Function: DfsGetDomainNameInfo
//
// Synopsis: Gets the Netbios & Dns name of the domain, then sends them
// down to the drvier;
//
// Returns: [STATUS_SUCCESS] -- Successfully created domain pkt entry.
// [other] -- return from DfsOpen or
// DsRoleGetPrimaryDomainInformation
//
//-----------------------------------------------------------------------------
NTSTATUS
DfsGetDomainNameInfo(void)
{
NTSTATUS Status;
ULONG dwErr;
HANDLE hDfs;
ULONG cbSize;
PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pPrimaryDomainInfo;
Status = DfsOpen( &hDfs, NULL );
if (!NT_SUCCESS(Status)) {
return (Status);
}
//
// Get our machine name and type/role.
//
dwErr = DsRoleGetPrimaryDomainInformation(
NULL,
DsRolePrimaryDomainInfoBasic,
(PBYTE *)&pPrimaryDomainInfo);
if (dwErr == ERROR_SUCCESS) {
if (pPrimaryDomainInfo->DomainNameFlat != NULL) {
cbSize = wcslen(pPrimaryDomainInfo->DomainNameFlat) * sizeof(WCHAR) + sizeof(WCHAR);
Status = DfsFsctl(
hDfs,
FSCTL_DFS_PKT_SET_DOMAINNAMEFLAT,
pPrimaryDomainInfo->DomainNameFlat,
cbSize,
NULL,
0L);
}
if (pPrimaryDomainInfo->DomainNameDns != NULL) {
cbSize = wcslen(pPrimaryDomainInfo->DomainNameDns) * sizeof(WCHAR) + sizeof(WCHAR);
Status = DfsFsctl(
hDfs,
FSCTL_DFS_PKT_SET_DOMAINNAMEDNS,
pPrimaryDomainInfo->DomainNameDns,
cbSize,
NULL,
0L);
}
DsRoleFreeMemory(pPrimaryDomainInfo);
GotDomainNameInfo = TRUE;
}
NtClose( hDfs );
return (Status);
}
UNICODE_STRING LocalDfsName = {
sizeof(DFS_DRIVER_NAME)-sizeof(UNICODE_NULL),
sizeof(DFS_DRIVER_NAME)-sizeof(UNICODE_NULL),
DFS_DRIVER_NAME
};
//+-------------------------------------------------------------------------
//
// Function: DfsOpen, public
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
//--------------------------------------------------------------------------
NTSTATUS
DfsOpen(
IN OUT PHANDLE DfsHandle,
IN PUNICODE_STRING DfsName OPTIONAL
)
{
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK ioStatus;
PUNICODE_STRING name;
if (ARGUMENT_PRESENT(DfsName)) {
name = DfsName;
} else {
name = &LocalDfsName;
}
InitializeObjectAttributes(
&objectAttributes,
name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
status = NtCreateFile(
DfsHandle,
SYNCHRONIZE | FILE_WRITE_DATA,
&objectAttributes,
&ioStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN_IF,
FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (NT_SUCCESS(status))
status = ioStatus.Status;
return status;
}
//+-------------------------------------------------------------------------
//
// Function: DfsFsctl, public
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
//--------------------------------------------------------------------------
NTSTATUS
DfsFsctl(
IN HANDLE DfsHandle,
IN ULONG FsControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength
)
{
NTSTATUS status;
IO_STATUS_BLOCK ioStatus;
status = NtFsControlFile(
DfsHandle,
NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&ioStatus,
FsControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength
);
if(NT_SUCCESS(status))
status = ioStatus.Status;
return status;
}
//+-------------------------------------------------------------------------
//
// CreateMUPEvent()
//
// Purpose: Creates an event so other processes can check if the
// MUP is ready yet
//
// Parameters: none
//
// Note: This handle should never be closed or other processes
// will fail on the call to OpenEvent().
//
// Return: Event handle if successful
// NULL if an error occurs
//
//+-------------------------------------------------------------------------
HANDLE
CreateMupEvent(void)
{
HANDLE hEvent;
// Use default security descriptor.
hEvent = CreateEvent (NULL, TRUE, FALSE, MUP_EVENT_NAME);
return hEvent;
}