|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
remote.c
Abstract:
Domain Name System (DNS) Server -- Admin Client API
Remote API that are not direct calls to RPC stubs.
Author:
Jim Gilroy (jamesg) April 1997
Environment:
User Mode - Win32
Revision History:
--*/
#include "dnsclip.h"
#include <ntdsapi.h>
#include <dsgetdc.h>
#include <lmapibuf.h>
//
// Error indicating talking to old server
//
#define DNS_ERROR_NT4 RPC_S_UNKNOWN_IF
//
// Macro to set up RPC structure header fields.
//
// Sample:
// DNS_RPC_FORWARDERS forwarders;
// INITIALIZE_RPC_STRUCT( FORWARDERS, forwarders );
//
#define INITIALIZE_RPC_STRUCT( rpcStructType, rpcStruct ) \
* ( DWORD * ) &( rpcStruct ) = \ DNS_RPC_## rpcStructType ##_VER; \ * ( ( ( DWORD * ) &( rpcStruct ) ) + 1 ) = 0;
//
// DNS_VERBOSE_ macros
//
#define DNS_DBG( _Level, _PrintArgs ) \
if ( _Level >= dwVerbose ) \ { \ printf _PrintArgs; \ }
//
// General Server\Zone, Query\Operation for DWORD properties
//
DNS_STATUS DNS_API_FUNCTION DnssrvQueryDwordPropertyEx( IN DWORD dwClientVersion, IN DWORD dwSettingFlags, IN LPCWSTR Server, IN LPCSTR pszZone, IN LPCSTR pszProperty, OUT PDWORD pdwResult ) { DNS_STATUS status; DWORD typeId;
DNSDBG( STUB, ( "Enter DnssrvQueryDwordProperty()\n" " Client ver = 0x%X\n" " Server = %s\n" " ZoneName = %s\n" " Property = %s\n" " pResult = %p\n", dwClientVersion, Server, pszZone, pszProperty, pdwResult ));
status = DnssrvComplexOperationEx( dwClientVersion, dwSettingFlags, Server, pszZone, DNSSRV_QUERY_DWORD_PROPERTY, DNSSRV_TYPEID_LPSTR, // property name as string
(LPSTR) pszProperty, & typeId, // DWORD property value back out
(PVOID *) pdwResult );
DNSDBG( STUB, ( "Leave DnssrvQueryDwordProperty(): status %d (%p)\n" " Server = %s\n" " ZoneName = %s\n" " Property = %s\n" " TypeId = %d\n" " Result = %d (%p)\n", status, status, Server, pszZone, pszProperty, typeId, *pdwResult, *pdwResult ));
ASSERT( (status == ERROR_SUCCESS && typeId == DNSSRV_TYPEID_DWORD) || (status != ERROR_SUCCESS && *pdwResult == 0 ) );
return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvResetDwordPropertyEx( IN DWORD dwClientVersion, IN DWORD dwSettingFlags, IN LPCWSTR Server, IN LPCSTR pszZone, IN DWORD dwContext, IN LPCSTR pszProperty, IN DWORD dwPropertyValue ) { DNS_STATUS status; DNS_RPC_NAME_AND_PARAM param;
param.dwParam = dwPropertyValue; param.pszNodeName = (LPSTR) pszProperty;
DNSDBG( STUB, ( "Enter DnssrvResetDwordPropertyEx()\n" " Client ver = 0x%X\n" " Server = %S\n" " ZoneName = %s\n" " Context = %p\n" " PropertyName = %s\n" " PropertyValue = %d (%p)\n", dwClientVersion, Server, pszZone, dwContext, pszProperty, dwPropertyValue, dwPropertyValue ));
status = DnssrvOperationEx( dwClientVersion, dwSettingFlags, Server, pszZone, dwContext, DNSSRV_OP_RESET_DWORD_PROPERTY, DNSSRV_TYPEID_NAME_AND_PARAM, ¶m );
DNSDBG( STUB, ( "Leaving DnssrvResetDwordPropertyEx(): status = %d (%p)\n", status, status ));
return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvResetStringPropertyEx( IN DWORD dwClientVersion, IN DWORD dwSettingFlags, IN LPCWSTR pwszServerName, IN LPCSTR pszZone, IN DWORD dwContext, IN LPCSTR pszProperty, IN LPCWSTR pswzPropertyValue, IN DWORD dwFlags ) /*++
Routine Description:
Set a string property on the server. The property value is unicode.
Arguments:
Server - server name
pszZone - pointer to zone
dwContext - context
pszProperty - name of property to set
pswzPropertyValue - unicode property value
dwFlags - flags, may be combination of: DNSSRV_OP_PARAM_APPLY_ALL_ZONES
Return Value:
None
--*/ { DNS_STATUS status;
DNSDBG( STUB, ( "Enter DnssrvResetStringPropertyEx()\n" " Client ver = 0x%X\n" " Server = %S\n" " ZoneName = %s\n" " Context = %p\n" " PropertyName = %s\n" " PropertyValue = %S\n", dwClientVersion, pwszServerName, pszZone, dwContext, pszProperty, pswzPropertyValue ));
status = DnssrvOperationEx( dwClientVersion, dwSettingFlags, pwszServerName, pszZone, dwContext, pszProperty, DNSSRV_TYPEID_LPWSTR, ( PVOID ) pswzPropertyValue );
DNSDBG( STUB, ( "Leaving DnssrvResetDwordPropertyEx(): status = %d (%p)\n", status, status ));
return status; }
DNS_STATUS DNS_API_FUNCTION DnssrvResetIPListPropertyEx( IN DWORD dwClientVersion, IN DWORD dwSettingFlags, IN LPCWSTR pwszServerName, IN LPCSTR pszZone, IN DWORD dwContext, IN LPCSTR pszProperty, IN PIP_ARRAY pipArray, IN DWORD dwFlags ) /*++
Routine Description:
Set an IP list property on the server.
Arguments:
Server - server name
pszZone - pointer to zone
dwContext - context
pszProperty - name of property to set
pipArray - new IP array property value
dwFlags - flags, may be combination of: DNSSRV_OP_PARAM_APPLY_ALL_ZONES
Return Value:
None
--*/ { DNS_STATUS status;
DNSDBG( STUB, ( "Enter DnssrvResetIPListPropertyEx()\n" " Client ver = 0x%X\n" " Server = %S\n" " ZoneName = %s\n" " Context = %p\n" " PropertyName = %s\n" " pipArray = %p\n", dwClientVersion, pwszServerName, pszZone, dwContext, pszProperty, pipArray ));
DnsDbg_Ip4Array( "DnssrvResetIPListPropertyEx\n", NULL, pipArray );
status = DnssrvOperationEx( dwClientVersion, dwSettingFlags, pwszServerName, pszZone, dwContext, pszProperty, DNSSRV_TYPEID_IPARRAY, ( pipArray && pipArray->AddrCount ) ? pipArray : NULL );
DNSDBG( STUB, ( "Leaving DnssrvResetIPListPropertyEx(): status = %d (%p)\n", status, status ));
return status; } // DnssrvResetIPListPropertyEx
//
// Server Queries
//
DNS_STATUS DNS_API_FUNCTION DnssrvGetServerInfo( IN LPCWSTR Server, OUT PDNS_RPC_SERVER_INFO * ppServerInfo ) { DNS_STATUS status; DWORD typeId;
status = DnssrvQuery( Server, NULL, DNSSRV_QUERY_SERVER_INFO, &typeId, ppServerInfo ); ASSERT( (status == ERROR_SUCCESS && typeId == DNSSRV_TYPEID_SERVER_INFO) || (status != ERROR_SUCCESS && *ppServerInfo == NULL ) );
return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvQueryZoneDwordProperty( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN LPCSTR pszProperty, OUT PDWORD pdwResult ) { DNS_STATUS status; DWORD typeId;
IF_DNSDBG( STUB ) { DNS_PRINT(( "Enter DnssrvQueryDwordProperty()\n" " Server = %s\n" " pszProperty = %s\n" " pResult = %p\n", Server, pszZoneName, pszProperty, pdwResult )); }
status = DnssrvQuery( Server, pszZoneName, pszProperty, & typeId, (PVOID *) pdwResult );
IF_DNSDBG( STUB ) { DNS_PRINT(( "Leave DnssrvQueryZoneDwordProperty(): status %d (%p)\n" " Server = %s\n" " pszProperty = %s\n" " TypeId = %d\n" " Result = %d (%p)\n", status, status, Server, pszProperty, typeId, *pdwResult, *pdwResult ));
ASSERT( (status == ERROR_SUCCESS && typeId == DNSSRV_TYPEID_DWORD) || (status != ERROR_SUCCESS && *pdwResult == 0 ) ); } return( status ); }
//
// Server Operations
//
DNS_STATUS DNS_API_FUNCTION DnssrvResetServerDwordProperty( IN LPCWSTR Server, IN LPCSTR pszProperty, IN DWORD dwPropertyValue ) { DNS_STATUS status;
DNSDBG( STUB, ( "Enter DnssrvResetServerDwordProperty()\n" " Server = %s\n" " pszPropertyName = %s\n" " dwPropertyValue = %p\n", Server, pszProperty, dwPropertyValue ));
status = DnssrvOperation( Server, NULL, pszProperty, DNSSRV_TYPEID_DWORD, (PVOID) (DWORD_PTR) dwPropertyValue );
DNSDBG( STUB, ( "Leaving DnssrvResetServerDwordProperty: status = %d (%p)\n", status, status ));
return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvCreateZoneEx( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN DWORD dwZoneType, IN DWORD fAllowUpdate, IN DWORD dwCreateFlags, IN LPCSTR pszAdminEmailName, IN DWORD cMasters, IN PIP_ADDRESS aipMasters, IN BOOL bDsIntegrated, IN LPCSTR pszDataFile, IN DWORD dwTimeout, // for forwarder zones
IN DWORD fSlave, // for forwarder zones
IN DWORD dwDpFlags, // for directory partition
IN LPCSTR pszDpFqdn // for directory partition
) { DNS_STATUS status; DNS_RPC_ZONE_CREATE_INFO zoneInfo; PIP_ARRAY arrayIp = NULL;
RtlZeroMemory( &zoneInfo, sizeof( DNS_RPC_ZONE_CREATE_INFO ) );
INITIALIZE_RPC_STRUCT( ZONE_CREATE_INFO, zoneInfo );
if ( cMasters && aipMasters ) { arrayIp = Dns_BuildIpArray( cMasters, aipMasters ); if ( !arrayIp && cMasters ) { return( DNS_ERROR_NO_MEMORY ); } } zoneInfo.pszZoneName = (LPSTR) pszZoneName; zoneInfo.dwZoneType = dwZoneType; zoneInfo.fAllowUpdate = fAllowUpdate; zoneInfo.fAging = 0; zoneInfo.dwFlags = dwCreateFlags; zoneInfo.fDsIntegrated = (DWORD) bDsIntegrated; // temp backward compat
zoneInfo.fLoadExisting = !!(dwCreateFlags & DNS_ZONE_LOAD_EXISTING); zoneInfo.pszDataFile = (LPSTR) pszDataFile; zoneInfo.pszAdmin = (LPSTR) pszAdminEmailName; zoneInfo.aipMasters = arrayIp; zoneInfo.dwTimeout = dwTimeout; zoneInfo.fSlave = fSlave;
zoneInfo.dwDpFlags = dwDpFlags; zoneInfo.pszDpFqdn = ( LPSTR ) pszDpFqdn;
status = DnssrvOperation( Server, NULL, // server operation
DNSSRV_OP_ZONE_CREATE, DNSSRV_TYPEID_ZONE_CREATE, (PVOID) &zoneInfo );
FREE_HEAP( arrayIp ); return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvCreateZone( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN DWORD dwZoneType, IN LPCSTR pszAdminEmailName, IN DWORD cMasters, IN PIP_ADDRESS aipMasters, IN DWORD fLoadExisting, IN DWORD fDsIntegrated, IN LPCSTR pszDataFile, IN DWORD dwTimeout, IN DWORD fSlave ) { DWORD flags = 0; DWORD dpFlags = 0;
if ( fLoadExisting ) { flags = DNS_ZONE_LOAD_EXISTING; }
return DnssrvCreateZoneEx( Server, pszZoneName, dwZoneType, 0, // update unknown, send off
flags, // load flags
pszAdminEmailName, cMasters, aipMasters, fDsIntegrated, pszDataFile, dwTimeout, fSlave, dpFlags, // dwDirPartFlag
NULL // pszDirPartFqdn
); }
DNS_STATUS DNS_API_FUNCTION DnssrvCreateZoneForDcPromoEx( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN LPCSTR pszDataFile, IN DWORD dwFlags ) /*++
Routine Description:
Create a zone during dcpromo. The DNS server will automagically move this zone to Active Directory when the directoy becomes available after reboot.
Arguments:
Server -- server to send request to
pszZoneName -- UTF-8 name of the new zone
pszDataFile -- UTF-8 zone file name
dwFlags -- zone creation flags, pass zero or one of: DNS_ZONE_CREATE_FOR_DCPROMO DNS_ZONE_CREATE_FOR_DCPROMO_FOREST
Return Value:
None
--*/ { //
// By default the new zone must be a dcpromo zone so make sure that
// flag is turned on. For a new forest dcpromo zone both this flag
// and DNS_ZONE_CREATE_FOR_NEW_FOREST_DCPROMO should be set.
//
dwFlags |= DNS_ZONE_CREATE_FOR_DCPROMO;
//
// Create the zone.
//
return DnssrvCreateZoneEx( Server, pszZoneName, 1, // primary
0, // update unknown, send off
dwFlags, NULL, // no admin name
0, // no masters
NULL, FALSE, // not DS integrated
pszDataFile, 0, // timeout - for forwarder zones
0, // slave - for forwarder zones
0, // dwDirPartFlag
NULL ); // pszDirPartFqdn
} // DnssrvCreateZoneForDcPromoEx
DNS_STATUS DNS_API_FUNCTION DnssrvCreateZoneForDcPromo( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN LPCSTR pszDataFile ) { return DnssrvCreateZoneForDcPromoEx( Server, pszZoneName, pszDataFile, 0 ); // flags
}
DNS_STATUS DNS_API_FUNCTION DnssrvCreateZoneInDirectoryPartition( IN LPCWSTR pwszServer, IN LPCSTR pszZoneName, IN DWORD dwZoneType, IN LPCSTR pszAdminEmailName, IN DWORD cMasters, IN PIP_ADDRESS aipMasters, IN DWORD fLoadExisting, IN DWORD dwTimeout, IN DWORD fSlave, IN DWORD dwDirPartFlags, IN LPCSTR pszDirPartFqdn ) { DWORD dwFlags = 0;
if ( fLoadExisting ) { dwFlags = DNS_ZONE_LOAD_EXISTING; }
return DnssrvCreateZoneEx( pwszServer, pszZoneName, dwZoneType, 0, // allow update
dwFlags, pszAdminEmailName, cMasters, // masters count
aipMasters, // masters array
TRUE, // DS integrated
NULL, // data file
dwTimeout, // for forwarder zones
fSlave, // for forwarder zones
dwDirPartFlags, pszDirPartFqdn ); }
DNS_STATUS DNS_API_FUNCTION DnssrvClearStatistics( IN LPCWSTR Server ) { DNS_STATUS status;
status = DnssrvOperation( Server, NULL, DNSSRV_OP_CLEAR_STATISTICS, DNSSRV_TYPEID_NULL, (PVOID) NULL ); return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvResetServerListenAddresses( IN LPCWSTR Server, IN DWORD cListenAddrs, IN PIP_ADDRESS aipListenAddrs ) { DNS_STATUS status; PIP_ARRAY arrayIp;
arrayIp = Dns_BuildIpArray( cListenAddrs, aipListenAddrs ); if ( !arrayIp && cListenAddrs ) { return( DNS_ERROR_NO_MEMORY ); }
status = DnssrvOperation( Server, NULL, DNS_REGKEY_LISTEN_ADDRESSES, DNSSRV_TYPEID_IPARRAY, (PVOID) arrayIp );
FREE_HEAP( arrayIp ); return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvResetForwarders( IN LPCWSTR Server, IN DWORD cForwarders, IN PIP_ADDRESS aipForwarders, IN DWORD dwForwardTimeout, IN DWORD fSlave ) { DNS_STATUS status; DNS_RPC_FORWARDERS forwarders; PIP_ARRAY arrayIp;
INITIALIZE_RPC_STRUCT( FORWARDERS, forwarders );
arrayIp = Dns_BuildIpArray( cForwarders, aipForwarders ); if ( !arrayIp && cForwarders ) { return( DNS_ERROR_NO_MEMORY ); } forwarders.fSlave = fSlave; forwarders.dwForwardTimeout = dwForwardTimeout; forwarders.aipForwarders = arrayIp;
status = DnssrvOperation( Server, NULL, DNS_REGKEY_FORWARDERS, DNSSRV_TYPEID_FORWARDERS, (PVOID) &forwarders );
FREE_HEAP( arrayIp ); return( status ); }
//
// Zone Queries
//
DNS_STATUS DNS_API_FUNCTION DnssrvGetZoneInfo( IN LPCWSTR Server, IN LPCSTR pszZone, OUT PDNS_RPC_ZONE_INFO * ppZoneInfo ) { DNS_STATUS status; DWORD typeId;
status = DnssrvQuery( Server, pszZone, DNSSRV_QUERY_ZONE_INFO, & typeId, ppZoneInfo ); ASSERT( (status == ERROR_SUCCESS && typeId == DNSSRV_TYPEID_ZONE_INFO) || (status != ERROR_SUCCESS && *ppZoneInfo == NULL ) );
return( status ); }
//
// Zone Operations
//
DNS_STATUS DNS_API_FUNCTION DnssrvResetZoneTypeEx( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN DWORD dwZoneType, IN DWORD cMasters, IN PIP_ADDRESS aipMasters, IN DWORD dwLoadOptions, IN DWORD fDsIntegrated, IN LPCSTR pszDataFile, IN DWORD dwDpFlags, IN LPCSTR pszDpFqdn ) { DNS_STATUS status; DNS_RPC_ZONE_CREATE_INFO zoneInfo; PIP_ARRAY arrayIp = NULL;
RtlZeroMemory( &zoneInfo, sizeof( DNS_RPC_ZONE_CREATE_INFO ) );
INITIALIZE_RPC_STRUCT( ZONE_CREATE_INFO, zoneInfo );
if ( cMasters ) { arrayIp = Dns_BuildIpArray( cMasters, aipMasters ); if ( !arrayIp ) { return( DNS_ERROR_NO_MEMORY ); } }
zoneInfo.pszZoneName = ( LPSTR ) pszZoneName; zoneInfo.dwZoneType = dwZoneType; zoneInfo.fDsIntegrated = fDsIntegrated; zoneInfo.fLoadExisting = dwLoadOptions; zoneInfo.pszDataFile = ( LPSTR ) pszDataFile; zoneInfo.pszAdmin = NULL; zoneInfo.aipMasters = arrayIp; zoneInfo.dwDpFlags = dwDpFlags; zoneInfo.pszDpFqdn = ( LPSTR ) pszDpFqdn;
status = DnssrvOperation( Server, pszZoneName, DNSSRV_OP_ZONE_TYPE_RESET, DNSSRV_TYPEID_ZONE_CREATE, ( PVOID ) &zoneInfo );
FREE_HEAP( arrayIp );
return status; }
DNS_STATUS DNS_API_FUNCTION DnssrvRenameZone( IN LPCWSTR Server, IN LPCSTR pszCurrentZoneName, IN LPCSTR pszNewZoneName, IN LPCSTR pszNewFileName ) { DNS_STATUS status; DNS_RPC_ZONE_RENAME_INFO renameInfo;
RtlZeroMemory( &renameInfo, sizeof( DNS_RPC_ZONE_RENAME_INFO ) );
INITIALIZE_RPC_STRUCT( ZONE_RENAME_INFO, renameInfo );
renameInfo.pszNewZoneName = ( LPSTR ) pszNewZoneName; renameInfo.pszNewFileName = ( LPSTR ) pszNewFileName;
status = DnssrvOperation( Server, pszCurrentZoneName, DNSSRV_OP_ZONE_RENAME, DNSSRV_TYPEID_ZONE_RENAME, ( PVOID ) &renameInfo ); return status; }
DNS_STATUS DNS_API_FUNCTION DnssrvChangeZoneDirectoryPartition( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN LPCSTR pszNewPartitionName ) { DNS_STATUS status; DNS_RPC_ZONE_CHANGE_DP rpcInfo;
RtlZeroMemory( &rpcInfo, sizeof( DNS_RPC_ZONE_CHANGE_DP ) );
INITIALIZE_RPC_STRUCT( ZONE_RENAME_INFO, rpcInfo );
rpcInfo.pszDestPartition = ( LPSTR ) pszNewPartitionName;
status = DnssrvOperation( Server, pszZoneName, DNSSRV_OP_ZONE_CHANGE_DP, DNSSRV_TYPEID_ZONE_CHANGE_DP, ( PVOID ) &rpcInfo ); return status; }
DNS_STATUS DNS_API_FUNCTION DnssrvExportZone( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN LPCSTR pszZoneExportFile ) { DNS_STATUS status; DNS_RPC_ZONE_EXPORT_INFO info;
RtlZeroMemory( &info, sizeof( DNS_RPC_ZONE_EXPORT_INFO ) );
INITIALIZE_RPC_STRUCT( ZONE_EXPORT_INFO, info );
info.pszZoneExportFile = ( LPSTR ) pszZoneExportFile;
status = DnssrvOperation( Server, pszZoneName, DNSSRV_OP_ZONE_EXPORT, DNSSRV_TYPEID_ZONE_EXPORT, ( PVOID ) &info );
return status; }
DNS_STATUS DNS_API_FUNCTION DnssrvResetZoneMastersEx( IN LPCWSTR Server, IN LPCSTR pszZone, IN DWORD cMasters, IN PIP_ADDRESS aipMasters, IN DWORD fSetLocalMasters ) { DNS_STATUS status; PIP_ARRAY arrayIp;
arrayIp = Dns_BuildIpArray( cMasters, aipMasters ); if ( !arrayIp && cMasters ) { return( DNS_ERROR_NO_MEMORY ); } status = DnssrvOperation( Server, pszZone, fSetLocalMasters ? DNS_REGKEY_ZONE_LOCAL_MASTERS : DNS_REGKEY_ZONE_MASTERS, DNSSRV_TYPEID_IPARRAY, (PVOID) arrayIp ); FREE_HEAP( arrayIp ); return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvResetZoneMasters( IN LPCWSTR Server, IN LPCSTR pszZone, IN DWORD cMasters, IN PIP_ADDRESS aipMasters ) { DNS_STATUS status; PIP_ARRAY arrayIp;
arrayIp = Dns_BuildIpArray( cMasters, aipMasters ); if ( !arrayIp && cMasters ) { return( DNS_ERROR_NO_MEMORY ); } status = DnssrvOperation( Server, pszZone, DNS_REGKEY_ZONE_MASTERS, DNSSRV_TYPEID_IPARRAY, (PVOID) arrayIp ); FREE_HEAP( arrayIp ); return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvResetZoneSecondaries( IN LPCWSTR Server, IN LPCSTR pszZone, IN DWORD fSecureSecondaries, IN DWORD cSecondaries, IN PIP_ADDRESS aipSecondaries, IN DWORD fNotifyLevel, IN DWORD cNotify, IN PIP_ADDRESS aipNotify ) { DNS_STATUS status; DNS_RPC_ZONE_SECONDARIES secondaryInfo; PIP_ARRAY arrayIp;
INITIALIZE_RPC_STRUCT( ZONE_SECONDARIES, secondaryInfo );
arrayIp = Dns_BuildIpArray( cSecondaries, aipSecondaries ); if ( !arrayIp && cSecondaries ) { return( DNS_ERROR_NO_MEMORY ); } secondaryInfo.fSecureSecondaries = fSecureSecondaries; secondaryInfo.aipSecondaries = arrayIp;
arrayIp = Dns_BuildIpArray( cNotify, aipNotify ); if ( !arrayIp && cNotify ) { return( DNS_ERROR_NO_MEMORY ); } secondaryInfo.aipNotify = arrayIp; secondaryInfo.fNotifyLevel = fNotifyLevel;
status = DnssrvOperation( Server, pszZone, DNS_REGKEY_ZONE_SECONDARIES, DNSSRV_TYPEID_ZONE_SECONDARIES, (PVOID) &secondaryInfo );
FREE_HEAP( secondaryInfo.aipNotify ); FREE_HEAP( secondaryInfo.aipSecondaries ); return( status ); }
#if 0
DNS_STATUS DNS_API_FUNCTION DnssrvResetZoneScavengeServers( IN LPCWSTR Server, IN LPCSTR pszZone, IN DWORD cServers, IN PIP_ADDRESS aipServers ) { DNS_STATUS status; PIP_ARRAY arrayIp;
arrayIp = Dns_BuildIpArray( cServers, aipServers ); if ( !arrayIp && cSecondaries ) { return( DNS_ERROR_NO_MEMORY ); }
status = DnssrvOperation( Server, pszZone, DNS_REGKEY_ZONE_SCAVENGE_SERVERS, DNSSRV_TYPEID_IPARRAY, arrayIp );
FREE_HEAP( arrayIp ); return( status ); } #endif
//
// Zone management API
//
DNS_STATUS DNS_API_FUNCTION DnssrvIncrementZoneVersion( IN LPCWSTR Server, IN LPCSTR pszZone ) { return DnssrvOperation( Server, pszZone, DNSSRV_OP_ZONE_INCREMENT_VERSION, DNSSRV_TYPEID_NULL, (PVOID) NULL ); }
DNS_STATUS DNS_API_FUNCTION DnssrvDeleteZone( IN LPCWSTR Server, IN LPCSTR pszZone ) { return DnssrvOperation( Server, pszZone, DNSSRV_OP_ZONE_DELETE, DNSSRV_TYPEID_NULL, (PVOID) NULL ); }
DNS_STATUS DNS_API_FUNCTION DnssrvPauseZone( IN LPCWSTR Server, IN LPCSTR pszZone ) { return DnssrvOperation( Server, pszZone, DNSSRV_OP_ZONE_PAUSE, DNSSRV_TYPEID_NULL, (PVOID) NULL ); }
DNS_STATUS DNS_API_FUNCTION DnssrvResumeZone( IN LPCWSTR Server, IN LPCSTR pszZone ) { return DnssrvOperation( Server, pszZone, DNSSRV_OP_ZONE_RESUME, DNSSRV_TYPEID_NULL, (PVOID) NULL ); }
//
// Record viewing API
//
DNS_STATUS DNS_API_FUNCTION DnssrvEnumRecordsAndConvertNodes( IN LPCWSTR pszServer, IN LPCSTR pszZoneName, IN LPCSTR pszNodeName, IN LPCSTR pszStartChild, IN WORD wRecordType, IN DWORD dwSelectFlag, IN LPCSTR pszFilterStart, IN LPCSTR pszFilterStop, OUT PDNS_NODE * ppNodeFirst, OUT PDNS_NODE * ppNodeLast ) { DNS_STATUS status; PDNS_NODE pnode; PDNS_NODE pnodeLast; PBYTE pbuffer; DWORD bufferLength;
//
// get records from server
//
status = DnssrvEnumRecords( pszServer, pszZoneName, pszNodeName, pszStartChild, wRecordType, dwSelectFlag, pszFilterStart, pszFilterStop, & bufferLength, & pbuffer );
if ( status != ERROR_SUCCESS && status != ERROR_MORE_DATA ) { return( status ); }
//
// pull nodes and records out of RPC buffer
//
pnode = DnsConvertRpcBuffer( & pnodeLast, bufferLength, pbuffer, TRUE // convert unicode
); if ( !pnode ) { DNS_PRINT(( "ERROR: failure converting RPC buffer to DNS records\n" " status = %p\n", GetLastError() )); ASSERT( FALSE ); return( ERROR_INVALID_DATA ); }
*ppNodeFirst = pnode; *ppNodeLast = pnodeLast; return( status ); }
//
// Record management API
//
DNS_STATUS DNS_API_FUNCTION DnssrvDeleteNode( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN LPCSTR pszNodeName, IN BOOL bDeleteSubtree ) { DNS_RPC_NAME_AND_PARAM param;
param.dwParam = (DWORD) bDeleteSubtree; param.pszNodeName = (LPSTR) pszNodeName;
return DnssrvOperation( Server, pszZoneName, DNSSRV_OP_DELETE_NODE, DNSSRV_TYPEID_NAME_AND_PARAM, (PVOID) ¶m ); }
DNS_STATUS DNS_API_FUNCTION DnssrvDeleteRecordSet( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN LPCSTR pszNodeName, IN WORD wType ) { DNS_RPC_NAME_AND_PARAM param;
param.dwParam = (DWORD) wType; param.pszNodeName = (LPSTR) pszNodeName;
return DnssrvOperation( Server, pszZoneName, DNSSRV_OP_DELETE_RECORD_SET, DNSSRV_TYPEID_NAME_AND_PARAM, (PVOID) ¶m ); }
DNS_STATUS DNS_API_FUNCTION DnssrvForceAging( IN LPCWSTR Server, IN LPCSTR pszZoneName, IN LPCSTR pszNodeName, IN BOOL bAgeSubtree ) { DNS_RPC_NAME_AND_PARAM param;
param.dwParam = (DWORD) bAgeSubtree; param.pszNodeName = (LPSTR) pszNodeName;
return DnssrvOperation( Server, pszZoneName, DNSSRV_OP_FORCE_AGING_ON_NODE, DNSSRV_TYPEID_NAME_AND_PARAM, (PVOID) ¶m ); }
//
// Server API
//
DNS_STATUS DNS_API_FUNCTION DnssrvEnumZonesEx( IN LPCWSTR Server, IN DWORD dwFilter, IN LPCSTR pszDirectoryPartitionFqdn, IN LPCSTR pszQueryString, IN LPCSTR pszLastZone, OUT PDNS_RPC_ZONE_LIST * ppZoneList ) { DNS_STATUS status; DWORD typeId; PDNS_RPC_ZONE_LIST pzoneEnum = NULL;
IF_DNSDBG( STUB ) { DNS_PRINT(( "Enter DnssrvEnumZones()\n" " Server = %s\n" " Filter = 0x%08X\n" " Partition = %s\n" " Query string = %s\n" " LastZone = %s\n" " ppZoneList = %p\n", Server, dwFilter, pszDirectoryPartitionFqdn, pszQueryString, pszLastZone, ppZoneList )); }
if ( pszDirectoryPartitionFqdn || pszQueryString ) { DNS_RPC_ENUM_ZONES_FILTER ezfilter = { 0 };
ezfilter.dwRpcStructureVersion = DNS_RPC_ENUM_ZONES_FILTER_VER; ezfilter.dwFilter = dwFilter; ezfilter.pszPartitionFqdn = ( LPSTR ) pszDirectoryPartitionFqdn; ezfilter.pszQueryString = ( LPSTR ) pszQueryString;
status = DnssrvComplexOperation( Server, NULL, DNSSRV_OP_ENUM_ZONES2, DNSSRV_TYPEID_ENUM_ZONES_FILTER, ( PVOID ) &ezfilter, &typeId, ( PVOID * ) &pzoneEnum ); } else { status = DnssrvComplexOperation( Server, NULL, DNSSRV_OP_ENUM_ZONES, DNSSRV_TYPEID_DWORD, ( PVOID ) ( DWORD_PTR ) dwFilter, & typeId, ( PVOID * ) &pzoneEnum ); }
if ( status != DNS_ERROR_NT4 ) { ASSERT( ( status == ERROR_SUCCESS && typeId == DNSSRV_TYPEID_ZONE_LIST ) || ( status != ERROR_SUCCESS && pzoneEnum == NULL ) );
*ppZoneList = pzoneEnum; } return status; }
DNS_STATUS DNS_API_FUNCTION DnssrvEnumDirectoryPartitions( IN LPCWSTR Server, IN DWORD dwFilter, OUT PDNS_RPC_DP_LIST * ppDpList ) { DNS_STATUS status; PDNS_RPC_DP_LIST pdpList = NULL; DWORD dwtypeId;
IF_DNSDBG( STUB ) { DNS_PRINT(( "Enter DnssrvEnumDirectoryPartitions()\n" "\tServer = %S\n" "\tppDpList = %p\n", Server, ppDpList )); }
status = DnssrvComplexOperation( Server, NULL, DNSSRV_OP_ENUM_DPS, DNSSRV_TYPEID_DWORD, ( PVOID ) ( DWORD_PTR ) dwFilter, &dwtypeId, ( PVOID * ) &pdpList );
ASSERT( ( status == ERROR_SUCCESS && dwtypeId == DNSSRV_TYPEID_DP_LIST ) || ( status != ERROR_SUCCESS && pdpList == NULL ) );
*ppDpList = pdpList; return status; } // DnssrvEnumDirectoryPartitions
DNS_STATUS DNS_API_FUNCTION DnssrvEnlistDirectoryPartition( IN LPCWSTR pszServer, IN DWORD dwOperation, IN LPCSTR pszDirPartFqdn ) { DNS_STATUS status;
IF_DNSDBG( STUB ) { DNS_PRINT(( "Enter DnssrvEnlistDirectoryPartition()\n" " pszServer = %S\n" " dwOperation = %d\n" " pszDirPartFqdn = %s\n", pszServer, dwOperation, pszDirPartFqdn )); }
if ( dwOperation == DNS_DP_OP_CREATE_ALL_DOMAINS ) { //
// This operation is not specific to any DNS server.
//
status = DnssrvCreateAllDomainDirectoryPartitions( pszServer, DNS_VERBOSE_PROGRESS ); } else { //
// This operation should be sent directly to pszServer.
//
DNS_RPC_ENLIST_DP param;
INITIALIZE_RPC_STRUCT( ENLIST_DP, param ); param.pszDpFqdn = ( LPSTR ) pszDirPartFqdn; param.dwOperation = dwOperation;
status = DnssrvOperation( pszServer, NULL, DNSSRV_OP_ENLIST_DP, DNSSRV_TYPEID_ENLIST_DP, ¶m ); }
return status; } // DnssrvEnlistDirectoryPartition
DNS_STATUS DNS_API_FUNCTION DnssrvSetupDefaultDirectoryPartitions( IN LPCWSTR pszServer, IN DWORD dwParam ) { DNS_STATUS status; DNS_RPC_ENLIST_DP param;
INITIALIZE_RPC_STRUCT( ENLIST_DP, param );
param.pszDpFqdn = NULL; param.dwOperation = dwParam;
IF_DNSDBG( STUB ) { DNS_PRINT(( "Enter DnssrvSetupDefaultDirectoryPartitions()\n" " pszServer = %S\n" " dwParam = %d\n", pszServer, dwParam )); }
status = DnssrvOperation( pszServer, NULL, DNSSRV_OP_ENLIST_DP, DNSSRV_TYPEID_ENLIST_DP, ¶m );
return status; } // DnssrvSetupDefaultDirectoryPartitions
DNS_STATUS DNS_API_FUNCTION DnssrvDirectoryPartitionInfo( IN LPCWSTR Server, IN LPSTR pszDpFqdn, OUT PDNS_RPC_DP_INFO * ppDpInfo ) { DNS_STATUS status; DWORD dwTypeId; PDNS_RPC_DP_INFO pDpInfo = NULL;
IF_DNSDBG( STUB ) { DNS_PRINT(( "Enter DnssrvDirectoryPartitionInfo()\n" " Server = %S\n" " pszDpFqdn = %s\n" " ppDpInfo = %p\n", Server, pszDpFqdn, ppDpInfo )); }
status = DnssrvComplexOperation( Server, NULL, DNSSRV_OP_DP_INFO, DNSSRV_TYPEID_LPSTR, ( PVOID ) ( DWORD_PTR ) pszDpFqdn, &dwTypeId, ( PVOID * ) &pDpInfo );
ASSERT( ( status == ERROR_SUCCESS && dwTypeId == DNSSRV_TYPEID_DP_INFO ) || status != ERROR_SUCCESS );
*ppDpInfo = pDpInfo; return status; } // DnssrvDirectoryPartitionInfo
/*++
Routine Description:
This function iterates all domains in the forest and creates any missing built-in DNS directory partitions that cannot be found.
Arguments:
pszServer -- host name of DC to contact for initial queries
dwVerbose -- output level via printf
Return Value:
DNS_STATUS return code
--*/ DNS_STATUS DNS_API_FUNCTION DnssrvCreateAllDomainDirectoryPartitions( IN LPCWSTR pszServer, IN DWORD dwVerbose ) { DNS_STATUS status = ERROR_SUCCESS; HANDLE hds = NULL; PDS_DOMAIN_TRUSTS pdomainTrusts = NULL; ULONG domainCount = 0; ULONG idomain; PDNS_RECORD pdnsRecordList = NULL; PDNS_RECORD pdnsRecord = NULL;
//
// Get domain list.
//
status = DsEnumerateDomainTrustsA( NULL, DS_DOMAIN_IN_FOREST, &pdomainTrusts, &domainCount ); if ( status != ERROR_SUCCESS ) { DNS_DBG( DNS_VERBOSE_ERROR, ( "Error 0x%X enumerating domains in the forest\n", status )); goto Done; }
//
// Iterate domains.
//
for ( idomain = 0; idomain < domainCount; ++idomain ) { int insCount = 0; PSTR pszdomainName = pdomainTrusts[ idomain ].DnsDomainName;
if ( !pszdomainName ) { continue; }
DNS_DBG( DNS_VERBOSE_PROGRESS, ( "\n\nFound domain: %s\n", pszdomainName ));
//
// Get the DNS server list for this domain.
//
status = DnsQuery_UTF8( pszdomainName, DNS_TYPE_NS, DNS_QUERY_STANDARD, NULL, // DNS server list
&pdnsRecordList, NULL ); // reserved
if ( status != ERROR_SUCCESS ) { if ( status == DNS_INFO_NO_RECORDS ) { DNS_DBG( DNS_VERBOSE_PROGRESS, ( "%s: no DNS servers could be found\n", pszdomainName )); } else { DNS_DBG( DNS_VERBOSE_PROGRESS, ( "%s: error 0x%X from query for DNS servers\n", pszdomainName, status )); } continue; }
for ( pdnsRecord = pdnsRecordList; pdnsRecord != NULL; pdnsRecord = pdnsRecord->pNext ) { PWSTR pwszserverName; DWORD dwtypeid; PDNS_RPC_SERVER_INFO pdata; DWORD dwmajorVersion; DWORD dwminorVersion; DWORD dwbuildNum;
if ( pdnsRecord->wType != DNS_TYPE_NS ) { continue; }
++insCount;
DNS_DBG( DNS_VERBOSE_PROGRESS, ( "\n%s: found DNS server %s\n", pszdomainName, pdnsRecord->Data.NS.pNameHost ));
pwszserverName = Dns_NameCopyAllocate( ( PSTR ) pdnsRecord->Data.NS.pNameHost, 0, DnsCharSetUtf8, DnsCharSetUnicode ); if ( !pwszserverName ) { status = DNS_ERROR_NO_MEMORY; goto Done; }
//
// "Ping" the DNS server with a server info query to get its
// version. This is not strictly necessary but it does allow us
// to find out if the server is up and of good version before
// we actually think about creating partitions.
//
status = DnssrvQuery( pwszserverName, NULL, DNSSRV_QUERY_SERVER_INFO, &dwtypeid, &pdata ); if ( status != ERROR_SUCCESS ) { DNS_DBG( DNS_VERBOSE_PROGRESS, ( "DNS server %S returned RPC error %d\n" " directory partitions cannot be created on this server\n", pwszserverName, status )); continue; }
dwmajorVersion = pdata->dwVersion & 0x000000FF; dwminorVersion = ( pdata->dwVersion & 0x0000FF00 ) >> 8; dwbuildNum = pdata->dwVersion >> 16;
if ( dwbuildNum > 10000 || dwmajorVersion < 5 || dwmajorVersion == 5 && dwminorVersion < 1 ) { //
// This is a W2K server so do nothing.
//
DNS_DBG( DNS_VERBOSE_PROGRESS, ( "DNS Server %S is version %u.%u\n" " directory partitions cannot be created on this server\n", pwszserverName, dwmajorVersion, dwminorVersion )); } else { //
// This is a Whistler server so attempt to create domain partition.
//
#if 0
DNS_DBG( DNS_VERBOSE_PROGRESS, ( "DNS Server %S is version %u.%u build %u\n", pwszserverName, dwmajorVersion, dwminorVersion, dwbuildNum )); #endif
status = DnssrvEnlistDirectoryPartition( pwszserverName, DNS_DP_OP_CREATE_DOMAIN, NULL ); if ( status == ERROR_SUCCESS ) { DNS_DBG( DNS_VERBOSE_PROGRESS, ( "DNS server %S successfully created the built-in\n" " domain directory partition for domain %s\n", pwszserverName, pszdomainName )); break; } else { DNS_DBG( DNS_VERBOSE_PROGRESS, ( "DNS server %S returned error %d\n" " will attempt to create built-in domain partition on another\n" " DNS server for this domain\n", pwszserverName, status )); } } } }
//
// Cleanup and return
//
Done:
DnsRecordListFree( pdnsRecordList, 0 );
if ( pdomainTrusts ) { NetApiBufferFree( pdomainTrusts ); }
return status; } // DnssrvCreateAllDomainDirectoryPartitions
DNS_STATUS DNS_API_FUNCTION DnssrvGetStatistics( IN LPCWSTR Server, IN DWORD dwFilter, OUT PDNS_RPC_BUFFER * ppStatsBuffer ) { DNS_STATUS status; DWORD typeId; PDNS_RPC_BUFFER pstatsBuf = NULL;
IF_DNSDBG( STUB ) { DNS_PRINT(( "Enter DnssrvGetStatistics()\n" " Server = %S\n" " Filter = %p\n" " ppStatsBuf = %p\n", Server, dwFilter, ppStatsBuffer )); }
status = DnssrvComplexOperation( Server, NULL, DNSSRV_QUERY_STATISTICS, DNSSRV_TYPEID_DWORD, // DWORD filter in
(PVOID) (DWORD_PTR) dwFilter, & typeId, // enumeration out
(PVOID*) &pstatsBuf );
ASSERT( (status == ERROR_SUCCESS && typeId == DNSSRV_TYPEID_BUFFER ) || (status != ERROR_SUCCESS && pstatsBuf == NULL ) );
*ppStatsBuffer = pstatsBuf; return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvWriteDirtyZones( IN LPCWSTR Server ) { DNS_STATUS status;
status = DnssrvOperation( Server, NULL, DNSSRV_OP_WRITE_DIRTY_ZONES, DNSSRV_TYPEID_NULL, NULL ); return( status ); }
//
// Old zone API -- discontinued
//
DNS_STATUS DNS_API_FUNCTION DnssrvResetZoneType( IN LPCWSTR Server, IN LPCSTR pszZone, IN DWORD dwZoneType, IN DWORD cMasters, IN PIP_ADDRESS aipMasters ) { DNS_STATUS status; DNS_RPC_ZONE_TYPE_RESET typeReset; PIP_ARRAY arrayIp;
INITIALIZE_RPC_STRUCT( ZONE_TYPE_RESET, typeReset );
arrayIp = Dns_BuildIpArray( cMasters, aipMasters ); if ( !arrayIp && cMasters ) { return( DNS_ERROR_NO_MEMORY ); } typeReset.dwZoneType = dwZoneType; typeReset.aipMasters = arrayIp;
status = DnssrvOperation( Server, pszZone, DNS_REGKEY_ZONE_TYPE, DNSSRV_TYPEID_ZONE_TYPE_RESET, (PVOID) &typeReset );
FREE_HEAP( arrayIp ); return( status ); }
DNS_STATUS DNS_API_FUNCTION DnssrvResetZoneDatabase( IN LPCWSTR Server, IN LPCSTR pszZone, IN DWORD fDsIntegrated, IN LPCSTR pszDataFile ) { DNS_STATUS status; DNS_RPC_ZONE_DATABASE dbase;
INITIALIZE_RPC_STRUCT( ZONE_DATABASE, dbase );
dbase.fDsIntegrated = fDsIntegrated; dbase.pszFileName = (LPSTR) pszDataFile;
return DnssrvOperation( Server, pszZone, DNS_REGKEY_ZONE_FILE, DNSSRV_TYPEID_ZONE_DATABASE, (PVOID) &dbase ); }
//
// End remote.c
//
|