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