335 lines
8.3 KiB
C
335 lines
8.3 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1997 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
netname.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Miscellaneous network naming helper functions
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Mac McLain (MacM) Oct 16, 1997
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
User Mode
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
#include <setpch.h>
|
||
|
#include <dssetp.h>
|
||
|
#include <lmcons.h>
|
||
|
#include <lmaccess.h>
|
||
|
#include <lmapibuf.h>
|
||
|
#include <lmerr.h>
|
||
|
#include <lmjoin.h>
|
||
|
#include <netsetup.h>
|
||
|
#include <lsarpc.h>
|
||
|
#include <db.h>
|
||
|
#include <lsasrvmm.h>
|
||
|
#include <lsaisrv.h>
|
||
|
|
||
|
#include <dns.h>
|
||
|
#include <dnsapi.h>
|
||
|
|
||
|
#define MAX_NAME_ATTEMPTS 260
|
||
|
|
||
|
DWORD
|
||
|
WINAPI
|
||
|
DsRolepDnsNameToFlatName(
|
||
|
IN LPWSTR DnsName,
|
||
|
OUT LPWSTR *FlatName,
|
||
|
OUT PULONG StatusFlag
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Determines the suggested netbios domain name for the given dns name
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
DnsName - The Dns domain name to generate a flat name for
|
||
|
|
||
|
FlatName - Where the flat name is to be returned
|
||
|
|
||
|
StatusFlag - Where the status is returned
|
||
|
|
||
|
Returns:
|
||
|
|
||
|
STATUS_SUCCESS - Success
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DWORD Win32Error = ERROR_SUCCESS;
|
||
|
NTSTATUS Status;
|
||
|
PPOLICY_DNS_DOMAIN_INFO DnsDomainInfo = NULL;
|
||
|
PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo;
|
||
|
BOOLEAN FindFromDns = TRUE;
|
||
|
WCHAR NbDomainName[ DNLEN + 1], NbNameAdd[ 4 ];
|
||
|
PWSTR Current = NULL;
|
||
|
WCHAR BaseChar;
|
||
|
ULONG CurrentAttempt = 0;
|
||
|
ULONG i,j;
|
||
|
|
||
|
|
||
|
*StatusFlag = 0;
|
||
|
|
||
|
DsRolepLogPrint(( DEB_TRACE,
|
||
|
"Getting NetBIOS name for Dns name %ws\n",
|
||
|
DnsName ));
|
||
|
|
||
|
//
|
||
|
// First, see if we are part of domain currently or not. If we are, then it's a simple
|
||
|
// matter of returning the current Netbios domain name.
|
||
|
//
|
||
|
Status = LsaIQueryInformationPolicyTrusted(
|
||
|
PolicyAccountDomainInformation,
|
||
|
( PLSAPR_POLICY_INFORMATION * )&AccountDomainInfo );
|
||
|
|
||
|
if ( NT_SUCCESS( Status ) ) {
|
||
|
|
||
|
Status = LsaIQueryInformationPolicyTrusted(
|
||
|
PolicyDnsDomainInformation,
|
||
|
( PLSAPR_POLICY_INFORMATION * )&DnsDomainInfo );
|
||
|
|
||
|
if ( !NT_SUCCESS( Status ) ) {
|
||
|
|
||
|
LsaIFree_LSAPR_POLICY_INFORMATION(
|
||
|
PolicyAccountDomainInformation,
|
||
|
( PLSAPR_POLICY_INFORMATION )AccountDomainInfo );
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( NT_SUCCESS( Status ) ) {
|
||
|
|
||
|
|
||
|
if ( DnsDomainInfo->Sid == NULL || AccountDomainInfo->DomainSid == NULL ||
|
||
|
!RtlEqualSid( AccountDomainInfo->DomainSid, DnsDomainInfo->Sid ) ) {
|
||
|
|
||
|
//
|
||
|
// We're not a member of the domain
|
||
|
//
|
||
|
FindFromDns = TRUE;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// We are a domain member
|
||
|
//
|
||
|
WCHAR *BufDomainName = NULL;
|
||
|
BufDomainName = (WCHAR*)malloc(DnsDomainInfo->Name.Length+sizeof(WCHAR));
|
||
|
if (BufDomainName) {
|
||
|
CopyMemory(BufDomainName,DnsDomainInfo->Name.Buffer,DnsDomainInfo->Name.Length);
|
||
|
BufDomainName[DnsDomainInfo->Name.Length/sizeof(WCHAR)] = L'\0';
|
||
|
DsRolepLogPrint(( DEB_TRACE,
|
||
|
"Using existing NetBIOS domain name %ws\n",
|
||
|
BufDomainName ));
|
||
|
free(BufDomainName);
|
||
|
}
|
||
|
|
||
|
*FlatName = MIDL_user_allocate(
|
||
|
( DnsDomainInfo->Name.Length + 1 ) * sizeof( WCHAR ) );
|
||
|
|
||
|
if ( *FlatName == NULL ) {
|
||
|
|
||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
RtlCopyMemory( *FlatName, DnsDomainInfo->Name.Buffer,
|
||
|
DnsDomainInfo->Name.Length );
|
||
|
( *FlatName )[DnsDomainInfo->Name.Length / sizeof( WCHAR )] = UNICODE_NULL;
|
||
|
*StatusFlag = DSROLE_FLATNAME_UPGRADE;
|
||
|
*StatusFlag |= DSROLE_FLATNAME_DEFAULT;
|
||
|
FindFromDns = FALSE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
LsaIFree_LSAPR_POLICY_INFORMATION(
|
||
|
PolicyAccountDomainInformation,
|
||
|
( PLSAPR_POLICY_INFORMATION )AccountDomainInfo );
|
||
|
|
||
|
LsaIFree_LSAPR_POLICY_INFORMATION(
|
||
|
PolicyDnsDomainInformation,
|
||
|
( PLSAPR_POLICY_INFORMATION )DnsDomainInfo );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If there was no domain name defined, we'll have to get one from the dns name
|
||
|
//
|
||
|
if ( Win32Error == ERROR_SUCCESS && FindFromDns ) {
|
||
|
|
||
|
//
|
||
|
// Ok, to start with, pull off the first DNLEN characters from the DNS name
|
||
|
//
|
||
|
RtlZeroMemory(NbDomainName, sizeof(WCHAR)*(DNLEN+1) );
|
||
|
wcsncpy( NbDomainName, DnsName, DNLEN );
|
||
|
|
||
|
Current = wcschr( NbDomainName, L'.' );
|
||
|
|
||
|
if ( Current ) {
|
||
|
|
||
|
*Current = UNICODE_NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// See if the name is currently in use or not
|
||
|
//
|
||
|
DsRolepLogPrint(( DEB_TRACE,
|
||
|
"Testing default NetBIOS name %ws\n",
|
||
|
NbDomainName ));
|
||
|
|
||
|
Win32Error = NetpValidateName( NULL,
|
||
|
NbDomainName,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NetSetupNonExistentDomain );
|
||
|
|
||
|
if ( Win32Error == ERROR_SUCCESS ) {
|
||
|
|
||
|
*StatusFlag = DSROLE_FLATNAME_DEFAULT;
|
||
|
|
||
|
} else if ( Win32Error == ERROR_DUP_NAME ) {
|
||
|
|
||
|
//
|
||
|
// Position on the last character in the name
|
||
|
//
|
||
|
Current = NbDomainName + wcslen( NbDomainName ) - 1;
|
||
|
|
||
|
ASSERT(Current <= (NbDomainName + DNLEN - 1));
|
||
|
|
||
|
//
|
||
|
// If our name is less than the max. Set our current next to the last character
|
||
|
//
|
||
|
if ( (NbDomainName + DNLEN - 1) != Current ) {
|
||
|
|
||
|
Current++;
|
||
|
*( Current + 1 ) = UNICODE_NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
while ( CurrentAttempt < MAX_NAME_ATTEMPTS ) {
|
||
|
|
||
|
_ultow( CurrentAttempt, NbNameAdd, 10 );
|
||
|
|
||
|
ASSERT( wcslen( NbNameAdd ) < 4 );
|
||
|
|
||
|
//
|
||
|
// See if we need to adjust the position of where we copy
|
||
|
//
|
||
|
if ( CurrentAttempt == 10 || CurrentAttempt == 100 ) {
|
||
|
|
||
|
if ( (NbDomainName + DNLEN) < (Current + wcslen(NbNameAdd)) ) {
|
||
|
|
||
|
Current--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
wcscpy( Current, NbNameAdd );
|
||
|
|
||
|
DsRolepLogPrint(( DEB_TRACE,
|
||
|
"Testing default NetBIOS name %ws\n",
|
||
|
NbDomainName ));
|
||
|
|
||
|
Win32Error = NetpValidateName( NULL,
|
||
|
NbDomainName,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NetSetupNonExistentDomain );
|
||
|
|
||
|
//
|
||
|
// If we've found a name that is in use, try again
|
||
|
//
|
||
|
if ( Win32Error != ERROR_DUP_NAME ) {
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
CurrentAttempt++;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// If we found a valid name, return it
|
||
|
//
|
||
|
if ( Win32Error == ERROR_SUCCESS ) {
|
||
|
|
||
|
*FlatName = MIDL_user_allocate( ( wcslen( NbDomainName ) + 1 ) * sizeof( WCHAR ) );
|
||
|
if ( *FlatName == NULL ) {
|
||
|
|
||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
wcscpy( *FlatName, NbDomainName );
|
||
|
|
||
|
DsRolepLogPrint(( DEB_TRACE,
|
||
|
"Found usable NetBIOS domain name %ws\n",
|
||
|
NbDomainName ));
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
return( Win32Error );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
DsRolepIsDnsNameChild(
|
||
|
IN LPWSTR ParentDnsName,
|
||
|
IN LPWSTR ChildDnsName
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Determines whether the child dns domain name is indeed a child of the parent. This means
|
||
|
that the only difference between the names is the left most component of the child dns name.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ParentDnsName - The Dns domain name of the parent
|
||
|
|
||
|
ChildDnsName - The Dns name of the childe .
|
||
|
|
||
|
Returns:
|
||
|
|
||
|
STATUS_SUCCESS - Success
|
||
|
|
||
|
ERROR_INVALID_DOMAINNAME - The child dns name is not a child of the parent dns name
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DWORD Win32Err = ERROR_SUCCESS;
|
||
|
|
||
|
PWSTR Sep = wcschr( ChildDnsName, L'.' );
|
||
|
|
||
|
if ( Sep == NULL || !DnsNameCompare_W( Sep + 1, ParentDnsName ) ) {
|
||
|
|
||
|
Win32Err = ERROR_INVALID_DOMAINNAME;
|
||
|
|
||
|
}
|
||
|
|
||
|
return( Win32Err );
|
||
|
}
|
||
|
|