⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 update.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
				       client->mctx, inception, expire));		} else {			INSIST(0);		}	}	/* Record our changes for the journal. */	while ((t = ISC_LIST_HEAD(sig_diff.tuples)) != NULL) {		ISC_LIST_UNLINK(sig_diff.tuples, t, link);		dns_diff_appendminimal(diff, &t);	}	while ((t = ISC_LIST_HEAD(nsec_mindiff.tuples)) != NULL) {		ISC_LIST_UNLINK(nsec_mindiff.tuples, t, link);		dns_diff_appendminimal(diff, &t);	}	INSIST(ISC_LIST_EMPTY(sig_diff.tuples));	INSIST(ISC_LIST_EMPTY(nsec_diff.tuples));	INSIST(ISC_LIST_EMPTY(nsec_mindiff.tuples)); failure:	dns_diff_clear(&sig_diff);	dns_diff_clear(&nsec_diff);	dns_diff_clear(&nsec_mindiff);	dns_diff_clear(&affected);	dns_diff_clear(&diffnames);	for (i = 0; i < nkeys; i++)		dst_key_free(&zone_keys[i]);	return (result);}/**************************************************************************//* * The actual update code in all its glory.  We try to follow * the RFC2136 pseudocode as closely as possible. */static isc_result_tsend_update_event(ns_client_t *client, dns_zone_t *zone) {	isc_result_t result = ISC_R_SUCCESS;	update_event_t *event = NULL;	isc_task_t *zonetask = NULL;	ns_client_t *evclient;	event = (update_event_t *)		isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE,				   update_action, NULL, sizeof(*event));	if (event == NULL)		FAIL(ISC_R_NOMEMORY);	event->zone = zone;	event->result = ISC_R_SUCCESS;	evclient = NULL;	ns_client_attach(client, &evclient);	INSIST(client->nupdates == 0);	client->nupdates++;	event->ev_arg = evclient;	dns_zone_gettask(zone, &zonetask);	isc_task_send(zonetask, ISC_EVENT_PTR(&event)); failure:	if (event != NULL)		isc_event_free(ISC_EVENT_PTR(&event));	return (result);}static voidrespond(ns_client_t *client, isc_result_t result) {	isc_result_t msg_result;	msg_result = dns_message_reply(client->message, ISC_TRUE);	if (msg_result != ISC_R_SUCCESS)		goto msg_failure;	client->message->rcode = dns_result_torcode(result);	ns_client_send(client);	return; msg_failure:	isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE,		      ISC_LOG_ERROR,		      "could not create update response message: %s",		      isc_result_totext(msg_result));	ns_client_next(client, msg_result);}voidns_update_start(ns_client_t *client, isc_result_t sigresult) {	dns_message_t *request = client->message;	isc_result_t result;	dns_name_t *zonename;	dns_rdataset_t *zone_rdataset;	dns_zone_t *zone = NULL;	/*	 * Interpret the zone section.	 */	result = dns_message_firstname(request, DNS_SECTION_ZONE);	if (result != ISC_R_SUCCESS)		FAILC(DNS_R_FORMERR,		      "update zone section empty");	/*	 * The zone section must contain exactly one "question", and	 * it must be of type SOA.	 */	zonename = NULL;	dns_message_currentname(request, DNS_SECTION_ZONE, &zonename);	zone_rdataset = ISC_LIST_HEAD(zonename->list);	if (zone_rdataset->type != dns_rdatatype_soa)		FAILC(DNS_R_FORMERR,		      "update zone section contains non-SOA");	if (ISC_LIST_NEXT(zone_rdataset, link) != NULL)		FAILC(DNS_R_FORMERR,		      "update zone section contains multiple RRs");	/* The zone section must have exactly one name. */	result = dns_message_nextname(request, DNS_SECTION_ZONE);	if (result != ISC_R_NOMORE)		FAILC(DNS_R_FORMERR,		      "update zone section contains multiple RRs");	result = dns_zt_find(client->view->zonetable, zonename, 0, NULL,			     &zone);	if (result != ISC_R_SUCCESS)		FAILC(DNS_R_NOTAUTH,		      "not authoritative for update zone");	switch(dns_zone_gettype(zone)) {	case dns_zone_master:		/*		 * We can now fail due to a bad signature as we now know		 * that we are the master.		 */		if (sigresult != ISC_R_SUCCESS)			FAIL(sigresult);		CHECK(send_update_event(client, zone));		break;	case dns_zone_slave:		CHECK(checkupdateacl(client, dns_zone_getforwardacl(zone),				     "update forwarding", zonename, ISC_TRUE));		CHECK(send_forward_event(client, zone));		break;	default:		FAILC(DNS_R_NOTAUTH,		      "not authoritative for update zone");	}	return; failure:	/*	 * We failed without having sent an update event to the zone.	 * We are still in the client task context, so we can	 * simply give an error response without switching tasks.	 */	respond(client, result);	if (zone != NULL)		dns_zone_detach(&zone);}/* * DS records are not allowed to exist without corresponding NS records, * draft-ietf-dnsext-delegation-signer-11.txt, 2.2 Protocol Change, * "DS RRsets MUST NOT appear at non-delegation points or at a zone's apex". */static isc_result_tremove_orphaned_ds(dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) {	isc_result_t result;	isc_boolean_t ns_exists, ds_exists;	dns_difftuple_t *t;	for (t = ISC_LIST_HEAD(diff->tuples);	     t != NULL;	     t = ISC_LIST_NEXT(t, link)) {		if (t->op != DNS_DIFFOP_DEL ||		    t->rdata.type != dns_rdatatype_ns)			continue;		CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0,				   &ns_exists));		if (ns_exists)			continue;		CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ds, 0,				   &ds_exists));		if (!ds_exists)			continue;		CHECK(delete_if(true_p, db, newver, &t->name,				dns_rdatatype_ds, 0, NULL, diff));	}	return (ISC_R_SUCCESS); failure:	return (result);}static voidupdate_action(isc_task_t *task, isc_event_t *event) {	update_event_t *uev = (update_event_t *) event;	dns_zone_t *zone = uev->zone;	ns_client_t *client = (ns_client_t *)event->ev_arg;	isc_result_t result;	dns_db_t *db = NULL;	dns_dbversion_t *oldver = NULL;	dns_dbversion_t *ver = NULL;	dns_diff_t diff; 	/* Pending updates. */	dns_diff_t temp; 	/* Pending RR existence assertions. */	isc_boolean_t soa_serial_changed = ISC_FALSE;	isc_mem_t *mctx = client->mctx;	dns_rdatatype_t covers;	dns_message_t *request = client->message;	dns_rdataclass_t zoneclass;	dns_name_t *zonename;	dns_ssutable_t *ssutable = NULL;	dns_fixedname_t tmpnamefixed;	dns_name_t *tmpname = NULL;	INSIST(event->ev_type == DNS_EVENT_UPDATE);	dns_diff_init(mctx, &diff);	dns_diff_init(mctx, &temp);	CHECK(dns_zone_getdb(zone, &db));	zonename = dns_db_origin(db);	zoneclass = dns_db_class(db);	dns_zone_getssutable(zone, &ssutable);	dns_db_currentversion(db, &oldver);	CHECK(dns_db_newversion(db, &ver));	/*	 * Check prerequisites.	 */	for (result = dns_message_firstname(request, DNS_SECTION_PREREQUISITE);	     result == ISC_R_SUCCESS;	     result = dns_message_nextname(request, DNS_SECTION_PREREQUISITE))	{		dns_name_t *name = NULL;		dns_rdata_t rdata = DNS_RDATA_INIT;		dns_ttl_t ttl;		dns_rdataclass_t update_class;		isc_boolean_t flag;		get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass,			       &name, &rdata, &covers, &ttl, &update_class);		if (ttl != 0)			FAILC(DNS_R_FORMERR, "prerequisite TTL is not zero");		if (! dns_name_issubdomain(name, zonename))			FAILN(DNS_R_NOTZONE, name,				"prerequisite name is out of zone");		if (update_class == dns_rdataclass_any) {			if (rdata.length != 0)				FAILC(DNS_R_FORMERR,				      "class ANY prerequisite "				      "RDATA is not empty");			if (rdata.type == dns_rdatatype_any) {				CHECK(name_exists(db, ver, name, &flag));				if (! flag) {					FAILN(DNS_R_NXDOMAIN, name,					      "'name in use' prerequisite "					      "not satisfied");				}			} else {				CHECK(rrset_exists(db, ver, name,						   rdata.type, covers, &flag));				if (! flag) {					/* RRset does not exist. */					FAILNT(DNS_R_NXRRSET, name, rdata.type,					"'rrset exists (value independent)' "					"prerequisite not satisfied");				}			}		} else if (update_class == dns_rdataclass_none) {			if (rdata.length != 0)				FAILC(DNS_R_FORMERR,				      "class NONE prerequisite "				      "RDATA is not empty");			if (rdata.type == dns_rdatatype_any) {				CHECK(name_exists(db, ver, name, &flag));				if (flag) {					FAILN(DNS_R_YXDOMAIN, name,					      "'name not in use' prerequisite "					      "not satisfied");				}			} else {				CHECK(rrset_exists(db, ver, name,						   rdata.type, covers, &flag));				if (flag) {					/* RRset exists. */					FAILNT(DNS_R_YXRRSET, name, rdata.type,					       "'rrset does not exist' "					       "prerequisite not satisfied");				}			}		} else if (update_class == zoneclass) {			/* "temp<rr.name, rr.type> += rr;" */			result = temp_append(&temp, name, &rdata);			if (result != ISC_R_SUCCESS) {				UNEXPECTED_ERROR(__FILE__, __LINE__,					 "temp entry creation failed: %s",						 dns_result_totext(result));				FAIL(ISC_R_UNEXPECTED);			}		} else {			FAILC(DNS_R_FORMERR, "malformed prerequisite");		}	}	if (result != ISC_R_NOMORE)		FAIL(result);	/*	 * Perform the final check of the "rrset exists (value dependent)"	 * prerequisites.	 */	if (ISC_LIST_HEAD(temp.tuples) != NULL) {		dns_rdatatype_t type;		/*		 * Sort the prerequisite records by owner name,		 * type, and rdata.		 */		result = dns_diff_sort(&temp, temp_order);		if (result != ISC_R_SUCCESS)			FAILC(result, "'RRset exists (value dependent)' "			      "prerequisite not satisfied");		dns_fixedname_init(&tmpnamefixed);		tmpname = dns_fixedname_name(&tmpnamefixed);		result = temp_check(mctx, &temp, db, ver, tmpname, &type);		if (result != ISC_R_SUCCESS)			FAILNT(result, tmpname, type,			       "'RRset exists (value dependent)' "			       "prerequisite not satisfied");	}	update_log(client, zone, LOGLEVEL_DEBUG,		   "prerequisites are OK");	/*	 * Check Requestor's Permissions.  It seems a bit silly to do this	 * only after prerequisite testing, but that is what RFC2136 says.	 */	result = ISC_R_SUCCESS;	if (ssutable == NULL)		CHECK(checkupdateacl(client, dns_zone_getupdateacl(zone),				     "update", zonename, ISC_FALSE));	else if (client->signer == NULL)		CHECK(checkupdateacl(client, NULL, "update", zonename,				     ISC_FALSE));		if (dns_zone_getupdatedisabled(zone))		FAILC(DNS_R_REFUSED, "dynamic update temporarily disabled");	/*	 * Perform the Update Section Prescan.	 */	for (result = dns_message_firstname(request, DNS_SECTION_UPDATE);	     result == ISC_R_SUCCESS;	     result = dns_message_nextname(request, DNS_SECTION_UPDATE))	{		dns_name_t *name = NULL;		dns_rdata_t rdata = DNS_RDATA_INIT;		dns_ttl_t ttl;		dns_rdataclass_t update_class;		get_current_rr(request, DNS_SECTION_UPDATE, zoneclass,			       &name, &rdata, &covers, &ttl, &update_class);		if (! dns_name_issubdomain(name, zonename))			FAILC(DNS_R_NOTZONE,			      "update RR is outside zone");		if (update_class == zoneclass) {			/*			 * Check for meta-RRs.  The RFC2136 pseudocode says			 * check for ANY|AXFR|MAILA|MAILB, but the text adds			 * "or any other QUERY metatype"			 */			if (dns_rdatatype_ismeta(rdata.type)) {				FAILC(DNS_R_FORMERR,				      "meta-RR in update");			}			result = dns_zone_checknames(zone, name, &rdata);			if (result != ISC_R_SUCCESS)				FAIL(DNS_R_REFUSED);		} else if (update_class == dns_rdataclass_any) {			if (ttl != 0 || rdata.length != 0 ||			    (dns_rdatatype_ismeta(rdata.type) &&			     rdata.type != dns_rdatatype_any))				FAILC(DNS_R_FORMERR,				      "meta-RR in update");		} else if (update_class == dns_rdataclass_none) {			if (ttl != 0 ||			    dns_rdatatype_ismeta(rdata.type))				FAILC(DNS_R_FORMERR,				      "meta-RR in update");		} else {			update_log(client, zone, ISC_LOG_WARNING,				   "update RR has incorrect class %d",				   update_class);			FAIL(DNS_R_FORMERR);		}		/*		 * draft-ietf-dnsind-simple-secure-update-01 says		 * "Unlike traditional dynamic update, the client		 * is forbidden from updating NSEC records."		 */		if (dns_db_issecure(db)) {			if (rdata.type == dns_rdatatype_nsec) {				FAILC(DNS_R_REFUSED,				      "explicit NSEC updates are not allowed "				      "in secure zones");			}			else if (rdata.type == dns_rdatatype_rrsig) {				FAILC(DNS_R_REFUSED,				      "explicit RRSIG updates are currently not "				      "supported in secure zones");			}		}		if (ssutable != NULL && client->signer != NULL) {			if (rdata.type != dns_rdatatype_any) {				if (!dns_ssutable_checkrules(ssutable,							     client->signer,							     name, rdata.type))					FAILC(DNS_R_REFUSED,					      "rejected by secure update");			}			else {				if (!ssu_checkall(db, ver, name, ssutable,						  client->signer))					FAILC(DNS_R_REFUSED,					      "rejected by secure update");			}		}	}	if (result != ISC_R_NOMORE)		FAIL(result);	update_log(client, zone, LOGLEVEL_DEBUG,		   "update section prescan OK");	/*	 * Process the Update Section.	 */	for (result = dns_message_firstname(request, DNS_SECTION_UPDATE);	     result == ISC_R_SUCCESS;	     result = dns_message_nextname(request, DNS_SECTION_UPDATE))	{		dns_name_t *name = NULL;		dns_rdata_t rdata = DNS_RDATA_INIT;		dns_ttl_t ttl;		dns_rdataclass_t update_class;		isc_boolean_t flag;		get_current_rr(request, DNS_SECTION_UPDATE, zoneclass,			       &name, &rdata, &covers, &ttl, &update_class);		if (update_class == zoneclass) {			/*			 * RFC 1123 doesn't allow MF and MD in master zones.				 */			if (rdata.type == dns_rdatatype_md ||			    rdata.type == dns_rdatatype_mf) {				char typebuf[DNS_RDATATYPE_FORMATSIZE];				dns_rdatatype_format(rdata.type, t

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -