Beispiel #1
0
static isc_result_t
set_nextqname(struct probe_trans *trans) {
	isc_result_t result;
	size_t domainlen;
	isc_buffer_t b;
	char buf[4096];	/* XXX ad-hoc constant, but should be enough */

	if (*trans->qlabel == NULL)
		return (ISC_R_NOMORE);

	result = isc_string_copy(buf, sizeof(buf), *trans->qlabel);
	if (result != ISC_R_SUCCESS)
		return (result);
	result = isc_string_append(buf, sizeof(buf), trans->domain);
	if (result != ISC_R_SUCCESS)
		return (result);

	domainlen = strlen(buf);
	isc_buffer_init(&b, buf, domainlen);
	isc_buffer_add(&b, domainlen);
	dns_fixedname_init(&trans->fixedname);
	trans->qname = dns_fixedname_name(&trans->fixedname);
	result = dns_name_fromtext(trans->qname, &b, dns_rootname,
				   0, NULL);

	trans->qlabel++;

	return (result);
}
Beispiel #2
0
/**
 * Convert DNS rdata type to LDAP attribute name.
 *
 * @param[in]  rdtype
 * @param[out] target   Output buffer with \0 terminated attribute name.
 * @param[in]  size     Target size.
 * @param[in]  unknown  ISC_TRUE = use generic syntax "UnknownRecord;TYPE65333",
 *                      ISC_FALSE = use type-specific mnemonic like "ARecord"
 */
isc_result_t
rdatatype_to_ldap_attribute(dns_rdatatype_t rdtype, char *target,
			    unsigned int size, isc_boolean_t unknown)
{
	isc_result_t result;
	char rdtype_str[DNS_RDATATYPE_FORMATSIZE];

	if (unknown) {
		/* "UnknownRecord;TYPE65333" */
		CHECK(isc_string_copy(target, size,
				      LDAP_RDATATYPE_UNKNOWN_PREFIX));
		snprintf(rdtype_str, sizeof(rdtype_str), "TYPE%u", rdtype);
		CHECK(isc_string_append(target, size, rdtype_str));
	} else {
		/* "ARecord" */
		dns_rdatatype_format(rdtype, rdtype_str, DNS_RDATATYPE_FORMATSIZE);
		CHECK(isc_string_copy(target, size, rdtype_str));
		CHECK(isc_string_append(target, size, LDAP_RDATATYPE_SUFFIX));
	}

cleanup:
	return result;
}
Beispiel #3
0
/**
 * Set all values specified by vector of strings to setting set. Setting name
 * is separated from it's argument with one or more characters defined by
 * @link SETTING_NAME_SEPARATORS@endlink.
 *
 * @retval ISC_R_SUCCESS All strings in argument vector were processed and set.
 * @retval Others        Memory or parsing errors.
 *
 * @warning One string in argument vector is limited to
 * @link SETTING_LINE_MAXLENGTH@endlink.
 *
 * @note
 * @code{.txt}
 * Calling settings_set_fill() with argument array
 *
 * {"setting1	value 1 ",
 *  "bind_dn cn=Directory manager" }
 *
 * will result in setting values to two separate settings:
 *
 * "setting1" = "value 1 "
 * "bind_dn"  = "cn=Directory manager"
 *
 * Please note the positions of white spaces.
 * @endcode
 */
isc_result_t
settings_set_fill(settings_set_t *set, const char *const *argv)
{
	isc_result_t result;
	int i;
	const char *name;
	char *value;

	for (i = 0; argv[i] != NULL; i++) {
		char buff[SETTING_LINE_MAXLENGTH] = "";
		CHECK(isc_string_copy(buff, SETTING_LINE_MAXLENGTH, argv[i]));
		value = buff;
		name = isc_string_separate(&value, SETTING_NAME_SEPARATORS);
		if (name == NULL || value == NULL)
			CLEANUP_WITH(ISC_R_UNEXPECTEDEND);
		value += strspn(value, SETTING_NAME_SEPARATORS);
		if (setting_find(name, set, ISC_FALSE, ISC_TRUE, NULL)
		    != ISC_R_NOTFOUND) {
			log_error("multiple definitions of setting '%s' in "
				  "set of settings '%s'", name, set->name);
			CLEANUP_WITH(ISC_R_EXISTS);
		}
		result = setting_set(name, set, value);
		if (result != ISC_R_SUCCESS && result != ISC_R_IGNORE)
			goto cleanup;
	}

	return ISC_R_SUCCESS;

cleanup:
	log_error_r("cannot parse settings from '%s': "
		    "problematic configuration line:"
		    "\n%s\n"
		    "error code", set->name, argv[i]);
	/* TODO: Free memory in case of error. */
	return result;
}
Beispiel #4
0
/**
 * Convert and copy value to setting structure.
 *
 * @retval ISC_R_SUCCESS  New value was converted and copied.
 * @retval ISC_R_IGNORE   New and old values are same, no change was made.
 * @retval ISC_R_NOMEMORY
 * @retval ISC_R_UNEXPECTEDEND
 * @retval ISC_R_UNEXPECTEDTOKEN
 * @retval others         Other errors from isc_parse_uint32().
 */
static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
set_value(isc_mem_t *mctx, const settings_set_t *set, setting_t *setting,
	  const char *value)
{
	isc_result_t result;
	isc_uint32_t numeric_value;
	isc_uint32_t len;

	REQUIRE(setting != NULL);
	REQUIRE(value != NULL);
	REQUIRE(set != NULL);

	/* catch attempts to modify built-in defaults */
	REQUIRE(set->lock != NULL);
	LOCK(set->lock);

	/* Check and convert new values. */
	switch (setting->type) {
	case ST_STRING:
		if (setting->filled &&
		    strcmp(setting->value.value_char, value) == 0)
			CLEANUP_WITH(ISC_R_IGNORE);
		break;

	case ST_UNSIGNED_INTEGER:
		if (*value == '\0')
			CLEANUP_WITH(ISC_R_UNEXPECTEDEND);

		result = isc_parse_uint32(&numeric_value, value, 10);
		if (result != ISC_R_SUCCESS) {
			log_error_r("setting '%s' has to be unsigned integer "
				    "(base 10)", setting->name);
			goto cleanup;
		}
		if (setting->filled &&
		    setting->value.value_uint == numeric_value)
			CLEANUP_WITH(ISC_R_IGNORE);
		break;

	case ST_BOOLEAN:
		if (strcasecmp(value, "yes") == 0 ||
		    strcasecmp(value, "true") == 0)
			numeric_value = 1;
		else if (strcasecmp(value, "no") == 0 ||
			 strcasecmp(value, "false") == 0)
			numeric_value = 0;
		else {
			log_error("unknown boolean expression "
				  "(setting '%s': value '%s')",
				  setting->name, value);
			CLEANUP_WITH(ISC_R_UNEXPECTEDTOKEN);
		}
		if (setting->filled &&
		    setting->value.value_boolean == ISC_TF(numeric_value))
			CLEANUP_WITH(ISC_R_IGNORE);
		break;
	default:
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "invalid setting_type_t value %u", setting->type);
		break;
	}

	switch (setting->type) {
	case ST_STRING:
		len = strlen(value) + 1;
		if (setting->is_dynamic)
			isc_mem_free(mctx, setting->value.value_char);
		CHECKED_MEM_ALLOCATE(mctx, setting->value.value_char, len);
		setting->is_dynamic = ISC_TRUE;
		CHECK(isc_string_copy(setting->value.value_char, len, value));
		break;

	case ST_UNSIGNED_INTEGER:
		setting->value.value_uint = numeric_value;
		break;

	case ST_BOOLEAN:
		setting->value.value_boolean = ISC_TF(numeric_value);
		break;
	default:
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "invalid setting_type_t value %u", setting->type);
		break;
	}
	setting->filled = 1;
	result = ISC_R_SUCCESS;

cleanup:
	UNLOCK(set->lock);
	return result;
}