]>
Commit | Line | Data |
---|---|---|
fe4ab6d6 TL |
1 | /* remote.c |
2 | ||
3 | The dhcpctl remote object. */ | |
4 | ||
5 | /* | |
edad9be5 | 6 | * Copyright (c) 2004,2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC") |
98311e4b | 7 | * Copyright (c) 1999-2003 by Internet Software Consortium |
fe4ab6d6 | 8 | * |
98311e4b DH |
9 | * Permission to use, copy, modify, and distribute this software for any |
10 | * purpose with or without fee is hereby granted, provided that the above | |
11 | * copyright notice and this permission notice appear in all copies. | |
fe4ab6d6 | 12 | * |
98311e4b DH |
13 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES |
14 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
15 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR | |
16 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
17 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
18 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | |
19 | * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
fe4ab6d6 | 20 | * |
98311e4b DH |
21 | * Internet Systems Consortium, Inc. |
22 | * 950 Charter Street | |
23 | * Redwood City, CA 94063 | |
24 | * <info@isc.org> | |
2c85ac9b | 25 | * https://www.isc.org/ |
49733f31 | 26 | * |
fe4ab6d6 TL |
27 | */ |
28 | ||
fe5b0fdd | 29 | #include "dhcpd.h" |
6a4c4be8 | 30 | #include <omapip/omapip_p.h> |
fe4ab6d6 TL |
31 | #include "dhcpctl.h" |
32 | ||
49146f3c DN |
33 | /* dhcpctl_new_authenticator |
34 | ||
35 | synchronous - creates an authenticator object. | |
36 | returns nonzero status code if the object couldn't be created | |
37 | stores handle to authenticator through h if successful, and returns zero. | |
38 | name is the authenticator name (NUL-terminated string). | |
39 | algorithm is the NUL-terminated string name of the algorithm to use | |
40 | (currently, only "hmac-md5" is supported). | |
41 | secret and secret_len is the key secret. */ | |
42 | ||
43 | dhcpctl_status dhcpctl_new_authenticator (dhcpctl_handle *h, | |
44 | const char *name, | |
45 | const char *algorithm, | |
6ad8c39d | 46 | const unsigned char *secret, |
49146f3c DN |
47 | unsigned secret_len) |
48 | { | |
49 | struct auth_key *key = (struct auth_key *)0; | |
50 | isc_result_t status; | |
51 | ||
52 | status = omapi_auth_key_new (&key, MDL); | |
53 | if (status != ISC_R_SUCCESS) | |
54 | return status; | |
55 | ||
56 | key -> name = dmalloc (strlen (name) + 1, MDL); | |
57 | if (!key -> name) { | |
58 | omapi_auth_key_dereference (&key, MDL); | |
59 | return ISC_R_NOMEMORY; | |
60 | } | |
61 | strcpy (key -> name, name); | |
62 | ||
8c3c6552 DN |
63 | /* If the algorithm name isn't an FQDN, tack on the |
64 | .SIG-ALG.REG.NET. domain. */ | |
65 | if (strchr (algorithm, '.') == 0) { | |
66 | static char add[] = ".SIG-ALG.REG.INT."; | |
67 | key -> algorithm = dmalloc (strlen (algorithm) + | |
68 | sizeof (add), MDL); | |
69 | if (!key -> algorithm) { | |
70 | omapi_auth_key_dereference (&key, MDL); | |
71 | return ISC_R_NOMEMORY; | |
72 | } | |
73 | strcpy (key -> algorithm, algorithm); | |
74 | strcat (key -> algorithm, add); | |
75 | } else { | |
76 | key -> algorithm = dmalloc (strlen (algorithm) + 1, MDL); | |
77 | if (!key -> algorithm) { | |
78 | omapi_auth_key_dereference (&key, MDL); | |
79 | return ISC_R_NOMEMORY; | |
80 | } | |
81 | strcpy (key -> algorithm, algorithm); | |
49146f3c | 82 | } |
49146f3c DN |
83 | |
84 | status = omapi_data_string_new (&key -> key, secret_len, MDL); | |
85 | if (status != ISC_R_SUCCESS) { | |
86 | omapi_auth_key_dereference (&key, MDL); | |
87 | return status; | |
88 | } | |
89 | memcpy (key -> key -> value, secret, secret_len); | |
90 | key -> key -> len = secret_len; | |
91 | ||
92 | *h = (dhcpctl_handle) key; | |
93 | return ISC_R_SUCCESS; | |
94 | } | |
95 | ||
96 | ||
fe4ab6d6 TL |
97 | /* dhcpctl_new_object |
98 | ||
99 | synchronous - creates a local handle for a host entry. | |
100 | returns nonzero status code if the local host entry couldn't | |
101 | be created | |
102 | stores handle to host through h if successful, and returns zero. | |
103 | object_type is a pointer to a NUL-terminated string containing | |
104 | the ascii name of the type of object being accessed - e.g., "host" */ | |
105 | ||
106 | dhcpctl_status dhcpctl_new_object (dhcpctl_handle *h, | |
107 | dhcpctl_handle connection, | |
b1b7b521 | 108 | const char *object_type) |
fe4ab6d6 TL |
109 | { |
110 | dhcpctl_remote_object_t *m; | |
111 | omapi_object_t *g; | |
112 | isc_result_t status; | |
113 | ||
eadee396 | 114 | m = (dhcpctl_remote_object_t *)0; |
06eb8bab SK |
115 | status = omapi_object_allocate((omapi_object_t **)&m, |
116 | dhcpctl_remote_type, 0, MDL); | |
eadee396 TL |
117 | if (status != ISC_R_SUCCESS) |
118 | return status; | |
fe4ab6d6 TL |
119 | |
120 | g = (omapi_object_t *)0; | |
4bd8800e | 121 | status = omapi_generic_new (&g, MDL); |
fe4ab6d6 | 122 | if (status != ISC_R_SUCCESS) { |
4bd8800e | 123 | dfree (m, MDL); |
fe4ab6d6 TL |
124 | return status; |
125 | } | |
4bd8800e | 126 | status = omapi_object_reference (&m -> inner, g, MDL); |
fe4ab6d6 | 127 | if (status != ISC_R_SUCCESS) { |
4bd8800e TL |
128 | omapi_object_dereference ((omapi_object_t **)&m, MDL); |
129 | omapi_object_dereference (&g, MDL); | |
fe4ab6d6 TL |
130 | return status; |
131 | } | |
132 | status = omapi_object_reference (&g -> outer, | |
4bd8800e | 133 | (omapi_object_t *)m, MDL); |
fe4ab6d6 TL |
134 | |
135 | if (status != ISC_R_SUCCESS) { | |
4bd8800e TL |
136 | omapi_object_dereference ((omapi_object_t **)&m, MDL); |
137 | omapi_object_dereference (&g, MDL); | |
fe4ab6d6 TL |
138 | return status; |
139 | } | |
140 | ||
4bd8800e | 141 | status = omapi_typed_data_new (MDL, &m -> rtype, |
fe4ab6d6 | 142 | omapi_datatype_string, |
4bd8800e | 143 | object_type); |
fe4ab6d6 | 144 | if (status != ISC_R_SUCCESS) { |
4bd8800e TL |
145 | omapi_object_dereference ((omapi_object_t **)&m, MDL); |
146 | omapi_object_dereference (&g, MDL); | |
fe4ab6d6 TL |
147 | return status; |
148 | } | |
149 | ||
4bd8800e TL |
150 | status = omapi_object_reference (h, (omapi_object_t *)m, MDL); |
151 | omapi_object_dereference ((omapi_object_t **)&m, MDL); | |
152 | omapi_object_dereference (&g, MDL); | |
fe4ab6d6 TL |
153 | if (status != ISC_R_SUCCESS) |
154 | return status; | |
155 | ||
156 | return status; | |
157 | } | |
158 | ||
159 | /* asynchronous - just queues the request | |
160 | returns nonzero status code if open couldn't be queued | |
161 | returns zero if open was queued | |
162 | h is a handle to an object created by dhcpctl_new_object | |
163 | connection is a connection to a DHCP server | |
164 | flags include: | |
165 | DHCPCTL_CREATE - if the object doesn't exist, create it | |
166 | DHCPCTL_UPDATE - update the object on the server using the | |
167 | attached parameters | |
168 | DHCPCTL_EXCL - error if the object exists and DHCPCTL_CREATE | |
169 | was also specified */ | |
170 | ||
171 | dhcpctl_status dhcpctl_open_object (dhcpctl_handle h, | |
172 | dhcpctl_handle connection, | |
173 | int flags) | |
174 | { | |
175 | isc_result_t status; | |
176 | omapi_object_t *message = (omapi_object_t *)0; | |
177 | dhcpctl_remote_object_t *remote; | |
178 | ||
179 | if (h -> type != dhcpctl_remote_type) | |
98bf1607 | 180 | return DHCP_R_INVALIDARG; |
fe4ab6d6 TL |
181 | remote = (dhcpctl_remote_object_t *)h; |
182 | ||
4bd8800e | 183 | status = omapi_message_new (&message, MDL); |
fe4ab6d6 TL |
184 | if (status != ISC_R_SUCCESS) |
185 | return status; | |
186 | status = omapi_set_int_value (message, (omapi_object_t *)0, | |
187 | "op", OMAPI_OP_OPEN); | |
188 | if (status != ISC_R_SUCCESS) { | |
4bd8800e | 189 | omapi_object_dereference (&message, MDL); |
fe4ab6d6 TL |
190 | return status; |
191 | } | |
192 | status = omapi_set_object_value (message, (omapi_object_t *)0, | |
193 | "object", h); | |
194 | if (status != ISC_R_SUCCESS) { | |
4bd8800e | 195 | omapi_object_dereference (&message, MDL); |
fe4ab6d6 TL |
196 | return status; |
197 | } | |
198 | if (flags & DHCPCTL_CREATE) { | |
199 | status = omapi_set_boolean_value (message, (omapi_object_t *)0, | |
200 | "create", 1); | |
201 | if (status != ISC_R_SUCCESS) { | |
4bd8800e | 202 | omapi_object_dereference (&message, MDL); |
fe4ab6d6 TL |
203 | return status; |
204 | } | |
205 | } | |
206 | if (flags & DHCPCTL_UPDATE) { | |
207 | status = omapi_set_boolean_value (message, (omapi_object_t *)0, | |
208 | "update", 1); | |
209 | if (status != ISC_R_SUCCESS) { | |
4bd8800e | 210 | omapi_object_dereference (&message, MDL); |
fe4ab6d6 TL |
211 | return status; |
212 | } | |
213 | } | |
214 | if (flags & DHCPCTL_EXCL) { | |
215 | status = omapi_set_boolean_value (message, (omapi_object_t *)0, | |
216 | "exclusive", 1); | |
217 | if (status != ISC_R_SUCCESS) { | |
4bd8800e | 218 | omapi_object_dereference (&message, MDL); |
fe4ab6d6 TL |
219 | return status; |
220 | } | |
221 | } | |
222 | ||
223 | if (remote -> rtype) { | |
224 | status = omapi_set_value_str (message, (omapi_object_t *)0, | |
225 | "type", remote -> rtype); | |
226 | if (status != ISC_R_SUCCESS) { | |
4bd8800e | 227 | omapi_object_dereference (&message, MDL); |
fe4ab6d6 TL |
228 | return status; |
229 | } | |
230 | } | |
231 | ||
232 | status = omapi_message_register (message); | |
233 | if (status != ISC_R_SUCCESS) { | |
4bd8800e | 234 | omapi_object_dereference (&message, MDL); |
fe4ab6d6 TL |
235 | return status; |
236 | } | |
98311e4b DH |
237 | |
238 | status = omapi_protocol_send_message (connection -> outer, | |
fe4ab6d6 TL |
239 | (omapi_object_t *)0, |
240 | message, (omapi_object_t *)0); | |
98311e4b DH |
241 | |
242 | if (status != ISC_R_SUCCESS) | |
243 | omapi_message_unregister (message); | |
244 | ||
245 | omapi_object_dereference (&message, MDL); | |
246 | return status; | |
fe4ab6d6 TL |
247 | } |
248 | ||
249 | /* Callback methods (not meant to be called directly) */ | |
250 | ||
251 | isc_result_t dhcpctl_remote_set_value (omapi_object_t *h, | |
252 | omapi_object_t *id, | |
253 | omapi_data_string_t *name, | |
254 | omapi_typed_data_t *value) | |
255 | { | |
f5423ffa | 256 | dhcpctl_remote_object_t *ro; |
013be24d TL |
257 | unsigned long rh; |
258 | isc_result_t status; | |
259 | ||
fe4ab6d6 | 260 | if (h -> type != dhcpctl_remote_type) |
98bf1607 | 261 | return DHCP_R_INVALIDARG; |
f5423ffa TL |
262 | ro = (dhcpctl_remote_object_t *)h; |
263 | ||
264 | if (!omapi_ds_strcmp (name, "remote-handle")) { | |
013be24d TL |
265 | status = omapi_get_int_value (&rh, value); |
266 | if (status == ISC_R_SUCCESS) | |
267 | ro -> remote_handle = rh; | |
268 | return status; | |
f5423ffa | 269 | } |
fe4ab6d6 TL |
270 | |
271 | if (h -> inner && h -> inner -> type -> set_value) | |
272 | return (*(h -> inner -> type -> set_value)) | |
273 | (h -> inner, id, name, value); | |
274 | return ISC_R_NOTFOUND; | |
275 | } | |
276 | ||
277 | isc_result_t dhcpctl_remote_get_value (omapi_object_t *h, | |
278 | omapi_object_t *id, | |
279 | omapi_data_string_t *name, | |
280 | omapi_value_t **value) | |
281 | { | |
282 | if (h -> type != dhcpctl_remote_type) | |
98bf1607 | 283 | return DHCP_R_INVALIDARG; |
fe4ab6d6 TL |
284 | |
285 | if (h -> inner && h -> inner -> type -> get_value) | |
286 | return (*(h -> inner -> type -> get_value)) | |
287 | (h -> inner, id, name, value); | |
288 | return ISC_R_NOTFOUND; | |
289 | } | |
290 | ||
291 | isc_result_t dhcpctl_remote_signal_handler (omapi_object_t *o, | |
b1b7b521 | 292 | const char *name, va_list ap) |
fe4ab6d6 TL |
293 | { |
294 | dhcpctl_remote_object_t *p; | |
295 | omapi_typed_data_t *tv; | |
296 | ||
297 | if (o -> type != dhcpctl_remote_type) | |
98bf1607 | 298 | return DHCP_R_INVALIDARG; |
fe4ab6d6 TL |
299 | p = (dhcpctl_remote_object_t *)o; |
300 | ||
301 | if (!strcmp (name, "updated")) { | |
302 | p -> waitstatus = ISC_R_SUCCESS; | |
d758ad8c TL |
303 | if (o -> inner -> type == omapi_type_generic) |
304 | omapi_generic_clear_flags (o -> inner); | |
fe4ab6d6 TL |
305 | return omapi_signal_in (o -> inner, "ready"); |
306 | } | |
307 | if (!strcmp (name, "status")) { | |
308 | p -> waitstatus = va_arg (ap, isc_result_t); | |
309 | if (p -> message) | |
4bd8800e | 310 | omapi_typed_data_dereference (&p -> message, MDL); |
fe4ab6d6 TL |
311 | tv = va_arg (ap, omapi_typed_data_t *); |
312 | if (tv) | |
4bd8800e | 313 | omapi_typed_data_reference (&p -> message, tv, MDL); |
fe4ab6d6 TL |
314 | return omapi_signal_in (o -> inner, "ready"); |
315 | } | |
316 | ||
317 | if (p -> inner && p -> inner -> type -> signal_handler) | |
318 | return (*(p -> inner -> type -> signal_handler)) | |
319 | (p -> inner, name, ap); | |
320 | ||
321 | return ISC_R_SUCCESS; | |
322 | } | |
323 | ||
4bd8800e TL |
324 | isc_result_t dhcpctl_remote_destroy (omapi_object_t *h, |
325 | const char *file, int line) | |
fe4ab6d6 TL |
326 | { |
327 | dhcpctl_remote_object_t *p; | |
328 | if (h -> type != dhcpctl_remote_type) | |
98bf1607 | 329 | return DHCP_R_INVALIDARG; |
fe4ab6d6 TL |
330 | p = (dhcpctl_remote_object_t *)h; |
331 | if (p -> handle) | |
332 | omapi_object_dereference ((omapi_object_t **)&p -> handle, | |
4bd8800e | 333 | file, line); |
98311e4b DH |
334 | if (p -> rtype) |
335 | omapi_typed_data_dereference ((omapi_typed_data_t **)&p->rtype, | |
336 | file, line); | |
fe4ab6d6 TL |
337 | return ISC_R_SUCCESS; |
338 | } | |
339 | ||
340 | /* Write all the published values associated with the object through the | |
341 | specified connection. */ | |
342 | ||
343 | isc_result_t dhcpctl_remote_stuff_values (omapi_object_t *c, | |
344 | omapi_object_t *id, | |
345 | omapi_object_t *p) | |
346 | { | |
fe4ab6d6 | 347 | if (p -> type != dhcpctl_remote_type) |
98bf1607 | 348 | return DHCP_R_INVALIDARG; |
fe4ab6d6 TL |
349 | |
350 | if (p -> inner && p -> inner -> type -> stuff_values) | |
351 | return (*(p -> inner -> type -> stuff_values)) (c, id, | |
352 | p -> inner); | |
353 | return ISC_R_SUCCESS; | |
354 | } | |
355 |