You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1994 lines
50 KiB
1994 lines
50 KiB
/*++
|
|
|
|
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
|
|
//
|