1219 lines
22 KiB
C
1219 lines
22 KiB
C
/*++
|
||
|
||
Copyright (c) 1995 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
local.c
|
||
|
||
Abstract:
|
||
|
||
Domain Name System (DNS) Server -- Admin Client API
|
||
|
||
DNS Admin API calls that do not use RPC.
|
||
Completely executed in client library.
|
||
|
||
Author:
|
||
|
||
Jim Gilroy (jamesg) 14-Oct-1995
|
||
|
||
Environment:
|
||
|
||
User Mode - Win32
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
#include "dnsclip.h"
|
||
|
||
//
|
||
// Debug globals
|
||
//
|
||
|
||
DWORD LocalDebugFlag;
|
||
|
||
//
|
||
// Buffer size for building WKS services string
|
||
//
|
||
|
||
#define WKS_SERVICES_BUFFER_SIZE (0x1000) // 4k
|
||
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvInitializeDebug(
|
||
VOID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initialize debugging -- use dnslib debugging.
|
||
|
||
Only purpose is generic interface that hides file flag
|
||
and name info so no need to put in header.
|
||
|
||
--*/
|
||
{
|
||
#if DBG
|
||
Dns_StartDebug(
|
||
0,
|
||
DNSRPC_DEBUG_FLAG_FILE,
|
||
& LocalDebugFlag,
|
||
DNSRPC_DEBUG_FILE_NAME,
|
||
1000000 // 1mb wrap
|
||
);
|
||
|
||
DNS_PRINT(( "LocalDebugFlag = %p\n", LocalDebugFlag ));
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
PVOID
|
||
DnssrvMidlAllocZero(
|
||
IN DWORD dwSize
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
MIDL allocate and zero memory.
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
Ptr to allocated and zeroed memory.
|
||
|
||
--*/
|
||
{
|
||
PVOID ptr;
|
||
|
||
ptr = MIDL_user_allocate( dwSize );
|
||
if ( !ptr )
|
||
{
|
||
return( NULL );
|
||
}
|
||
|
||
RtlZeroMemory(
|
||
ptr,
|
||
dwSize );
|
||
|
||
return( ptr );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvFreeRpcBuffer(
|
||
IN OUT PDNS_RPC_BUFFER pBuf
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Free generic (no substructures) RPC buffer.
|
||
|
||
Arguments:
|
||
|
||
pBuf -- ptr to buf to free
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
if ( !pBuf )
|
||
{
|
||
return;
|
||
}
|
||
MIDL_user_free( pBuf );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvFreeServerInfo(
|
||
IN OUT PDNS_RPC_SERVER_INFO pServerInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Deep free of DNS_SERVER_INFO structure.
|
||
|
||
Arguments:
|
||
|
||
pServerInfo -- ptr to server info to free
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
if ( !pServerInfo )
|
||
{
|
||
return;
|
||
}
|
||
|
||
//
|
||
// free allocated items inside the server info blob
|
||
//
|
||
|
||
if ( pServerInfo->pszServerName )
|
||
{
|
||
MIDL_user_free( pServerInfo->pszServerName );
|
||
}
|
||
if ( pServerInfo->aipServerAddrs )
|
||
{
|
||
MIDL_user_free( pServerInfo->aipServerAddrs );
|
||
}
|
||
if ( pServerInfo->aipListenAddrs )
|
||
{
|
||
MIDL_user_free( pServerInfo->aipListenAddrs );
|
||
}
|
||
if ( pServerInfo->aipForwarders )
|
||
{
|
||
MIDL_user_free( pServerInfo->aipForwarders );
|
||
}
|
||
if ( pServerInfo->aipLogFilter )
|
||
{
|
||
MIDL_user_free( pServerInfo->aipLogFilter );
|
||
}
|
||
if ( pServerInfo->pwszLogFilePath )
|
||
{
|
||
MIDL_user_free( pServerInfo->pwszLogFilePath );
|
||
}
|
||
if ( pServerInfo->pszDsContainer )
|
||
{
|
||
MIDL_user_free( pServerInfo->pszDsContainer );
|
||
}
|
||
if ( pServerInfo->pszDomainName )
|
||
{
|
||
MIDL_user_free( pServerInfo->pszDomainName );
|
||
}
|
||
if ( pServerInfo->pszForestName )
|
||
{
|
||
MIDL_user_free( pServerInfo->pszForestName );
|
||
}
|
||
if ( pServerInfo->pszDomainDirectoryPartition )
|
||
{
|
||
MIDL_user_free( pServerInfo->pszDomainDirectoryPartition );
|
||
}
|
||
if ( pServerInfo->pszForestDirectoryPartition )
|
||
{
|
||
MIDL_user_free( pServerInfo->pszForestDirectoryPartition );
|
||
}
|
||
|
||
//
|
||
// free DNS_SERVER_INFO struct itself
|
||
//
|
||
|
||
MIDL_user_free( pServerInfo );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvFreeZoneInfo(
|
||
IN OUT PDNS_RPC_ZONE_INFO pZoneInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Deep free of DNS_ZONE_INFO structure.
|
||
|
||
Arguments:
|
||
|
||
pZoneInfo -- ptr to zone info to free
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
if ( !pZoneInfo )
|
||
{
|
||
return;
|
||
}
|
||
|
||
//
|
||
// free substructures
|
||
// - name string
|
||
// - data file string
|
||
// - secondary IP array
|
||
// - WINS server array
|
||
//
|
||
|
||
if ( pZoneInfo->pszZoneName )
|
||
{
|
||
MIDL_user_free( pZoneInfo->pszZoneName );
|
||
}
|
||
if ( pZoneInfo->pszDataFile )
|
||
{
|
||
MIDL_user_free( pZoneInfo->pszDataFile );
|
||
}
|
||
if ( pZoneInfo->aipMasters )
|
||
{
|
||
MIDL_user_free( pZoneInfo->aipMasters );
|
||
}
|
||
if ( pZoneInfo->aipSecondaries )
|
||
{
|
||
MIDL_user_free( pZoneInfo->aipSecondaries );
|
||
}
|
||
if ( pZoneInfo->pszDpFqdn )
|
||
{
|
||
MIDL_user_free( pZoneInfo->pszDpFqdn );
|
||
}
|
||
if ( pZoneInfo->pwszZoneDn )
|
||
{
|
||
MIDL_user_free( pZoneInfo->pwszZoneDn );
|
||
}
|
||
|
||
//
|
||
// free DNS_ZONE_INFO struct itself
|
||
//
|
||
|
||
MIDL_user_free( pZoneInfo );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvFreeNode(
|
||
IN OUT PDNS_NODE pNode,
|
||
IN BOOLEAN fFreeRecords
|
||
)
|
||
{
|
||
if ( pNode->pRecord )
|
||
{
|
||
Dns_RecordListFree(
|
||
pNode->pRecord,
|
||
TRUE );
|
||
}
|
||
|
||
if ( pNode->Flags.S.FreeOwner )
|
||
{
|
||
FREE_HEAP( pNode->pName );
|
||
}
|
||
FREE_HEAP( pNode );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvFreeNodeList(
|
||
IN OUT PDNS_NODE pNode,
|
||
IN BOOLEAN fFreeRecords
|
||
)
|
||
{
|
||
PDNS_NODE pnext;
|
||
|
||
// free all nodes in list
|
||
|
||
while ( pNode )
|
||
{
|
||
pnext = pNode->pNext;
|
||
DnssrvFreeNode(
|
||
pNode,
|
||
fFreeRecords );
|
||
pNode = pnext;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvFreeZone(
|
||
IN OUT PDNS_RPC_ZONE pZone
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Deep free of DNS_RPC_ZONE structure.
|
||
|
||
Arguments:
|
||
|
||
pZone -- ptr to zone to free
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
if ( !pZone )
|
||
{
|
||
return;
|
||
}
|
||
|
||
// free zone name, then zone itself
|
||
|
||
if ( pZone->pszZoneName )
|
||
{
|
||
MIDL_user_free( pZone->pszZoneName );
|
||
}
|
||
if ( pZone->pszDpFqdn )
|
||
{
|
||
MIDL_user_free( pZone->pszDpFqdn );
|
||
}
|
||
MIDL_user_free( pZone );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvFreeZoneList(
|
||
IN OUT PDNS_RPC_ZONE_LIST pZoneList
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Deep free of list of DNS_RPC_ZONE structures.
|
||
|
||
Arguments:
|
||
|
||
pZoneList -- ptr RPC_ZONE_LIST structure to free
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
DWORD i;
|
||
PDNS_RPC_ZONE pzone;
|
||
|
||
if ( !pZoneList )
|
||
{
|
||
return;
|
||
}
|
||
for( i=0; i< pZoneList->dwZoneCount; i++ )
|
||
{
|
||
// zone name is only sub-structure
|
||
|
||
pzone = pZoneList->ZoneArray[i];
|
||
MIDL_user_free( pzone->pszZoneName );
|
||
MIDL_user_free( pzone );
|
||
}
|
||
|
||
MIDL_user_free( pZoneList );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvFreeDirectoryPartitionEnum(
|
||
IN OUT PDNS_RPC_DP_ENUM pDp
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Deep free of PDNS_RPC_DP_ENUM structure.
|
||
|
||
Arguments:
|
||
|
||
pDp -- ptr to directory partition to free
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
if ( !pDp )
|
||
{
|
||
return;
|
||
}
|
||
if ( pDp->pszDpFqdn )
|
||
{
|
||
MIDL_user_free( pDp->pszDpFqdn );
|
||
}
|
||
MIDL_user_free( pDp );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvFreeDirectoryPartitionInfo(
|
||
IN OUT PDNS_RPC_DP_INFO pDp
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Deep free of PDNS_RPC_DP_INFO structure.
|
||
|
||
Arguments:
|
||
|
||
pDp -- ptr to directory partition to free
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
DWORD i;
|
||
|
||
if ( !pDp )
|
||
{
|
||
return;
|
||
}
|
||
|
||
if ( pDp->pszDpFqdn )
|
||
{
|
||
MIDL_user_free( pDp->pszDpFqdn );
|
||
}
|
||
if ( pDp->pszDpDn )
|
||
{
|
||
MIDL_user_free( pDp->pszDpDn );
|
||
}
|
||
if ( pDp->pszCrDn )
|
||
{
|
||
MIDL_user_free( pDp->pszCrDn );
|
||
}
|
||
for( i = 0; i < pDp->dwReplicaCount; i++ )
|
||
{
|
||
PDNS_RPC_DP_REPLICA p = pDp->ReplicaArray[ i ];
|
||
|
||
if ( p )
|
||
{
|
||
if ( p->pszReplicaDn )
|
||
{
|
||
MIDL_user_free( p->pszReplicaDn );
|
||
}
|
||
MIDL_user_free( p );
|
||
}
|
||
}
|
||
MIDL_user_free( pDp );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
DnssrvFreeDirectoryPartitionList(
|
||
IN OUT PDNS_RPC_DP_LIST pDpList
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Deep free of list of PDNS_RPC_DP_LIST structures.
|
||
|
||
Arguments:
|
||
|
||
pZoneList -- ptr PDNS_RPC_DP_LIST structure to free
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
DWORD i;
|
||
PDNS_RPC_DP_ENUM pDp;
|
||
|
||
if ( !pDpList )
|
||
{
|
||
return;
|
||
}
|
||
|
||
for( i=0; i < pDpList->dwDpCount; ++i )
|
||
{
|
||
pDp = pDpList->DpArray[ i ];
|
||
DnssrvFreeDirectoryPartitionEnum( pDp );
|
||
}
|
||
|
||
MIDL_user_free( pDpList );
|
||
}
|
||
|
||
|
||
|
||
PCHAR
|
||
DnssrvGetWksServicesInRecord(
|
||
IN PDNS_FLAT_RECORD pRR
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Get list of services in WKS record.
|
||
|
||
Arguments:
|
||
|
||
pRR - flat WKS record being written
|
||
|
||
Return Value:
|
||
|
||
Ptr to services string, caller MUST free.
|
||
NULL on error.
|
||
|
||
--*/
|
||
{
|
||
struct servent * pServent;
|
||
struct protoent * pProtoent;
|
||
INT i;
|
||
DWORD length;
|
||
USHORT port;
|
||
UCHAR bBitmask;
|
||
CHAR buffer[ WKS_SERVICES_BUFFER_SIZE ];
|
||
PCHAR pch = buffer;
|
||
PCHAR pchstart;
|
||
PCHAR pchstop;
|
||
|
||
// protocol
|
||
|
||
pProtoent = getprotobynumber( (INT) pRR->Data.WKS.chProtocol );
|
||
if ( ! pProtoent )
|
||
{
|
||
DNS_PRINT((
|
||
"ERROR: Unable to find protocol %d, writing WKS record.\n",
|
||
(INT) pRR->Data.WKS.chProtocol
|
||
));
|
||
return( NULL );
|
||
}
|
||
|
||
//
|
||
// services
|
||
//
|
||
// find each bit set in bitmask, lookup and write service
|
||
// corresponding to that port
|
||
//
|
||
// note, that since that port zero is the front of port bitmask,
|
||
// lowest ports are the highest bits in each byte
|
||
//
|
||
|
||
pchstart = pch;
|
||
pchstop = pch + WKS_SERVICES_BUFFER_SIZE;
|
||
|
||
for ( i = 0;
|
||
i < (INT)(pRR->wDataLength - SIZEOF_WKS_FIXED_DATA);
|
||
i++ )
|
||
{
|
||
bBitmask = (UCHAR) pRR->Data.WKS.bBitMask[i];
|
||
|
||
port = i * 8;
|
||
|
||
// write service name for each bit set in byte
|
||
// - get out as soon byte is empty of ports
|
||
// - terminate each name with blank (until last)
|
||
|
||
while ( bBitmask )
|
||
{
|
||
if ( bBitmask & 0x80 )
|
||
{
|
||
pServent = getservbyport(
|
||
(INT) htons(port),
|
||
pProtoent->p_name );
|
||
|
||
if ( pServent )
|
||
{
|
||
INT copyCount = strlen(pServent->s_name);
|
||
|
||
pch++;
|
||
if ( pchstop - pch <= copyCount+1 )
|
||
{
|
||
return( NULL );
|
||
}
|
||
RtlCopyMemory(
|
||
pch,
|
||
pServent->s_name,
|
||
copyCount );
|
||
pch += copyCount;
|
||
*pch = ' ';
|
||
}
|
||
else
|
||
{
|
||
DNS_PRINT((
|
||
"ERROR: Unable to find service for port %d, "
|
||
"writing WKS record.\n",
|
||
port
|
||
));
|
||
pch += sprintf( pch, "%d", port );
|
||
}
|
||
}
|
||
port++; // next service port
|
||
bBitmask <<= 1; // shift mask up to read next port
|
||
}
|
||
}
|
||
|
||
// NULL terminate services string
|
||
// and determine length
|
||
|
||
*pch++ = 0;
|
||
length = (DWORD) (pch - pchstart);
|
||
|
||
// allocate copy of this string
|
||
|
||
pch = ALLOCATE_HEAP( length );
|
||
if ( !pch )
|
||
{
|
||
SetLastError( DNS_ERROR_NO_MEMORY );
|
||
return( NULL );
|
||
}
|
||
|
||
RtlCopyMemory(
|
||
pch,
|
||
pchstart,
|
||
length );
|
||
|
||
return( pch );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Build LDAP \ DS names for objects
|
||
//
|
||
|
||
//
|
||
// Build Unicode LDAP paths
|
||
//
|
||
|
||
#define DN_TEXT(string) (L##string)
|
||
|
||
|
||
LPWSTR
|
||
DNS_API_FUNCTION
|
||
DnssrvCreateDsNodeName(
|
||
IN PDNS_RPC_SERVER_INFO pServerInfo,
|
||
IN LPWSTR pszZone,
|
||
IN LPWSTR pszNode
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build node DS name.
|
||
|
||
Arguments:
|
||
|
||
pServerInfo -- server info for server
|
||
|
||
pszZone -- zone name
|
||
|
||
pszNode -- node name RELATIVE to zone root
|
||
|
||
Return Value:
|
||
|
||
Ptr to node's DS name. Caller must free.
|
||
NULL on error.
|
||
|
||
--*/
|
||
{
|
||
PWCHAR psznodeDN;
|
||
DWORD length;
|
||
|
||
// if not DS integrated, bail
|
||
|
||
if ( !pServerInfo->pszDsContainer )
|
||
{
|
||
return( NULL );
|
||
}
|
||
|
||
// special case zone root
|
||
|
||
if ( !pszNode )
|
||
{
|
||
pszNode = DN_TEXT("@");
|
||
}
|
||
|
||
// allocate required space
|
||
|
||
length = sizeof(DN_TEXT("dc=,dc=, "));
|
||
length += sizeof(WCHAR) * wcslen( pszNode );
|
||
length += sizeof(WCHAR) * wcslen( pszZone );
|
||
length += sizeof(WCHAR) * wcslen( (LPWSTR)pServerInfo->pszDsContainer );
|
||
|
||
psznodeDN = (PWCHAR) ALLOCATE_HEAP( length );
|
||
if ( !psznodeDN )
|
||
{
|
||
return( psznodeDN );
|
||
}
|
||
|
||
// build DN
|
||
|
||
wcscpy( psznodeDN, DN_TEXT("dc=") );
|
||
wcscat( psznodeDN, pszNode );
|
||
length = wcslen(psznodeDN);
|
||
ASSERT ( length > 3 );
|
||
|
||
if ( length != 4 && // "dc=." case
|
||
psznodeDN[ length - 1 ] == '.' )
|
||
{
|
||
//
|
||
// we have a dot terminated node name, strip it out
|
||
//
|
||
psznodeDN[ length - 1 ] = '\0';
|
||
}
|
||
wcscat( psznodeDN, DN_TEXT(",dc=") );
|
||
wcscat( psznodeDN, pszZone );
|
||
length = wcslen(psznodeDN);
|
||
ASSERT ( length > 1 );
|
||
|
||
if ( 1 != wcslen ( pszZone ) && // zone = "." case
|
||
psznodeDN[ length - 1 ] == '.' )
|
||
{
|
||
//
|
||
// we have a dot terminated zone name, strip it out
|
||
//
|
||
psznodeDN[ length - 1 ] = '\0';
|
||
}
|
||
wcscat( psznodeDN, DN_TEXT(",") );
|
||
wcscat( psznodeDN, (LPWSTR)pServerInfo->pszDsContainer );
|
||
|
||
DNSDBG( STUB, (
|
||
"Node DN built: %s\n",
|
||
psznodeDN ));
|
||
|
||
return( psznodeDN );
|
||
}
|
||
|
||
|
||
|
||
LPWSTR
|
||
DNS_API_FUNCTION
|
||
DnssrvCreateDsZoneName(
|
||
IN PDNS_RPC_SERVER_INFO pServerInfo,
|
||
IN LPWSTR pszZone
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build zone DS name.
|
||
|
||
This routine should only be used for legacy zones on W2K servers.
|
||
For Whistler+ servers the zone info structure has the zone object DN.
|
||
|
||
Arguments:
|
||
|
||
pServerInfo -- server info for server
|
||
|
||
pszZone -- zone name
|
||
|
||
Return Value:
|
||
|
||
Ptr to zone's DS name. Caller must free.
|
||
NULL on error.
|
||
|
||
--*/
|
||
{
|
||
|
||
PWCHAR pszzoneDN;
|
||
DWORD length;
|
||
|
||
// if not DS integrated, bail
|
||
|
||
if ( !(LPWSTR)pServerInfo->pszDsContainer )
|
||
{
|
||
return( NULL );
|
||
}
|
||
|
||
// allocate required space
|
||
|
||
length = sizeof(DN_TEXT("dc=, "));
|
||
length += sizeof(WCHAR) * wcslen( pszZone );
|
||
length += sizeof(WCHAR) * wcslen( (LPWSTR)pServerInfo->pszDsContainer );
|
||
|
||
pszzoneDN = (PWCHAR) ALLOCATE_HEAP( length );
|
||
if ( !pszzoneDN )
|
||
{
|
||
return( pszzoneDN );
|
||
}
|
||
|
||
// build DN
|
||
|
||
wcscpy( pszzoneDN, DN_TEXT("dc=") );
|
||
wcscat( pszzoneDN, pszZone );
|
||
length = wcslen(pszzoneDN);
|
||
ASSERT ( length > 1 );
|
||
|
||
if ( length != 4 && // "dc=." case
|
||
pszzoneDN[ length - 1 ] == '.' )
|
||
{
|
||
//
|
||
// we have a dot terminated zone name, strip it out
|
||
//
|
||
pszzoneDN[ length - 1 ] = '\0';
|
||
}
|
||
wcscat( pszzoneDN, DN_TEXT(",") );
|
||
wcscat( pszzoneDN, (LPWSTR)pServerInfo->pszDsContainer );
|
||
|
||
DNSDBG( STUB, (
|
||
"Zone DN built: %s\n",
|
||
pszzoneDN ));
|
||
|
||
return( pszzoneDN );
|
||
}
|
||
|
||
|
||
|
||
LPWSTR
|
||
DNS_API_FUNCTION
|
||
DnssrvCreateDsServerName(
|
||
IN PDNS_RPC_SERVER_INFO pServerInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build zone DS name.
|
||
|
||
Arguments:
|
||
|
||
pServerInfo -- server info for server
|
||
|
||
Return Value:
|
||
|
||
Ptr to server's DS name. Caller must free.
|
||
NULL on error.
|
||
|
||
--*/
|
||
{
|
||
PWCHAR pszserverDN;
|
||
DWORD length;
|
||
|
||
//
|
||
// DEVNOTE: need investigation here,
|
||
// may just be able to use DNS folder in DS
|
||
//
|
||
|
||
// if not DS integrated, bail
|
||
|
||
if ( !(LPWSTR)pServerInfo->pszDsContainer )
|
||
{
|
||
return( NULL );
|
||
}
|
||
|
||
// allocate space
|
||
|
||
length = sizeof(DN_TEXT(" "));
|
||
length += sizeof(WCHAR) * wcslen( (LPWSTR)pServerInfo->pszDsContainer );
|
||
|
||
pszserverDN = (PWCHAR) ALLOCATE_HEAP( length );
|
||
if ( !pszserverDN )
|
||
{
|
||
return( pszserverDN );
|
||
}
|
||
|
||
// build DN
|
||
|
||
wcscpy( pszserverDN, (LPWSTR)pServerInfo->pszDsContainer );
|
||
|
||
DNSDBG( STUB, (
|
||
"Server DN built: %s\n",
|
||
pszserverDN ));
|
||
|
||
return( pszserverDN );
|
||
}
|
||
|
||
//
|
||
// End local.c
|
||
//
|
||
|
||
|
||
#if 0
|
||
|
||
|
||
VOID
|
||
convertRpcUnionTypeToUnicode(
|
||
IN DWORD dwTypeId,
|
||
IN OUT DNS_RPC_UNION pData
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Convert RPC union types to unicode.
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
switch ( dwTypeId )
|
||
{
|
||
case DNSSRV_TYPEID_LPSTR:
|
||
|
||
pwideString = DnsStringCopyAllocateEx(
|
||
pData.String,
|
||
0,
|
||
FALSE, // UTF8 in
|
||
TRUE // Unicode out
|
||
);
|
||
if ( !pwideString )
|
||
{
|
||
ASSERT( FALSE );
|
||
return;
|
||
}
|
||
MIDL_user_free( pData.String );
|
||
pData.String = (LPSTR) pwideString;
|
||
|
||
case DNSSRV_TYPEID_SERVER_INFO:
|
||
|
||
DnsPrint_RpcServerInfo(
|
||
PrintRoutine,
|
||
pszHeader,
|
||
(PDNS_RPC_SERVER_INFO) pData );
|
||
break;
|
||
|
||
case DNSSRV_TYPEID_ZONE:
|
||
|
||
DnsPrint_RpcZone(
|
||
PrintRoutine,
|
||
pszHeader,
|
||
(PDNS_RPC_ZONE) pData );
|
||
break;
|
||
|
||
case DNSSRV_TYPEID_ZONE_INFO:
|
||
|
||
DnsPrint_RpcZoneInfo(
|
||
PrintRoutine,
|
||
pszHeader,
|
||
(PDNS_RPC_ZONE_INFO) pData );
|
||
break;
|
||
|
||
case DNSSRV_TYPEID_ZONE_DBASE_INFO:
|
||
|
||
PrintRoutine(
|
||
"%sZone Dbase Info:\n"
|
||
"\tDS Integrated = %d\n"
|
||
"\tFile Name = %s\n",
|
||
pszHeader,
|
||
((PDNS_RPC_ZONE_DBASE_INFO)pData)->fDsIntegrated,
|
||
((PDNS_RPC_ZONE_DBASE_INFO)pData)->pszFileName );
|
||
break;
|
||
}
|
||
|
||
|
||
VOID
|
||
convertStringToUnicodeInPlace(
|
||
IN LPSTR * ppszString
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Convert string to unicode and return it to its current
|
||
position in structure.
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
switch ( dwTypeId )
|
||
{
|
||
case DNSSRV_TYPEID_LPSTR:
|
||
|
||
pwideString = Dns_StringCopyAllocateEx(
|
||
pData.String,
|
||
0,
|
||
FALSE, // UTF8 in
|
||
TRUE // Unicode out
|
||
);
|
||
if ( !pwideString )
|
||
{
|
||
ASSERT( FALSE );
|
||
return;
|
||
}
|
||
MIDL_user_free( pData.String );
|
||
pData.String = (LPSTR) pwideString;
|
||
|
||
case DNSSRV_TYPEID_SERVER_INFO:
|
||
|
||
DnsPrint_RpcServerInfo(
|
||
PrintRoutine,
|
||
pszHeader,
|
||
(PDNS_RPC_SERVER_INFO) pData );
|
||
break;
|
||
|
||
case DNSSRV_TYPEID_STATS:
|
||
|
||
DnsPrint_RpcStatistics(
|
||
PrintRoutine,
|
||
pszHeader,
|
||
(PDNS_RPC_STATISTICS) pData );
|
||
break;
|
||
|
||
case DNSSRV_TYPEID_ZONE:
|
||
|
||
DnsPrint_RpcZone(
|
||
PrintRoutine,
|
||
pszHeader,
|
||
(PDNS_RPC_ZONE) pData );
|
||
break;
|
||
|
||
case DNSSRV_TYPEID_FORWARDERS:
|
||
|
||
DnsPrint_RpcIpArrayPlusParameters(
|
||
PrintRoutine,
|
||
pszHeader,
|
||
"Forwarders Info:",
|
||
"Slave",
|
||
((PDNS_RPC_FORWARDERS)pData)->fSlave,
|
||
"Timeout",
|
||
((PDNS_RPC_FORWARDERS)pData)->dwForwardTimeout,
|
||
"\tForwarders:\n",
|
||
((PDNS_RPC_FORWARDERS)pData)->aipForwarders );
|
||
break;
|
||
|
||
case DNSSRV_TYPEID_ZONE_INFO:
|
||
|
||
DnsPrint_RpcZoneInfo(
|
||
PrintRoutine,
|
||
pszHeader,
|
||
(PDNS_RPC_ZONE_INFO) pData );
|
||
break;
|
||
|
||
case DNSSRV_TYPEID_ZONE_SECONDARIES:
|
||
|
||
DnsPrint_RpcIpArrayPlusParameters(
|
||
PrintRoutine,
|
||
pszHeader,
|
||
"Zone Secondary Info:",
|
||
"Secure Secondaries",
|
||
((PDNS_RPC_ZONE_SECONDARIES)pData)->fSecureSecondaries,
|
||
NULL,
|
||
0,
|
||
"\tSecondaries:\n",
|
||
((PDNS_RPC_ZONE_SECONDARIES)pData)->aipSecondaries );
|
||
break;
|
||
|
||
case DNSSRV_TYPEID_ZONE_TYPE_RESET:
|
||
|
||
DnsPrint_RpcIpArrayPlusParameters(
|
||
PrintRoutine,
|
||
pszHeader,
|
||
"Zone Type Reset Info:",
|
||
"ZoneType",
|
||
((PDNS_RPC_ZONE_TYPE_RESET)pData)->dwZoneType,
|
||
NULL,
|
||
0,
|
||
"\tMasters:\n",
|
||
((PDNS_RPC_ZONE_TYPE_RESET)pData)->aipMasters );
|
||
break;
|
||
|
||
case DNSSRV_TYPEID_ZONE_DBASE_INFO:
|
||
|
||
PrintRoutine(
|
||
"%sZone Dbase Info:\n"
|
||
"\tDS Integrated = %d\n"
|
||
"\tFile Name = %s\n",
|
||
pszHeader,
|
||
((PDNS_RPC_ZONE_DBASE_INFO)pData)->fDsIntegrated,
|
||
((PDNS_RPC_ZONE_DBASE_INFO)pData)->pszFileName );
|
||
break;
|
||
|
||
default:
|
||
|
||
PrintRoutine(
|
||
"%s\n"
|
||
"WARNING: Unknown RPC structure typeid = %d at %p\n",
|
||
dwTypeId,
|
||
pData );
|
||
break;
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|
||
PDNSSRV_STAT
|
||
DNS_API_FUNCTION
|
||
DnssrvFindStatisticsInBuffer(
|
||
IN PDNS_RPC_BUFFER pBuffer,
|
||
IN DWORD StatId
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Finds desired statistics in stats buffer.
|
||
|
||
Arguments:
|
||
|
||
pStatsBuf -- stats buffer
|
||
|
||
StatId -- ID of desired stats
|
||
|
||
Return Value:
|
||
|
||
Ptr to desired stats in buffer.
|
||
|
||
--*/
|
||
{
|
||
PDNSSRV_STAT pstat;
|
||
PCHAR pch;
|
||
PCHAR pchstop;
|
||
|
||
pch = pBuffer->Buffer;
|
||
pchstop = pch + pBuffer->dwLength;
|
||
|
||
//
|
||
// check all stat blobs within buffer
|
||
//
|
||
|
||
while ( pch < pchstop )
|
||
{
|
||
pstat = (PDNSSRV_STAT) pch;
|
||
pch = (PCHAR) GET_NEXT_STAT_IN_BUFFER( pstat );
|
||
if ( pch > pchstop )
|
||
{
|
||
DNS_PRINT(( "ERROR: invalid stats buffer\n" ));
|
||
break;
|
||
}
|
||
|
||
// found matching stats
|
||
// - verify correct length
|
||
// - return
|
||
|
||
if ( pstat->Header.StatId == StatId )
|
||
{
|
||
if ( DnssrvValidityCheckStatistic(pstat) != ERROR_SUCCESS )
|
||
{
|
||
DNS_PRINT(( "WARNING: Mismatched stats length.\n" ));
|
||
break;
|
||
}
|
||
return( pstat );
|
||
}
|
||
}
|
||
|
||
return( NULL );
|
||
}
|
||
|
||
|
||
|