message.c 22.6 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 362 363 364 365 366 367 368 369 370 371
#ifdef DEBUG_PROTOCOL
static const char *omapi_message_op_name(int op) {
	switch (op) {
	case OMAPI_OP_OPEN:    return "OMAPI_OP_OPEN";
	case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH";
	case OMAPI_OP_UPDATE:  return "OMAPI_OP_UPDATE";
	case OMAPI_OP_STATUS:  return "OMAPI_OP_STATUS";
	case OMAPI_OP_DELETE:  return "OMAPI_OP_DELETE";
	case OMAPI_OP_NOTIFY:  return "OMAPI_OP_NOTIFY";
	default:               return "(unknown op)";
	}
}
#endif

372 373 374 375
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
376
	omapi_value_t *tv = (omapi_value_t *)0;
377 378
	unsigned long create, update, exclusive;
	unsigned long wsi;
379 380 381 382 383 384 385
	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;

386 387 388 389 390 391 392
#ifdef DEBUG_PROTOCOL
	log_debug ("omapi_message_process(): "
		   "op=%s  handle=%#x  id=%#x  rid=%#x",
		   omapi_message_op_name (message -> op),
		   message -> h, message -> id, message -> rid);
#endif

393 394 395 396 397 398 399 400 401
	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;
402 403 404 405 406
		/* 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
407
		m = (omapi_message_object_t *)0;
408

409 410 411 412 413 414 415 416 417 418 419
		/* 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");
		}
	}

420 421 422
	switch (message -> op) {
	      case OMAPI_OP_OPEN:
		if (m) {
Ted Lemon's avatar
Ted Lemon committed
423
			return omapi_protocol_send_status
424
				(po, message -> id_object, ISC_R_INVALIDARG,
Ted Lemon's avatar
Ted Lemon committed
425
				 message -> id, "OPEN can't be a response");
426 427 428 429
		}

		/* Get the type of the requested object, if one was
		   specified. */
430
		status = omapi_get_value_str (mo, message -> id_object,
431 432 433 434 435 436 437 438 439 440 441 442
					      "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
443
			omapi_value_dereference (&tv, MDL);
444

445 446 447 448 449 450 451 452 453 454
		/* 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");
		}

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

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

		/* Get the exclusive flag. */
486
		status = omapi_get_value_str (mo, message -> id_object,
487 488
					      "exclusive", &tv);
		if (status == ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
489
			status = omapi_get_int_value (&exclusive, tv -> value);
Ted Lemon's avatar
Ted Lemon committed
490
			omapi_value_dereference (&tv, MDL);
491
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
492
				return omapi_protocol_send_status
493
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
494
					 status, message -> id,
495 496 497 498 499 500 501 502 503
					 "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
504
				return omapi_protocol_send_status
505 506 507
					(po, message -> id_object,
					 ISC_R_INVALIDARG,
					 message -> id,
508 509 510 511 512 513 514 515
					 "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
516
			return omapi_protocol_send_status
517
				(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
518
				 ISC_R_NOTIMPLEMENTED, message -> id,
519 520
				 "unsearchable object type");
		}
521 522 523

		if (!message -> object) {
			return omapi_protocol_send_status
524
				(po, message -> id_object,
525 526 527
				 ISC_R_NOTFOUND, message -> id,
				 "no lookup key specified");
		}
528
		status = (*(type -> lookup)) (&object, message -> id_object,
529 530
					      message -> object);

531 532 533
		if (status != ISC_R_SUCCESS &&
		    status != ISC_R_NOTFOUND &&
		    status != ISC_R_NOKEYS) {
Ted Lemon's avatar
Ted Lemon committed
534
			return omapi_protocol_send_status
535
				(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
536
				 status, message -> id,
537 538 539 540 541 542
				 "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
543
			return omapi_protocol_send_status
544
				(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
545
				 ISC_R_NOTFOUND, message -> id,
546 547 548 549 550 551 552
				 "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
553
			omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
554
			return omapi_protocol_send_status
555
				(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
556
				 ISC_R_EXISTS, message -> id,
557 558 559 560 561
				 "specified object already exists");
		}

		/* If we're creating the object, do it now. */
		if (!object) {
Ted Lemon's avatar
Ted Lemon committed
562
			status = omapi_object_create (&object,
563
						      message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
564
						      type);
565
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
566
				return omapi_protocol_send_status
567
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
568
					 status, message -> id,
569 570 571 572 573 574
					 "can't create new object");
			}
		}

		/* If we're updating it, do so now. */
		if (create || update) {
575 576 577 578 579 580 581 582 583
			/* 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");
			}

584
			status = omapi_object_update (object,
585
						      message -> id_object,
586
						      message -> object,
Ted Lemon's avatar
Ted Lemon committed
587
						      message -> h);
588
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
589
				omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
590
				return omapi_protocol_send_status
591
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
592
					 status, message -> id,
593 594 595
					 "can't update object");
			}
		}
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618

		/* 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");
			}
		}
619 620 621 622 623 624 625
		
		/* 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
626
		status = omapi_handle_lookup (&object, message -> h);
627
		if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
628
			return omapi_protocol_send_status
629
				(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
630
				 status, message -> id,
631 632 633
				 "no matching handle");
		}
	      send:		
634
		status = omapi_protocol_send_update (po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
635
						     message -> id, object);
Ted Lemon's avatar
Ted Lemon committed
636
		omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
637
		return status;
638 639

	      case OMAPI_OP_UPDATE:
640
		if (m && m -> object) {
Ted Lemon's avatar
Ted Lemon committed
641
			omapi_object_reference (&object, m -> object, MDL);
642
		} else {
Ted Lemon's avatar
Ted Lemon committed
643
			status = omapi_handle_lookup (&object, message -> h);
644
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
645
				return omapi_protocol_send_status
646
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
647
					 status, message -> id,
648 649 650 651
					 "no matching handle");
			}
		}

652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
		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);
		}
671
		if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
672
			omapi_object_dereference (&object, MDL);
673
			if (!message -> rid)
Ted Lemon's avatar
Ted Lemon committed
674
				return omapi_protocol_send_status
675
					(po, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
676
					 status, message -> id,
677 678 679
					 "can't update object");
			if (m)
				omapi_signal ((omapi_object_t *)m,
Ted Lemon's avatar
Ted Lemon committed
680 681
					      "status", status,
					      (omapi_typed_data_t *)0);
682 683 684
			return ISC_R_SUCCESS;
		}
		if (!message -> rid)
Ted Lemon's avatar
Ted Lemon committed
685
			status = omapi_protocol_send_status
686
				(po, message -> id_object, ISC_R_SUCCESS,
Ted Lemon's avatar
Ted Lemon committed
687
				 message -> id, (char *)0);
688 689
		if (m)
			omapi_signal ((omapi_object_t *)m,
Ted Lemon's avatar
Ted Lemon committed
690 691 692
				      "status", ISC_R_SUCCESS,
				      (omapi_typed_data_t *)0);
		return status;
693 694

	      case OMAPI_OP_NOTIFY:
Ted Lemon's avatar
Ted Lemon committed
695
		return omapi_protocol_send_status
696
			(po, message -> id_object, ISC_R_NOTIMPLEMENTED,
Ted Lemon's avatar
Ted Lemon committed
697
			 message -> id, "notify not implemented yet");
698

Ted Lemon's avatar
Ted Lemon committed
699 700
	      case OMAPI_OP_STATUS:
		/* The return status of a request. */
701 702 703 704
		if (!m)
			return ISC_R_UNEXPECTED;

		/* Get the wait status. */
705
		status = omapi_get_value_str (mo, message -> id_object,
706 707
					      "result", &tv);
		if (status == ISC_R_SUCCESS) {
708 709
			status = omapi_get_int_value (&wsi, tv -> value);
			waitstatus = wsi;
Ted Lemon's avatar
Ted Lemon committed
710
			omapi_value_dereference (&tv, MDL);
711 712 713 714 715
			if (status != ISC_R_SUCCESS)
				waitstatus = ISC_R_UNEXPECTED;
		} else
			waitstatus = ISC_R_UNEXPECTED;

716
		status = omapi_get_value_str (mo, message -> id_object,
Ted Lemon's avatar
Ted Lemon committed
717 718 719
					      "message", &tv);
		omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv);
		if (status == ISC_R_SUCCESS)
Ted Lemon's avatar
Ted Lemon committed
720
			omapi_value_dereference (&tv, MDL);
721
		return ISC_R_SUCCESS;
722 723

	      case OMAPI_OP_DELETE:
Ted Lemon's avatar
Ted Lemon committed
724
		status = omapi_handle_lookup (&object, message -> h);
725 726
		if (status != ISC_R_SUCCESS) {
			return omapi_protocol_send_status
727
				(po, message -> id_object,
728 729 730 731
				 status, message -> id,
				 "no matching handle");
		}

732
		if (!object -> type -> remove)
733
			return omapi_protocol_send_status
734
				(po, message -> id_object,
735
				 ISC_R_NOTIMPLEMENTED, message -> id,
736
				 "no remove method for object");
737

738
		status = (*(object -> type -> remove)) (object,
739
							message -> id_object);
Ted Lemon's avatar
Ted Lemon committed
740
		omapi_object_dereference (&object, MDL);
741

742
		return omapi_protocol_send_status (po, message -> id_object,
743 744
						   status, message -> id,
						   (char *)0);
745 746 747
	}
	return ISC_R_NOTIMPLEMENTED;
}