|
|
/*++
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 ); }
|