message.c 21.9 KB
Newer Older
Ted Lemon's avatar
Ted Lemon committed
1 2 3 4 5
/* message.c

   Subroutines for dealing with message objects. */

/*
Ted Lemon's avatar
Ted Lemon committed
6 7
 * Copyright (c) 1999-2000 Internet Software Consortium.
 * All rights reserved.
Ted Lemon's avatar
Ted Lemon committed
8
 *
Ted Lemon's avatar
Ted Lemon committed
9 10 11
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
Ted Lemon's avatar
Ted Lemon committed
12
 *
Ted Lemon's avatar
Ted Lemon committed
13 14 15 16 17 18 19 20
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of The Internet Software Consortium nor the names
 *    of its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
Ted Lemon's avatar
Ted Lemon committed
21
 *
Ted Lemon's avatar
Ted Lemon committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This software has been written for the Internet Software Consortium
 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
 * To learn more about the Internet Software Consortium, see
 * ``http://www.isc.org/''.  To learn more about Vixie Enterprises,
 * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
 * ``http://www.nominum.com''.
Ted Lemon's avatar
Ted Lemon committed
42 43
 */

44
#include <omapip/omapip_p.h>
Ted Lemon's avatar
Ted Lemon committed
45

46 47 48
OMAPI_OBJECT_ALLOC (omapi_message,
		    omapi_message_object_t, omapi_type_message)

Ted Lemon's avatar
Ted Lemon committed
49 50
omapi_message_object_t *omapi_registered_messages;

Ted Lemon's avatar
Ted Lemon committed
51
isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line)
Ted Lemon's avatar
Ted Lemon committed
52 53
{
	omapi_message_object_t *m;
54
	omapi_object_t *g;
Ted Lemon's avatar
Ted Lemon committed
55 56
	isc_result_t status;

57
	m = dmalloc (sizeof *m, file, line);
Ted Lemon's avatar
Ted Lemon committed
58 59 60 61
	if (!m)
		return ISC_R_NOMEMORY;
	memset (m, 0, sizeof *m);
	m -> type = omapi_type_message;
62
	rc_register (file, line, &m, m, m -> refcnt);
Ted Lemon's avatar
Ted Lemon committed
63 64
	m -> refcnt = 1;

65
	g = (omapi_object_t *)0;
Ted Lemon's avatar
Ted Lemon committed
66
	status = omapi_generic_new (&g, file, line);
67
	if (status != ISC_R_SUCCESS) {
68
		dfree (m, file, line);
69 70
		return status;
	}
Ted Lemon's avatar
Ted Lemon committed
71
	status = omapi_object_reference (&m -> inner, g, file, line);
72
	if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
73
		omapi_object_dereference ((omapi_object_t **)&m, file, line);
74
		omapi_object_dereference (&g, file, line);
75 76 77
		return status;
	}
	status = omapi_object_reference (&g -> outer,
Ted Lemon's avatar
Ted Lemon committed
78
					 (omapi_object_t *)m, file, line);
79 80

	if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
81
		omapi_object_dereference ((omapi_object_t **)&m, file, line);
82
		omapi_object_dereference (&g, file, line);
83 84 85
		return status;
	}

Ted Lemon's avatar
Ted Lemon committed
86 87 88
	status = omapi_object_reference (o, (omapi_object_t *)m, file, line);
	omapi_object_dereference ((omapi_object_t **)&m, file, line);
	omapi_object_dereference (&g, file, line);
89 90 91
	if (status != ISC_R_SUCCESS)
		return status;

Ted Lemon's avatar
Ted Lemon committed
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
	return status;
}

isc_result_t omapi_message_set_value (omapi_object_t *h,
				      omapi_object_t *id,
				      omapi_data_string_t *name,
				      omapi_typed_data_t *value)
{
	omapi_message_object_t *m;
	isc_result_t status;

	if (h -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
	m = (omapi_message_object_t *)h;

	/* Can't set authlen. */

	/* Can set authenticator, but the value must be typed data. */
	if (!omapi_ds_strcmp (name, "authenticator")) {
		if (m -> authenticator)
112 113 114
			omapi_typed_data_dereference (&m -> authenticator,
						      MDL);
		omapi_typed_data_reference (&m -> authenticator, value, MDL);
Ted Lemon's avatar
Ted Lemon committed
115 116
		return ISC_R_SUCCESS;

117 118 119 120
	} else if (!omapi_ds_strcmp (name, "object")) {
		if (value -> type != omapi_datatype_object)
			return ISC_R_INVALIDARG;
		if (m -> object)
121 122
			omapi_object_dereference (&m -> object, MDL);
		omapi_object_reference (&m -> object, value -> u.object, MDL);
123 124
		return ISC_R_SUCCESS;

125 126 127 128
	} else if (!omapi_ds_strcmp (name, "notify-object")) {
		if (value -> type != omapi_datatype_object)
			return ISC_R_INVALIDARG;
		if (m -> notify_object)
129
			omapi_object_dereference (&m -> notify_object, MDL);
130
		omapi_object_reference (&m -> notify_object,
Ted Lemon's avatar
Ted Lemon committed
131
					value -> u.object, MDL);
132 133
		return ISC_R_SUCCESS;

Ted Lemon's avatar
Ted Lemon committed
134 135 136 137 138
	/* Can set authid, but it has to be an integer. */
	} else if (!omapi_ds_strcmp (name, "authid")) {
		if (value -> type != omapi_datatype_int)
			return ISC_R_INVALIDARG;
		m -> authid = value -> u.integer;
139
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
140 141 142 143 144 145

	/* Can set op, but it has to be an integer. */
	} else if (!omapi_ds_strcmp (name, "op")) {
		if (value -> type != omapi_datatype_int)
			return ISC_R_INVALIDARG;
		m -> op = value -> u.integer;
146
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
147 148 149 150 151 152

	/* Handle also has to be an integer. */
	} else if (!omapi_ds_strcmp (name, "handle")) {
		if (value -> type != omapi_datatype_int)
			return ISC_R_INVALIDARG;
		m -> h = value -> u.integer;
153
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
154 155 156 157 158 159

	/* Transaction ID has to be an integer. */
	} else if (!omapi_ds_strcmp (name, "id")) {
		if (value -> type != omapi_datatype_int)
			return ISC_R_INVALIDARG;
		m -> id = value -> u.integer;
160
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
161 162 163 164 165 166

	/* Remote transaction ID has to be an integer. */
	} else if (!omapi_ds_strcmp (name, "rid")) {
		if (value -> type != omapi_datatype_int)
			return ISC_R_INVALIDARG;
		m -> rid = value -> u.integer;
167
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	}

	/* Try to find some inner object that can take the value. */
	if (h -> inner && h -> inner -> type -> set_value) {
		status = ((*(h -> inner -> type -> set_value))
			  (h -> inner, id, name, value));
		if (status == ISC_R_SUCCESS)
			return status;
	}
			  
	return ISC_R_NOTFOUND;
}

isc_result_t omapi_message_get_value (omapi_object_t *h,
				      omapi_object_t *id,
				      omapi_data_string_t *name,
				      omapi_value_t **value)
{
	omapi_message_object_t *m;
	if (h -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
	m = (omapi_message_object_t *)h;

	/* Look for values that are in the message data structure. */
	if (!omapi_ds_strcmp (name, "authlen"))
193
		return omapi_make_int_value (value, name, (int)m -> authlen,
Ted Lemon's avatar
Ted Lemon committed
194
					     MDL);
Ted Lemon's avatar
Ted Lemon committed
195 196
	else if (!omapi_ds_strcmp (name, "authenticator")) {
		if (m -> authenticator)
Ted Lemon's avatar
Ted Lemon committed
197 198
			return omapi_make_value (value, name,
						 m -> authenticator, MDL);
Ted Lemon's avatar
Ted Lemon committed
199 200 201
		else
			return ISC_R_NOTFOUND;
	} else if (!omapi_ds_strcmp (name, "authid")) {
Ted Lemon's avatar
Ted Lemon committed
202 203
		return omapi_make_int_value (value,
					     name, (int)m -> authid, MDL);
Ted Lemon's avatar
Ted Lemon committed
204
	} else if (!omapi_ds_strcmp (name, "op")) {
Ted Lemon's avatar
Ted Lemon committed
205
		return omapi_make_int_value (value, name, (int)m -> op, MDL);
Ted Lemon's avatar
Ted Lemon committed
206
	} else if (!omapi_ds_strcmp (name, "handle")) {
Ted Lemon's avatar
Ted Lemon committed
207
		return omapi_make_int_value (value, name, (int)m -> h, MDL);
Ted Lemon's avatar
Ted Lemon committed
208
	} else if (!omapi_ds_strcmp (name, "id")) {
Ted Lemon's avatar
Ted Lemon committed
209
		return omapi_make_int_value (value, name, (int)m -> id, MDL);
Ted Lemon's avatar
Ted Lemon committed
210
	} else if (!omapi_ds_strcmp (name, "rid")) {
Ted Lemon's avatar
Ted Lemon committed
211
		return omapi_make_int_value (value, name, (int)m -> rid, MDL);
Ted Lemon's avatar
Ted Lemon committed
212 213 214 215 216 217 218 219 220
	}

	/* See if there's an inner object that has the value. */
	if (h -> inner && h -> inner -> type -> get_value)
		return (*(h -> inner -> type -> get_value))
			(h -> inner, id, name, value);
	return ISC_R_NOTFOUND;
}

Ted Lemon's avatar
Ted Lemon committed
221 222
isc_result_t omapi_message_destroy (omapi_object_t *h,
				    const char *file, int line)
Ted Lemon's avatar
Ted Lemon committed
223 224 225 226 227 228
{
	int i;

	omapi_message_object_t *m;
	if (h -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
229
	m = (omapi_message_object_t *)h;
Ted Lemon's avatar
Ted Lemon committed
230
	if (m -> authenticator) {
Ted Lemon's avatar
Ted Lemon committed
231
		omapi_typed_data_dereference (&m -> authenticator, file, line);
Ted Lemon's avatar
Ted Lemon committed
232 233 234 235 236
	}
	if (!m -> prev && omapi_registered_messages != m)
		omapi_message_unregister (h);
	if (m -> id_object)
		omapi_object_dereference ((omapi_object_t **)&m -> id_object,
Ted Lemon's avatar
Ted Lemon committed
237
					  file, line);
Ted Lemon's avatar
Ted Lemon committed
238 239
	if (m -> object)
		omapi_object_dereference ((omapi_object_t **)&m -> object,
Ted Lemon's avatar
Ted Lemon committed
240
					  file, line);
Ted Lemon's avatar
Ted Lemon committed
241 242 243 244
	return ISC_R_SUCCESS;
}

isc_result_t omapi_message_signal_handler (omapi_object_t *h,
245
					   const char *name, va_list ap)
Ted Lemon's avatar
Ted Lemon committed
246
{
Ted Lemon's avatar
Ted Lemon committed
247
	omapi_message_object_t *m;
Ted Lemon's avatar
Ted Lemon committed
248 249
	if (h -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
Ted Lemon's avatar
Ted Lemon committed
250
	m = (omapi_message_object_t *)h;
Ted Lemon's avatar
Ted Lemon committed
251
	
252 253 254
	if (!strcmp (name, "status")) {
		if (m -> notify_object &&
		    m -> notify_object -> type -> signal_handler)
255 256
			return ((m -> notify_object -> type -> signal_handler))
				(m -> notify_object, name, ap);
257 258 259
		else if (m -> object && m -> object -> type -> signal_handler)
			return ((m -> object -> type -> signal_handler))
				(m -> object, name, ap);
Ted Lemon's avatar
Ted Lemon committed
260
	}
Ted Lemon's avatar
Ted Lemon committed
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
	if (h -> inner && h -> inner -> type -> signal_handler)
		return (*(h -> inner -> type -> signal_handler)) (h -> inner,
								  name, ap);
	return ISC_R_NOTFOUND;
}

/* Write all the published values associated with the object through the
   specified connection. */

isc_result_t omapi_message_stuff_values (omapi_object_t *c,
					 omapi_object_t *id,
					 omapi_object_t *m)
{
	int i;

	if (m -> type != omapi_type_message)
		return ISC_R_INVALIDARG;

	if (m -> inner && m -> inner -> type -> stuff_values)
		return (*(m -> inner -> type -> stuff_values)) (c, id,
								m -> inner);
	return ISC_R_SUCCESS;
}

isc_result_t omapi_message_register (omapi_object_t *mo)
{
	omapi_message_object_t *m;

	if (mo -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
	m = (omapi_message_object_t *)mo;
	
	/* Already registered? */
	if (m -> prev || m -> next || omapi_registered_messages == m)
		return ISC_R_INVALIDARG;

	if (omapi_registered_messages) {
		omapi_object_reference
			((omapi_object_t **)&m -> next,
300
			 (omapi_object_t *)omapi_registered_messages, MDL);
Ted Lemon's avatar
Ted Lemon committed
301 302
		omapi_object_reference
			((omapi_object_t **)&omapi_registered_messages -> prev,
303
			 (omapi_object_t *)m, MDL);
Ted Lemon's avatar
Ted Lemon committed
304
		omapi_object_dereference
305
			((omapi_object_t **)&omapi_registered_messages, MDL);
Ted Lemon's avatar
Ted Lemon committed
306 307 308
	}
	omapi_object_reference
		((omapi_object_t **)&omapi_registered_messages,
309
		 (omapi_object_t *)m, MDL);
Ted Lemon's avatar
Ted Lemon committed
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
	return ISC_R_SUCCESS;;
}

isc_result_t omapi_message_unregister (omapi_object_t *mo)
{
	omapi_message_object_t *m;
	omapi_message_object_t *n;

	if (mo -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
	m = (omapi_message_object_t *)mo;
	
	/* Not registered? */
	if (!m -> prev && omapi_registered_messages != m)
		return ISC_R_INVALIDARG;

	n = (omapi_message_object_t *)0;
	if (m -> next) {
		omapi_object_reference ((omapi_object_t **)&n,
Ted Lemon's avatar
Ted Lemon committed
329 330
					(omapi_object_t *)m -> next, MDL);
		omapi_object_dereference ((omapi_object_t **)&m -> next, MDL);
Ted Lemon's avatar
Ted Lemon committed
331 332 333 334
	}
	if (m -> prev) {
		omapi_message_object_t *tmp = (omapi_message_object_t *)0;
		omapi_object_reference ((omapi_object_t **)&tmp,
Ted Lemon's avatar
Ted Lemon committed
335 336
					(omapi_object_t *)m -> prev, MDL);
		omapi_object_dereference ((omapi_object_t **)&m -> prev, MDL);
Ted Lemon's avatar
Ted Lemon committed
337 338
		if (tmp -> next)
			omapi_object_dereference
Ted Lemon's avatar
Ted Lemon committed
339
				((omapi_object_t **)&tmp -> next, MDL);
Ted Lemon's avatar
Ted Lemon committed
340 341 342
		if (n)
			omapi_object_reference
				((omapi_object_t **)&tmp -> next,
Ted Lemon's avatar
Ted Lemon committed
343 344
				 (omapi_object_t *)n, MDL);
		omapi_object_dereference ((omapi_object_t **)&tmp, MDL);
Ted Lemon's avatar
Ted Lemon committed
345 346
	} else {
		omapi_object_dereference
Ted Lemon's avatar
Ted Lemon committed
347
			((omapi_object_t **)&omapi_registered_messages, MDL);
Ted Lemon's avatar
Ted Lemon committed
348 349 350
		if (n)
			omapi_object_reference
				((omapi_object_t **)&omapi_registered_messages,
Ted Lemon's avatar
Ted Lemon committed
351
				 (omapi_object_t *)n, MDL);
Ted Lemon's avatar
Ted Lemon committed
352 353
	}
	if (n)
Ted Lemon's avatar
Ted Lemon committed
354
		omapi_object_dereference ((omapi_object_t **)&n, MDL);
Ted Lemon's avatar
Ted Lemon committed
355 356
	return ISC_R_SUCCESS;
}
357 358 359 360 361

isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
{
	omapi_message_object_t *message, *m;
	omapi_object_t *object = (omapi_object_t *)0;
Ted Lemon's avatar
Ted Lemon committed
362
	omapi_value_t *tv = (omapi_value_t *)0;
363 364
	unsigned long create, update, exclusive;
	unsigned long wsi;
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
	isc_result_t status, waitstatus;
	omapi_object_type_t *type;

	if (mo -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
	message = (omapi_message_object_t *)mo;

	if (message -> rid) {
		for (m = omapi_registered_messages; m; m = m -> next)
			if (m -> id == message -> rid)
				break;
		/* If we don't have a real message corresponding to
		   the message ID to which this message claims it is a
		   response, something's fishy. */
		if (!m)
			return ISC_R_NOTFOUND;
381 382 383 384 385
		/* The authenticator on responses must match the initial
		   message. */
		if (message -> authid != m -> authid)
			return ISC_R_NOTFOUND;
	} else {
Ted Lemon's avatar
Ted Lemon committed
386
		m = (omapi_message_object_t *)0;
387

388 389 390 391 392 393 394 395 396 397 398
		/* All messages must have an authenticator, with the exception
		   of messages that are opening a new authenticator. */
		if (omapi_protocol_authenticated (po) &&
		    !message -> id_object &&
		    message -> op != OMAPI_OP_OPEN) {
			return omapi_protocol_send_status
				(po, message -> id_object, ISC_R_NOKEYS,
				 message -> id, "No authenticator on message");
		}
	}

399 400 401
	switch (message -> op) {
	      case OMAPI_OP_OPEN:
		if (m) {
Ted Lemon's avatar
Ted Lemon committed
402
			return omapi_protocol_send_status
403
				(po, message -> id_object, ISC_R_INVALIDARG,
Ted Lemon's avatar
Ted Lemon committed
404
				 message -> id, "OPEN can't be a response");
405 406 407 408
		}

		/* Get the type of the requested object, if one was
		   specified. */
409
		status = omapi_get_value_str (mo, message -> id_object,
410 411 412 413 414 415 416 417 418 419 420 421
					      "type", &tv);
		if (status == ISC_R_SUCCESS &&
		    (tv -> value -> type == omapi_datatype_data ||
		     tv -> value -> type == omapi_datatype_string)) {
			for (type = omapi_object_types;
			     type; type = type -> next)
				if (!omapi_td_strcmp (tv -> value,
						      type -> name))
					break;
		} else
			type = (omapi_object_type_t *)0;
		if (tv)
Ted Lemon's avatar
Ted Lemon committed
422
			omapi_value_dereference (&tv, MDL);
423

424 425 426 427 428 429 430 431 432 433
		/* If this object had no authenticator, the requested object
		   must be an authenticator object. */
		if (omapi_protocol_authenticated (po) &&
		    !message -> id_object &&
		    type != omapi_type_auth_key) {
			return omapi_protocol_send_status
				(po, message -> id_object, ISC_R_NOKEYS,
				 message -> id, "No authenticator on message");
		}

434
		/* Get the create flag. */
435
		status = omapi_get_value_str (mo, message -> id_object,
436 437
					      "create", &tv);
		if (status == ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
438
			status = omapi_get_int_value (&create, tv -> value);
Ted Lemon's avatar
Ted Lemon committed
439
			omapi_value_dereference (&tv, MDL);
440
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
441
				return omapi_protocol_send_status
442
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
443
					 status, message -> id,
444 445 446 447 448 449
					 "invalid create flag value");
			}
		} else
			create = 0;

		/* Get the update flag. */
450
		status = omapi_get_value_str (mo, message -> id_object,
451 452
					      "update", &tv);
		if (status == ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
453
			status = omapi_get_int_value (&update, tv -> value);
Ted Lemon's avatar
Ted Lemon committed
454
			omapi_value_dereference (&tv, MDL);
455
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
456
				return omapi_protocol_send_status
457
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
458
					 status, message -> id,
459 460 461 462 463 464
					 "invalid update flag value");
			}
		} else
			update = 0;

		/* Get the exclusive flag. */
465
		status = omapi_get_value_str (mo, message -> id_object,
466 467
					      "exclusive", &tv);
		if (status == ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
468
			status = omapi_get_int_value (&exclusive, tv -> value);
Ted Lemon's avatar
Ted Lemon committed
469
			omapi_value_dereference (&tv, MDL);
470
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
471
				return omapi_protocol_send_status
472
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
473
					 status, message -> id,
474 475 476 477 478 479 480 481 482
					 "invalid exclusive flag value");
			}
		} else
			exclusive = 0;

		/* If we weren't given a type, look the object up with
                   the handle. */
		if (!type) {
			if (create) {
Ted Lemon's avatar
Ted Lemon committed
483
				return omapi_protocol_send_status
484 485 486
					(po, message -> id_object,
					 ISC_R_INVALIDARG,
					 message -> id,
487 488 489 490 491 492 493 494
					 "type required on create");
			}
			goto refresh;
		}

		/* If the type doesn't provide a lookup method, we can't
		   look up the object. */
		if (!type -> lookup) {
Ted Lemon's avatar
Ted Lemon committed
495
			return omapi_protocol_send_status
496
				(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
497
				 ISC_R_NOTIMPLEMENTED, message -> id,
498 499
				 "unsearchable object type");
		}
500 501 502

		if (!message -> object) {
			return omapi_protocol_send_status
503
				(po, message -> id_object,
504 505 506
				 ISC_R_NOTFOUND, message -> id,
				 "no lookup key specified");
		}
507
		status = (*(type -> lookup)) (&object, message -> id_object,
508 509
					      message -> object);

510 511 512
		if (status != ISC_R_SUCCESS &&
		    status != ISC_R_NOTFOUND &&
		    status != ISC_R_NOKEYS) {
Ted Lemon's avatar
Ted Lemon committed
513
			return omapi_protocol_send_status
514
				(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
515
				 status, message -> id,
516 517 518 519 520 521
				 "object lookup failed");
		}

		/* If we didn't find the object and we aren't supposed to
		   create it, return an error. */
		if (status == ISC_R_NOTFOUND && !create) {
Ted Lemon's avatar
Ted Lemon committed
522
			return omapi_protocol_send_status
523
				(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
524
				 ISC_R_NOTFOUND, message -> id,
525 526 527 528 529 530 531
				 "no object matches specification");
		}			

		/* If we found an object, we're supposed to be creating an
		   object, and we're not supposed to have found an object,
		   return an error. */
		if (status == ISC_R_SUCCESS && create && exclusive) {
Ted Lemon's avatar
Ted Lemon committed
532
			omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
533
			return omapi_protocol_send_status
534
				(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
535
				 ISC_R_EXISTS, message -> id,
536 537 538 539 540
				 "specified object already exists");
		}

		/* If we're creating the object, do it now. */
		if (!object) {
Ted Lemon's avatar
Ted Lemon committed
541
			status = omapi_object_create (&object,
542
						      message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
543
						      type);
544
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
545
				return omapi_protocol_send_status
546
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
547
					 status, message -> id,
548 549 550 551 552 553
					 "can't create new object");
			}
		}

		/* If we're updating it, do so now. */
		if (create || update) {
554 555 556 557 558 559 560 561 562
			/* This check does not belong here. */
			if (object -> type == omapi_type_auth_key) {
				omapi_object_dereference (&object, MDL);
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "can't update object");
			}

563
			status = omapi_object_update (object,
564
						      message -> id_object,
565
						      message -> object,
Ted Lemon's avatar
Ted Lemon committed
566
						      message -> h);
567
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
568
				omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
569
				return omapi_protocol_send_status
570
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
571
					 status, message -> id,
572 573 574
					 "can't update object");
			}
		}
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597

		/* If this is an authenticator object, add it to the active
		   set for the connection. */
		if (object -> type == omapi_type_auth_key) {
			omapi_handle_t handle;
			status = omapi_object_handle (&handle, object);
			if (status != ISC_R_SUCCESS) {
				omapi_object_dereference (&object, MDL);
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "can't select authenticator");
			}

			status = omapi_protocol_add_auth (po, object, handle);
			if (status != ISC_R_SUCCESS) {
				omapi_object_dereference (&object, MDL);
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "can't select authenticator");
			}
		}
598 599 600 601 602 603 604
		
		/* Now send the new contents of the object back in
		   response. */
		goto send;

	      case OMAPI_OP_REFRESH:
	      refresh:
Ted Lemon's avatar
Ted Lemon committed
605
		status = omapi_handle_lookup (&object, message -> h);
606
		if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
607
			return omapi_protocol_send_status
608
				(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
609
				 status, message -> id,
610 611 612
				 "no matching handle");
		}
	      send:		
613
		status = omapi_protocol_send_update (po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
614
						     message -> id, object);
Ted Lemon's avatar
Ted Lemon committed
615
		omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
616
		return status;
617 618

	      case OMAPI_OP_UPDATE:
619
		if (m && m -> object) {
Ted Lemon's avatar
Ted Lemon committed
620
			omapi_object_reference (&object, m -> object, MDL);
621
		} else {
Ted Lemon's avatar
Ted Lemon committed
622
			status = omapi_handle_lookup (&object, message -> h);
623
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
624
				return omapi_protocol_send_status
625
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
626
					 status, message -> id,
627 628 629 630
					 "no matching handle");
			}
		}

631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649
		if (object -> type == omapi_type_auth_key ||
		    (object -> inner &&
		     object -> inner -> type == omapi_type_auth_key)) {
			if (!m) {
				omapi_object_dereference (&object, MDL);
				return omapi_protocol_send_status
					(po, message -> id_object,
					 status, message -> id,
					 "cannot update authenticator");
			}
			
			status = omapi_protocol_add_auth (po, object,
							  message -> h);
		} else {
			status = omapi_object_update (object,
						      message -> id_object,
						      message -> object,
						      message -> h);
		}
650
		if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
651
			omapi_object_dereference (&object, MDL);
652
			if (!message -> rid)
Ted Lemon's avatar
Ted Lemon committed
653
				return omapi_protocol_send_status
654
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
655
					 status, message -> id,
656 657 658
					 "can't update object");
			if (m)
				omapi_signal ((omapi_object_t *)m,
Ted Lemon's avatar
Ted Lemon committed
659 660
					      "status", status,
					      (omapi_typed_data_t *)0);
661 662 663
			return ISC_R_SUCCESS;
		}
		if (!message -> rid)
Ted Lemon's avatar
Ted Lemon committed
664
			status = omapi_protocol_send_status
665
				(po, message -> id_object, ISC_R_SUCCESS,
Ted Lemon's avatar
Ted Lemon committed
666
				 message -> id, (char *)0);
667 668
		if (m)
			omapi_signal ((omapi_object_t *)m,
Ted Lemon's avatar
Ted Lemon committed
669 670 671
				      "status", ISC_R_SUCCESS,
				      (omapi_typed_data_t *)0);
		return status;
672 673

	      case OMAPI_OP_NOTIFY:
Ted Lemon's avatar
Ted Lemon committed
674
		return omapi_protocol_send_status
675
			(po, message -> id_object, ISC_R_NOTIMPLEMENTED,
Ted Lemon's avatar
Ted Lemon committed
676
			 message -> id, "notify not implemented yet");
677

Ted Lemon's avatar
Ted Lemon committed
678 679
	      case OMAPI_OP_STATUS:
		/* The return status of a request. */
680 681 682 683
		if (!m)
			return ISC_R_UNEXPECTED;

		/* Get the wait status. */
684
		status = omapi_get_value_str (mo, message -> id_object,
685 686
					      "result", &tv);
		if (status == ISC_R_SUCCESS) {
687 688
			status = omapi_get_int_value (&wsi, tv -> value);
			waitstatus = wsi;
Ted Lemon's avatar
Ted Lemon committed
689
			omapi_value_dereference (&tv, MDL);
690 691 692 693 694
			if (status != ISC_R_SUCCESS)
				waitstatus = ISC_R_UNEXPECTED;
		} else
			waitstatus = ISC_R_UNEXPECTED;

695
		status = omapi_get_value_str (mo, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
696 697 698
					      "message", &tv);
		omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv);
		if (status == ISC_R_SUCCESS)
Ted Lemon's avatar
Ted Lemon committed
699
			omapi_value_dereference (&tv, MDL);
700
		return ISC_R_SUCCESS;
701 702

	      case OMAPI_OP_DELETE:
Ted Lemon's avatar
Ted Lemon committed
703
		status = omapi_handle_lookup (&object, message -> h);
704 705
		if (status != ISC_R_SUCCESS) {
			return omapi_protocol_send_status
706
				(po, message -> id_object,
707 708 709 710
				 status, message -> id,
				 "no matching handle");
		}

711
		if (!object -> type -> remove)
712
			return omapi_protocol_send_status
713
				(po, message -> id_object,
714
				 ISC_R_NOTIMPLEMENTED, message -> id,
715
				 "no remove method for object");
716

717
		status = (*(object -> type -> remove)) (object,
718
							message -> id_object);
Ted Lemon's avatar
Ted Lemon committed
719
		omapi_object_dereference (&object, MDL);
720

721
		return omapi_protocol_send_status (po, message -> id_object,
722 723
						   status, message -> id,
						   (char *)0);
724 725 726
	}
	return ISC_R_NOTIMPLEMENTED;
}