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