Commit c63e4595 authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[v4_1_esv] Host declaration name can now be used in DNS forward name

    Merges in rt21323.
parent 7a0fb4d2
......@@ -57,7 +57,7 @@ ISC DHCP is open source software maintained by Internet Systems
Consortium. This product includes cryptographic software written
by Eric Young (eay@cryptsoft.com).
Changes since 4.1.-ESV
Changes since 4.1.-ESV-R10
- Corrected parser's right brace matching when a statement contains an error.
[ISC-Bugs #36021]
......@@ -113,11 +113,24 @@ by Eric Young (eay@cryptsoft.com).
is defined globally.
[ISC-Bugs #32545]
- By default, the server will now choose the value to use in the forward DNS
name from the following in order of preference:
1. FQDN option if provided by the client
2. Host name option if provided by the client
3. Configured option host-name if defined
As before, this may be overridden by defining ddns-hostname to the desired
value (or expression). In addition, the server logic has been extended to
use the value of the host name declaration if use-host-decl-names is enabled
and no other value is available.
[ISC-Bugs #21323]
Changes since 4.1-ESV-R10rc1
- None
Changes since 4.3.1b1
Changes since 4.1-ESV-R10b1
- Modify the linux and openwrt dhclient scripts to process information
from a stateless request. Thanks to Jiri Popelka at Red Hat for the
......
......@@ -1253,6 +1253,70 @@ int binding_scope_reference (ptr, bp, file, line)
return 1;
}
/*!
* \brief Constructs a null-terminated data_string from a char* and length.
*
* Allocates a data_string and copies into it the given length of bytes
* from the given source, adding a terminating null if not present in the source
* at length-1.
*
* \param new_string pointer to the data_string to construct. Cannot be
* NULL. Note that its contents will be overwritten. Passing in the address
* of an allocated data_string will result in memory leaks.
* \param src data to be copied. Cannot be NULL.
* \param len length of the data to copied
*
* \return 1 - if the data_string is constructed successfully, 0 if
* target data_struct is NULL or the buffer allocation fails.
*/
int
data_string_new(struct data_string *new_string,
const char *src, unsigned int len,
const char *file, int line)
{
unsigned int copy_len = 0;
if (new_string == NULL) {
log_error("data_string_new: new_string cannot be NULL %s(%d)",
file, line);
return (0);
}
if (src == NULL) {
log_error("data_string_new: src cannot be NULL %s(%d)",
file, line);
return (0);
}
memset(new_string, 0, sizeof (struct data_string));
/* If we already have a NULL back off length by one. This lets
* us always just add a NULL at the end. */
copy_len = (len > 0 && src[len - 1 ] == 0) ? len - 1 : len;
/* Allocate the buffer, accounting for terminating null */
if (!buffer_allocate(&(new_string->buffer), copy_len + 1, MDL)) {
log_error("data_string_new: No memory %s(%d)", file, line);
return (0);
}
/* Only copy if there's something to copy */
if (copy_len > 0) {
memcpy(new_string->buffer->data, src, copy_len);
}
/* Always tack on the null */
new_string->buffer->data[copy_len + 1] = 0;
/* Update data_string accessor values. Note len does NOT include
* the NULL. */
new_string->data = new_string->buffer->data;
new_string->len = copy_len;
new_string->terminated = 1;
return (1);
}
/* Make a copy of the data in data_string, upping the buffer reference
count if there's a buffer. */
......
/*
* Copyright (c) 2007,2009,2012 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2007,2009-2014 by Internet Systems Consortium, Inc. ("ISC")
*
* We test the functions provided in alloc.c here. These are very
* basic functions, and it is very important that they work correctly.
......@@ -27,6 +27,8 @@
#include <atf-c.h>
#include "dhcpd.h"
static const char* checkString (struct data_string* ds, const char *src);
ATF_TC(buffer_allocate);
ATF_TC_HEAD(buffer_allocate, tc) {
......@@ -187,7 +189,7 @@ ATF_TC_BODY(buffer_dereference, tc) {
if (!buffer_reference(&b, a, MDL)) {
atf_tc_fail("buffer_reference() failed");
}
a->refcnt = 0; /* purposely set to invalid value */
a->refcnt = 0; /* purposely set to invalid value */
if (buffer_dereference(&a, MDL)) {
atf_tc_fail("buffer_dereference() succeeded on error input");
}
......@@ -387,6 +389,103 @@ ATF_TC_BODY(data_string_copy_nobuf, tc) {
}
ATF_TC(data_string_new);
ATF_TC_HEAD(data_string_new, tc) {
atf_tc_set_md_var(tc, "descr", "data_string_new test, "
"exercises data_string_new function");
}
ATF_TC_BODY(data_string_new, tc) {
struct data_string new_string;
const char *src = "Really? Latin? ... geeks";
int len_arg = 0;
const char *error;
/* Case 1: Call with an invalid data_string pointer, should fail */
if (data_string_new(NULL, src, len_arg, MDL)) {
atf_tc_fail("case 1: call should have failed");
}
/* Case 2: Passing in NULL src should fail */
if (data_string_new(&new_string, NULL, 10, MDL)) {
atf_tc_fail("case 2: did not return success");
}
/* Case 3: Call with valid params, length includes NULL */
len_arg = strlen(src) + 1;
if (data_string_new(&new_string, src, len_arg, MDL) == 0) {
atf_tc_fail("case 3: did not return success");
}
error = checkString(&new_string, src);
ATF_REQUIRE_MSG((error == NULL), "case 3: %s", error);
data_string_forget(&new_string, MDL);
/* Case 4: Call with valid params, length does not include NULL */
len_arg = 7;
if (data_string_new(&new_string, src, len_arg, MDL) == 0) {
atf_tc_fail("case 4: did not return success");
}
error = checkString(&new_string, "Really?");
ATF_REQUIRE_MSG((error == NULL), "case 4: %s", error);
data_string_forget(&new_string, MDL);
/* Case 5: Call with valid params, source string is "" */
len_arg = 0;
if (data_string_new(&new_string, "", len_arg, MDL) == 0) {
atf_tc_fail("case 5: did not return success");
}
error = checkString(&new_string, "");
ATF_REQUIRE_MSG((error == NULL), "case 4: %s", error);
data_string_forget(&new_string, MDL);
}
/* Helper function which tests validity of a data_string
*
* Verifies that the given data_string contains a null-terminated string
* equal to a given string.
*
* \param string data_string to test
* \param src text content string should contain
* \return returns NULL if data_string is validate or an error message
* describing why it is invalid
*/
const char* checkString (struct data_string* string,
const char* src) {
int src_len = strlen(src);
if (string->buffer == NULL) {
return ("buffer is NULL");
}
if (string->data != string->buffer->data) {
return ("data not set to buffer->data");
}
if (string->len != src_len) {
return ("len is wrong ");
}
if (string->terminated != 1) {
return ("terminated flag not set");
}
if (memcmp(string->data, src, src_len + 1)) {
return ("data content wrong");
}
return (NULL);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, buffer_allocate);
......@@ -396,6 +495,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, data_string_forget_nobuf);
ATF_TP_ADD_TC(tp, data_string_copy);
ATF_TP_ADD_TC(tp, data_string_copy_nobuf);
ATF_TP_ADD_TC(tp, data_string_new);
return (atf_no_error());
}
......@@ -2117,6 +2117,8 @@ int option_state_reference (struct option_state **,
struct option_state *, const char *, int);
int option_state_dereference (struct option_state **,
const char *, int);
int data_string_new(struct data_string *, const char *, unsigned int,
const char *, int);
void data_string_copy(struct data_string *, const struct data_string *,
const char *, int);
void data_string_forget (struct data_string *, const char *, int);
......
......@@ -328,6 +328,22 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
else
s1 = 0;
/* If we don't have a host name based on ddns-hostname then use
* the host declaration name if there is one and use-host-decl-names
* is turned on. */
if ((s1 == 0) && (lease && lease->host && lease->host->name)) {
oc = lookup_option(&server_universe, options,
SV_USE_HOST_DECL_NAMES);
if (evaluate_boolean_option_cache(NULL, packet, lease,
NULL, packet->options,
options, scope, oc, MDL)) {
s1 = ((data_string_new(&ddns_hostname,
lease->host->name,
strlen(lease->host->name),
MDL) && ddns_hostname.len > 0));
}
}
oc = lookup_option(&server_universe, options, SV_DDNS_DOMAIN_NAME);
if (oc)
s2 = evaluate_option_cache(&ddns_domainname, packet, lease,
......
......@@ -63,10 +63,9 @@ int server_identifier_matched;
/* This stuff is always executed to figure the default values for certain
ddns variables. */
char std_nsupdate [] = " \n\
option server.ddns-hostname = \n\
pick (option fqdn.hostname, option host-name); \n\
pick (option fqdn.hostname, option host-name, config-option host-name); \n\
option server.ddns-domainname = config-option domain-name; \n\
option server.ddns-ttl = encode-int(lease-time / 2, 32); \n\
option server.ddns-rev-domainname = \"in-addr.arpa.\";";
......
......@@ -1203,19 +1203,24 @@ IP address, it can update its own A record, assuming that the
"radish.org" DNS server will allow it to do so.
.PP
If the server is configured not to allow client updates, or if the
client doesn't want to do its own update, the server will simply
choose a name for the client from either the \fBfqdn\fR option (if present)
or the hostname option (if present). It will use its own
domain name for the client, just as in the ad-hoc update scheme.
It will then update both the A and PTR record, using the name that it
chose for the client. If the client sends a fully-qualified domain
name in the \fBfqdn\fR option, the server uses only the leftmost part of the
domain name - in the example above, "jschmoe" instead of
"jschmoe.radish.org".
.PP
If the defaults for choosing the host name are not appropriate
client doesn\'t want to do its own update, the server will simply
choose a name for the client. By default, the server will choose
from the following three values:
.PP
1. \fBfqdn\fR option (if present)
2. hostname option (if present)
3. Configured hostname option (if defined).
.PP
If these defaults for choosing the host name are not appropriate
you can write your own statement to set the ddns-hostname variable
as you wish.
as you wish. If none of the above are found the server will use
the host declaration name (if one) and use-host-decl-names is on.
.PP
It will use its own domain name for the client. It will then update
both the A and PTR record, using the name that it chose for the client.
If the client sends a fully-qualified domain name in the \fBfqdn\fR option,
the server uses only the leftmost part of the domain name - in the example
above, "jschmoe" instead of "jschmoe.radish.org".
.PP
Further, if the \fIignore client-updates;\fR directive is used, then
the server will in addition send a response in the DHCP packet, using
......@@ -2862,6 +2867,11 @@ is equivalent to
}
.fi
.PP
Additionally, enabling use-host-decl-names instructs the server to use
the host declaration name in the the forward DNS name, if no other values
are available. This value selection process is discussed in more detail
under DNS updates.
.PP
An \fIoption host-name\fR statement within a host declaration will
override the use of the name in the host declaration.
.PP
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment