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