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