confzone.c 80.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * Copyright (C) 1999  Internet Software Consortium.
 * 
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

#include <config.h>

#include <isc/assertions.h>

#include <dns/confzone.h>
#include <dns/confcommon.h>
James Brister's avatar
James Brister committed
24
25
#include <dns/log.h>

26
27
28
29
#include "confpvt.h"


/*
30
 * Bit positions in the dns_c_masterzone_t structure setflags field.
31
32
33
34
35
36
 */
#define MZ_CHECK_NAME_BIT		0
#define MZ_DIALUP_BIT			1
#define MZ_NOTIFY_BIT			2
#define MZ_MAINT_IXFR_BASE_BIT		3
#define MZ_MAX_IXFR_LOG_BIT		4
37
#define MZ_FORWARD_BIT			5
38
39
40


/*
41
 * Bit positions in the dns_c_slavezone_t structure setflags field.
42
43
44
45
46
47
 */
#define SZ_CHECK_NAME_BIT		0
#define SZ_DIALUP_BIT			1
#define SZ_MASTER_PORT_BIT		2
#define SZ_TRANSFER_SOURCE_BIT		3
#define SZ_MAX_TRANS_TIME_IN_BIT	4
48
49
50
51
52
53
54
#define SZ_MAX_TRANS_TIME_OUT_BIT	5
#define SZ_MAX_TRANS_IDLE_IN_BIT	6
#define SZ_MAX_TRANS_IDLE_OUT_BIT	7
#define SZ_NOTIFY_BIT			8
#define SZ_MAINT_IXFR_BASE_BIT		9
#define SZ_MAX_IXFR_LOG_BIT		10
#define SZ_FORWARD_BIT			11
55
56


57
58

/* Bit positions of the stub zones */
59
60
61
62
63
#define TZ_CHECK_NAME_BIT		0
#define TZ_DIALUP_BIT			1
#define TZ_MASTER_PORT_BIT		2
#define TZ_TRANSFER_SOURCE_BIT		3
#define TZ_MAX_TRANS_TIME_IN_BIT	4
64
65
66
67
#define TZ_MAX_TRANS_TIME_OUT_BIT	5
#define TZ_MAX_TRANS_IDLE_IN_BIT	6
#define TZ_MAX_TRANS_IDLE_OUT_BIT	7
#define TZ_FORWARD_BIT			8
68
69
70


/*
71
 * Bit positions in the dns_c_forwardzone_t structure setflags field.
72
73
74
75
76
77
 */
#define FZ_CHECK_NAME_BIT		0
#define FZ_FORWARD_BIT			1


/*
78
 * Bit positions in the dns_c_hintzone_t structure setflags field.
79
80
81
82
83
84
 */
#define HZ_CHECK_NAME_BIT		0


typedef enum { zones_preopts, zones_postopts, zones_all } zone_print_type;

85
86
87
88
89
90
91
static isc_result_t master_zone_init(dns_c_masterzone_t *mzone);
static isc_result_t slave_zone_init(dns_c_slavezone_t *szone);
static isc_result_t stub_zone_init(dns_c_stubzone_t *szone);
static isc_result_t hint_zone_init(dns_c_hintzone_t *hzone);
static isc_result_t forward_zone_init(dns_c_forwardzone_t *fzone);
static isc_result_t zone_delete(dns_c_zone_t **zone);
static isc_result_t master_zone_clear(isc_mem_t *mem,
92
				      dns_c_masterzone_t *mzone);
93
static isc_result_t slave_zone_clear(isc_mem_t *mem,
94
				     dns_c_slavezone_t *szone);
95
static isc_result_t stub_zone_clear(isc_mem_t *mem,
James Brister's avatar
James Brister committed
96
				    dns_c_stubzone_t *szone);
97
static isc_result_t forward_zone_clear(isc_mem_t *mem,
98
				       dns_c_forwardzone_t *fzone);
99
static isc_result_t hint_zone_clear(isc_mem_t *mem,
100
				    dns_c_hintzone_t *hzone);
101

102
static void	master_zone_print(FILE *fp, int indent,
103
				  dns_c_masterzone_t *mzone);
104
static void	slave_zone_print(FILE *fp, int indent,
105
				 dns_c_slavezone_t *szone);
106
static void	stub_zone_print(FILE *fp, int indent,
James Brister's avatar
James Brister committed
107
				dns_c_stubzone_t *szone);
108
static void	hint_zone_print(FILE *fp, int indent,
109
				dns_c_hintzone_t *hzone);
110
static void	forward_zone_print(FILE *fp, int indent,
111
				   dns_c_forwardzone_t *fzone);
112
static isc_result_t set_iplist_field(isc_mem_t *mem,
113
114
115
				     dns_c_iplist_t **dest,
				     dns_c_iplist_t *src,
				     isc_boolean_t deepcopy);
116
static isc_result_t set_ipmatch_list_field(isc_mem_t *mem,
117
118
					   dns_c_ipmatchlist_t **dest,
					   dns_c_ipmatchlist_t *src,
119
120
					   isc_boolean_t deepcopy);

121
static void zone_list_print(zone_print_type zpt,
James Brister's avatar
James Brister committed
122
			    FILE *fp, int indent, dns_c_zonelist_t *list);
123
124
125
126



isc_result_t
127
dns_c_zonelist_new(isc_mem_t *mem, dns_c_zonelist_t **zlist)
128
{
129
	dns_c_zonelist_t *list;
130
131
132
133
134
135
136
137
138

	REQUIRE(zlist != NULL);

	list = isc_mem_get(mem, sizeof *list);
	if (list == NULL) {
		return (ISC_R_NOMEMORY);
	}

	list->mem = mem;
139
	list->magic = DNS_C_ZONELIST_MAGIC;
140
141
142
143
144
145
146
147
148
149

	ISC_LIST_INIT(list->zones);

	*zlist = list;

	return (ISC_R_SUCCESS);
}


isc_result_t
150
dns_c_zonelist_delete(dns_c_zonelist_t **zlist)
151
{
152
	dns_c_zonelist_t *list;
James Brister's avatar
James Brister committed
153
154
155
	dns_c_zonelem_t *zoneelem;
	dns_c_zonelem_t *tmpelem;
	dns_c_zone_t *zone;
156
157
158
	isc_result_t res;

	REQUIRE(zlist != NULL);
159
	REQUIRE(*zlist != NULL);
160
161
162

	list = *zlist;

James Brister's avatar
James Brister committed
163
164
165
166
	zoneelem = ISC_LIST_HEAD(list->zones);
	while (zoneelem != NULL) {
		tmpelem = ISC_LIST_NEXT(zoneelem, next);
		ISC_LIST_UNLINK(list->zones, zoneelem, next);
167

James Brister's avatar
James Brister committed
168
169
170
		zone = zoneelem->thezone;
		isc_mem_put(list->mem, zoneelem, sizeof *zoneelem);
		
171
		res = dns_c_zone_detach(&zone);
172
		if (res != ISC_R_SUCCESS) {
173
174
175
			return (res);
		}

James Brister's avatar
James Brister committed
176
		zoneelem = tmpelem;
177
178
	}

179
	list->magic = 0;
180
181
182
183
184
	isc_mem_put(list->mem, list, sizeof *list);

	return (ISC_R_SUCCESS);
}

James Brister's avatar
James Brister committed
185
isc_result_t
186
dns_c_zonelist_addzone(dns_c_zonelist_t *zlist,
James Brister's avatar
James Brister committed
187
188
189
190
		       dns_c_zone_t *zone)
{
	dns_c_zonelem_t *zoneelem;

191
192
	REQUIRE(DNS_C_ZONELIST_VALID(zlist));
	REQUIRE(DNS_C_ZONE_VALID(zone));
James Brister's avatar
James Brister committed
193
194
195
196
197
198
199
	REQUIRE(zone->refcount > 0);

	zoneelem = isc_mem_get(zlist->mem, sizeof *zoneelem);
	if (zoneelem == NULL) {
		return (ISC_R_NOMEMORY);
	}
	
200
	zoneelem->thezone = zone;
James Brister's avatar
James Brister committed
201
202
203
204
205
206
207
208
	ISC_LINK_INIT(zoneelem, next);

	ISC_LIST_APPEND(zlist->zones, zoneelem, next);

	return (ISC_R_SUCCESS);
}
	
	
209
210

isc_result_t
211
dns_c_zonelist_find(dns_c_zonelist_t *zlist, const char *name,
James Brister's avatar
James Brister committed
212
		    dns_c_zone_t **retval)
213
{
James Brister's avatar
James Brister committed
214
	dns_c_zonelem_t *zoneelem;
215

216
	REQUIRE(DNS_C_ZONELIST_VALID(zlist));
217
218
219
220
	REQUIRE(name != NULL);
	REQUIRE(strlen(name) > 0);
	REQUIRE(retval != NULL);

James Brister's avatar
James Brister committed
221
222
223
224
225
	zoneelem = ISC_LIST_HEAD(zlist->zones);
	while (zoneelem != NULL) {
		REQUIRE(zoneelem->thezone != NULL);
		
		if (strcmp(name, zoneelem->thezone->name) == 0) {
226
227
228
229
			break;
		}
	}

James Brister's avatar
James Brister committed
230
231
	if (zoneelem != NULL) {
		*retval = zoneelem->thezone;
232
233
	}

James Brister's avatar
James Brister committed
234
	return (zoneelem == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
235
236
237
238
}


isc_result_t
239
dns_c_zonelist_rmbyname(dns_c_zonelist_t *zlist,
James Brister's avatar
James Brister committed
240
			const char *name)
241
{
James Brister's avatar
James Brister committed
242
	dns_c_zonelem_t *zoneelem;
243
244
	isc_result_t res;

245
	REQUIRE(DNS_C_ZONELIST_VALID(zlist));
James Brister's avatar
James Brister committed
246
	REQUIRE(name != NULL);
247
	REQUIRE(strlen(name) > 0);
James Brister's avatar
James Brister committed
248
249
250
251
252
253
254
255
256
257
258
259

	zoneelem = ISC_LIST_HEAD(zlist->zones);
	while (zoneelem != NULL) {
		REQUIRE(zoneelem->thezone != NULL);
		
		if (strcmp(name, zoneelem->thezone->name) == 0) {
			break;
		}
	}

	if (zoneelem != NULL) {
		ISC_LIST_UNLINK(zlist->zones, zoneelem, next);
260
		res = dns_c_zone_detach(&zoneelem->thezone);
James Brister's avatar
James Brister committed
261
262
263
		isc_mem_put(zlist->mem, zoneelem, sizeof *zoneelem);
	} else {
		res = ISC_R_NOTFOUND;
264
265
266
267
268
269
270
	}

	return (res);
}


isc_result_t
271
dns_c_zonelist_rmzone(dns_c_zonelist_t *zlist,
James Brister's avatar
James Brister committed
272
		      dns_c_zone_t *zone)
273
{
James Brister's avatar
James Brister committed
274
	dns_c_zonelem_t *zoneelem;
275
276
277
278
279
	isc_result_t res;
	
	REQUIRE(zlist != NULL);
	REQUIRE(zone != NULL);

James Brister's avatar
James Brister committed
280
281
282
283
284
285
286
287
288
289
290
	zoneelem = ISC_LIST_HEAD(zlist->zones);
	while (zoneelem != NULL) {
		REQUIRE(zoneelem->thezone != NULL);
		
		if (zone == zoneelem->thezone) {
			break;
		}
	}

	if (zoneelem != NULL) {
		ISC_LIST_UNLINK(zlist->zones, zoneelem, next);
291
		res = dns_c_zone_detach(&zoneelem->thezone);
James Brister's avatar
James Brister committed
292
293
294
295
		isc_mem_put(zlist->mem, zoneelem, sizeof *zoneelem);
	} else {
		res = ISC_R_NOTFOUND;
	}
296
297
298
299
300
301

	return (res);
}


void
302
dns_c_zonelist_print(FILE *fp, int indent,
James Brister's avatar
James Brister committed
303
		     dns_c_zonelist_t *list)
304
{
305
	REQUIRE(DNS_C_ZONELIST_VALID(list));
306
	zone_list_print(zones_all, fp, indent, list);
307
308
309
310
}


void
311
dns_c_zonelist_printpreopts(FILE *fp, int indent,
James Brister's avatar
James Brister committed
312
			    dns_c_zonelist_t *list)
313
{
314
	REQUIRE(DNS_C_ZONELIST_VALID(list));
315
	zone_list_print(zones_preopts, fp, indent, list);
316
317
318
319
}


void
320
dns_c_zonelist_printpostopts(FILE *fp, int indent,
James Brister's avatar
James Brister committed
321
			     dns_c_zonelist_t *list)
322
{
323
	REQUIRE(DNS_C_ZONELIST_VALID(list));
324
	zone_list_print(zones_postopts, fp, indent, list);
325
326
327
328
329
}



static void
330
zone_list_print(zone_print_type zpt, FILE *fp, int indent,
331
		dns_c_zonelist_t *list) 
332
{
James Brister's avatar
James Brister committed
333
	dns_c_zonelem_t *zoneelem;
334
335
336
337
338
339
340
341
342
343
344
345
346
	
	REQUIRE(fp != NULL);
	REQUIRE(indent >= 0);

	if (list == NULL) {
		return;
	}

#define PRINTIT(zone, zpt)						\
	((zpt == zones_preopts && zone->afteropts == ISC_FALSE) ||	\
	 (zpt == zones_postopts && zone->afteropts == ISC_TRUE) ||	\
	 zpt == zones_all)
			    
James Brister's avatar
James Brister committed
347
348
349
	zoneelem = ISC_LIST_HEAD(list->zones);
	while (zoneelem != NULL) {
		if (PRINTIT(zoneelem->thezone, zpt)) {
350
			dns_c_zone_print(fp, indent, zoneelem->thezone);
351
352
		}
		
James Brister's avatar
James Brister committed
353
354
		zoneelem = ISC_LIST_NEXT(zoneelem, next);
		if (zoneelem != NULL && PRINTIT(zoneelem->thezone, zpt)) {
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
			fprintf(fp, "\n");
		}
	}

#undef PRINTIT

	return;
}


/* ************************************************************************ */
/* ******************************** ZONEs ********************************* */
/* ************************************************************************ */

isc_result_t
370
dns_c_zone_new(isc_mem_t *mem,
James Brister's avatar
James Brister committed
371
372
373
	       dns_c_zonetype_t ztype, dns_rdataclass_t zclass,
	       const char *name, const char *internalname,
	       dns_c_zone_t **zone)
374
375
376
377
{
	dns_c_zone_t *newzone;
	isc_result_t res;

James Brister's avatar
James Brister committed
378
	REQUIRE(mem != NULL);
379
380
381
	REQUIRE(name != NULL);
	REQUIRE(strlen(name) > 0);

James Brister's avatar
James Brister committed
382
	newzone = isc_mem_get(mem, sizeof *newzone);
383
384
385
386
	if (newzone == NULL) {
		return (ISC_R_NOMEMORY);
	}

387
	newzone->magic = DNS_C_ZONE_MAGIC;
James Brister's avatar
James Brister committed
388
389
	newzone->mem = mem;
	newzone->refcount = 1;
390
391
392
	newzone->ztype = ztype;
	newzone->zclass = zclass;
	newzone->afteropts = ISC_FALSE;
James Brister's avatar
James Brister committed
393
394
395
396
	newzone->name = isc_mem_strdup(mem, name);
	newzone->internalname = (internalname == NULL ?
				 isc_mem_strdup(mem, name) :
				 isc_mem_strdup(mem, internalname));
397
398
399

	switch (ztype) {
	case dns_c_zone_master:
400
		res = master_zone_init(&newzone->u.mzone);
401
402
403
		break;
		
	case dns_c_zone_slave:
404
		res = slave_zone_init(&newzone->u.szone);
405
406
407
		break;

	case dns_c_zone_stub:
408
		res = stub_zone_init(&newzone->u.tzone);
409
410
411
		break;
		
	case dns_c_zone_hint:
412
		res = hint_zone_init(&newzone->u.hzone);
413
414
415
		break;
		
	case dns_c_zone_forward:
416
		res = forward_zone_init(&newzone->u.fzone);
417
418
419
420
421
422
423
424
425
		break;
	}
	
	*zone = newzone;

	return (ISC_R_SUCCESS);
}


James Brister's avatar
James Brister committed
426
isc_result_t
427
dns_c_zone_detach(dns_c_zone_t **zone)
James Brister's avatar
James Brister committed
428
{
429
	dns_c_zone_t *zoneptr;
James Brister's avatar
James Brister committed
430
431
	isc_result_t res = ISC_R_SUCCESS;

432
	REQUIRE(zone != NULL);
433
	REQUIRE(DNS_C_ZONE_VALID(*zone));
434
435

	zoneptr = *zone;
James Brister's avatar
James Brister committed
436
437
438
439
440
441
	*zone = NULL;

	REQUIRE(zoneptr->refcount > 0);
	zoneptr->refcount--;

	if (zoneptr->refcount == 0) {
442
		res = zone_delete(&zoneptr);
James Brister's avatar
James Brister committed
443
444
445
446
447
448
449
	}

	return (res);
}


void
450
dns_c_zone_attach(dns_c_zone_t *source,
451
		  dns_c_zone_t **target)
James Brister's avatar
James Brister committed
452
{
453
	REQUIRE(DNS_C_ZONE_VALID(source));
454
	REQUIRE(target != NULL);
James Brister's avatar
James Brister committed
455

456
	source->refcount++;
James Brister's avatar
James Brister committed
457

458
	*target = source;
James Brister's avatar
James Brister committed
459
460
461
462
}
		


463
void
464
dns_c_zone_print(FILE *fp, int indent, dns_c_zone_t *zone)
465
466
{
	REQUIRE(fp != NULL);
467
	REQUIRE(DNS_C_ZONE_VALID(zone));
468

469
	dns_c_printtabs(fp, indent);
470
471
472
	fprintf(fp, "zone \"%s\"", zone->name);
	if (zone->zclass != dns_rdataclass_in) {
		fputc(' ', fp);
473
		dns_c_dataclass_tostream(fp, zone->zclass);
474
475
476
477
478
479
	}

	fprintf(fp, " {\n");

	switch (zone->ztype) {
	case dns_c_zone_master:
480
		dns_c_printtabs(fp, indent + 1);
481
		fprintf(fp, "type master;\n");
482
		master_zone_print(fp, indent + 1, &zone->u.mzone);
483
484
485
		break;
		
	case dns_c_zone_slave:
486
		dns_c_printtabs(fp, indent + 1);
487
		fprintf(fp, "type slave;\n");
488
		slave_zone_print(fp, indent + 1, &zone->u.szone);
489
490
491
		break;

	case dns_c_zone_stub:
492
		dns_c_printtabs(fp, indent + 1);
493
		fprintf(fp, "type stub;\n");
494
		stub_zone_print(fp, indent + 1, &zone->u.tzone);
495
496
497
		break;
		
	case dns_c_zone_hint:
498
		dns_c_printtabs(fp, indent + 1);
499
		fprintf(fp, "type hint;\n");
500
		hint_zone_print(fp, indent + 1, &zone->u.hzone);
501
502
503
		break;

	case dns_c_zone_forward:
504
		dns_c_printtabs(fp, indent + 1);
505
		fprintf(fp, "type forward;\n");
506
		forward_zone_print(fp, indent + 1, &zone->u.fzone);
507
508
509
		break;
	}

510
	dns_c_printtabs(fp, indent);
511
512
513
514
515
	fprintf(fp, "};\n");
}


isc_result_t
516
dns_c_zone_setfile(dns_c_zone_t *zone, const char *newfile)
517
518
519
520
{
	char **p = NULL;
	isc_result_t res;
	
521
522
523
	REQUIRE(DNS_C_ZONE_VALID(zone));
	REQUIRE(newfile != NULL);
	REQUIRE(strlen(newfile) > 0);
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

	switch (zone->ztype) {
	case dns_c_zone_master:
		p = &zone->u.mzone.file;
		break;

	case dns_c_zone_slave:
		p = &zone->u.szone.file;
		break;
		
	case dns_c_zone_stub:
		p = &zone->u.tzone.file;
		break;

	case dns_c_zone_hint:
		p = &zone->u.hzone.file;
		break;
			
	case dns_c_zone_forward:
543
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
544
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
545
			      "Forward zones do not have a file field");
546
547
548
549
		return (ISC_R_FAILURE);
	}

	if (*p != NULL) {
James Brister's avatar
James Brister committed
550
		isc_mem_free(zone->mem, *p);
551
552
553
554
555
		res = ISC_R_EXISTS;
	} else {
		res = ISC_R_SUCCESS;
	}

James Brister's avatar
James Brister committed
556
	*p = isc_mem_strdup(zone->mem, newfile);
557
558
559
560
561
562
563
564
565
	if (*p == NULL) {
		res = ISC_R_NOMEMORY;
	}

	return (res);
}


isc_result_t
566
dns_c_zone_setchecknames(dns_c_zone_t *zone,
James Brister's avatar
James Brister committed
567
			 dns_c_severity_t severity)
568
569
{
	dns_c_severity_t *p = NULL;
James Brister's avatar
James Brister committed
570
	dns_c_setbits_t *bits = NULL;
571
572
	int bit = 0;
	isc_result_t res;
James Brister's avatar
James Brister committed
573

574
	REQUIRE(DNS_C_ZONE_VALID(zone));
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621

	switch (zone->ztype) {
	case dns_c_zone_master:
		p = &zone->u.mzone.check_names;
		bits = &zone->u.mzone.setflags;
		bit = MZ_CHECK_NAME_BIT;
		break;
			
	case dns_c_zone_slave:
		p = &zone->u.szone.check_names;
		bits = &zone->u.szone.setflags;
		bit = SZ_CHECK_NAME_BIT;
		break;
		
	case dns_c_zone_stub:
		p = &zone->u.tzone.check_names;
		bits = &zone->u.tzone.setflags;
		bit = TZ_CHECK_NAME_BIT;
		break;
		
	case dns_c_zone_hint:
		p = &zone->u.hzone.check_names;
		bits = &zone->u.hzone.setflags;
		bit = HZ_CHECK_NAME_BIT;
		break;
			
	case dns_c_zone_forward:
		p = &zone->u.fzone.check_names;
		bits = &zone->u.fzone.setflags;
		bit = FZ_CHECK_NAME_BIT;
		break;
	}

	if (DNS_C_CHECKBIT(bit, bits)) {
		res = ISC_R_EXISTS;
	} else {
		res = ISC_R_SUCCESS;
	}
	
	*p = severity;
	DNS_C_SETBIT(bit, bits);

	return (res);
}


isc_result_t
622
dns_c_zone_setallowupd(dns_c_zone_t *zone,
James Brister's avatar
James Brister committed
623
624
		       dns_c_ipmatchlist_t *ipml,
		       isc_boolean_t deepcopy)
625
{
626
	dns_c_ipmatchlist_t **p = NULL;
627
628
629
	isc_result_t res;
	isc_boolean_t existed;
	
630
631
	REQUIRE(DNS_C_ZONE_VALID(zone));
	REQUIRE(DNS_C_IPMLIST_VALID(ipml));
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646

	switch (zone->ztype) {
	case dns_c_zone_master:
		p = &zone->u.mzone.allow_update;
		break;
			
	case dns_c_zone_slave:
		p = &zone->u.szone.allow_update;
		break;
		
	case dns_c_zone_stub:
		p = &zone->u.tzone.allow_update;
		break;
		
	case dns_c_zone_hint:
647
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
648
649
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Hint zones do not have an allow_update field");
650
651
652
		return (ISC_R_FAILURE);
			
	case dns_c_zone_forward:
653
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
654
655
656
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Forward zones do not have an "
			      "allow_update field");
657
658
659
660
661
		return (ISC_R_FAILURE);
	}

	existed = (*p != NULL ? ISC_TRUE : ISC_FALSE);
	
662
	res = set_ipmatch_list_field(zone->mem, p,
James Brister's avatar
James Brister committed
663
				     ipml, deepcopy);
664
665
666
667
668
669
670
671
672
	if (res == ISC_R_SUCCESS && existed) {
		res = ISC_R_EXISTS;
	}

	return (res);
}


isc_result_t
673
dns_c_zone_setallowquery(dns_c_zone_t *zone,
James Brister's avatar
James Brister committed
674
675
			 dns_c_ipmatchlist_t *ipml,
			 isc_boolean_t deepcopy)
676
{
677
	dns_c_ipmatchlist_t **p = NULL;
678
679
680
	isc_boolean_t existed;
	isc_result_t res;
	
681
682
	REQUIRE(DNS_C_ZONE_VALID(zone));
	REQUIRE(DNS_C_IPMLIST_VALID(ipml));
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697

	switch (zone->ztype) {
	case dns_c_zone_master:
		p = &zone->u.mzone.allow_query;
		break;
			
	case dns_c_zone_slave:
		p = &zone->u.szone.allow_query;
		break;
		
	case dns_c_zone_stub:
		p = &zone->u.tzone.allow_query;
		break;
		
	case dns_c_zone_hint:
698
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
699
700
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Hint zones do not have an allow_query field");
701
702
703
		return (ISC_R_FAILURE);
			
	case dns_c_zone_forward:
704
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
705
706
707
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Forward zones do not have an "
			      "allow_query field");
708
709
710
711
712
		return (ISC_R_FAILURE);
	}

	existed = (*p != NULL ? ISC_TRUE : ISC_FALSE);
	
713
	res = set_ipmatch_list_field(zone->mem, p,
James Brister's avatar
James Brister committed
714
				     ipml, deepcopy);
715
716
717
718
719
720
721
722
723
	if (res == ISC_R_SUCCESS && existed) {
		res = ISC_R_EXISTS;
	}

	return (res);
}


isc_result_t
724
dns_c_zone_setallowtransfer(dns_c_zone_t *zone,
James Brister's avatar
James Brister committed
725
726
			    dns_c_ipmatchlist_t *ipml,
			    isc_boolean_t deepcopy)
727
{
728
	dns_c_ipmatchlist_t **p = NULL;
729
730
731
	isc_boolean_t existed;
	isc_result_t res;
	
732
733
	REQUIRE(DNS_C_ZONE_VALID(zone));
	REQUIRE(DNS_C_IPMLIST_VALID(ipml));
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

	switch (zone->ztype) {
	case dns_c_zone_master:
		p = &zone->u.mzone.allow_transfer;
		break;
			
	case dns_c_zone_slave:
		p = &zone->u.szone.allow_transfer;
		break;
		
	case dns_c_zone_stub:
		p = &zone->u.tzone.allow_transfer;
		break;
		
	case dns_c_zone_hint:
749
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
750
751
752
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Hint zones do not have an "
			      "allow_transfer field");
753
754
755
		return (ISC_R_FAILURE);
			
	case dns_c_zone_forward:
756
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
757
758
759
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Forward zones do not have an "
			      "allow_transfer field");
760
761
762
763
		return (ISC_R_FAILURE);
	}

	existed = (*p != NULL ? ISC_TRUE : ISC_FALSE);
764
	res = set_ipmatch_list_field(zone->mem, p,
James Brister's avatar
James Brister committed
765
				     ipml, deepcopy);
766
767
768
769
770
771
772
773
774
775

	if (res == ISC_R_SUCCESS && existed) {
		res = ISC_R_EXISTS;
	}

	return (res);
}


isc_result_t
776
dns_c_zone_setdialup(dns_c_zone_t *zone, isc_boolean_t newval)
777
778
779
{
	isc_boolean_t existed = ISC_FALSE;

780
	REQUIRE(DNS_C_ZONE_VALID(zone));
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804

	switch (zone->ztype) {
	case dns_c_zone_master:
		zone->u.mzone.dialup = newval;
		existed = DNS_C_CHECKBIT(MZ_DIALUP_BIT,
					 &zone->u.mzone.setflags);
		DNS_C_SETBIT(MZ_DIALUP_BIT, &zone->u.mzone.setflags);
		break;

	case dns_c_zone_slave:
		zone->u.szone.dialup = newval;
		existed = DNS_C_CHECKBIT(SZ_DIALUP_BIT,
					 &zone->u.szone.setflags);
		DNS_C_SETBIT(SZ_DIALUP_BIT, &zone->u.szone.setflags);
		break;

	case dns_c_zone_stub:
		zone->u.tzone.dialup = newval;
		existed = DNS_C_CHECKBIT(TZ_DIALUP_BIT,
					 &zone->u.tzone.setflags);
		DNS_C_SETBIT(TZ_DIALUP_BIT, &zone->u.tzone.setflags);
		break;

	case dns_c_zone_hint:
805
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
806
807
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Hint zones do not have a dialup field");
808
809
810
		return (ISC_R_FAILURE);
			
	case dns_c_zone_forward:
811
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
812
813
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Forward zones do not have a dialup field");
814
815
816
817
818
819
820
821
		return (ISC_R_FAILURE);
	}

	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}


isc_result_t
822
dns_c_zone_setnotify(dns_c_zone_t *zone, isc_boolean_t newval)
823
824
825
{
	isc_boolean_t existed = ISC_FALSE;
	
826
	REQUIRE(DNS_C_ZONE_VALID(zone));
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843

	switch (zone->ztype) {
	case dns_c_zone_master:
		zone->u.mzone.notify = newval;
		existed = DNS_C_CHECKBIT(MZ_DIALUP_BIT,
					 &zone->u.mzone.setflags);
		DNS_C_SETBIT(MZ_DIALUP_BIT, &zone->u.mzone.setflags);
		break;
			
	case dns_c_zone_slave:
		zone->u.szone.notify = newval;
		existed = DNS_C_CHECKBIT(SZ_DIALUP_BIT,
					 &zone->u.szone.setflags);
		DNS_C_SETBIT(SZ_DIALUP_BIT, &zone->u.szone.setflags);
		break;
		
	case dns_c_zone_stub:
844
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
845
846
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Stub zones do not have a notify field");
847
848
849
		return (ISC_R_FAILURE);

	case dns_c_zone_hint:
850
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
851
852
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Hint zones do not have a notify field");
853
854
855
		return (ISC_R_FAILURE);
			
	case dns_c_zone_forward:
856
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
857
858
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Forward zones do not have a notify field");
859
860
861
862
863
864
865
866
		return (ISC_R_FAILURE);
	}

	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}


isc_result_t
867
dns_c_zone_setmaintixfrbase(dns_c_zone_t *zone,
James Brister's avatar
James Brister committed
868
			    isc_boolean_t newval)
869
870
871
{
	isc_boolean_t existed = ISC_FALSE;
	
872
	REQUIRE(DNS_C_ZONE_VALID(zone));
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889

	switch (zone->ztype) {
	case dns_c_zone_master:
		zone->u.mzone.maint_ixfr_base = newval;
		existed = DNS_C_CHECKBIT(MZ_MAINT_IXFR_BASE_BIT,
					 &zone->u.mzone.setflags);
		DNS_C_SETBIT(MZ_MAINT_IXFR_BASE_BIT, &zone->u.mzone.setflags);
		break;
			
	case dns_c_zone_slave:
		zone->u.szone.notify = newval;
		existed = DNS_C_CHECKBIT(SZ_MAINT_IXFR_BASE_BIT,
					 &zone->u.szone.setflags);
		DNS_C_SETBIT(SZ_MAINT_IXFR_BASE_BIT, &zone->u.szone.setflags);
		break;
		
	case dns_c_zone_stub:
890
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
891
892
893
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Stub zones do not have a "
			      "maintain-xfer-base field");
894
895
896
		return (ISC_R_FAILURE);

	case dns_c_zone_hint:
897
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
898
899
900
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Hint zones do not have a "
			      "maintain-xfer-base field");
901
902
903
		return (ISC_R_FAILURE);
			
	case dns_c_zone_forward:
904
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
905
906
907
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Forward zones do not have a "
			      "maintain-xfer-base field");
908
909
910
911
912
913
914
915
		return (ISC_R_FAILURE);
	}

	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}


isc_result_t
916
dns_c_zone_setalsonotify(dns_c_zone_t *zone,
James Brister's avatar
James Brister committed
917
918
			 dns_c_iplist_t *newval,
			 isc_boolean_t deepcopy)
919
920
921
922
923
{
	isc_boolean_t existed;
	isc_result_t res;
	dns_c_iplist_t **p = NULL;

924
925
926
	REQUIRE(zone != NULL);
	REQUIRE(DNS_C_IPLIST_VALID(newval));
	
927
928
929
930
931
932
933
934
935
936
	switch (zone->ztype) {
	case dns_c_zone_master:
		p = &zone->u.mzone.also_notify ;
		break;
			
	case dns_c_zone_slave:
		p = &zone->u.szone.also_notify ;
		break;
		
	case dns_c_zone_stub:
937
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
938
939
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Stub zones do not have a also_notify field");
940
941
942
		return (ISC_R_FAILURE);
			
	case dns_c_zone_hint:
943
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
944
945
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Hint zones do not have a also_notify field");
946
947
948
		return (ISC_R_FAILURE);
			
	case dns_c_zone_forward:
949
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
950
951
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Forward zones do not have a also_notify field");
952
953
954
955
		return (ISC_R_FAILURE);
	}

	existed = (*p != NULL ? ISC_TRUE : ISC_FALSE);
956
	res = set_iplist_field(zone->mem, p, newval, deepcopy);
957
958
959
960
961
962
963
964
965
	if (res == ISC_R_SUCCESS && existed) {
		res = ISC_R_EXISTS;
	}

	return (res);
}


isc_result_t
966
dns_c_zone_setixfrbase(dns_c_zone_t *zone, const char *newval)
967
968
969
970
{
	isc_boolean_t existed ;
	char **p = NULL;
	
971
972
973
	REQUIRE(DNS_C_ZONE_VALID(zone));
	REQUIRE(newval != NULL);
	REQUIRE(strlen(newval) > 0);
974
975
976
977
978
979
980
981
982
983
984

	switch (zone->ztype) {
	case dns_c_zone_master:
		p = &zone->u.mzone.ixfr_base;
		break;
			
	case dns_c_zone_slave:
		p = &zone->u.szone.ixfr_base;
		break;
		
	case dns_c_zone_stub:
985
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
986
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
987
			      "Stub zones do not have a ixfr_base field");
988
989
990
		return (ISC_R_FAILURE);

	case dns_c_zone_hint:
991
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
992
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
993
			      "Hint zones do not have a ixfr_base field");
994
995
996
		return (ISC_R_FAILURE);
			
	case dns_c_zone_forward:
997
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
998
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
999
			      "Forward zones do not have a file field");
1000
1001
1002
1003
1004
		return (ISC_R_FAILURE);
	}

	if (*p != NULL) {
		existed = ISC_TRUE;
James Brister's avatar
James Brister committed
1005
		isc_mem_free(zone->mem, *p);
1006
1007
1008
1009
	} else {
		existed = ISC_FALSE;
	}

James Brister's avatar
James Brister committed
1010
	*p = isc_mem_strdup(zone->mem, newval);
1011
1012
1013
1014
1015
1016
1017
1018
1019
	if (*p == NULL) {
		return (ISC_R_NOMEMORY);
	}

	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}


isc_result_t
1020
dns_c_zone_setixfrtmp(dns_c_zone_t *zone, const char *newval)
1021
{
1022
	isc_boolean_t existed;
1023
	char **p = NULL;
1024
1025
1026
1027

	REQUIRE(DNS_C_ZONE_VALID(zone));
	REQUIRE(newval != NULL);
	REQUIRE(strlen(newval) > 0);
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038

	switch (zone->ztype) {
	case dns_c_zone_master:
		p = &zone->u.mzone.ixfr_tmp;
		break;
			
	case dns_c_zone_slave:
		p = &zone->u.szone.ixfr_tmp;
		break;
		
	case dns_c_zone_stub:
1039
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
1040
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
1041
			      "Stub zones do not have a ixfr_tmp field");
1042
1043
1044
		return (ISC_R_FAILURE);

	case dns_c_zone_hint:
1045
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
1046
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
1047
			      "Hint zones do not have a ixfr_tmp field");
1048
1049
1050
		return (ISC_R_FAILURE);
			
	case dns_c_zone_forward:
1051
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
1052
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
1053
			      "Forward zones do not have a file field");
1054
1055
1056
1057
1058
		return (ISC_R_FAILURE);
	}

	if (*p != NULL) {
		existed = ISC_TRUE;
James Brister's avatar
James Brister committed
1059
		isc_mem_free(zone->mem, *p);
1060
1061
1062
1063
	} else {
		existed = ISC_FALSE;
	}

James Brister's avatar
James Brister committed
1064
	*p = isc_mem_strdup(zone->mem, newval);
1065
1066
1067
1068
1069
1070
1071
1072
1073
	if (*p == NULL) {
		return (ISC_R_NOMEMORY);
	}

	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
}


isc_result_t
1074
dns_c_zone_addpubkey(dns_c_zone_t *zone,
James Brister's avatar
James Brister committed
1075
1076
		     dns_c_pubkey_t *pubkey,
		     isc_boolean_t deepcopy)
1077
{
1078
	dns_c_pklist_t **p = NULL;
1079
1080
	isc_result_t res;
	
1081
1082
1083
	REQUIRE(DNS_C_ZONE_VALID(zone));
	REQUIRE(DNS_C_PUBKEY_VALID(pubkey));

1084
1085
	switch (zone->ztype) {
	case dns_c_zone_master:
1086
		p = &zone->u.mzone.pubkeylist;
1087
1088
1089
		break;
			
	case dns_c_zone_slave:
1090
		p = &zone->u.szone.pubkeylist;
1091
1092
1093
		break;
		
	case dns_c_zone_stub:
1094
		p = &zone->u.tzone.pubkeylist;
1095
1096
1097
		break;
		
	case dns_c_zone_hint:
1098
1099
1100
#if 1
		p = &zone->u.hzone.pubkeylist;
#else
1101
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
1102
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
1103
			      "Hint zones do not have a pubkey field");
1104
#endif 
1105
1106
1107
		return (ISC_R_FAILURE);
			
	case dns_c_zone_forward:
1108
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
1109
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
1110
			      "Forward zones do not have a pubkey field");
1111
1112
1113
		return (ISC_R_FAILURE);
	}

1114
	if (*p == NULL) {
1115
		res = dns_c_pklist_new(zone->mem, p);
1116
1117
1118
		if (res != ISC_R_SUCCESS) {
			return (res);
		}
1119
1120
	}
	
1121
	res = dns_c_pklist_addpubkey(*p, pubkey, deepcopy);
1122

1123
1124
1125
1126
1127
	return (res);
}


isc_result_t
1128
dns_c_zone_setmasterport(dns_c_zone_t *zone, in_port_t port)
1129
1130
1131
{
	isc_boolean_t existed = ISC_FALSE;
	
1132
	REQUIRE(DNS_C_ZONE_VALID(zone));
1133
1134
1135

	switch(zone->ztype) {
	case dns_c_zone_master:
1136
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
James Brister's avatar
James Brister committed
1137
1138
			      DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
			      "Forward zones do not have a "
1139
			      "master_port field");