Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

411 lines
9.9 KiB

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
r_init.c
Abstract:
This module contains routines to initialize the DNS resolver.
Author:
Mike Massa (mikemas) Sept 20, 1991
Revision History:
Who When What
-------- -------- ----------------------------------------------
mikemas 9-20-91 created
Notes:
Exports:
res_init()
--*/
#ident "@(#)res_init.c 5.3 3/8/91"
/******************************************************************
*
* SpiderTCP BIND
*
* Copyright 1990 Spider Systems Limited
*
* RES_INIT.C
*
******************************************************************/
/*-
* /usr/projects/tcp/SCCS.rel3/rel/src/lib/net/0/s.res_init.c
* @(#)res_init.c 5.3
*
* Last delta created 14:11:42 3/4/91
* This file extracted 11:20:32 3/8/91
*
* Modifications:
*
* GSS 24 Jul 90 New File
*/
/*
* Copyright (c) 1985, 1989 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted provided
* that: (1) source distributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* Neither the name of the University nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_init.c 6.14 (Berkeley) 6/27/90";
#endif /* LIBC_SCCS and not lint */
/****************************************************************************/
#include "winsockp.h"
#define LOCALHOST "127.0.0.1"
#define WORK_BUFFER_SIZE 1024
#define RESCONF_SIZE (_MAX_PATH + 10)
#define index strchr
BOOL
BuildDnsServerList(
LPADDR_LIST AddressList,
PUCHAR RawData
);
int
_pgethostname(
OUT char *name,
IN int namelen
);
/*
* Set up default settings. If the configuration file exist, the values
* there will have precedence. Otherwise, the server address is set to
* LOCALHOST and the default domain name comes from the gethostname().
*
* The configuration file should only be used if you want to redefine your
* domain or run without a server on your machine.
*
* Return 0 if completes successfully, -1 on error
*/
int
res_init(
void
)
{
register char *cp, *cpt, **pp;
register int n;
int nserv = 0; /* number of nameserver records read from file */
int havesearch = 0;
long options = 0L;
PUCHAR temp;
HANDLE myKey;
NTSTATUS status;
ULONG myType;
DWORD numLists = 0;
DWORD oneAddress;
extern int GetIpAddressList(LPDWORD IpAddressList, WORD ListCount);
IF_DEBUG(RESOLVER) {
WS_PRINT(("res_init entered\n"));
}
if ((_res.options & RES_INIT) != 0) {
return (0);
}
//
// Hack! If there are no IP addresses, then fail resolver init.
//
if( GetIpAddressList( &oneAddress, 1 ) <= 0 ||
oneAddress == htonl( INADDR_LOOPBACK ) ) {
SetLastError( WSANO_DATA );
return -1;
}
RtlZeroMemory(
&_res.nslist,
sizeof(_res.nslist)
);
status = SockOpenKeyEx( &myKey, VTCPPARM, NTCPPARM, TCPPARM );
if (!NT_SUCCESS(status)) {
IF_DEBUG(RESOLVER) {
WS_PRINT(("Required Registry Key is missing -- %s\n", NTCPPARM));
}
SetLastError( ERROR_INVALID_PARAMETER );
return -1;
}
if ((temp=ALLOCATE_HEAP(WORK_BUFFER_SIZE))==NULL) {
IF_DEBUG(RESOLVER) {
WS_PRINT(("Out of memory!\n"));
}
NtClose(myKey);
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return -1;
}
/* read default domain name */
status = SockGetSingleValue(myKey, "Domain", temp,
&myType, WORK_BUFFER_SIZE);
if (!NT_SUCCESS(status) || (strlen(temp) == 0)) {
status = SockGetSingleValue(myKey, "DhcpDomain", temp,
&myType, WORK_BUFFER_SIZE);
}
if (NT_SUCCESS(status)) {
(void)strncpy(_res.defdname, temp, sizeof(_res.defdname) - 1);
havesearch = 0;
}
/* set search list */
status = SockGetSingleValue(myKey, "SearchList", temp,
&myType, WORK_BUFFER_SIZE);
if (NT_SUCCESS(status) && (strlen(temp)>0)) {
(void)strncpy(_res.defdname, temp, sizeof(_res.defdname) - 1);
/*
* Set search list to be blank-separated strings
* on rest of line.
*/
cp = _res.defdname;
pp = _res.dnsrch;
*pp++ = cp;
for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
if (*cp == ' ' || *cp == '\t') {
*cp = 0;
n = 1;
} else if (n) {
*pp++ = cp;
n = 0;
}
}
/* null terminate last domain if there are excess */
while (*cp != '\0' && *cp != ' ' && *cp != '\t') {
cp++;
}
*cp = '\0';
*pp++ = 0;
havesearch = 1;
}
//
// List 0 is the statically configured DNS server list.
//
status = SockGetSingleValue(
myKey,
"NameServer",
temp,
&myType,
WORK_BUFFER_SIZE
);
if( NT_SUCCESS(status) ) {
if( BuildDnsServerList(
&_res.nslist[0],
temp
) ) {
numLists++;
}
}
//
// List 1 is the DHCP configured list.
//
status = SockGetSingleValue(
myKey,
"DhcpNameServer",
temp,
&myType,
WORK_BUFFER_SIZE
);
if( NT_SUCCESS(status) ) {
if( BuildDnsServerList(
&_res.nslist[numLists],
temp
) ) {
numLists++;
}
}
//
// List 2 is the RAS configured list.
//
{
HANDLE tKey;
status = SockOpenKey( &tKey, TTCPPARM );
if( NT_SUCCESS(status) ) {
status = SockGetSingleValue(
tKey,
"NameServer",
temp,
&myType,
WORK_BUFFER_SIZE
);
if( NT_SUCCESS(status) ) {
if( BuildDnsServerList(
&_res.nslist[numLists],
temp
) ) {
numLists++;
}
}
NtClose( tKey );
}
}
NtClose(myKey);
IF_DEBUG(RESOLVER) {
WS_PRINT(("options = %lx\n", options));
}
_res.options |= options;
if (_res.defdname[0] == 0) {
if (_pgethostname(temp, sizeof(_res.defdname)) == 0 &&
(cp = index(temp, '.'))) {
(void)strcpy(_res.defdname, cp + 1);
}
}
/* find components of local domain that might be searched */
if (havesearch == 0) {
pp = _res.dnsrch;
*pp++ = _res.defdname;
for (cp = _res.defdname, n = 0; *cp; cp++) {
if (*cp == '.') {
n++;
}
}
cp = _res.defdname;
for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch+MAXDFLSRCH; n--) {
cp = index(cp, '.');
*pp++ = ++cp;
}
*pp++ = 0;
}
_res.options |= RES_INIT;
FREE_HEAP(temp);
return (0);
}
BOOL
querydnsaddrs (
IN LPDWORD *Array,
IN PVOID Buffer
)
{
u_long listIndex;
u_long serverIndex;
u_long numServers;
int i;
LPDWORD next = Buffer;
if (res_init() == -1) {
return FALSE;
}
i = 0;
for( listIndex = 0 ; listIndex < MAXNSLIST ; listIndex++ ) {
numServers = _res.nslist[listIndex].ServerCount;
for( serverIndex = 0 ; serverIndex < numServers ; serverIndex++ ) {
*next = _res.nslist[listIndex].Servers[serverIndex];
*(Array + i) = next;
next++;
i++;
}
}
*(Array + i) = NULL;
if ( i == 0 ) {
return FALSE;
}
return TRUE;
} // querydnsaddrs
BOOL
BuildDnsServerList(
LPADDR_LIST AddressList,
PUCHAR RawData
)
{
int dataLength;
u_long numServers;
PUCHAR tmp;
dataLength = strlen( RawData );
numServers = 0;
while( ( *RawData != '\0' ) && ( numServers < MAXNS ) ) {
while( dataLength > 0 &&
( *RawData == ' ' || *RawData == '\t' || *RawData == ',' ) ) {
RawData++;
dataLength--;
}
tmp = RawData;
while( dataLength > 0 &&
( *tmp != ' ' && *tmp != '\t' && *tmp != '\0' && *tmp != ',' ) ) {
tmp++;
dataLength--;
}
*tmp = '\0';
AddressList->Servers[numServers] = inet_addr( RawData );
if( AddressList->Servers[numServers] == INADDR_ANY ||
AddressList->Servers[numServers] == INADDR_NONE ) {
return FALSE;
}
numServers++;
if( dataLength > 0 ) {
RawData = tmp + 1;
dataLength--;
} else {
*RawData = '\0';
}
}
AddressList->ServerCount = numServers;
return TRUE;
} // BuildDnsServerList