1 /* $NetBSD: lwconfig.c,v 1.5 2014/12/10 04:38:02 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004, 2006, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 2002 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id: lwconfig.c,v 1.7 2007/12/14 01:40:42 marka Exp */ 21 22 /* 23 * We do this so that we may incorporate everything in the main routines 24 * so that we can take advantage of the fixes and changes made there 25 * without having to add them twice. We can then call the parse routine 26 * if there is a resolv.conf file and fetch our own data from the 27 * Windows environment otherwise. 28 */ 29 30 /* 31 * Note that on Win32 there is normally no resolv.conf since all information 32 * is stored in the registry. Therefore there is no ordering like the 33 * contents of resolv.conf. Since the "search" or "domain" keyword, on 34 * Win32 if a search list is found it is used, otherwise the domain name 35 * is used since they are mutually exclusive. The search list can be entered 36 * in the DNS tab of the "Advanced TCP/IP settings" window under the same place 37 * that you add your nameserver list. 38 */ 39 40 #define lwres_conf_parse generic_lwres_conf_parse 41 #include "../lwconfig.c" 42 #undef lwres_conf_parse 43 44 #include <iphlpapi.h> 45 46 #define TCPIP_SUBKEY \ 47 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" 48 49 void 50 get_win32_searchlist(lwres_context_t *ctx) { 51 HKEY hKey; 52 BOOL keyFound = TRUE; 53 char searchlist[MAX_PATH]; 54 DWORD searchlen = MAX_PATH; 55 char *cp; 56 lwres_conf_t *confdata; 57 58 REQUIRE(ctx != NULL); 59 confdata = &ctx->confdata; 60 61 memset(searchlist, 0, MAX_PATH); 62 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TCPIP_SUBKEY, 0, KEY_READ, &hKey) 63 != ERROR_SUCCESS) 64 keyFound = FALSE; 65 66 if (keyFound == TRUE) { 67 /* Get the named directory */ 68 if (RegQueryValueEx(hKey, "SearchList", NULL, NULL, 69 (LPBYTE)searchlist, &searchlen) != ERROR_SUCCESS) 70 keyFound = FALSE; 71 RegCloseKey(hKey); 72 } 73 74 confdata->searchnxt = 0; 75 76 if (!keyFound) 77 return; 78 79 cp = strtok((char *)searchlist, ", \0"); 80 while (cp != NULL) { 81 if (confdata->searchnxt == LWRES_CONFMAXSEARCH) 82 break; 83 if (strlen(cp) <= MAX_PATH && strlen(cp) > 0) { 84 confdata->search[confdata->searchnxt] = lwres_strdup(ctx, cp); 85 if (confdata->search[confdata->searchnxt] != NULL) 86 confdata->searchnxt++; 87 } 88 cp = strtok(NULL, ", \0"); 89 } 90 } 91 92 lwres_result_t 93 lwres_conf_parse(lwres_context_t *ctx, const char *filename) { 94 lwres_result_t ret; 95 lwres_conf_t *confdata; 96 FIXED_INFO * FixedInfo; 97 ULONG BufLen = sizeof(FIXED_INFO); 98 DWORD dwRetVal; 99 IP_ADDR_STRING *pIPAddr; 100 101 REQUIRE(ctx != NULL); 102 confdata = &ctx->confdata; 103 REQUIRE(confdata != NULL); 104 105 /* Use the resolver if there is one */ 106 ret = generic_lwres_conf_parse(ctx, filename); 107 if ((ret != LWRES_R_NOTFOUND && ret != LWRES_R_SUCCESS) || 108 (ret == LWRES_R_SUCCESS && confdata->nsnext > 0)) 109 return (ret); 110 111 /* 112 * We didn't get any nameservers so we need to do this ourselves 113 */ 114 FixedInfo = (FIXED_INFO *) GlobalAlloc(GPTR, BufLen); 115 dwRetVal = GetNetworkParams(FixedInfo, &BufLen); 116 if (dwRetVal == ERROR_BUFFER_OVERFLOW) { 117 GlobalFree(FixedInfo); 118 FixedInfo = GlobalAlloc(GPTR, BufLen); 119 dwRetVal = GetNetworkParams(FixedInfo, &BufLen); 120 } 121 if (dwRetVal != ERROR_SUCCESS) { 122 GlobalFree(FixedInfo); 123 return (LWRES_R_FAILURE); 124 } 125 126 /* Get the search list from the registry */ 127 get_win32_searchlist(ctx); 128 129 /* Use only if there is no search list */ 130 if (confdata->searchnxt == 0 && strlen(FixedInfo->DomainName) > 0) { 131 confdata->domainname = lwres_strdup(ctx, FixedInfo->DomainName); 132 if (confdata->domainname == NULL) { 133 GlobalFree(FixedInfo); 134 return (LWRES_R_FAILURE); 135 } 136 } else 137 confdata->domainname = NULL; 138 139 /* Get the list of nameservers */ 140 pIPAddr = &FixedInfo->DnsServerList; 141 while (pIPAddr) { 142 if (confdata->nsnext >= LWRES_CONFMAXNAMESERVERS) 143 break; 144 145 ret = lwres_create_addr(pIPAddr->IpAddress.String, 146 &confdata->nameservers[confdata->nsnext++], 1); 147 if (ret != LWRES_R_SUCCESS) { 148 GlobalFree(FixedInfo); 149 return (ret); 150 } 151 pIPAddr = pIPAddr ->Next; 152 } 153 154 GlobalFree(FixedInfo); 155 return (LWRES_R_SUCCESS); 156 } 157