Exemple #1
0
static isc_result_t
convert_named_acl(const cfg_obj_t *nameobj, const cfg_obj_t *cctx,
		  isc_log_t *lctx, cfg_aclconfctx_t *ctx,
		  isc_mem_t *mctx, unsigned int nest_level,
		  dns_acl_t **target)
{
	isc_result_t result;
	const cfg_obj_t *cacl = NULL;
	dns_acl_t *dacl;
	dns_acl_t loop;
	const char *aclname = cfg_obj_asstring(nameobj);

	/* Look for an already-converted version. */
	for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache);
	     dacl != NULL;
	     dacl = ISC_LIST_NEXT(dacl, nextincache))
	{
		if (strcasecmp(aclname, dacl->name) == 0) {
			if (ISC_MAGIC_VALID(dacl, LOOP_MAGIC)) {
				cfg_obj_log(nameobj, lctx, ISC_LOG_ERROR,
					    "acl loop detected: %s", aclname);
				return (ISC_R_FAILURE);
			}
			dns_acl_attach(dacl, target);
			return (ISC_R_SUCCESS);
		}
	}
	/* Not yet converted.  Convert now. */
	result = get_acl_def(cctx, aclname, &cacl);
	if (result != ISC_R_SUCCESS) {
		cfg_obj_log(nameobj, lctx, ISC_LOG_WARNING,
			    "undefined ACL '%s'", aclname);
		return (result);
	}
	/*
	 * Add a loop detection element.
	 */
	memset(&loop, 0, sizeof(loop));
	ISC_LINK_INIT(&loop, nextincache);
	DE_CONST(aclname, loop.name);
	loop.magic = LOOP_MAGIC;
	ISC_LIST_APPEND(ctx->named_acl_cache, &loop, nextincache);
	result = cfg_acl_fromconfig(cacl, cctx, lctx, ctx, mctx,
				    nest_level, &dacl);
	ISC_LIST_UNLINK(ctx->named_acl_cache, &loop, nextincache);
	loop.magic = 0;
	loop.name = NULL;
	if (result != ISC_R_SUCCESS)
		return (result);
	dacl->name = isc_mem_strdup(dacl->mctx, aclname);
	if (dacl->name == NULL)
		return (ISC_R_NOMEMORY);
	ISC_LIST_APPEND(ctx->named_acl_cache, dacl, nextincache);
	dns_acl_attach(dacl, target);
	return (ISC_R_SUCCESS);
}
Exemple #2
0
/*
 * Recursively pre-parse an ACL definition to find the total number
 * of non-IP-prefix elements (localhost, localnets, key) in all nested
 * ACLs, so that the parent will have enough space allocated for the
 * elements table after all the nested ACLs have been merged in to the
 * parent.
 */
static int
count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx,
		   isc_boolean_t *has_negative)
{
	const cfg_listelt_t *elt;
	const cfg_obj_t *cacl = NULL;
	isc_result_t result;
	int n = 0;

	if (has_negative != NULL)
		*has_negative = ISC_FALSE;

	for (elt = cfg_list_first(caml);
	     elt != NULL;
	     elt = cfg_list_next(elt)) {
		const cfg_obj_t *ce = cfg_listelt_value(elt);

		/* negated element; just get the value. */
		if (cfg_obj_istuple(ce)) {
			ce = cfg_tuple_get(ce, "value");
			if (has_negative != NULL)
				*has_negative = ISC_TRUE;
		}

		if (cfg_obj_istype(ce, &cfg_type_keyref)) {
			n++;
		} else if (cfg_obj_islist(ce)) {
			isc_boolean_t negative;
			n += count_acl_elements(ce, cctx, &negative);
			if (negative)
				n++;
		} else if (cfg_obj_isstring(ce)) {
			const char *name = cfg_obj_asstring(ce);
			if (strcasecmp(name, "localhost") == 0 ||
#ifdef SUPPORT_GEOIP
			    strncasecmp(name, "country_", 8) == 0 ||
#endif
			    strcasecmp(name, "localnets") == 0) {
				n++;
			} else if (strcasecmp(name, "any") != 0 &&
				   strcasecmp(name, "none") != 0) {
				result = get_acl_def(cctx, name, &cacl);
				if (result == ISC_R_SUCCESS)
					n += count_acl_elements(cacl, cctx,
								NULL) + 1;
			}
		}
	}

	return n;
}