Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / contrib / isc-dhcp / dhcpctl / remote.c
1 /* remote.c
2
3    The dhcpctl remote object. */
4
5 /*
6  * Copyright (c) 1999-2003 Internet Software Consortium.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of The Internet Software Consortium nor the names
19  *    of its contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * This software has been written for the Internet Software Consortium
37  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
38  * To learn more about the Internet Software Consortium, see
39  * ``http://www.isc.org/''.  To learn more about Vixie Enterprises,
40  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
41  * ``http://www.nominum.com''.
42  */
43
44 #include <omapip/omapip_p.h>
45 #include "dhcpctl.h"
46
47 /* dhcpctl_new_authenticator
48
49    synchronous - creates an authenticator object.
50    returns nonzero status code if the object couldn't be created
51    stores handle to authenticator through h if successful, and returns zero.
52    name is the authenticator name (NUL-terminated string).
53    algorithm is the NUL-terminated string name of the algorithm to use
54    (currently, only "hmac-md5" is supported).
55    secret and secret_len is the key secret. */
56
57 dhcpctl_status dhcpctl_new_authenticator (dhcpctl_handle *h,
58                                           const char *name,
59                                           const char *algorithm,
60                                           const unsigned char *secret,
61                                           unsigned secret_len)
62 {
63         struct auth_key *key = (struct auth_key *)0;
64         isc_result_t status;
65
66         status = omapi_auth_key_new (&key, MDL);
67         if (status != ISC_R_SUCCESS)
68                 return status;
69
70         key -> name = dmalloc (strlen (name) + 1, MDL);
71         if (!key -> name) {
72                 omapi_auth_key_dereference (&key, MDL);
73                 return ISC_R_NOMEMORY;
74         }
75         strcpy (key -> name, name);
76
77         /* If the algorithm name isn't an FQDN, tack on the
78            .SIG-ALG.REG.NET. domain. */
79         if (strchr (algorithm, '.') == 0) {
80                 static char add[] = ".SIG-ALG.REG.INT.";
81                 key -> algorithm = dmalloc (strlen (algorithm) +
82                                             sizeof (add), MDL);
83                 if (!key -> algorithm) {
84                         omapi_auth_key_dereference (&key, MDL);
85                         return ISC_R_NOMEMORY;
86                 }
87                 strcpy (key -> algorithm, algorithm);
88                 strcat (key -> algorithm, add);
89         } else {
90                 key -> algorithm = dmalloc (strlen (algorithm) + 1, MDL);
91                 if (!key -> algorithm) {
92                         omapi_auth_key_dereference (&key, MDL);
93                         return ISC_R_NOMEMORY;
94                 }
95                 strcpy (key -> algorithm, algorithm);
96         }
97
98         status = omapi_data_string_new (&key -> key, secret_len, MDL);
99         if (status != ISC_R_SUCCESS) {
100                 omapi_auth_key_dereference (&key, MDL);
101                 return status;
102         }
103         memcpy (key -> key -> value, secret, secret_len);
104         key -> key -> len = secret_len;
105
106         *h = (dhcpctl_handle) key;
107         return ISC_R_SUCCESS;
108 }
109
110
111 /* dhcpctl_new_object
112
113    synchronous - creates a local handle for a host entry.
114    returns nonzero status code if the local host entry couldn't
115    be created
116    stores handle to host through h if successful, and returns zero.
117    object_type is a pointer to a NUL-terminated string containing
118    the ascii name of the type of object being accessed - e.g., "host" */
119
120 dhcpctl_status dhcpctl_new_object (dhcpctl_handle *h,
121                                    dhcpctl_handle connection,
122                                    const char *object_type)
123 {
124         dhcpctl_remote_object_t *m;
125         omapi_object_t *g;
126         isc_result_t status;
127
128         m = (dhcpctl_remote_object_t *)0;
129         status = omapi_object_allocate ((omapi_object_t **)&m,
130                                         dhcpctl_remote_type, 0, MDL);
131         if (status != ISC_R_SUCCESS)
132                 return status;
133
134         g = (omapi_object_t *)0;
135         status = omapi_generic_new (&g, MDL);
136         if (status != ISC_R_SUCCESS) {
137                 dfree (m, MDL);
138                 return status;
139         }
140         status = omapi_object_reference (&m -> inner, g, MDL);
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         status = omapi_object_reference (&g -> outer,
147                                          (omapi_object_t *)m, MDL);
148
149         if (status != ISC_R_SUCCESS) {
150                 omapi_object_dereference ((omapi_object_t **)&m, MDL);
151                 omapi_object_dereference (&g, MDL);
152                 return status;
153         }
154
155         status = omapi_typed_data_new (MDL, &m -> rtype,
156                                        omapi_datatype_string,
157                                        object_type);
158         if (status != ISC_R_SUCCESS) {
159                 omapi_object_dereference ((omapi_object_t **)&m, MDL);
160                 omapi_object_dereference (&g, MDL);
161                 return status;
162         }
163
164         status = omapi_object_reference (h, (omapi_object_t *)m, MDL);
165         omapi_object_dereference ((omapi_object_t **)&m, MDL);
166         omapi_object_dereference (&g, MDL);
167         if (status != ISC_R_SUCCESS)
168                 return status;
169
170         return status;
171 }
172
173 /* asynchronous - just queues the request
174    returns nonzero status code if open couldn't be queued
175    returns zero if open was queued
176    h is a handle to an object created by dhcpctl_new_object
177    connection is a connection to a DHCP server
178    flags include:
179      DHCPCTL_CREATE - if the object doesn't exist, create it
180      DHCPCTL_UPDATE - update the object on the server using the
181                       attached parameters 
182      DHCPCTL_EXCL - error if the object exists and DHCPCTL_CREATE
183                       was also specified */
184
185 dhcpctl_status dhcpctl_open_object (dhcpctl_handle h,
186                                     dhcpctl_handle connection,
187                                     int flags)
188 {
189         isc_result_t status;
190         omapi_object_t *message = (omapi_object_t *)0;
191         dhcpctl_remote_object_t *remote;
192
193         if (h -> type != dhcpctl_remote_type)
194                 return ISC_R_INVALIDARG;
195         remote = (dhcpctl_remote_object_t *)h;
196
197         status = omapi_message_new (&message, MDL);
198         if (status != ISC_R_SUCCESS)
199                 return status;
200         status = omapi_set_int_value (message, (omapi_object_t *)0,
201                                       "op", OMAPI_OP_OPEN);
202         if (status != ISC_R_SUCCESS) {
203                 omapi_object_dereference (&message, MDL);
204                 return status;
205         }
206         status = omapi_set_object_value (message, (omapi_object_t *)0,
207                                          "object", h);
208         if (status != ISC_R_SUCCESS) {
209                 omapi_object_dereference (&message, MDL);
210                 return status;
211         }
212         if (flags & DHCPCTL_CREATE) {
213                 status = omapi_set_boolean_value (message, (omapi_object_t *)0,
214                                                   "create", 1);
215                 if (status != ISC_R_SUCCESS) {
216                         omapi_object_dereference (&message, MDL);
217                         return status;
218                 }
219         }
220         if (flags & DHCPCTL_UPDATE) {
221                 status = omapi_set_boolean_value (message, (omapi_object_t *)0,
222                                                   "update", 1);
223                 if (status != ISC_R_SUCCESS) {
224                         omapi_object_dereference (&message, MDL);
225                         return status;
226                 }
227         }
228         if (flags & DHCPCTL_EXCL) {
229                 status = omapi_set_boolean_value (message, (omapi_object_t *)0,
230                                                   "exclusive", 1);
231                 if (status != ISC_R_SUCCESS) {
232                         omapi_object_dereference (&message, MDL);
233                         return status;
234                 }
235         }
236
237         if (remote -> rtype) {
238                 status = omapi_set_value_str (message, (omapi_object_t *)0,
239                                               "type", remote -> rtype);
240                 if (status != ISC_R_SUCCESS) {
241                         omapi_object_dereference (&message, MDL);
242                         return status;
243                 }
244         }
245
246         status = omapi_message_register (message);
247         if (status != ISC_R_SUCCESS) {
248                 omapi_object_dereference (&message, MDL);
249                 return status;
250         }
251
252         status = omapi_protocol_send_message (connection -> outer,
253                                             (omapi_object_t *)0,
254                                             message, (omapi_object_t *)0);
255
256         if (status != ISC_R_SUCCESS)
257                 omapi_message_unregister (message);
258
259         omapi_object_dereference (&message, MDL);
260         return status;
261 }
262
263 /* Callback methods (not meant to be called directly) */
264
265 isc_result_t dhcpctl_remote_set_value (omapi_object_t *h,
266                                        omapi_object_t *id,
267                                        omapi_data_string_t *name,
268                                        omapi_typed_data_t *value)
269 {
270         dhcpctl_remote_object_t *ro;
271         unsigned long rh;
272         isc_result_t status;
273
274         if (h -> type != dhcpctl_remote_type)
275                 return ISC_R_INVALIDARG;
276         ro = (dhcpctl_remote_object_t *)h;
277
278         if (!omapi_ds_strcmp (name, "remote-handle")) {
279                 status = omapi_get_int_value (&rh, value);
280                 if (status == ISC_R_SUCCESS)
281                         ro -> remote_handle = rh;
282                 return status;
283         }
284
285         if (h -> inner && h -> inner -> type -> set_value)
286                 return (*(h -> inner -> type -> set_value))
287                         (h -> inner, id, name, value);
288         return ISC_R_NOTFOUND;
289 }
290
291 isc_result_t dhcpctl_remote_get_value (omapi_object_t *h,
292                                        omapi_object_t *id,
293                                        omapi_data_string_t *name,
294                                        omapi_value_t **value)
295 {
296         if (h -> type != dhcpctl_remote_type)
297                 return ISC_R_INVALIDARG;
298         
299         if (h -> inner && h -> inner -> type -> get_value)
300                 return (*(h -> inner -> type -> get_value))
301                         (h -> inner, id, name, value);
302         return ISC_R_NOTFOUND;
303 }
304
305 isc_result_t dhcpctl_remote_signal_handler (omapi_object_t *o,
306                                             const char *name, va_list ap)
307 {
308         dhcpctl_remote_object_t *p;
309         omapi_typed_data_t *tv;
310
311         if (o -> type != dhcpctl_remote_type)
312                 return ISC_R_INVALIDARG;
313         p = (dhcpctl_remote_object_t *)o;
314
315         if (!strcmp (name, "updated")) {
316                 p -> waitstatus = ISC_R_SUCCESS;
317                 if (o -> inner -> type == omapi_type_generic)
318                         omapi_generic_clear_flags (o -> inner);
319                 return omapi_signal_in (o -> inner, "ready");
320         }
321         if (!strcmp (name, "status")) {
322                 p -> waitstatus = va_arg (ap, isc_result_t);
323                 if (p -> message)
324                         omapi_typed_data_dereference (&p -> message, MDL);
325                 tv = va_arg (ap, omapi_typed_data_t *);
326                 if (tv)
327                         omapi_typed_data_reference (&p -> message, tv, MDL);
328                 return omapi_signal_in (o -> inner, "ready");
329         }
330
331         if (p -> inner && p -> inner -> type -> signal_handler)
332                 return (*(p -> inner -> type -> signal_handler))
333                         (p -> inner, name, ap);
334
335         return ISC_R_SUCCESS;
336 }
337
338 isc_result_t dhcpctl_remote_destroy (omapi_object_t *h,
339                                      const char *file, int line)
340 {
341         dhcpctl_remote_object_t *p;
342         if (h -> type != dhcpctl_remote_type)
343                 return ISC_R_INVALIDARG;
344         p = (dhcpctl_remote_object_t *)h;
345         if (p -> handle)
346                 omapi_object_dereference ((omapi_object_t **)&p -> handle,
347                                           file, line);
348         if (p -> rtype)
349                 omapi_typed_data_dereference ((omapi_typed_data_t **)&p->rtype,
350                                               file, line);
351         return ISC_R_SUCCESS;
352 }
353
354 /* Write all the published values associated with the object through the
355    specified connection. */
356
357 isc_result_t dhcpctl_remote_stuff_values (omapi_object_t *c,
358                                           omapi_object_t *id,
359                                           omapi_object_t *p)
360 {
361         int i;
362
363         if (p -> type != dhcpctl_remote_type)
364                 return ISC_R_INVALIDARG;
365
366         if (p -> inner && p -> inner -> type -> stuff_values)
367                 return (*(p -> inner -> type -> stuff_values)) (c, id,
368                                                                 p -> inner);
369         return ISC_R_SUCCESS;
370 }
371