]> jfr.im git - solanum.git/blame - authd/reslist.c
Mailmap and copyright update for Ariadne
[solanum.git] / authd / reslist.c
CommitLineData
76ebf6c4
AC
1/*
2 * reslist.c - get nameservers from windows *
4094d2fa 3 *
76ebf6c4 4 * ircd-ratbox related changes are as follows
4094d2fa 5 *
76ebf6c4
AC
6 * Copyright (C) 2008 Aaron Sethman <androsyn@ratbox.org>
7 * Copyright (C) 2008-2012 ircd-ratbox development team
4094d2fa
EM
8 *
9 * pretty much all of this was yanked from c-ares ares_init.c here is the original
76ebf6c4
AC
10 * header from there --
11 *
4094d2fa 12 * Id: ares_init.c,v 1.72 2008-05-15 00:00:19 yangtse Exp $
76ebf6c4
AC
13 * Copyright 1998 by the Massachusetts Institute of Technology.
14 * Copyright (C) 2007-2008 by Daniel Stenberg
15 *
16 * Permission to use, copy, modify, and distribute this
17 * software and its documentation for any purpose and without
18 * fee is hereby granted, provided that the above copyright
19 * notice appear in all copies and that both that copyright
20 * notice and this permission notice appear in supporting
21 * documentation, and that the name of M.I.T. not be used in
22 * advertising or publicity pertaining to distribution of the
23 * software without specific, written prior permission.
24 * M.I.T. makes no representations about the suitability of
25 * this software for any purpose. It is provided "as is"
26 * without express or implied warranty.
27 *
28 *
29 */
30
31#ifdef _WIN32
2dea53a2 32#include <rb_lib.h>
76ebf6c4
AC
33
34#include <windows.h>
35#include <iphlpapi.h>
36
37const char *get_windows_nameservers(void);
38
b143df9a
AJ
39#ifndef INADDR_NONE
40#define INADDR_NONE ((unsigned int) 0xffffffff)
41#endif /* INADDR_NONE */
76ebf6c4
AC
42
43#define IS_NT() ((int)GetVersion() > 0)
44#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
45#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
46#define NAMESERVER "NameServer"
47#define DHCPNAMESERVER "DhcpNameServer"
48#define DATABASEPATH "DatabasePath"
49#define WIN_PATH_HOSTS "\\hosts"
50
51static int
52get_iphlpapi_dns_info(char *ret_buf, size_t ret_size)
53{
54 FIXED_INFO *fi = alloca(sizeof(*fi));
55 DWORD size = sizeof(*fi);
56 typedef DWORD(WINAPI * get_net_param_func) (FIXED_INFO *, DWORD *);
57 get_net_param_func xxGetNetworkParams; /* available only on Win-98/2000+ */
58 HMODULE handle;
59 IP_ADDR_STRING *ipAddr;
60 int i, count = 0;
61 int debug = 0;
62 size_t ip_size = sizeof("255.255.255.255,") - 1;
63 size_t left = ret_size;
64 char *ret = ret_buf;
65 HRESULT res;
66
67 if(!fi)
68 return (0);
69
70 handle = LoadLibrary("iphlpapi.dll");
71 if(!handle)
72 return (0);
73
74 xxGetNetworkParams = (get_net_param_func) GetProcAddress(handle, "GetNetworkParams");
75 if(!xxGetNetworkParams)
76 goto quit;
77
78 res = (*xxGetNetworkParams) (fi, &size);
79 if((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
80 goto quit;
81
82 fi = alloca(size);
83 if(!fi || (*xxGetNetworkParams) (fi, &size) != ERROR_SUCCESS)
84 goto quit;
85
86 if(debug)
87 {
88 printf("Host Name: %s\n", fi->HostName);
89 printf("Domain Name: %s\n", fi->DomainName);
90 printf("DNS Servers:\n" " %s (primary)\n", fi->DnsServerList.IpAddress.String);
91 }
92 if(strlen(fi->DnsServerList.IpAddress.String) > 0 &&
93 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE && left > ip_size)
94 {
95 ret += sprintf(ret, "%s,", fi->DnsServerList.IpAddress.String);
96 left -= ret - ret_buf;
97 count++;
98 }
99
100 for(i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
101 ipAddr = ipAddr->Next, i++)
102 {
103 if(inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
104 {
105 ret += sprintf(ret, "%s,", ipAddr->IpAddress.String);
106 left -= ret - ret_buf;
107 count++;
108 }
109 if(debug)
110 printf(" %s (secondary %d)\n", ipAddr->IpAddress.String, i + 1);
111 }
112
113 quit:
114 if(handle)
115 FreeLibrary(handle);
116
117 if(debug && left <= ip_size)
118 printf("Too many nameservers. Truncating to %d addressess", count);
119 if(ret > ret_buf)
120 ret[-1] = '\0';
121 return (count);
122}
123
124/*
125 * Warning: returns a dynamically allocated buffer, the user MUST
126 * use free() / rb_free() if the function returns 1
127 */
128static int
129get_res_nt(HKEY hKey, const char *subkey, char **obuf)
130{
131 /* Test for the size we need */
132 DWORD size = 0;
133 int result;
134
135 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
136 if((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
137 return 0;
138 *obuf = rb_malloc(size + 1);
139 if(!*obuf)
140 return 0;
141
142 if(RegQueryValueEx(hKey, subkey, 0, NULL, (LPBYTE) * obuf, &size) != ERROR_SUCCESS)
143 {
144 rb_free(*obuf);
145 return 0;
146 }
147 if(size == 1)
148 {
149 rb_free(*obuf);
150 return 0;
151 }
152 return 1;
153}
154
155static int
156get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
157{
158 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
159 DWORD enum_size = 39;
160 int idx = 0;
161 HKEY hVal;
162
163 while(RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
164 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
165 {
166 int rc;
167
168 enum_size = 39;
169 if(RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) != ERROR_SUCCESS)
170 continue;
171 rc = get_res_nt(hVal, subkey, obuf);
172 RegCloseKey(hVal);
173 if(rc)
174 return 1;
175 }
176 return 0;
177}
178
179const char *
180get_windows_nameservers(void)
181{
182 /*
183 NameServer info via IPHLPAPI (IP helper API):
184 GetNetworkParams() should be the trusted source for this.
185 Available in Win-98/2000 and later. If that fail, fall-back to
186 registry information.
187
188 NameServer Registry:
189
190 On Windows 9X, the DNS server can be found in:
191 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
192
193 On Windows NT/2000/XP/2003:
194 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
195 or
196 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
197 or
198 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
199 NameServer
200 or
201 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
202 DhcpNameServer
203 */
204 static char namelist[512];
205 HKEY mykey;
206 HKEY subkey;
207 DWORD data_type;
208 DWORD bytes;
209 DWORD result;
210 char *line = NULL;
211 memset(&namelist, 0, sizeof(namelist));
212 if(get_iphlpapi_dns_info(namelist, sizeof(namelist)) > 0)
213 {
214 return namelist;
215 }
216
217 if(IS_NT())
218 {
219 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
220 KEY_READ, &mykey) == ERROR_SUCCESS)
221 {
222 RegOpenKeyEx(mykey, "Interfaces", 0,
223 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &subkey);
224 if(get_res_nt(mykey, NAMESERVER, &line))
225 {
226 rb_strlcpy(namelist, line, sizeof(namelist));
227 return namelist;
228 }
229 else if(get_res_nt(mykey, DHCPNAMESERVER, &line))
230 {
231 rb_strlcpy(namelist, line, sizeof(namelist));
232 rb_free(line);
233 }
234 /* Try the interfaces */
235 else if(get_res_interfaces_nt(subkey, NAMESERVER, &line))
236 {
237 rb_strlcpy(namelist, line, sizeof(namelist));
238 rb_free(line);
239 }
240 else if(get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
241 {
242 rb_strlcpy(namelist, line, sizeof(namelist));
243 rb_free(line);
244 }
245 RegCloseKey(subkey);
246 RegCloseKey(mykey);
247 }
248 }
249 else
250 {
251 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
252 KEY_READ, &mykey) == ERROR_SUCCESS)
253 {
254 if((result = RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
255 NULL, &bytes)) == ERROR_SUCCESS ||
256 result == ERROR_MORE_DATA)
257 {
258 if(bytes)
259 {
260 line = (char *)rb_malloc(bytes + 1);
261 if(RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
262 (unsigned char *)line, &bytes) ==
263 ERROR_SUCCESS)
264 {
265 rb_strlcpy(namelist, line, sizeof(namelist));
266 }
267 free(line);
268 }
269 }
270 }
271 RegCloseKey(mykey);
272 }
273 if(strlen(namelist) > 0)
274 return namelist;
275 return NULL;
276}
277
278
279#endif