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); }
/** * 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; }
/** * 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; }
/** * 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; }