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