]>
Commit | Line | Data |
---|---|---|
98bf1607 | 1 | /* |
47e8308d | 2 | * Copyright(c) 2009-2010,2013 by Internet Systems Consortium, Inc.("ISC") |
98bf1607 SR |
3 | * |
4 | * Permission to use, copy, modify, and distribute this software for any | |
5 | * purpose with or without fee is hereby granted, provided that the above | |
6 | * copyright notice and this permission notice appear in all copies. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | |
14 | * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | * | |
16 | * Internet Systems Consortium, Inc. | |
17 | * 950 Charter Street | |
18 | * Redwood City, CA 94063 | |
19 | * <info@isc.org> | |
20 | * http://www.isc.org/ | |
21 | * | |
22 | */ | |
23 | ||
24 | /*Trying to figure out what we need to define to get things to work. | |
25 | It looks like we want/need the export library but need the fdwatchcommand | |
26 | which may be a problem */ | |
27 | ||
28 | #include "dhcpd.h" | |
29 | ||
3ac2a573 | 30 | #include <sys/time.h> |
47e8308d | 31 | #include <signal.h> |
3ac2a573 | 32 | |
98bf1607 | 33 | dhcp_context_t dhcp_gbl_ctx; |
0895c955 | 34 | int shutdown_signal = 0; |
98bf1607 | 35 | |
e54ff84f SR |
36 | #if defined (NSUPDATE) |
37 | ||
38 | /* This routine will open up the /etc/resolv.conf file and | |
39 | * send any nameservers it finds to the DNS client code. | |
40 | * It may be moved to be part of the dns client code instead | |
41 | * of being in the DHCP code | |
42 | */ | |
43 | isc_result_t | |
44 | dhcp_dns_client_setservers(void) | |
45 | { | |
46 | isc_result_t result; | |
47 | irs_resconf_t *resconf = NULL; | |
48 | isc_sockaddrlist_t *nameservers; | |
49 | isc_sockaddr_t *sa; | |
50 | ||
51 | result = irs_resconf_load(dhcp_gbl_ctx.mctx, _PATH_RESOLV_CONF, | |
52 | &resconf); | |
22ceb8bb | 53 | if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { |
e54ff84f SR |
54 | log_error("irs_resconf_load failed: %d.", result); |
55 | return (result); | |
56 | } | |
57 | ||
58 | nameservers = irs_resconf_getnameservers(resconf); | |
59 | ||
60 | /* Initialize port numbers */ | |
61 | for (sa = ISC_LIST_HEAD(*nameservers); | |
62 | sa != NULL; | |
63 | sa = ISC_LIST_NEXT(sa, link)) { | |
64 | switch (sa->type.sa.sa_family) { | |
65 | case AF_INET: | |
66 | sa->type.sin.sin_port = htons(NS_DEFAULTPORT); | |
67 | break; | |
68 | case AF_INET6: | |
69 | sa->type.sin6.sin6_port = htons(NS_DEFAULTPORT); | |
70 | break; | |
71 | default: | |
72 | break; | |
73 | } | |
74 | } | |
75 | ||
76 | result = dns_client_setservers(dhcp_gbl_ctx.dnsclient, | |
77 | dns_rdataclass_in, | |
78 | NULL, nameservers); | |
79 | if (result != ISC_R_SUCCESS) { | |
80 | log_error("dns_client_setservers failed: %d.", | |
81 | result); | |
82 | } | |
83 | return (result); | |
84 | } | |
85 | #endif | |
86 | ||
98bf1607 SR |
87 | void |
88 | isclib_cleanup(void) | |
89 | { | |
90 | #if defined (NSUPDATE) | |
91 | if (dhcp_gbl_ctx.dnsclient != NULL) | |
92 | dns_client_destroy((dns_client_t **)&dhcp_gbl_ctx.dnsclient); | |
93 | #endif | |
94 | ||
95 | if (dhcp_gbl_ctx.task != NULL) { | |
98bf1607 SR |
96 | isc_task_shutdown(dhcp_gbl_ctx.task); |
97 | isc_task_detach(&dhcp_gbl_ctx.task); | |
98 | } | |
99 | ||
100 | if (dhcp_gbl_ctx.timermgr != NULL) | |
101 | isc_timermgr_destroy(&dhcp_gbl_ctx.timermgr); | |
102 | ||
103 | if (dhcp_gbl_ctx.socketmgr != NULL) | |
104 | isc_socketmgr_destroy(&dhcp_gbl_ctx.socketmgr); | |
105 | ||
106 | if (dhcp_gbl_ctx.taskmgr != NULL) | |
107 | isc_taskmgr_destroy(&dhcp_gbl_ctx.taskmgr); | |
108 | ||
109 | if (dhcp_gbl_ctx.actx_started != ISC_FALSE) { | |
110 | isc_app_ctxfinish(dhcp_gbl_ctx.actx); | |
111 | dhcp_gbl_ctx.actx_started = ISC_FALSE; | |
112 | } | |
113 | ||
114 | if (dhcp_gbl_ctx.actx != NULL) | |
115 | isc_appctx_destroy(&dhcp_gbl_ctx.actx); | |
116 | ||
117 | if (dhcp_gbl_ctx.mctx != NULL) | |
118 | isc_mem_detach(&dhcp_gbl_ctx.mctx); | |
119 | ||
120 | return; | |
121 | } | |
122 | ||
123 | isc_result_t | |
61ef216b SR |
124 | dhcp_context_create(int flags, |
125 | struct in_addr *local4, | |
126 | struct in6_addr *local6) { | |
98bf1607 SR |
127 | isc_result_t result; |
128 | ||
61ef216b SR |
129 | if ((flags & DHCP_CONTEXT_PRE_DB) != 0) { |
130 | /* | |
131 | * Set up the error messages, this isn't the right place | |
132 | * for this call but it is convienent for now. | |
133 | */ | |
134 | result = dhcp_result_register(); | |
135 | if (result != ISC_R_SUCCESS) { | |
136 | log_fatal("register_table() %s: %u", "failed", result); | |
137 | } | |
98bf1607 | 138 | |
61ef216b | 139 | memset(&dhcp_gbl_ctx, 0, sizeof (dhcp_gbl_ctx)); |
98bf1607 | 140 | |
61ef216b | 141 | isc_lib_register(); |
98bf1607 | 142 | |
61ef216b SR |
143 | /* get the current time for use as the random seed */ |
144 | gettimeofday(&cur_tv, (struct timezone *)0); | |
145 | isc_random_seed(cur_tv.tv_sec); | |
98bf1607 SR |
146 | |
147 | #if defined (NSUPDATE) | |
61ef216b SR |
148 | result = dns_lib_init(); |
149 | if (result != ISC_R_SUCCESS) | |
150 | goto cleanup; | |
151 | #else | |
152 | /* The dst library is inited as part of dns_lib_init, we don't | |
153 | * need it if NSUPDATE is enabled */ | |
154 | result = dst_lib_init(dhcp_gbl_ctx.mctx, NULL, 0); | |
155 | if (result != ISC_R_SUCCESS) | |
156 | goto cleanup; | |
98bf1607 | 157 | |
61ef216b SR |
158 | #endif |
159 | result = isc_mem_create(0, 0, &dhcp_gbl_ctx.mctx); | |
160 | if (result != ISC_R_SUCCESS) | |
161 | goto cleanup; | |
162 | ||
163 | result = isc_appctx_create(dhcp_gbl_ctx.mctx, | |
164 | &dhcp_gbl_ctx.actx); | |
165 | if (result != ISC_R_SUCCESS) | |
166 | goto cleanup; | |
167 | ||
168 | result = isc_app_ctxstart(dhcp_gbl_ctx.actx); | |
169 | if (result != ISC_R_SUCCESS) | |
170 | return (result); | |
171 | dhcp_gbl_ctx.actx_started = ISC_TRUE; | |
172 | ||
173 | result = isc_taskmgr_createinctx(dhcp_gbl_ctx.mctx, | |
174 | dhcp_gbl_ctx.actx, | |
175 | 1, 0, | |
176 | &dhcp_gbl_ctx.taskmgr); | |
177 | if (result != ISC_R_SUCCESS) | |
178 | goto cleanup; | |
179 | ||
180 | result = isc_socketmgr_createinctx(dhcp_gbl_ctx.mctx, | |
181 | dhcp_gbl_ctx.actx, | |
182 | &dhcp_gbl_ctx.socketmgr); | |
183 | if (result != ISC_R_SUCCESS) | |
184 | goto cleanup; | |
185 | ||
186 | result = isc_timermgr_createinctx(dhcp_gbl_ctx.mctx, | |
187 | dhcp_gbl_ctx.actx, | |
188 | &dhcp_gbl_ctx.timermgr); | |
189 | if (result != ISC_R_SUCCESS) | |
190 | goto cleanup; | |
191 | ||
192 | result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task); | |
193 | if (result != ISC_R_SUCCESS) | |
194 | goto cleanup; | |
195 | } | |
98bf1607 SR |
196 | |
197 | #if defined (NSUPDATE) | |
61ef216b SR |
198 | if ((flags & DHCP_CONTEXT_POST_DB) != 0) { |
199 | isc_sockaddr_t localaddr4, *localaddr4_ptr = NULL; | |
200 | isc_sockaddr_t localaddr6, *localaddr6_ptr = NULL; | |
201 | if (local4 != NULL) { | |
202 | isc_sockaddr_fromin(&localaddr4, local4, 0); | |
203 | localaddr4_ptr = &localaddr4; | |
204 | } | |
205 | if (local6 != NULL) { | |
206 | isc_sockaddr_fromin6(&localaddr6, local6, 0); | |
207 | localaddr6_ptr = &localaddr6; | |
208 | } | |
98bf1607 | 209 | |
61ef216b SR |
210 | result = dns_client_createx2(dhcp_gbl_ctx.mctx, |
211 | dhcp_gbl_ctx.actx, | |
212 | dhcp_gbl_ctx.taskmgr, | |
213 | dhcp_gbl_ctx.socketmgr, | |
214 | dhcp_gbl_ctx.timermgr, | |
215 | 0, | |
216 | &dhcp_gbl_ctx.dnsclient, | |
217 | localaddr4_ptr, | |
218 | localaddr6_ptr); | |
219 | if (result != ISC_R_SUCCESS) | |
220 | goto cleanup; | |
221 | ||
222 | result = dhcp_dns_client_setservers(); | |
223 | if (result != ISC_R_SUCCESS) | |
224 | goto cleanup; | |
225 | } | |
98bf1607 | 226 | #endif |
61ef216b | 227 | |
98bf1607 SR |
228 | return(ISC_R_SUCCESS); |
229 | ||
230 | cleanup: | |
d122accf SR |
231 | /* |
232 | * Currently we don't try and cleanup, just return an error | |
233 | * expecting that our caller will log the error and exit. | |
234 | */ | |
98bf1607 SR |
235 | |
236 | return(result); | |
237 | } | |
238 | ||
f4bc8261 SR |
239 | /* |
240 | * Convert a string name into the proper structure for the isc routines | |
241 | * | |
242 | * Previously we allowed names without a trailing '.' however the current | |
243 | * dns and dst code requires the names to end in a period. If the | |
244 | * name doesn't have a trailing period add one as part of creating | |
245 | * the dns name. | |
246 | */ | |
247 | ||
98bf1607 SR |
248 | isc_result_t |
249 | dhcp_isc_name(unsigned char *namestr, | |
250 | dns_fixedname_t *namefix, | |
251 | dns_name_t **name) | |
252 | { | |
253 | size_t namelen; | |
254 | isc_buffer_t b; | |
255 | isc_result_t result; | |
f4bc8261 | 256 | |
98bf1607 SR |
257 | namelen = strlen((char *)namestr); |
258 | isc_buffer_init(&b, namestr, namelen); | |
259 | isc_buffer_add(&b, namelen); | |
260 | dns_fixedname_init(namefix); | |
261 | *name = dns_fixedname_name(namefix); | |
f4bc8261 | 262 | result = dns_name_fromtext(*name, &b, dns_rootname, 0, NULL); |
98bf1607 SR |
263 | isc_buffer_invalidate(&b); |
264 | return(result); | |
265 | } | |
266 | ||
267 | isc_result_t | |
268 | isclib_make_dst_key(char *inname, | |
269 | char *algorithm, | |
270 | unsigned char *secret, | |
271 | int length, | |
272 | dst_key_t **dstkey) | |
273 | { | |
274 | isc_result_t result; | |
275 | dns_name_t *name; | |
276 | dns_fixedname_t name0; | |
277 | isc_buffer_t b; | |
98bf1607 SR |
278 | |
279 | isc_buffer_init(&b, secret, length); | |
280 | isc_buffer_add(&b, length); | |
281 | ||
282 | /* We only support HMAC_MD5 currently */ | |
283 | if (strcasecmp(algorithm, DHCP_HMAC_MD5_NAME) != 0) { | |
284 | return(DHCP_R_INVALIDARG); | |
285 | } | |
286 | ||
f4bc8261 | 287 | result = dhcp_isc_name((unsigned char *)inname, &name0, &name); |
98bf1607 SR |
288 | if (result != ISC_R_SUCCESS) { |
289 | return(result); | |
290 | } | |
291 | ||
292 | return(dst_key_frombuffer(name, DST_ALG_HMACMD5, DNS_KEYOWNER_ENTITY, | |
293 | DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, | |
294 | &b, dhcp_gbl_ctx.mctx, dstkey)); | |
295 | } | |
296 | ||
47e8308d SR |
297 | /** |
298 | * signal handler that initiates server shutdown | |
299 | * | |
300 | * @param signal signal code that we received | |
301 | */ | |
302 | void dhcp_signal_handler(int signal) { | |
303 | isc_appctx_t *ctx = dhcp_gbl_ctx.actx; | |
0895c955 SR |
304 | int prev = shutdown_signal; |
305 | ||
306 | if (prev != 0) { | |
307 | /* Already in shutdown. */ | |
308 | return; | |
309 | } | |
310 | /* Possible race but does it matter? */ | |
311 | shutdown_signal = signal; | |
312 | ||
313 | /* Use reload (aka suspend) for easier dispatch() reenter. */ | |
314 | if (ctx && ctx->methods && ctx->methods->ctxsuspend) { | |
315 | (void) isc_app_ctxsuspend(ctx); | |
47e8308d SR |
316 | } |
317 | } |