|
|
45d60a |
diff --git a/client/dhclient.8 b/client/dhclient.8
|
|
|
45d60a |
index a29757a..c66a912 100644
|
|
|
45d60a |
--- a/client/dhclient.8
|
|
|
45d60a |
+++ b/client/dhclient.8
|
|
|
45d60a |
@@ -56,6 +56,12 @@ dhclient - Dynamic Host Configuration Protocol Client
|
|
|
45d60a |
]
|
|
|
45d60a |
]
|
|
|
45d60a |
[
|
|
|
45d60a |
+.B -i
|
|
|
45d60a |
+]
|
|
|
45d60a |
+[
|
|
|
45d60a |
+.B -C
|
|
|
45d60a |
+]
|
|
|
45d60a |
+[
|
|
|
45d60a |
.B -D
|
|
|
45d60a |
.I LL|LLT
|
|
|
45d60a |
]
|
|
|
45d60a |
@@ -441,6 +447,17 @@ Set the giaddr field of all packets to the \fIrelay\fR IP address
|
|
|
45d60a |
simulating a relay agent. This is for testing pruposes only and
|
|
|
45d60a |
should not be expected to work in any consistent or useful way.
|
|
|
45d60a |
.TP
|
|
|
45d60a |
+.BI \-i
|
|
|
45d60a |
+Use a DUID with DHCPv4 clients. If no DUID is available in the
|
|
|
45d60a |
+lease file one will be constructed and saved. The DUID will be
|
|
|
45d60a |
+used to contstuct a RFC4361 style client id that will be included
|
|
|
45d60a |
+in the client's messages. This client id can be overridden by
|
|
|
45d60a |
+setting a client id in the configuration file. Overridding the
|
|
|
45d60a |
+client id in this fashion is discouraged.
|
|
|
45d60a |
+.TP
|
|
|
45d60a |
+.BI \-C
|
|
|
45d60a |
+Use the standard DDNS scheme from RFCs 4701 & 4702.
|
|
|
45d60a |
+.TP
|
|
|
45d60a |
.BI \--version
|
|
|
45d60a |
Print version number and exit.
|
|
|
45d60a |
.PP
|
|
|
45d60a |
@@ -470,8 +487,10 @@ DHCPv6 \fBdhclient\fR creates an identifier based on the link-layer address
|
|
|
45d60a |
(DUID-LL) if it is running in stateless mode (with \fB\-S\fR, not
|
|
|
45d60a |
requesting an address), or it creates an identifier based on the
|
|
|
45d60a |
link-layer address plus a timestamp (DUID-LLT) if it is running in
|
|
|
45d60a |
-stateful mode (without \fB\-S\fR, requesting an address). \fB\-D\fR
|
|
|
45d60a |
-overrides this default, with a value of either \fILL\fR or \fILLT\fR.
|
|
|
45d60a |
+stateful mode (without \fB\-S\fR, requesting an address). When DHCPv4
|
|
|
45d60a |
+is configued to use a DUID using \fB\-i\fR option the default is to use
|
|
|
45d60a |
+a DUID-LLT. \fB\-D\fR
|
|
|
45d60a |
+overrides these default, with a value of either \fILL\fR or \fILLT\fR.
|
|
|
45d60a |
.TP
|
|
|
45d60a |
.BI \-N
|
|
|
45d60a |
.\" TODO: is this for telling an already running dhclient?
|
|
|
45d60a |
diff --git a/client/dhclient.c b/client/dhclient.c
|
|
|
45d60a |
index 0db4703..6403754 100644
|
|
|
45d60a |
--- a/client/dhclient.c
|
|
|
45d60a |
+++ b/client/dhclient.c
|
|
|
45d60a |
@@ -79,6 +79,8 @@ struct sockaddr_in sockaddr_broadcast;
|
|
|
45d60a |
struct in_addr giaddr;
|
|
|
45d60a |
struct data_string default_duid;
|
|
|
45d60a |
int duid_type = 0;
|
|
|
45d60a |
+int duid_v4 = 0;
|
|
|
45d60a |
+int std_dhcid = 0;
|
|
|
45d60a |
|
|
|
45d60a |
/* ASSERT_STATE() does nothing now; it used to be
|
|
|
45d60a |
assert (state_is == state_shouldbe). */
|
|
|
45d60a |
@@ -325,12 +327,9 @@ main(int argc, char **argv) {
|
|
|
45d60a |
wanted_ia_na = 0;
|
|
|
45d60a |
}
|
|
|
45d60a |
wanted_ia_pd++;
|
|
|
45d60a |
+#endif /* DHCPv6 */
|
|
|
45d60a |
} else if (!strcmp(argv[i], "-D")) {
|
|
|
45d60a |
- if (local_family_set && (local_family == AF_INET)) {
|
|
|
45d60a |
- usage();
|
|
|
45d60a |
- }
|
|
|
45d60a |
- local_family_set = 1;
|
|
|
45d60a |
- local_family = AF_INET6;
|
|
|
45d60a |
+ duid_v4 = 1;
|
|
|
45d60a |
if (++i == argc)
|
|
|
45d60a |
usage();
|
|
|
45d60a |
if (!strcasecmp(argv[i], "LL")) {
|
|
|
45d60a |
@@ -340,7 +339,12 @@ main(int argc, char **argv) {
|
|
|
45d60a |
} else {
|
|
|
45d60a |
usage();
|
|
|
45d60a |
}
|
|
|
45d60a |
-#endif /* DHCPv6 */
|
|
|
45d60a |
+ } else if (!strcmp(argv[i], "-i")) {
|
|
|
45d60a |
+ /* enable DUID support for DHCPv4 clients */
|
|
|
45d60a |
+ duid_v4 = 1;
|
|
|
45d60a |
+ } else if (!strcmp(argv[i], "-C")) {
|
|
|
45d60a |
+ /* enable standard DHCID support for DDNS updates */
|
|
|
45d60a |
+ std_dhcid = 1;
|
|
|
45d60a |
} else if (!strcmp(argv[i], "-v")) {
|
|
|
45d60a |
quiet = 0;
|
|
|
45d60a |
} else if (!strcmp(argv[i], "--version")) {
|
|
|
45d60a |
@@ -970,12 +974,13 @@ main(int argc, char **argv) {
|
|
|
45d60a |
}
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
- /* Start a configuration state machine for each interface. */
|
|
|
45d60a |
-#ifdef DHCPv6
|
|
|
45d60a |
- if (local_family == AF_INET6) {
|
|
|
45d60a |
- /* Establish a default DUID. This may be moved to the
|
|
|
45d60a |
- * DHCPv4 area later.
|
|
|
45d60a |
- */
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /*
|
|
|
45d60a |
+ * Establish a default DUID. We always do so for v6 and
|
|
|
45d60a |
+ * do so if desired for v4 via the -D or -i options
|
|
|
45d60a |
+ */
|
|
|
45d60a |
+ if ((local_family == AF_INET6) ||
|
|
|
45d60a |
+ ((local_family == AF_INET) && (duid_v4 == 1))) {
|
|
|
45d60a |
if (default_duid.len == 0) {
|
|
|
45d60a |
if (default_duid.buffer != NULL)
|
|
|
45d60a |
data_string_forget(&default_duid, MDL);
|
|
|
45d60a |
@@ -983,7 +988,11 @@ main(int argc, char **argv) {
|
|
|
45d60a |
if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS)
|
|
|
45d60a |
write_duid(&default_duid);
|
|
|
45d60a |
}
|
|
|
45d60a |
+ }
|
|
|
45d60a |
|
|
|
45d60a |
+ /* Start a configuration state machine for each interface. */
|
|
|
45d60a |
+#ifdef DHCPv6
|
|
|
45d60a |
+ if (local_family == AF_INET6) {
|
|
|
45d60a |
for (ip = interfaces ; ip != NULL ; ip = ip->next) {
|
|
|
45d60a |
for (client = ip->client ; client != NULL ;
|
|
|
45d60a |
client = client->next) {
|
|
|
45d60a |
@@ -1115,9 +1124,9 @@ static void usage()
|
|
|
45d60a |
|
|
|
45d60a |
log_fatal("Usage: dhclient "
|
|
|
45d60a |
#ifdef DHCPv6
|
|
|
45d60a |
- "[-4|-6] [-SNTP1dvrx] [-nw] [-p <port>] [-D LL|LLT]\n"
|
|
|
45d60a |
+ "[-4|-6] [-SNTPI1dvrxc] [-nw] [-p <port>] [-D LL|LLT] \n"
|
|
|
45d60a |
#else /* DHCPv6 */
|
|
|
45d60a |
- "[-1dvrx] [-nw] [-p <port>]\n"
|
|
|
45d60a |
+ "[-C1dvrxc] [-nw] [-p <port>] [-D LL|LLT] \n"
|
|
|
45d60a |
#endif /* DHCPv6 */
|
|
|
45d60a |
" [-s server-addr] [-cf config-file] "
|
|
|
45d60a |
"[-lf lease-file]\n"
|
|
|
45d60a |
@@ -2823,24 +2832,24 @@ make_client_options(struct client_state *client, struct client_lease *lease,
|
|
|
45d60a |
unsigned i;
|
|
|
45d60a |
struct option_cache *oc;
|
|
|
45d60a |
struct option *option = NULL;
|
|
|
45d60a |
- struct buffer *bp = (struct buffer *)0;
|
|
|
45d60a |
+ struct buffer *bp = NULL;
|
|
|
45d60a |
|
|
|
45d60a |
/* If there are any leftover options, get rid of them. */
|
|
|
45d60a |
if (*op)
|
|
|
45d60a |
- option_state_dereference (op, MDL);
|
|
|
45d60a |
+ option_state_dereference(op, MDL);
|
|
|
45d60a |
|
|
|
45d60a |
/* Allocate space for options. */
|
|
|
45d60a |
- option_state_allocate (op, MDL);
|
|
|
45d60a |
+ option_state_allocate(op, MDL);
|
|
|
45d60a |
|
|
|
45d60a |
/* Send the server identifier if provided. */
|
|
|
45d60a |
if (sid)
|
|
|
45d60a |
- save_option (&dhcp_universe, *op, sid);
|
|
|
45d60a |
+ save_option(&dhcp_universe, *op, sid);
|
|
|
45d60a |
|
|
|
45d60a |
- oc = (struct option_cache *)0;
|
|
|
45d60a |
+ oc = NULL;
|
|
|
45d60a |
|
|
|
45d60a |
/* Send the requested address if provided. */
|
|
|
45d60a |
if (rip) {
|
|
|
45d60a |
- client -> requested_address = *rip;
|
|
|
45d60a |
+ client->requested_address = *rip;
|
|
|
45d60a |
i = DHO_DHCP_REQUESTED_ADDRESS;
|
|
|
45d60a |
if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash,
|
|
|
45d60a |
&i, 0, MDL) &&
|
|
|
45d60a |
@@ -2848,22 +2857,22 @@ make_client_options(struct client_state *client, struct client_lease *lease,
|
|
|
45d60a |
option, MDL)))
|
|
|
45d60a |
log_error ("can't make requested address cache.");
|
|
|
45d60a |
else {
|
|
|
45d60a |
- save_option (&dhcp_universe, *op, oc);
|
|
|
45d60a |
- option_cache_dereference (&oc, MDL);
|
|
|
45d60a |
+ save_option(&dhcp_universe, *op, oc);
|
|
|
45d60a |
+ option_cache_dereference(&oc, MDL);
|
|
|
45d60a |
}
|
|
|
45d60a |
option_dereference(&option, MDL);
|
|
|
45d60a |
} else {
|
|
|
45d60a |
- client -> requested_address.len = 0;
|
|
|
45d60a |
+ client->requested_address.len = 0;
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
i = DHO_DHCP_MESSAGE_TYPE;
|
|
|
45d60a |
if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash, &i, 0,
|
|
|
45d60a |
MDL) &&
|
|
|
45d60a |
make_const_option_cache(&oc, NULL, type, 1, option, MDL)))
|
|
|
45d60a |
- log_error ("can't make message type.");
|
|
|
45d60a |
+ log_error("can't make message type.");
|
|
|
45d60a |
else {
|
|
|
45d60a |
- save_option (&dhcp_universe, *op, oc);
|
|
|
45d60a |
- option_cache_dereference (&oc, MDL);
|
|
|
45d60a |
+ save_option(&dhcp_universe, *op, oc);
|
|
|
45d60a |
+ option_cache_dereference(&oc, MDL);
|
|
|
45d60a |
}
|
|
|
45d60a |
option_dereference(&option, MDL);
|
|
|
45d60a |
|
|
|
45d60a |
@@ -2876,8 +2885,8 @@ make_client_options(struct client_state *client, struct client_lease *lease,
|
|
|
45d60a |
if (prl[i]->universe == &dhcp_universe)
|
|
|
45d60a |
len++;
|
|
|
45d60a |
|
|
|
45d60a |
- if (!buffer_allocate (&bp, len, MDL))
|
|
|
45d60a |
- log_error ("can't make parameter list buffer.");
|
|
|
45d60a |
+ if (!buffer_allocate(&bp, len, MDL))
|
|
|
45d60a |
+ log_error("can't make parameter list buffer.");
|
|
|
45d60a |
else {
|
|
|
45d60a |
unsigned code = DHO_DHCP_PARAMETER_REQUEST_LIST;
|
|
|
45d60a |
|
|
|
45d60a |
@@ -2891,15 +2900,69 @@ make_client_options(struct client_state *client, struct client_lease *lease,
|
|
|
45d60a |
&code, 0, MDL) &&
|
|
|
45d60a |
make_const_option_cache(&oc, &bp, NULL, len,
|
|
|
45d60a |
option, MDL)))
|
|
|
45d60a |
- log_error ("can't make option cache");
|
|
|
45d60a |
+ log_error("can't make option cache");
|
|
|
45d60a |
else {
|
|
|
45d60a |
- save_option (&dhcp_universe, *op, oc);
|
|
|
45d60a |
- option_cache_dereference (&oc, MDL);
|
|
|
45d60a |
+ save_option(&dhcp_universe, *op, oc);
|
|
|
45d60a |
+ option_cache_dereference(&oc, MDL);
|
|
|
45d60a |
}
|
|
|
45d60a |
option_dereference(&option, MDL);
|
|
|
45d60a |
}
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
+ /*
|
|
|
45d60a |
+ * If requested (duid_v4 == 1) add an RFC4361 compliant client-identifier
|
|
|
45d60a |
+ * This can be overridden by including a client id in the configuration
|
|
|
45d60a |
+ * file.
|
|
|
45d60a |
+ */
|
|
|
45d60a |
+ if (duid_v4 == 1) {
|
|
|
45d60a |
+ struct data_string client_identifier;
|
|
|
45d60a |
+ int hw_idx, hw_len;
|
|
|
45d60a |
+
|
|
|
45d60a |
+ memset(&client_identifier, 0, sizeof(client_identifier));
|
|
|
45d60a |
+ client_identifier.len = 1 + 4 + default_duid.len;
|
|
|
45d60a |
+ if (!buffer_allocate(&client_identifier.buffer,
|
|
|
45d60a |
+ client_identifier.len, MDL))
|
|
|
45d60a |
+ log_fatal("no memory for default DUID!");
|
|
|
45d60a |
+ client_identifier.data = client_identifier.buffer->data;
|
|
|
45d60a |
+
|
|
|
45d60a |
+ i = DHO_DHCP_CLIENT_IDENTIFIER;
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /* Client-identifier type : 1 byte */
|
|
|
45d60a |
+ *client_identifier.buffer->data = 255;
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /* IAID : 4 bytes
|
|
|
45d60a |
+ * we use the low 4 bytes from the interface address
|
|
|
45d60a |
+ */
|
|
|
45d60a |
+ if (client->interface->hw_address.hlen > 4) {
|
|
|
45d60a |
+ hw_idx = client->interface->hw_address.hlen - 4;
|
|
|
45d60a |
+ hw_len = 4;
|
|
|
45d60a |
+ } else {
|
|
|
45d60a |
+ hw_idx = 0;
|
|
|
45d60a |
+ hw_len = client->interface->hw_address.hlen;
|
|
|
45d60a |
+ }
|
|
|
45d60a |
+ memcpy(&client_identifier.buffer->data + 5 - hw_len,
|
|
|
45d60a |
+ client->interface->hw_address.hbuf + hw_idx,
|
|
|
45d60a |
+ hw_len);
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /* Add the default duid */
|
|
|
45d60a |
+ memcpy(&client_identifier.buffer->data+(1+4),
|
|
|
45d60a |
+ default_duid.data, default_duid.len);
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /* And save the option */
|
|
|
45d60a |
+ if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash,
|
|
|
45d60a |
+ &i, 0, MDL) &&
|
|
|
45d60a |
+ make_const_option_cache(&oc, NULL,
|
|
|
45d60a |
+ (u_int8_t *)client_identifier.data,
|
|
|
45d60a |
+ client_identifier.len,
|
|
|
45d60a |
+ option, MDL)))
|
|
|
45d60a |
+ log_error ("can't make requested client id cache..");
|
|
|
45d60a |
+ else {
|
|
|
45d60a |
+ save_option (&dhcp_universe, *op, oc);
|
|
|
45d60a |
+ option_cache_dereference (&oc, MDL);
|
|
|
45d60a |
+ }
|
|
|
45d60a |
+ option_dereference(&option, MDL);
|
|
|
45d60a |
+ }
|
|
|
45d60a |
+
|
|
|
45d60a |
/* Run statements that need to be run on transmission. */
|
|
|
45d60a |
if (client -> config -> on_transmission)
|
|
|
45d60a |
execute_statements_in_scope
|
|
|
45d60a |
@@ -4522,6 +4585,7 @@ client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb)
|
|
|
45d60a |
struct option_cache *oc;
|
|
|
45d60a |
int ignorep;
|
|
|
45d60a |
int result;
|
|
|
45d60a |
+ int ddns_v4_type;
|
|
|
45d60a |
isc_result_t rcode;
|
|
|
45d60a |
|
|
|
45d60a |
/* If we didn't send an FQDN option, we certainly aren't going to
|
|
|
45d60a |
@@ -4564,47 +4628,82 @@ client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb)
|
|
|
45d60a |
&global_scope, oc, MDL))
|
|
|
45d60a |
return ISC_R_SUCCESS;
|
|
|
45d60a |
|
|
|
45d60a |
- /* If this is a DHCPv6 client update, make a dhcid string out of
|
|
|
45d60a |
- * the DUID. If this is a DHCPv4 client update, choose either
|
|
|
45d60a |
- * the client identifier, if there is one, or the interface's
|
|
|
45d60a |
- * MAC address.
|
|
|
45d60a |
+ /*
|
|
|
45d60a |
+ * Construct the DHCID value for use in the DDNS update process
|
|
|
45d60a |
+ * We have the newer standard version and the older interim version
|
|
|
45d60a |
+ * chosen by the '-C' option. The interim version is left as is
|
|
|
45d60a |
+ * for backwards compatibility. The standard version is based on
|
|
|
45d60a |
+ * RFC 4701 section 3.3
|
|
|
45d60a |
*/
|
|
|
45d60a |
+
|
|
|
45d60a |
result = 0;
|
|
|
45d60a |
memset(&client_identifier, 0, sizeof(client_identifier));
|
|
|
45d60a |
- if (client->active_lease != NULL) {
|
|
|
45d60a |
- if (((oc =
|
|
|
45d60a |
- lookup_option(&dhcpv6_universe, client->sent_options,
|
|
|
45d60a |
- D6O_CLIENTID)) != NULL) &&
|
|
|
45d60a |
- evaluate_option_cache(&client_identifier, NULL, NULL,
|
|
|
45d60a |
- client, client->sent_options, NULL,
|
|
|
45d60a |
+
|
|
|
45d60a |
+ if (std_dhcid == 1) {
|
|
|
45d60a |
+ /* standard style */
|
|
|
45d60a |
+ ddns_cb->dhcid_class = dns_rdatatype_dhcid;
|
|
|
45d60a |
+ ddns_v4_type = 1;
|
|
|
45d60a |
+ } else {
|
|
|
45d60a |
+ /* interim style */
|
|
|
45d60a |
+ ddns_cb->dhcid_class = dns_rdatatype_txt;
|
|
|
45d60a |
+ /* for backwards compatibility */
|
|
|
45d60a |
+ ddns_v4_type = DHO_DHCP_CLIENT_IDENTIFIER;
|
|
|
45d60a |
+ }
|
|
|
45d60a |
+
|
|
|
45d60a |
+ if (client->active_lease != NULL) {
|
|
|
45d60a |
+ /* V6 request, get the client identifier, then
|
|
|
45d60a |
+ * construct the dhcid for either standard
|
|
|
45d60a |
+ * or interim */
|
|
|
45d60a |
+ if (((oc = lookup_option(&dhcpv6_universe,
|
|
|
45d60a |
+ client->sent_options,
|
|
|
45d60a |
+ D6O_CLIENTID)) != NULL) &&
|
|
|
45d60a |
+ evaluate_option_cache(&client_identifier, NULL,
|
|
|
45d60a |
+ NULL, client,
|
|
|
45d60a |
+ client->sent_options, NULL,
|
|
|
45d60a |
&global_scope, oc, MDL)) {
|
|
|
45d60a |
- /* RFC4701 defines type '2' as being for the DUID
|
|
|
45d60a |
- * field. We aren't using RFC4701 DHCID RR's yet,
|
|
|
45d60a |
- * but this is as good a value as any.
|
|
|
45d60a |
- */
|
|
|
45d60a |
- result = get_dhcid(&ddns_cb->dhcid, 2,
|
|
|
45d60a |
+ result = get_dhcid(ddns_cb, 2,
|
|
|
45d60a |
client_identifier.data,
|
|
|
45d60a |
client_identifier.len);
|
|
|
45d60a |
data_string_forget(&client_identifier, MDL);
|
|
|
45d60a |
} else
|
|
|
45d60a |
log_fatal("Impossible condition at %s:%d.", MDL);
|
|
|
45d60a |
} else {
|
|
|
45d60a |
- if (((oc =
|
|
|
45d60a |
- lookup_option(&dhcp_universe, client->sent_options,
|
|
|
45d60a |
- DHO_DHCP_CLIENT_IDENTIFIER)) != NULL) &&
|
|
|
45d60a |
- evaluate_option_cache(&client_identifier, NULL, NULL,
|
|
|
45d60a |
- client, client->sent_options, NULL,
|
|
|
45d60a |
+ /*
|
|
|
45d60a |
+ * V4 request, use the client id if there is one or the
|
|
|
45d60a |
+ * mac address if there isn't. If we have a client id
|
|
|
45d60a |
+ * we check to see if it is an embedded DUID.
|
|
|
45d60a |
+ */
|
|
|
45d60a |
+ if (((oc = lookup_option(&dhcp_universe,
|
|
|
45d60a |
+ client->sent_options,
|
|
|
45d60a |
+ DHO_DHCP_CLIENT_IDENTIFIER)) != NULL) &&
|
|
|
45d60a |
+ evaluate_option_cache(&client_identifier, NULL,
|
|
|
45d60a |
+ NULL, client,
|
|
|
45d60a |
+ client->sent_options, NULL,
|
|
|
45d60a |
&global_scope, oc, MDL)) {
|
|
|
45d60a |
- result = get_dhcid(&ddns_cb->dhcid,
|
|
|
45d60a |
- DHO_DHCP_CLIENT_IDENTIFIER,
|
|
|
45d60a |
- client_identifier.data,
|
|
|
45d60a |
- client_identifier.len);
|
|
|
45d60a |
+ if ((std_dhcid == 1) && (duid_v4 == 1) &&
|
|
|
45d60a |
+ (client_identifier.data[0] == 255)) {
|
|
|
45d60a |
+ /*
|
|
|
45d60a |
+ * This appears to be an embedded DUID,
|
|
|
45d60a |
+ * extract it and treat it as such
|
|
|
45d60a |
+ */
|
|
|
45d60a |
+ if (client_identifier.len <= 5)
|
|
|
45d60a |
+ log_fatal("Impossible condition at %s:%d.",
|
|
|
45d60a |
+ MDL);
|
|
|
45d60a |
+ result = get_dhcid(ddns_cb, 2,
|
|
|
45d60a |
+ client_identifier.data + 5,
|
|
|
45d60a |
+ client_identifier.len - 5);
|
|
|
45d60a |
+ } else {
|
|
|
45d60a |
+ result = get_dhcid(ddns_cb, ddns_v4_type,
|
|
|
45d60a |
+ client_identifier.data,
|
|
|
45d60a |
+ client_identifier.len);
|
|
|
45d60a |
+ }
|
|
|
45d60a |
data_string_forget(&client_identifier, MDL);
|
|
|
45d60a |
} else
|
|
|
45d60a |
- result = get_dhcid(&ddns_cb->dhcid, 0,
|
|
|
45d60a |
+ result = get_dhcid(ddns_cb, 0,
|
|
|
45d60a |
client->interface->hw_address.hbuf,
|
|
|
45d60a |
client->interface->hw_address.hlen);
|
|
|
45d60a |
}
|
|
|
45d60a |
+
|
|
|
45d60a |
if (!result) {
|
|
|
45d60a |
return ISC_R_SUCCESS;
|
|
|
45d60a |
}
|
|
|
45d60a |
@@ -4886,3 +4985,4 @@ dhclient_ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, char* file, int line) {
|
|
|
45d60a |
ddns_cb_free(ddns_cb, file, line);
|
|
|
45d60a |
}
|
|
|
45d60a |
}
|
|
|
45d60a |
+
|
|
|
45d60a |
diff --git a/common/conflex.c b/common/conflex.c
|
|
|
45d60a |
index 4611616..c99732e 100644
|
|
|
45d60a |
--- a/common/conflex.c
|
|
|
45d60a |
+++ b/common/conflex.c
|
|
|
45d60a |
@@ -879,10 +879,6 @@ intern(char *atom, enum dhcp_token dfv) {
|
|
|
45d60a |
case 'd':
|
|
|
45d60a |
if (!strcasecmp(atom + 1, "b-time-format"))
|
|
|
45d60a |
return DB_TIME_FORMAT;
|
|
|
45d60a |
- if (!strcasecmp (atom + 1, "ns-update"))
|
|
|
45d60a |
- return DNS_UPDATE;
|
|
|
45d60a |
- if (!strcasecmp (atom + 1, "ns-delete"))
|
|
|
45d60a |
- return DNS_DELETE;
|
|
|
45d60a |
if (!strcasecmp (atom + 1, "omain"))
|
|
|
45d60a |
return DOMAIN;
|
|
|
45d60a |
if (!strncasecmp (atom + 1, "omain-", 6)) {
|
|
|
45d60a |
@@ -1178,8 +1174,6 @@ intern(char *atom, enum dhcp_token dfv) {
|
|
|
45d60a |
return TOKEN_NOT;
|
|
|
45d60a |
if (!strcasecmp (atom + 1, "o"))
|
|
|
45d60a |
return TOKEN_NO;
|
|
|
45d60a |
- if (!strcasecmp (atom + 1, "s-update"))
|
|
|
45d60a |
- return NS_UPDATE;
|
|
|
45d60a |
if (!strcasecmp (atom + 1, "oerror"))
|
|
|
45d60a |
return NS_NOERROR;
|
|
|
45d60a |
if (!strcasecmp (atom + 1, "otauth"))
|
|
|
45d60a |
@@ -1496,8 +1490,6 @@ intern(char *atom, enum dhcp_token dfv) {
|
|
|
45d60a |
}
|
|
|
45d60a |
if (!strcasecmp (atom + 1, "nauthenticated"))
|
|
|
45d60a |
return UNAUTHENTICATED;
|
|
|
45d60a |
- if (!strcasecmp (atom + 1, "pdated-dns-rr"))
|
|
|
45d60a |
- return UPDATED_DNS_RR;
|
|
|
45d60a |
if (!strcasecmp (atom + 1, "pdate"))
|
|
|
45d60a |
return UPDATE;
|
|
|
45d60a |
break;
|
|
|
45d60a |
diff --git a/common/dns.c b/common/dns.c
|
|
|
45d60a |
index d3ac966..a04c61d 100644
|
|
|
45d60a |
--- a/common/dns.c
|
|
|
45d60a |
+++ b/common/dns.c
|
|
|
45d60a |
@@ -30,10 +30,12 @@
|
|
|
45d60a |
* asynchronous DNS routines.
|
|
|
45d60a |
*/
|
|
|
45d60a |
|
|
|
45d60a |
+/*! \file common/dns.c
|
|
|
45d60a |
+ */
|
|
|
45d60a |
#include "dhcpd.h"
|
|
|
45d60a |
#include "arpa/nameser.h"
|
|
|
45d60a |
#include <isc/md5.h>
|
|
|
45d60a |
-
|
|
|
45d60a |
+#include <isc/sha2.h>
|
|
|
45d60a |
#include <dns/result.h>
|
|
|
45d60a |
|
|
|
45d60a |
/*
|
|
|
45d60a |
@@ -823,45 +825,123 @@ void repudiate_zone (struct dns_zone **zone)
|
|
|
45d60a |
dns_zone_dereference (zone, MDL);
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
-/* Have to use TXT records for now. */
|
|
|
45d60a |
-#define T_DHCID T_TXT
|
|
|
45d60a |
+/*!
|
|
|
45d60a |
+ * \brief Create an id for a client
|
|
|
45d60a |
+ *
|
|
|
45d60a |
+ * This function is used to create an id for a client to use with DDNS
|
|
|
45d60a |
+ * This version of the function is for the standard style, RFC 4701
|
|
|
45d60a |
+ *
|
|
|
45d60a |
+ * This function takes information from the type and data fields and
|
|
|
45d60a |
+ * mangles it into a dhcid string which it places in ddns_cb. It also
|
|
|
45d60a |
+ * sets a field in ddns_cb to specify the class that should be used
|
|
|
45d60a |
+ * when sending the dhcid, in this case it is a DHCID record so we use
|
|
|
45d60a |
+ * dns_rdatatype_dhcid
|
|
|
45d60a |
+ *
|
|
|
45d60a |
+ * The DHCID we construct is:
|
|
|
45d60a |
+ * 2 bytes - identifier type (see 4701 and IANA)
|
|
|
45d60a |
+ * 1 byte - digest type, currently only SHA256 (1)
|
|
|
45d60a |
+ * n bytes - digest, length depends on digest type, currently 32 for
|
|
|
45d60a |
+ * SHA256
|
|
|
45d60a |
+ *
|
|
|
45d60a |
+ * What we base the digest on is up to the calling code for an id type of
|
|
|
45d60a |
+ * 0 - 1 octet htype followed by hlen octets of chaddr from v4 client request
|
|
|
45d60a |
+ * 1 - data octets from a dhcpv4 client's client identifier option
|
|
|
45d60a |
+ * 2 - the client DUID from a v4 or v6 client's client id option
|
|
|
45d60a |
+ * This identifier is concatenated with the fqdn and the result is digested.
|
|
|
45d60a |
+ */
|
|
|
45d60a |
+int get_std_dhcid(dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
+ int type,
|
|
|
45d60a |
+ const u_int8_t *identifier,
|
|
|
45d60a |
+ unsigned id_len)
|
|
|
45d60a |
+{
|
|
|
45d60a |
+ struct data_string *id = &ddns_cb->dhcid;
|
|
|
45d60a |
+ isc_sha256_t sha256;
|
|
|
45d60a |
+ unsigned char buf[ISC_SHA256_DIGESTLENGTH];
|
|
|
45d60a |
+ unsigned char fwd_buf[256];
|
|
|
45d60a |
+ unsigned fwd_buflen = 0;
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /* Types can only be 0..(2^16)-1. */
|
|
|
45d60a |
+ if (type < 0 || type > 65535)
|
|
|
45d60a |
+ return (0);
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /* We need to convert the fwd name to wire representation */
|
|
|
45d60a |
+ if (MRns_name_pton((char *)ddns_cb->fwd_name.data, fwd_buf, 256) == -1)
|
|
|
45d60a |
+ return (0);
|
|
|
45d60a |
+ while(fwd_buf[fwd_buflen] != 0) {
|
|
|
45d60a |
+ fwd_buflen += fwd_buf[fwd_buflen] + 1;
|
|
|
45d60a |
+ }
|
|
|
45d60a |
+ fwd_buflen++;
|
|
|
45d60a |
+
|
|
|
45d60a |
+ if (!buffer_allocate(&id->buffer,
|
|
|
45d60a |
+ ISC_SHA256_DIGESTLENGTH + 2 + 1,
|
|
|
45d60a |
+ MDL))
|
|
|
45d60a |
+ return (0);
|
|
|
45d60a |
+ id->data = id->buffer->data;
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /* The two first bytes contain the type identifier. */
|
|
|
45d60a |
+ putUShort(id->buffer->data, (unsigned)type);
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /* The next is the digest type, SHA-256 is 1 */
|
|
|
45d60a |
+ putUChar(id->buffer->data + 2, 1u);
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /* Computing the digest */
|
|
|
45d60a |
+ isc_sha256_init(&sha256);
|
|
|
45d60a |
+ isc_sha256_update(&sha256, identifier, id_len);
|
|
|
45d60a |
+ isc_sha256_update(&sha256, fwd_buf, fwd_buflen);
|
|
|
45d60a |
+ isc_sha256_final(buf, &sha256);
|
|
|
45d60a |
|
|
|
45d60a |
-int get_dhcid (struct data_string *id,
|
|
|
45d60a |
- int type, const u_int8_t *data, unsigned len)
|
|
|
45d60a |
+ memcpy(id->buffer->data + 3, &buf, ISC_SHA256_DIGESTLENGTH);
|
|
|
45d60a |
+
|
|
|
45d60a |
+ id->len = ISC_SHA256_DIGESTLENGTH + 2 + 1;
|
|
|
45d60a |
+
|
|
|
45d60a |
+ return (1);
|
|
|
45d60a |
+}
|
|
|
45d60a |
+
|
|
|
45d60a |
+/*!
|
|
|
45d60a |
+ *
|
|
|
45d60a |
+ * \brief Create an id for a client
|
|
|
45d60a |
+ *
|
|
|
45d60a |
+ * This function is used to create an id for a client to use with DDNS
|
|
|
45d60a |
+ * This version of the function is for the interim style. It is retained
|
|
|
45d60a |
+ * to allow users to continue using the interim style but they should
|
|
|
45d60a |
+ * switch to the standard style (which uses get_std_dhcid) for better
|
|
|
45d60a |
+ * interoperability.
|
|
|
45d60a |
+ *
|
|
|
45d60a |
+ * This function takes information from the type and data fields and
|
|
|
45d60a |
+ * mangles it into a dhcid string which it places in ddns_cb. It also
|
|
|
45d60a |
+ * sets a field in ddns_cb to specify the class that should be used
|
|
|
45d60a |
+ * when sending the dhcid, in this case it is a txt record so we use
|
|
|
45d60a |
+ * dns_rdata_type_txt
|
|
|
45d60a |
+ *
|
|
|
45d60a |
+ * NOTE WELL: this function has issues with how it calculates the
|
|
|
45d60a |
+ * dhcid, they can't be changed now as that would break the records
|
|
|
45d60a |
+ * already in use.
|
|
|
45d60a |
+ */
|
|
|
45d60a |
+
|
|
|
45d60a |
+int get_int_dhcid (dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
+ int type,
|
|
|
45d60a |
+ const u_int8_t *data,
|
|
|
45d60a |
+ unsigned len)
|
|
|
45d60a |
{
|
|
|
45d60a |
+ struct data_string *id = &ddns_cb->dhcid;
|
|
|
45d60a |
unsigned char buf[ISC_MD5_DIGESTLENGTH];
|
|
|
45d60a |
isc_md5_t md5;
|
|
|
45d60a |
int i;
|
|
|
45d60a |
|
|
|
45d60a |
/* Types can only be 0..(2^16)-1. */
|
|
|
45d60a |
if (type < 0 || type > 65535)
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
+ return (0);
|
|
|
45d60a |
|
|
|
45d60a |
/*
|
|
|
45d60a |
* Hexadecimal MD5 digest plus two byte type, NUL,
|
|
|
45d60a |
* and one byte for length for dns.
|
|
|
45d60a |
*/
|
|
|
45d60a |
- if (!buffer_allocate (&id -> buffer,
|
|
|
45d60a |
- (ISC_MD5_DIGESTLENGTH * 2) + 4, MDL))
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
- id -> data = id -> buffer -> data;
|
|
|
45d60a |
+ if (!buffer_allocate(&id -> buffer,
|
|
|
45d60a |
+ (ISC_MD5_DIGESTLENGTH * 2) + 4, MDL))
|
|
|
45d60a |
+ return (0);
|
|
|
45d60a |
+ id->data = id->buffer->data;
|
|
|
45d60a |
|
|
|
45d60a |
/*
|
|
|
45d60a |
- * DHCP clients and servers should use the following forms of client
|
|
|
45d60a |
- * identification, starting with the most preferable, and finishing
|
|
|
45d60a |
- * with the least preferable. If the client does not send any of these
|
|
|
45d60a |
- * forms of identification, the DHCP/DDNS interaction is not defined by
|
|
|
45d60a |
- * this specification. The most preferable form of identification is
|
|
|
45d60a |
- * the Globally Unique Identifier Option [TBD]. Next is the DHCP
|
|
|
45d60a |
- * Client Identifier option. Last is the client's link-layer address,
|
|
|
45d60a |
- * as conveyed in its DHCPREQUEST message. Implementors should note
|
|
|
45d60a |
- * that the link-layer address cannot be used if there are no
|
|
|
45d60a |
- * significant bytes in the chaddr field of the DHCP client's request,
|
|
|
45d60a |
- * because this does not constitute a unique identifier.
|
|
|
45d60a |
- * -- "Interaction between DHCP and DNS"
|
|
|
45d60a |
- * <draft-ietf-dhc-dhcp-dns-12.txt>
|
|
|
45d60a |
- * M. Stapp, Y. Rekhter
|
|
|
45d60a |
- *
|
|
|
45d60a |
* We put the length into the first byte to turn
|
|
|
45d60a |
* this into a dns text string. This avoid needing to
|
|
|
45d60a |
* copy the string to add the byte later.
|
|
|
45d60a |
@@ -893,7 +973,18 @@ int get_dhcid (struct data_string *id,
|
|
|
45d60a |
id->buffer->data[id->len] = 0;
|
|
|
45d60a |
id->terminated = 1;
|
|
|
45d60a |
|
|
|
45d60a |
- return 1;
|
|
|
45d60a |
+ return (1);
|
|
|
45d60a |
+}
|
|
|
45d60a |
+
|
|
|
45d60a |
+int get_dhcid(dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
+ int type,
|
|
|
45d60a |
+ const u_int8_t *identifier,
|
|
|
45d60a |
+ unsigned id_len)
|
|
|
45d60a |
+{
|
|
|
45d60a |
+ if (ddns_cb->dhcid_class == dns_rdatatype_dhcid)
|
|
|
45d60a |
+ return get_std_dhcid(ddns_cb, type, identifier, id_len);
|
|
|
45d60a |
+ else
|
|
|
45d60a |
+ return get_int_dhcid(ddns_cb, type, identifier, id_len);
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
/*
|
|
|
45d60a |
@@ -1015,12 +1106,12 @@ make_dns_dataset(dns_rdataclass_t dataclass,
|
|
|
45d60a |
* For the server the first step will have a request of:
|
|
|
45d60a |
* The name is not in use
|
|
|
45d60a |
* Add an A RR
|
|
|
45d60a |
- * Add a DHCID RR (currently txt)
|
|
|
45d60a |
+ * Add a DHCID RR
|
|
|
45d60a |
*
|
|
|
45d60a |
* For the client the first step will have a request of:
|
|
|
45d60a |
* The A RR does not exist
|
|
|
45d60a |
* Add an A RR
|
|
|
45d60a |
- * Add a DHCID RR (currently txt)
|
|
|
45d60a |
+ * Add a DHCID RR
|
|
|
45d60a |
*/
|
|
|
45d60a |
|
|
|
45d60a |
static isc_result_t
|
|
|
45d60a |
@@ -1062,7 +1153,7 @@ ddns_modify_fwd_add1(dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
dataspace++;
|
|
|
45d60a |
|
|
|
45d60a |
/* Add the DHCID RR */
|
|
|
45d60a |
- result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt,
|
|
|
45d60a |
+ result = make_dns_dataset(dns_rdataclass_in, ddns_cb->dhcid_class,
|
|
|
45d60a |
dataspace,
|
|
|
45d60a |
(unsigned char *)ddns_cb->dhcid.data,
|
|
|
45d60a |
ddns_cb->dhcid.len, ddns_cb->ttl);
|
|
|
45d60a |
@@ -1108,7 +1199,7 @@ ddns_modify_fwd_add2(dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
dns_name_t *pname,
|
|
|
45d60a |
dns_name_t *uname)
|
|
|
45d60a |
{
|
|
|
45d60a |
- isc_result_t result;
|
|
|
45d60a |
+ isc_result_t result = ISC_R_SUCCESS;
|
|
|
45d60a |
|
|
|
45d60a |
/*
|
|
|
45d60a |
* If we are doing conflict resolution (unset) we use a prereq list.
|
|
|
45d60a |
@@ -1117,7 +1208,7 @@ ddns_modify_fwd_add2(dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
if ((ddns_cb->flags & DDNS_CONFLICT_OVERRIDE) == 0) {
|
|
|
45d60a |
/* Construct the prereq list */
|
|
|
45d60a |
/* The DHCID RR exists and matches the client identity */
|
|
|
45d60a |
- result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt,
|
|
|
45d60a |
+ result = make_dns_dataset(dns_rdataclass_in, ddns_cb->dhcid_class,
|
|
|
45d60a |
dataspace,
|
|
|
45d60a |
(unsigned char *)ddns_cb->dhcid.data,
|
|
|
45d60a |
ddns_cb->dhcid.len, 0);
|
|
|
45d60a |
@@ -1130,7 +1221,7 @@ ddns_modify_fwd_add2(dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
/* Start constructing the update list.
|
|
|
45d60a |
* Conflict detection override: delete DHCID RRs */
|
|
|
45d60a |
result = make_dns_dataset(dns_rdataclass_any,
|
|
|
45d60a |
- dns_rdatatype_txt,
|
|
|
45d60a |
+ ddns_cb->dhcid_class,
|
|
|
45d60a |
dataspace, NULL, 0, 0);
|
|
|
45d60a |
if (result != ISC_R_SUCCESS) {
|
|
|
45d60a |
return(result);
|
|
|
45d60a |
@@ -1139,7 +1230,7 @@ ddns_modify_fwd_add2(dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
dataspace++;
|
|
|
45d60a |
|
|
|
45d60a |
/* Add current DHCID RR */
|
|
|
45d60a |
- result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt,
|
|
|
45d60a |
+ result = make_dns_dataset(dns_rdataclass_in, ddns_cb->dhcid_class,
|
|
|
45d60a |
dataspace,
|
|
|
45d60a |
(unsigned char *)ddns_cb->dhcid.data,
|
|
|
45d60a |
ddns_cb->dhcid.len, ddns_cb->ttl);
|
|
|
45d60a |
@@ -1201,11 +1292,11 @@ ddns_modify_fwd_rem1(dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
dns_name_t *pname,
|
|
|
45d60a |
dns_name_t *uname)
|
|
|
45d60a |
{
|
|
|
45d60a |
- isc_result_t result;
|
|
|
45d60a |
+ isc_result_t result = ISC_R_SUCCESS;
|
|
|
45d60a |
|
|
|
45d60a |
/* Consruct the prereq list */
|
|
|
45d60a |
/* The DHCID RR exists and matches the client identity */
|
|
|
45d60a |
- result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt,
|
|
|
45d60a |
+ result = make_dns_dataset(dns_rdataclass_in, ddns_cb->dhcid_class,
|
|
|
45d60a |
dataspace,
|
|
|
45d60a |
(unsigned char *)ddns_cb->dhcid.data,
|
|
|
45d60a |
ddns_cb->dhcid.len, 0);
|
|
|
45d60a |
@@ -1271,7 +1362,7 @@ ddns_modify_fwd_rem2(dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
|
|
|
45d60a |
/* Construct the update list */
|
|
|
45d60a |
/* Delete DHCID RR */
|
|
|
45d60a |
- result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_txt,
|
|
|
45d60a |
+ result = make_dns_dataset(dns_rdataclass_none, ddns_cb->dhcid_class,
|
|
|
45d60a |
dataspace,
|
|
|
45d60a |
(unsigned char *)ddns_cb->dhcid.data,
|
|
|
45d60a |
ddns_cb->dhcid.len, 0);
|
|
|
45d60a |
diff --git a/common/parse.c b/common/parse.c
|
|
|
45d60a |
index fc51327..7477543 100644
|
|
|
45d60a |
--- a/common/parse.c
|
|
|
45d60a |
+++ b/common/parse.c
|
|
|
45d60a |
@@ -3558,42 +3558,7 @@ int parse_numeric_expression (expr, cfile, lose)
|
|
|
45d60a |
}
|
|
|
45d60a |
return 1;
|
|
|
45d60a |
}
|
|
|
45d60a |
-#if defined (NSUPDATE_OLD)
|
|
|
45d60a |
-/*
|
|
|
45d60a |
- * dns-expression :==
|
|
|
45d60a |
- * UPDATE LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
|
|
|
45d60a |
- * data-expression COMMA numeric-expression RPAREN
|
|
|
45d60a |
- * DELETE LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
|
|
|
45d60a |
- * data-expression RPAREN
|
|
|
45d60a |
- * EXISTS LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
|
|
|
45d60a |
- * data-expression RPAREN
|
|
|
45d60a |
- * NOT EXISTS LPAREN ns-class COMMA ns-type COMMA data-expression COMMA
|
|
|
45d60a |
- * data-expression RPAREN
|
|
|
45d60a |
- * ns-class :== IN | CHAOS | HS | NUMBER
|
|
|
45d60a |
- * ns-type :== A | PTR | MX | TXT | NUMBER
|
|
|
45d60a |
- */
|
|
|
45d60a |
-
|
|
|
45d60a |
-int parse_dns_expression (expr, cfile, lose)
|
|
|
45d60a |
- struct expression **expr;
|
|
|
45d60a |
- struct parse *cfile;
|
|
|
45d60a |
- int *lose;
|
|
|
45d60a |
-{
|
|
|
45d60a |
- /* Parse an expression... */
|
|
|
45d60a |
- if (!parse_expression (expr, cfile, lose, context_dns,
|
|
|
45d60a |
- (struct expression **)0, expr_none))
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
|
|
|
45d60a |
- if (!is_dns_expression (*expr) &&
|
|
|
45d60a |
- (*expr) -> op != expr_variable_reference &&
|
|
|
45d60a |
- (*expr) -> op != expr_funcall) {
|
|
|
45d60a |
- expression_dereference (expr, MDL);
|
|
|
45d60a |
- parse_warn (cfile, "Expecting a dns update subexpression.");
|
|
|
45d60a |
- *lose = 1;
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- return 1;
|
|
|
45d60a |
-}
|
|
|
45d60a |
-#endif /* NSUPDATE_OLD */
|
|
|
45d60a |
/* Parse a subexpression that does not contain a binary operator. */
|
|
|
45d60a |
|
|
|
45d60a |
int parse_non_binary (expr, cfile, lose, context)
|
|
|
45d60a |
@@ -3608,11 +3573,6 @@ int parse_non_binary (expr, cfile, lose, context)
|
|
|
45d60a |
struct expression *nexp, **ep;
|
|
|
45d60a |
int known;
|
|
|
45d60a |
char *cptr;
|
|
|
45d60a |
-#if defined (NSUPDATE_OLD)
|
|
|
45d60a |
- enum expr_op opcode;
|
|
|
45d60a |
- const char *s;
|
|
|
45d60a |
- unsigned long u;
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
isc_result_t status;
|
|
|
45d60a |
unsigned len;
|
|
|
45d60a |
|
|
|
45d60a |
@@ -3645,12 +3605,7 @@ int parse_non_binary (expr, cfile, lose, context)
|
|
|
45d60a |
|
|
|
45d60a |
case TOKEN_NOT:
|
|
|
45d60a |
token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
-#if defined(NSUPDATE_OLD)
|
|
|
45d60a |
- if (context == context_dns) {
|
|
|
45d60a |
- token = peek_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- goto not_exists;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
+
|
|
|
45d60a |
if (!expression_allocate (expr, MDL))
|
|
|
45d60a |
log_fatal ("can't allocate expression");
|
|
|
45d60a |
(*expr) -> op = expr_not;
|
|
|
45d60a |
@@ -3662,7 +3617,7 @@ int parse_non_binary (expr, cfile, lose, context)
|
|
|
45d60a |
}
|
|
|
45d60a |
*lose = 1;
|
|
|
45d60a |
expression_dereference (expr, MDL);
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
+ return (0);
|
|
|
45d60a |
}
|
|
|
45d60a |
if (!is_boolean_expression ((*expr) -> data.not)) {
|
|
|
45d60a |
*lose = 1;
|
|
|
45d60a |
@@ -3694,10 +3649,6 @@ int parse_non_binary (expr, cfile, lose, context)
|
|
|
45d60a |
break;
|
|
|
45d60a |
|
|
|
45d60a |
case EXISTS:
|
|
|
45d60a |
-#if defined(NSUPDATE_OLD)
|
|
|
45d60a |
- if (context == context_dns)
|
|
|
45d60a |
- goto ns_exists;
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
if (!expression_allocate (expr, MDL))
|
|
|
45d60a |
log_fatal ("can't allocate expression");
|
|
|
45d60a |
@@ -3710,7 +3661,7 @@ int parse_non_binary (expr, cfile, lose, context)
|
|
|
45d60a |
(*expr)->data.option == NULL) {
|
|
|
45d60a |
*lose = 1;
|
|
|
45d60a |
expression_dereference (expr, MDL);
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
+ return (0);
|
|
|
45d60a |
}
|
|
|
45d60a |
break;
|
|
|
45d60a |
|
|
|
45d60a |
@@ -4011,285 +3962,7 @@ int parse_non_binary (expr, cfile, lose, context)
|
|
|
45d60a |
goto norparen;
|
|
|
45d60a |
break;
|
|
|
45d60a |
|
|
|
45d60a |
-#if defined(NSUPDATE_OLD)
|
|
|
45d60a |
- /* dns-update and dns-delete are present for historical
|
|
|
45d60a |
- purposes, but are deprecated in favor of ns-update
|
|
|
45d60a |
- in combination with update, delete, exists and not
|
|
|
45d60a |
- exists. */
|
|
|
45d60a |
- case DNS_UPDATE:
|
|
|
45d60a |
- case DNS_DELETE:
|
|
|
45d60a |
-#if !defined (NSUPDATE)
|
|
|
45d60a |
- parse_warn (cfile,
|
|
|
45d60a |
- "Please rebuild dhcpd with --with-nsupdate.");
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token == DNS_UPDATE)
|
|
|
45d60a |
- opcode = expr_ns_add;
|
|
|
45d60a |
- else
|
|
|
45d60a |
- opcode = expr_ns_delete;
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != LPAREN)
|
|
|
45d60a |
- goto nolparen;
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != STRING) {
|
|
|
45d60a |
- parse_warn (cfile,
|
|
|
45d60a |
- "parse_expression: expecting string.");
|
|
|
45d60a |
- badnsupdate:
|
|
|
45d60a |
- skip_to_semi (cfile);
|
|
|
45d60a |
- *lose = 1;
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (!strcasecmp (val, "a"))
|
|
|
45d60a |
- u = T_A;
|
|
|
45d60a |
- else if (!strcasecmp (val, "aaaa"))
|
|
|
45d60a |
- u = T_AAAA;
|
|
|
45d60a |
- else if (!strcasecmp (val, "ptr"))
|
|
|
45d60a |
- u = T_PTR;
|
|
|
45d60a |
- else if (!strcasecmp (val, "mx"))
|
|
|
45d60a |
- u = T_MX;
|
|
|
45d60a |
- else if (!strcasecmp (val, "cname"))
|
|
|
45d60a |
- u = T_CNAME;
|
|
|
45d60a |
- else if (!strcasecmp (val, "TXT"))
|
|
|
45d60a |
- u = T_TXT;
|
|
|
45d60a |
- else {
|
|
|
45d60a |
- parse_warn (cfile, "unexpected rrtype: %s", val);
|
|
|
45d60a |
- goto badnsupdate;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- s = (opcode == expr_ns_add
|
|
|
45d60a |
- ? "old-dns-update"
|
|
|
45d60a |
- : "old-dns-delete");
|
|
|
45d60a |
- cptr = dmalloc (strlen (s) + 1, MDL);
|
|
|
45d60a |
- if (!cptr)
|
|
|
45d60a |
- log_fatal ("can't allocate name for %s", s);
|
|
|
45d60a |
- strcpy (cptr, s);
|
|
|
45d60a |
- if (!expression_allocate (expr, MDL))
|
|
|
45d60a |
- log_fatal ("can't allocate expression");
|
|
|
45d60a |
- (*expr) -> op = expr_funcall;
|
|
|
45d60a |
- (*expr) -> data.funcall.name = cptr;
|
|
|
45d60a |
-
|
|
|
45d60a |
- /* Fake up a function call. */
|
|
|
45d60a |
- ep = &(*expr) -> data.funcall.arglist;
|
|
|
45d60a |
- if (!expression_allocate (ep, MDL))
|
|
|
45d60a |
- log_fatal ("can't allocate expression");
|
|
|
45d60a |
- (*ep) -> op = expr_arg;
|
|
|
45d60a |
- if (!make_const_int (&(*ep) -> data.arg.val, u))
|
|
|
45d60a |
- log_fatal ("can't allocate rrtype value.");
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != COMMA)
|
|
|
45d60a |
- goto nocomma;
|
|
|
45d60a |
- ep = &((*ep) -> data.arg.next);
|
|
|
45d60a |
- if (!expression_allocate (ep, MDL))
|
|
|
45d60a |
- log_fatal ("can't allocate expression");
|
|
|
45d60a |
- (*ep) -> op = expr_arg;
|
|
|
45d60a |
- if (!(parse_data_expression (&(*ep) -> data.arg.val,
|
|
|
45d60a |
- cfile, lose)))
|
|
|
45d60a |
- goto nodata;
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != COMMA)
|
|
|
45d60a |
- goto nocomma;
|
|
|
45d60a |
-
|
|
|
45d60a |
- ep = &((*ep) -> data.arg.next);
|
|
|
45d60a |
- if (!expression_allocate (ep, MDL))
|
|
|
45d60a |
- log_fatal ("can't allocate expression");
|
|
|
45d60a |
- (*ep) -> op = expr_arg;
|
|
|
45d60a |
- if (!(parse_data_expression (&(*ep) -> data.arg.val,
|
|
|
45d60a |
- cfile, lose)))
|
|
|
45d60a |
- goto nodata;
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (opcode == expr_ns_add) {
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != COMMA)
|
|
|
45d60a |
- goto nocomma;
|
|
|
45d60a |
-
|
|
|
45d60a |
- ep = &((*ep) -> data.arg.next);
|
|
|
45d60a |
- if (!expression_allocate (ep, MDL))
|
|
|
45d60a |
- log_fatal ("can't allocate expression");
|
|
|
45d60a |
- (*ep) -> op = expr_arg;
|
|
|
45d60a |
- if (!(parse_numeric_expression (&(*ep) -> data.arg.val,
|
|
|
45d60a |
- cfile, lose))) {
|
|
|
45d60a |
- parse_warn (cfile,
|
|
|
45d60a |
- "expecting numeric expression.");
|
|
|
45d60a |
- goto badnsupdate;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != RPAREN)
|
|
|
45d60a |
- goto norparen;
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case NS_UPDATE:
|
|
|
45d60a |
-#if !defined (NSUPDATE)
|
|
|
45d60a |
- parse_warn (cfile,
|
|
|
45d60a |
- "Please rebuild dhcpd with --with-nsupdate.");
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (!expression_allocate (expr, MDL))
|
|
|
45d60a |
- log_fatal ("can't allocate expression");
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != LPAREN)
|
|
|
45d60a |
- goto nolparen;
|
|
|
45d60a |
-
|
|
|
45d60a |
- nexp = *expr;
|
|
|
45d60a |
- do {
|
|
|
45d60a |
- nexp -> op = expr_dns_transaction;
|
|
|
45d60a |
- if (!(parse_dns_expression
|
|
|
45d60a |
- (&nexp -> data.dns_transaction.car,
|
|
|
45d60a |
- cfile, lose)))
|
|
|
45d60a |
- {
|
|
|
45d60a |
- if (!*lose)
|
|
|
45d60a |
- parse_warn
|
|
|
45d60a |
- (cfile,
|
|
|
45d60a |
- "expecting dns expression.");
|
|
|
45d60a |
- expression_dereference (expr, MDL);
|
|
|
45d60a |
- *lose = 1;
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (token == COMMA) {
|
|
|
45d60a |
- if (!(expression_allocate
|
|
|
45d60a |
- (&nexp -> data.dns_transaction.cdr,
|
|
|
45d60a |
- MDL)))
|
|
|
45d60a |
- log_fatal
|
|
|
45d60a |
- ("can't allocate expression");
|
|
|
45d60a |
- nexp = nexp -> data.dns_transaction.cdr;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- } while (token == COMMA);
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (token != RPAREN)
|
|
|
45d60a |
- goto norparen;
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
- /* NOT EXISTS is special cased above... */
|
|
|
45d60a |
- not_exists:
|
|
|
45d60a |
- token = peek_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != EXISTS) {
|
|
|
45d60a |
- parse_warn (cfile, "expecting DNS prerequisite.");
|
|
|
45d60a |
- *lose = 1;
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- opcode = expr_ns_not_exists;
|
|
|
45d60a |
- goto nsupdatecode;
|
|
|
45d60a |
- case TOKEN_ADD:
|
|
|
45d60a |
- opcode = expr_ns_add;
|
|
|
45d60a |
- goto nsupdatecode;
|
|
|
45d60a |
- case TOKEN_DELETE:
|
|
|
45d60a |
- opcode = expr_ns_delete;
|
|
|
45d60a |
- goto nsupdatecode;
|
|
|
45d60a |
- ns_exists:
|
|
|
45d60a |
- opcode = expr_ns_exists;
|
|
|
45d60a |
- nsupdatecode:
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
-
|
|
|
45d60a |
-#if !defined (NSUPDATE)
|
|
|
45d60a |
- parse_warn (cfile,
|
|
|
45d60a |
- "Please rebuild dhcpd with --with-nsupdate.");
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
- if (!expression_allocate (expr, MDL))
|
|
|
45d60a |
- log_fatal ("can't allocate expression");
|
|
|
45d60a |
- (*expr) -> op = opcode;
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != LPAREN)
|
|
|
45d60a |
- goto nolparen;
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (!is_identifier (token) && token != NUMBER) {
|
|
|
45d60a |
- parse_warn (cfile, "expecting identifier or number.");
|
|
|
45d60a |
- badnsop:
|
|
|
45d60a |
- expression_dereference (expr, MDL);
|
|
|
45d60a |
- skip_to_semi (cfile);
|
|
|
45d60a |
- *lose = 1;
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (token == NUMBER)
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrclass = atoi (val);
|
|
|
45d60a |
- else if (!strcasecmp (val, "in"))
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrclass = C_IN;
|
|
|
45d60a |
- else if (!strcasecmp (val, "chaos"))
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrclass = C_CHAOS;
|
|
|
45d60a |
- else if (!strcasecmp (val, "hs"))
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrclass = C_HS;
|
|
|
45d60a |
- else {
|
|
|
45d60a |
- parse_warn (cfile, "unexpected rrclass: %s", val);
|
|
|
45d60a |
- goto badnsop;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != COMMA)
|
|
|
45d60a |
- goto nocomma;
|
|
|
45d60a |
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (!is_identifier (token) && token != NUMBER) {
|
|
|
45d60a |
- parse_warn (cfile, "expecting identifier or number.");
|
|
|
45d60a |
- goto badnsop;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (token == NUMBER)
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrtype = atoi (val);
|
|
|
45d60a |
- else if (!strcasecmp (val, "a"))
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrtype = T_A;
|
|
|
45d60a |
- else if (!strcasecmp (val, "aaaa"))
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrtype = T_AAAA;
|
|
|
45d60a |
- else if (!strcasecmp (val, "ptr"))
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrtype = T_PTR;
|
|
|
45d60a |
- else if (!strcasecmp (val, "mx"))
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrtype = T_MX;
|
|
|
45d60a |
- else if (!strcasecmp (val, "cname"))
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrtype = T_CNAME;
|
|
|
45d60a |
- else if (!strcasecmp (val, "TXT"))
|
|
|
45d60a |
- (*expr) -> data.ns_add.rrtype = T_TXT;
|
|
|
45d60a |
- else {
|
|
|
45d60a |
- parse_warn (cfile, "unexpected rrtype: %s", val);
|
|
|
45d60a |
- goto badnsop;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != COMMA)
|
|
|
45d60a |
- goto nocomma;
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (!(parse_data_expression
|
|
|
45d60a |
- (&(*expr) -> data.ns_add.rrname, cfile, lose)))
|
|
|
45d60a |
- goto nodata;
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != COMMA)
|
|
|
45d60a |
- goto nocomma;
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (!(parse_data_expression
|
|
|
45d60a |
- (&(*expr) -> data.ns_add.rrdata, cfile, lose)))
|
|
|
45d60a |
- goto nodata;
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (opcode == expr_ns_add) {
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != COMMA)
|
|
|
45d60a |
- goto nocomma;
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (!(parse_numeric_expression
|
|
|
45d60a |
- (&(*expr) -> data.ns_add.ttl, cfile,
|
|
|
45d60a |
- lose))) {
|
|
|
45d60a |
- if (!*lose)
|
|
|
45d60a |
- parse_warn (cfile,
|
|
|
45d60a |
- "expecting numeric expression.");
|
|
|
45d60a |
- goto badnsupdate;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != RPAREN)
|
|
|
45d60a |
- goto norparen;
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-#endif /* NSUPDATE_OLD */
|
|
|
45d60a |
case OPTION:
|
|
|
45d60a |
case CONFIG_OPTION:
|
|
|
45d60a |
if (!expression_allocate (expr, MDL))
|
|
|
45d60a |
@@ -4366,44 +4039,7 @@ int parse_non_binary (expr, cfile, lose, context)
|
|
|
45d60a |
(*expr) -> op = expr_host_decl_name;
|
|
|
45d60a |
break;
|
|
|
45d60a |
|
|
|
45d60a |
-#if defined(NSUPDATE_OLD)
|
|
|
45d60a |
- case UPDATED_DNS_RR:
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != LPAREN)
|
|
|
45d60a |
- goto nolparen;
|
|
|
45d60a |
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != STRING) {
|
|
|
45d60a |
- parse_warn (cfile, "expecting string.");
|
|
|
45d60a |
- bad_rrtype:
|
|
|
45d60a |
- *lose = 1;
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- if (!strcasecmp (val, "a"))
|
|
|
45d60a |
- s = "ddns-fwd-name";
|
|
|
45d60a |
- else if (!strcasecmp (val, "ptr"))
|
|
|
45d60a |
- s = "ddns-rev-name";
|
|
|
45d60a |
- else {
|
|
|
45d60a |
- parse_warn (cfile, "invalid DNS rrtype: %s", val);
|
|
|
45d60a |
- goto bad_rrtype;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
- if (token != RPAREN)
|
|
|
45d60a |
- goto norparen;
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (!expression_allocate (expr, MDL))
|
|
|
45d60a |
- log_fatal ("can't allocate expression");
|
|
|
45d60a |
- (*expr) -> op = expr_variable_reference;
|
|
|
45d60a |
- (*expr) -> data.variable =
|
|
|
45d60a |
- dmalloc (strlen (s) + 1, MDL);
|
|
|
45d60a |
- if (!(*expr) -> data.variable)
|
|
|
45d60a |
- log_fatal ("can't allocate variable name.");
|
|
|
45d60a |
- strcpy ((*expr) -> data.variable, s);
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-#endif /* NSUPDATE_OLD */
|
|
|
45d60a |
case PACKET:
|
|
|
45d60a |
token = next_token (&val, (unsigned *)0, cfile);
|
|
|
45d60a |
if (!expression_allocate (expr, MDL))
|
|
|
45d60a |
diff --git a/common/tree.c b/common/tree.c
|
|
|
45d60a |
index 8c2056c..26e0add 100644
|
|
|
45d60a |
--- a/common/tree.c
|
|
|
45d60a |
+++ b/common/tree.c
|
|
|
45d60a |
@@ -645,15 +645,6 @@ int evaluate_expression (result, packet, lease, client_state,
|
|
|
45d60a |
status = (evaluate_data_expression
|
|
|
45d60a |
(&bv -> value.data, packet, lease, client_state,
|
|
|
45d60a |
in_options, cfg_options, scope, expr, MDL));
|
|
|
45d60a |
-#if defined (NSUPDATE_OLD)
|
|
|
45d60a |
- } else if (is_dns_expression (expr)) {
|
|
|
45d60a |
- if (!binding_value_allocate (&bv, MDL))
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
- bv -> type = binding_dns;
|
|
|
45d60a |
- status = (evaluate_dns_expression
|
|
|
45d60a |
- (&bv -> value.dns, packet, lease, client_state,
|
|
|
45d60a |
- in_options, cfg_options, scope, expr));
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
} else {
|
|
|
45d60a |
log_error ("%s: invalid expression type: %d",
|
|
|
45d60a |
"evaluate_expression", expr -> op);
|
|
|
45d60a |
@@ -699,19 +690,6 @@ int binding_value_dereference (struct binding_value **v,
|
|
|
45d60a |
if (bv -> value.data.buffer)
|
|
|
45d60a |
data_string_forget (&bv -> value.data, file, line);
|
|
|
45d60a |
break;
|
|
|
45d60a |
- case binding_dns:
|
|
|
45d60a |
-#if defined (NSUPDATE_OLD)
|
|
|
45d60a |
- if (bv -> value.dns) {
|
|
|
45d60a |
- if (bv -> value.dns -> r_data) {
|
|
|
45d60a |
- dfree (bv -> value.dns -> r_data_ephem, MDL);
|
|
|
45d60a |
- bv -> value.dns -> r_data = (unsigned char *)0;
|
|
|
45d60a |
- bv -> value.dns -> r_data_ephem =
|
|
|
45d60a |
- (unsigned char *)0;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- minires_freeupdrec (bv -> value.dns);
|
|
|
45d60a |
- }
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
default:
|
|
|
45d60a |
log_error ("%s(%d): invalid binding type: %d",
|
|
|
45d60a |
file, line, bv -> type);
|
|
|
45d60a |
@@ -721,270 +699,6 @@ int binding_value_dereference (struct binding_value **v,
|
|
|
45d60a |
return 1;
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
-#if defined (NSUPDATE_OLD)
|
|
|
45d60a |
-int evaluate_dns_expression (result, packet, lease, client_state, in_options,
|
|
|
45d60a |
- cfg_options, scope, expr)
|
|
|
45d60a |
- ns_updrec **result;
|
|
|
45d60a |
- struct packet *packet;
|
|
|
45d60a |
- struct lease *lease;
|
|
|
45d60a |
- struct client_state *client_state;
|
|
|
45d60a |
- struct option_state *in_options;
|
|
|
45d60a |
- struct option_state *cfg_options;
|
|
|
45d60a |
- struct binding_scope **scope;
|
|
|
45d60a |
- struct expression *expr;
|
|
|
45d60a |
-{
|
|
|
45d60a |
- unsigned long ttl = 0;
|
|
|
45d60a |
- char *tname;
|
|
|
45d60a |
- struct data_string name, data;
|
|
|
45d60a |
- int r0, r1, r2;
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (!result || *result) {
|
|
|
45d60a |
- log_error ("evaluate_dns_expression called with non-null %s",
|
|
|
45d60a |
- "result pointer");
|
|
|
45d60a |
-#if defined (POINTER_DEBUG)
|
|
|
45d60a |
- abort ();
|
|
|
45d60a |
-#else
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- switch (expr -> op) {
|
|
|
45d60a |
-#if defined (NSUPDATE)
|
|
|
45d60a |
- case expr_ns_add:
|
|
|
45d60a |
- r0 = evaluate_numeric_expression (&ttl, packet, lease,
|
|
|
45d60a |
- client_state,
|
|
|
45d60a |
- in_options, cfg_options,
|
|
|
45d60a |
- scope,
|
|
|
45d60a |
- expr -> data.ns_add.ttl);
|
|
|
45d60a |
- goto nsfinish;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_ns_exists:
|
|
|
45d60a |
- ttl = 1;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_ns_delete:
|
|
|
45d60a |
- case expr_ns_not_exists:
|
|
|
45d60a |
- r0 = 1;
|
|
|
45d60a |
- nsfinish:
|
|
|
45d60a |
- memset (&name, 0, sizeof name);
|
|
|
45d60a |
- r1 = evaluate_data_expression (&name, packet, lease,
|
|
|
45d60a |
- client_state,
|
|
|
45d60a |
- in_options, cfg_options, scope,
|
|
|
45d60a |
- expr -> data.ns_add.rrname,
|
|
|
45d60a |
- MDL);
|
|
|
45d60a |
- if (r1) {
|
|
|
45d60a |
- /* The result of the evaluation may or may not
|
|
|
45d60a |
- be NUL-terminated, but we need it
|
|
|
45d60a |
- terminated for sure, so we have to allocate
|
|
|
45d60a |
- a buffer and terminate it. */
|
|
|
45d60a |
- tname = dmalloc (name.len + 1, MDL);
|
|
|
45d60a |
- if (!tname) {
|
|
|
45d60a |
- r2 = 0;
|
|
|
45d60a |
- r1 = 0;
|
|
|
45d60a |
- data_string_forget (&name, MDL);
|
|
|
45d60a |
- } else {
|
|
|
45d60a |
- memcpy (tname, name.data, name.len);
|
|
|
45d60a |
- tname [name.len] = 0;
|
|
|
45d60a |
- memset (&data, 0, sizeof data);
|
|
|
45d60a |
- r2 = evaluate_data_expression
|
|
|
45d60a |
- (&data, packet, lease, client_state,
|
|
|
45d60a |
- in_options, cfg_options, scope,
|
|
|
45d60a |
- expr -> data.ns_add.rrdata, MDL);
|
|
|
45d60a |
- }
|
|
|
45d60a |
- } else {
|
|
|
45d60a |
- r2 = 0;
|
|
|
45d60a |
- tname = NULL;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- if (r0 && r1 && (r2 || expr -> op != expr_ns_add)) {
|
|
|
45d60a |
- *result = minires_mkupdrec (((expr -> op == expr_ns_add ||
|
|
|
45d60a |
- expr -> op == expr_ns_delete)
|
|
|
45d60a |
- ? S_UPDATE : S_PREREQ),
|
|
|
45d60a |
- tname,
|
|
|
45d60a |
- expr -> data.ns_add.rrclass,
|
|
|
45d60a |
- expr -> data.ns_add.rrtype,
|
|
|
45d60a |
- ttl);
|
|
|
45d60a |
- if (!*result) {
|
|
|
45d60a |
- ngood:
|
|
|
45d60a |
- if (r2) {
|
|
|
45d60a |
- data_string_forget (&data, MDL);
|
|
|
45d60a |
- r2 = 0;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- } else {
|
|
|
45d60a |
- if (data.len) {
|
|
|
45d60a |
- /* As a special case, if we get exactly
|
|
|
45d60a |
- four bytes of data, it's an IP address
|
|
|
45d60a |
- represented as a 32-bit quantity, which
|
|
|
45d60a |
- is actually what we *should* be getting
|
|
|
45d60a |
- here. Because res_mkupdrec is currently
|
|
|
45d60a |
- broken and expects a dotted quad, convert
|
|
|
45d60a |
- it. This should be fixed when the new
|
|
|
45d60a |
- resolver is merged. */
|
|
|
45d60a |
- if (data.len == 4) {
|
|
|
45d60a |
- (*result) -> r_data_ephem =
|
|
|
45d60a |
- dmalloc (16, MDL);
|
|
|
45d60a |
- if (!(*result) -> r_data_ephem)
|
|
|
45d60a |
- goto dpngood;
|
|
|
45d60a |
- (*result) -> r_data =
|
|
|
45d60a |
- (*result) -> r_data_ephem;
|
|
|
45d60a |
- /*%Audit% 16 bytes max. %2004.06.17,Safe%*/
|
|
|
45d60a |
- sprintf ((char *)(*result) -> r_data_ephem,
|
|
|
45d60a |
- "%u.%u.%u.%u",
|
|
|
45d60a |
- data.data [0] & 0xff,
|
|
|
45d60a |
- data.data [1] & 0xff,
|
|
|
45d60a |
- data.data [2] & 0xff,
|
|
|
45d60a |
- data.data [3] & 0xff);
|
|
|
45d60a |
- (*result) -> r_size =
|
|
|
45d60a |
- strlen ((const char *)
|
|
|
45d60a |
- (*result) -> r_data);
|
|
|
45d60a |
- } else {
|
|
|
45d60a |
- (*result) -> r_size = data.len;
|
|
|
45d60a |
- (*result) -> r_data_ephem =
|
|
|
45d60a |
- dmalloc (data.len, MDL);
|
|
|
45d60a |
- if (!(*result) -> r_data_ephem) {
|
|
|
45d60a |
- dpngood: /* double plus ungood. */
|
|
|
45d60a |
- minires_freeupdrec (*result);
|
|
|
45d60a |
- *result = 0;
|
|
|
45d60a |
- goto ngood;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- (*result) -> r_data =
|
|
|
45d60a |
- (*result) -> r_data_ephem;
|
|
|
45d60a |
- memcpy ((*result) -> r_data_ephem,
|
|
|
45d60a |
- data.data, data.len);
|
|
|
45d60a |
- }
|
|
|
45d60a |
- } else {
|
|
|
45d60a |
- (*result) -> r_data = 0;
|
|
|
45d60a |
- (*result) -> r_size = 0;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- switch (expr -> op) {
|
|
|
45d60a |
- case expr_ns_add:
|
|
|
45d60a |
- (*result) -> r_opcode = ADD;
|
|
|
45d60a |
- break;
|
|
|
45d60a |
- case expr_ns_delete:
|
|
|
45d60a |
- (*result) -> r_opcode = DELETE;
|
|
|
45d60a |
- break;
|
|
|
45d60a |
- case expr_ns_exists:
|
|
|
45d60a |
- (*result) -> r_opcode = YXRRSET;
|
|
|
45d60a |
- break;
|
|
|
45d60a |
- case expr_ns_not_exists:
|
|
|
45d60a |
- (*result) -> r_opcode = NXRRSET;
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
- /* Can't happen, but satisfy gcc. */
|
|
|
45d60a |
- default:
|
|
|
45d60a |
- break;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- }
|
|
|
45d60a |
- }
|
|
|
45d60a |
- if (r1) {
|
|
|
45d60a |
- data_string_forget (&name, MDL);
|
|
|
45d60a |
- dfree (tname, MDL);
|
|
|
45d60a |
- }
|
|
|
45d60a |
- if (r2)
|
|
|
45d60a |
- data_string_forget (&data, MDL);
|
|
|
45d60a |
- /* One flaw in the thinking here: an IP address and an
|
|
|
45d60a |
- ASCII string both look like data expressions, but
|
|
|
45d60a |
- for A records, we want an ASCII string, not a
|
|
|
45d60a |
- binary IP address. Do I need to turn binary IP
|
|
|
45d60a |
- addresses into a separate type? */
|
|
|
45d60a |
- return (r0 && r1 &&
|
|
|
45d60a |
- (r2 || expr -> op != expr_ns_add) && *result);
|
|
|
45d60a |
-
|
|
|
45d60a |
-#else
|
|
|
45d60a |
- case expr_ns_add:
|
|
|
45d60a |
- case expr_ns_delete:
|
|
|
45d60a |
- case expr_ns_exists:
|
|
|
45d60a |
- case expr_ns_not_exists:
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
- case expr_funcall:
|
|
|
45d60a |
- log_error ("%s: dns values for functions not supported.",
|
|
|
45d60a |
- expr -> data.funcall.name);
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_variable_reference:
|
|
|
45d60a |
- log_error ("%s: dns values for variables not supported.",
|
|
|
45d60a |
- expr -> data.variable);
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_check:
|
|
|
45d60a |
- case expr_equal:
|
|
|
45d60a |
- case expr_not_equal:
|
|
|
45d60a |
- case expr_regex_match:
|
|
|
45d60a |
- case expr_iregex_match:
|
|
|
45d60a |
- case expr_and:
|
|
|
45d60a |
- case expr_or:
|
|
|
45d60a |
- case expr_not:
|
|
|
45d60a |
- case expr_match:
|
|
|
45d60a |
- case expr_static:
|
|
|
45d60a |
- case expr_known:
|
|
|
45d60a |
- case expr_exists:
|
|
|
45d60a |
- case expr_variable_exists:
|
|
|
45d60a |
- log_error ("Boolean opcode in evaluate_dns_expression: %d",
|
|
|
45d60a |
- expr -> op);
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_none:
|
|
|
45d60a |
- case expr_substring:
|
|
|
45d60a |
- case expr_suffix:
|
|
|
45d60a |
- case expr_lcase:
|
|
|
45d60a |
- case expr_ucase:
|
|
|
45d60a |
- case expr_option:
|
|
|
45d60a |
- case expr_hardware:
|
|
|
45d60a |
- case expr_const_data:
|
|
|
45d60a |
- case expr_packet:
|
|
|
45d60a |
- case expr_concat:
|
|
|
45d60a |
- case expr_encapsulate:
|
|
|
45d60a |
- case expr_host_lookup:
|
|
|
45d60a |
- case expr_encode_int8:
|
|
|
45d60a |
- case expr_encode_int16:
|
|
|
45d60a |
- case expr_encode_int32:
|
|
|
45d60a |
- case expr_binary_to_ascii:
|
|
|
45d60a |
- case expr_reverse:
|
|
|
45d60a |
- case expr_filename:
|
|
|
45d60a |
- case expr_sname:
|
|
|
45d60a |
- case expr_pick_first_value:
|
|
|
45d60a |
- case expr_host_decl_name:
|
|
|
45d60a |
- case expr_config_option:
|
|
|
45d60a |
- case expr_leased_address:
|
|
|
45d60a |
- case expr_null:
|
|
|
45d60a |
- case expr_gethostname:
|
|
|
45d60a |
- log_error ("Data opcode in evaluate_dns_expression: %d",
|
|
|
45d60a |
- expr -> op);
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_extract_int8:
|
|
|
45d60a |
- case expr_extract_int16:
|
|
|
45d60a |
- case expr_extract_int32:
|
|
|
45d60a |
- case expr_const_int:
|
|
|
45d60a |
- case expr_lease_time:
|
|
|
45d60a |
- case expr_dns_transaction:
|
|
|
45d60a |
- case expr_add:
|
|
|
45d60a |
- case expr_subtract:
|
|
|
45d60a |
- case expr_multiply:
|
|
|
45d60a |
- case expr_divide:
|
|
|
45d60a |
- case expr_remainder:
|
|
|
45d60a |
- case expr_binary_and:
|
|
|
45d60a |
- case expr_binary_or:
|
|
|
45d60a |
- case expr_binary_xor:
|
|
|
45d60a |
- case expr_client_state:
|
|
|
45d60a |
- log_error ("Numeric opcode in evaluate_dns_expression: %d",
|
|
|
45d60a |
- expr -> op);
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_function:
|
|
|
45d60a |
- log_error ("Function opcode in evaluate_dns_expression: %d",
|
|
|
45d60a |
- expr -> op);
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_arg:
|
|
|
45d60a |
- break;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- log_error ("Bogus opcode in evaluate_dns_expression: %d",
|
|
|
45d60a |
- expr -> op);
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
-}
|
|
|
45d60a |
-#endif /* defined (NSUPDATE_OLD) */
|
|
|
45d60a |
-
|
|
|
45d60a |
int evaluate_boolean_expression (result, packet, lease, client_state,
|
|
|
45d60a |
in_options, cfg_options, scope, expr)
|
|
|
45d60a |
int *result;
|
|
|
45d60a |
@@ -1056,20 +770,7 @@ int evaluate_boolean_expression (result, packet, lease, client_state,
|
|
|
45d60a |
else
|
|
|
45d60a |
*result = expr -> op == expr_not_equal;
|
|
|
45d60a |
break;
|
|
|
45d60a |
-#if defined (NSUPDATE_OLD)
|
|
|
45d60a |
- case binding_dns:
|
|
|
45d60a |
-#if defined (NSUPDATE)
|
|
|
45d60a |
- /* XXX This should be a comparison for equal
|
|
|
45d60a |
- XXX values, not for identity. */
|
|
|
45d60a |
- if (bv -> value.dns == obv -> value.dns)
|
|
|
45d60a |
- *result = expr -> op == expr_equal;
|
|
|
45d60a |
- else
|
|
|
45d60a |
- *result = expr -> op == expr_not_equal;
|
|
|
45d60a |
-#else
|
|
|
45d60a |
- *result = expr -> op == expr_not_equal;
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-#endif /* NSUPDATE_OLD */
|
|
|
45d60a |
+
|
|
|
45d60a |
case binding_function:
|
|
|
45d60a |
if (bv -> value.fundef == obv -> value.fundef)
|
|
|
45d60a |
*result = expr -> op == expr_equal;
|
|
|
45d60a |
@@ -2369,7 +2070,7 @@ int evaluate_data_expression (result, packet, lease, client_state,
|
|
|
45d60a |
case expr_ns_delete:
|
|
|
45d60a |
case expr_ns_exists:
|
|
|
45d60a |
case expr_ns_not_exists:
|
|
|
45d60a |
- log_error ("dns update opcode in evaluate_data_expression: %d",
|
|
|
45d60a |
+ log_error ("dns opcode in evaluate_boolean_expression: %d",
|
|
|
45d60a |
expr -> op);
|
|
|
45d60a |
return 0;
|
|
|
45d60a |
|
|
|
45d60a |
@@ -2398,11 +2099,6 @@ int evaluate_numeric_expression (result, packet, lease, client_state,
|
|
|
45d60a |
{
|
|
|
45d60a |
struct data_string data;
|
|
|
45d60a |
int status, sleft, sright;
|
|
|
45d60a |
-#if defined (NSUPDATE_OLD)
|
|
|
45d60a |
- ns_updrec *nut;
|
|
|
45d60a |
- ns_updque uq;
|
|
|
45d60a |
- struct expression *cur, *next;
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
|
|
|
45d60a |
struct binding *binding;
|
|
|
45d60a |
struct binding_value *bv;
|
|
|
45d60a |
@@ -2541,53 +2237,6 @@ int evaluate_numeric_expression (result, packet, lease, client_state,
|
|
|
45d60a |
#endif
|
|
|
45d60a |
return (1);
|
|
|
45d60a |
|
|
|
45d60a |
- case expr_dns_transaction:
|
|
|
45d60a |
-#if !defined (NSUPDATE_OLD)
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
-#else
|
|
|
45d60a |
- if (!resolver_inited) {
|
|
|
45d60a |
- minires_ninit (&resolver_state);
|
|
|
45d60a |
- resolver_inited = 1;
|
|
|
45d60a |
- resolver_state.retrans = 1;
|
|
|
45d60a |
- resolver_state.retry = 1;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- ISC_LIST_INIT (uq);
|
|
|
45d60a |
- cur = expr;
|
|
|
45d60a |
- do {
|
|
|
45d60a |
- next = cur -> data.dns_transaction.cdr;
|
|
|
45d60a |
- nut = 0;
|
|
|
45d60a |
- status = (evaluate_dns_expression
|
|
|
45d60a |
- (&nut, packet,
|
|
|
45d60a |
- lease, client_state, in_options, cfg_options,
|
|
|
45d60a |
- scope, cur -> data.dns_transaction.car));
|
|
|
45d60a |
- if (!status)
|
|
|
45d60a |
- goto dns_bad;
|
|
|
45d60a |
- ISC_LIST_APPEND (uq, nut, r_link);
|
|
|
45d60a |
- cur = next;
|
|
|
45d60a |
- } while (next);
|
|
|
45d60a |
-
|
|
|
45d60a |
- /* Do the update and record the error code, if there was
|
|
|
45d60a |
- an error; otherwise set it to NOERROR. */
|
|
|
45d60a |
- *result = minires_nupdate (&resolver_state,
|
|
|
45d60a |
- ISC_LIST_HEAD (uq));
|
|
|
45d60a |
- status = 1;
|
|
|
45d60a |
-
|
|
|
45d60a |
- print_dns_status ((int)*result, &uq;;
|
|
|
45d60a |
-
|
|
|
45d60a |
- dns_bad:
|
|
|
45d60a |
- while (!ISC_LIST_EMPTY (uq)) {
|
|
|
45d60a |
- ns_updrec *tmp = ISC_LIST_HEAD (uq);
|
|
|
45d60a |
- ISC_LIST_UNLINK (uq, tmp, r_link);
|
|
|
45d60a |
- if (tmp -> r_data_ephem) {
|
|
|
45d60a |
- dfree (tmp -> r_data_ephem, MDL);
|
|
|
45d60a |
- tmp -> r_data = (unsigned char *)0;
|
|
|
45d60a |
- tmp -> r_data_ephem = (unsigned char *)0;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- minires_freeupdrec (tmp);
|
|
|
45d60a |
- }
|
|
|
45d60a |
- return status;
|
|
|
45d60a |
-#endif /* NSUPDATE_OLD */
|
|
|
45d60a |
-
|
|
|
45d60a |
case expr_variable_reference:
|
|
|
45d60a |
if (scope && *scope) {
|
|
|
45d60a |
binding = find_binding (*scope, expr -> data.variable);
|
|
|
45d60a |
@@ -2877,14 +2526,6 @@ int evaluate_numeric_expression (result, packet, lease, client_state,
|
|
|
45d60a |
return 0;
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
- case expr_ns_add:
|
|
|
45d60a |
- case expr_ns_delete:
|
|
|
45d60a |
- case expr_ns_exists:
|
|
|
45d60a |
- case expr_ns_not_exists:
|
|
|
45d60a |
- log_error ("dns opcode in evaluate_numeric_expression: %d",
|
|
|
45d60a |
- expr -> op);
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
-
|
|
|
45d60a |
case expr_function:
|
|
|
45d60a |
log_error ("function definition in evaluate_numeric_expr");
|
|
|
45d60a |
return 0;
|
|
|
45d60a |
@@ -3182,38 +2823,6 @@ void expression_dereference (eptr, file, line)
|
|
|
45d60a |
(&expr -> data.reverse.buffer, file, line);
|
|
|
45d60a |
break;
|
|
|
45d60a |
|
|
|
45d60a |
- case expr_dns_transaction:
|
|
|
45d60a |
- if (expr -> data.dns_transaction.car)
|
|
|
45d60a |
- expression_dereference (&expr -> data.dns_transaction.car,
|
|
|
45d60a |
- file, line);
|
|
|
45d60a |
- if (expr -> data.dns_transaction.cdr)
|
|
|
45d60a |
- expression_dereference (&expr -> data.dns_transaction.cdr,
|
|
|
45d60a |
- file, line);
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_ns_add:
|
|
|
45d60a |
- if (expr -> data.ns_add.rrname)
|
|
|
45d60a |
- expression_dereference (&expr -> data.ns_add.rrname,
|
|
|
45d60a |
- file, line);
|
|
|
45d60a |
- if (expr -> data.ns_add.rrdata)
|
|
|
45d60a |
- expression_dereference (&expr -> data.ns_add.rrdata,
|
|
|
45d60a |
- file, line);
|
|
|
45d60a |
- if (expr -> data.ns_add.ttl)
|
|
|
45d60a |
- expression_dereference (&expr -> data.ns_add.ttl,
|
|
|
45d60a |
- file, line);
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_ns_delete:
|
|
|
45d60a |
- case expr_ns_exists:
|
|
|
45d60a |
- case expr_ns_not_exists:
|
|
|
45d60a |
- if (expr -> data.ns_delete.rrname)
|
|
|
45d60a |
- expression_dereference (&expr -> data.ns_delete.rrname,
|
|
|
45d60a |
- file, line);
|
|
|
45d60a |
- if (expr -> data.ns_delete.rrdata)
|
|
|
45d60a |
- expression_dereference (&expr -> data.ns_delete.rrdata,
|
|
|
45d60a |
- file, line);
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
case expr_variable_reference:
|
|
|
45d60a |
case expr_variable_exists:
|
|
|
45d60a |
if (expr -> data.variable)
|
|
|
45d60a |
@@ -3262,15 +2871,6 @@ void expression_dereference (eptr, file, line)
|
|
|
45d60a |
free_expression (expr, MDL);
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
-int is_dns_expression (expr)
|
|
|
45d60a |
- struct expression *expr;
|
|
|
45d60a |
-{
|
|
|
45d60a |
- return (expr -> op == expr_ns_add ||
|
|
|
45d60a |
- expr -> op == expr_ns_delete ||
|
|
|
45d60a |
- expr -> op == expr_ns_exists ||
|
|
|
45d60a |
- expr -> op == expr_ns_not_exists);
|
|
|
45d60a |
-}
|
|
|
45d60a |
-
|
|
|
45d60a |
int is_boolean_expression (expr)
|
|
|
45d60a |
struct expression *expr;
|
|
|
45d60a |
{
|
|
|
45d60a |
@@ -3325,7 +2925,6 @@ int is_numeric_expression (expr)
|
|
|
45d60a |
expr -> op == expr_extract_int32 ||
|
|
|
45d60a |
expr -> op == expr_const_int ||
|
|
|
45d60a |
expr -> op == expr_lease_time ||
|
|
|
45d60a |
- expr -> op == expr_dns_transaction ||
|
|
|
45d60a |
expr -> op == expr_add ||
|
|
|
45d60a |
expr -> op == expr_subtract ||
|
|
|
45d60a |
expr -> op == expr_multiply ||
|
|
|
45d60a |
@@ -3340,11 +2939,7 @@ int is_numeric_expression (expr)
|
|
|
45d60a |
int is_compound_expression (expr)
|
|
|
45d60a |
struct expression *expr;
|
|
|
45d60a |
{
|
|
|
45d60a |
- return (expr -> op == expr_ns_add ||
|
|
|
45d60a |
- expr -> op == expr_ns_delete ||
|
|
|
45d60a |
- expr -> op == expr_ns_exists ||
|
|
|
45d60a |
- expr -> op == expr_ns_not_exists ||
|
|
|
45d60a |
- expr -> op == expr_substring ||
|
|
|
45d60a |
+ return (expr -> op == expr_substring ||
|
|
|
45d60a |
expr -> op == expr_suffix ||
|
|
|
45d60a |
expr -> op == expr_option ||
|
|
|
45d60a |
expr -> op == expr_concat ||
|
|
|
45d60a |
@@ -3357,8 +2952,7 @@ int is_compound_expression (expr)
|
|
|
45d60a |
expr -> op == expr_config_option ||
|
|
|
45d60a |
expr -> op == expr_extract_int8 ||
|
|
|
45d60a |
expr -> op == expr_extract_int16 ||
|
|
|
45d60a |
- expr -> op == expr_extract_int32 ||
|
|
|
45d60a |
- expr -> op == expr_dns_transaction);
|
|
|
45d60a |
+ expr -> op == expr_extract_int32);
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
static int op_val (enum expr_op);
|
|
|
45d60a |
@@ -3456,8 +3050,6 @@ enum expression_context expression_context (struct expression *expr)
|
|
|
45d60a |
return context_numeric;
|
|
|
45d60a |
if (is_boolean_expression (expr))
|
|
|
45d60a |
return context_boolean;
|
|
|
45d60a |
- if (is_dns_expression (expr))
|
|
|
45d60a |
- return context_dns;
|
|
|
45d60a |
return context_any;
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
@@ -3928,99 +3520,6 @@ int write_expression (file, expr, col, indent, firstp)
|
|
|
45d60a |
"lease-time");
|
|
|
45d60a |
break;
|
|
|
45d60a |
|
|
|
45d60a |
- case expr_dns_transaction:
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, "", "",
|
|
|
45d60a |
- "ns-update");
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, " ", "",
|
|
|
45d60a |
- "(");
|
|
|
45d60a |
- scol = 0;
|
|
|
45d60a |
- for (e = expr;
|
|
|
45d60a |
- e && e -> op == expr_dns_transaction;
|
|
|
45d60a |
- e = e -> data.dns_transaction.cdr) {
|
|
|
45d60a |
- if (!scol) {
|
|
|
45d60a |
- scol = col;
|
|
|
45d60a |
- firstp = 1;
|
|
|
45d60a |
- } else
|
|
|
45d60a |
- firstp = 0;
|
|
|
45d60a |
- col = write_expression (file,
|
|
|
45d60a |
- e -> data.dns_transaction.car,
|
|
|
45d60a |
- col, scol, firstp);
|
|
|
45d60a |
- if (e -> data.dns_transaction.cdr)
|
|
|
45d60a |
- col = token_print_indent (file, col, scol,
|
|
|
45d60a |
- "", " ", ",");
|
|
|
45d60a |
- }
|
|
|
45d60a |
- if (e)
|
|
|
45d60a |
- col = write_expression (file, e, col, scol, 0);
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, "", "", ")");
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_ns_add:
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, "", "",
|
|
|
45d60a |
- "update");
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, " ", "",
|
|
|
45d60a |
- "(");
|
|
|
45d60a |
- scol = col;
|
|
|
45d60a |
- sprintf (obuf, "%d", expr -> data.ns_add.rrclass);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", "", obuf);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", " ",
|
|
|
45d60a |
- ",");
|
|
|
45d60a |
- sprintf (obuf, "%d", expr -> data.ns_add.rrtype);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", "", obuf);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", " ",
|
|
|
45d60a |
- ",");
|
|
|
45d60a |
- col = write_expression (file, expr -> data.ns_add.rrname,
|
|
|
45d60a |
- col, scol, 0);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", " ",
|
|
|
45d60a |
- ",");
|
|
|
45d60a |
- col = write_expression (file, expr -> data.ns_add.rrdata,
|
|
|
45d60a |
- col, scol, 0);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", " ",
|
|
|
45d60a |
- ",");
|
|
|
45d60a |
- col = write_expression (file, expr -> data.ns_add.ttl,
|
|
|
45d60a |
- col, scol, 0);
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, "", "",
|
|
|
45d60a |
- ")");
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_ns_delete:
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, "", "",
|
|
|
45d60a |
- "delete");
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, " ", "",
|
|
|
45d60a |
- "(");
|
|
|
45d60a |
- finish_ns_small:
|
|
|
45d60a |
- scol = col;
|
|
|
45d60a |
- sprintf (obuf, "%d", expr -> data.ns_add.rrclass);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", "", obuf);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", " ",
|
|
|
45d60a |
- ",");
|
|
|
45d60a |
- sprintf (obuf, "%d", expr -> data.ns_add.rrtype);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", "", obuf);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", " ",
|
|
|
45d60a |
- ",");
|
|
|
45d60a |
- col = write_expression (file, expr -> data.ns_add.rrname,
|
|
|
45d60a |
- col, scol, 0);
|
|
|
45d60a |
- col = token_print_indent (file, col, scol, "", " ",
|
|
|
45d60a |
- ",");
|
|
|
45d60a |
- col = write_expression (file, expr -> data.ns_add.rrdata,
|
|
|
45d60a |
- col, scol, 0);
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, "", "",
|
|
|
45d60a |
- ")");
|
|
|
45d60a |
- break;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_ns_exists:
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, "", "",
|
|
|
45d60a |
- "exists");
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, " ", "",
|
|
|
45d60a |
- "(");
|
|
|
45d60a |
- goto finish_ns_small;
|
|
|
45d60a |
-
|
|
|
45d60a |
- case expr_ns_not_exists:
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, "", "",
|
|
|
45d60a |
- "not exists");
|
|
|
45d60a |
- col = token_print_indent (file, col, indent, " ", "",
|
|
|
45d60a |
- "(");
|
|
|
45d60a |
- goto finish_ns_small;
|
|
|
45d60a |
-
|
|
|
45d60a |
case expr_static:
|
|
|
45d60a |
col = token_print_indent (file, col, indent, "", "",
|
|
|
45d60a |
"static");
|
|
|
45d60a |
@@ -4293,12 +3792,7 @@ int data_subexpression_length (int *rv,
|
|
|
45d60a |
case expr_const_int:
|
|
|
45d60a |
case expr_exists:
|
|
|
45d60a |
case expr_known:
|
|
|
45d60a |
- case expr_dns_transaction:
|
|
|
45d60a |
case expr_static:
|
|
|
45d60a |
- case expr_ns_add:
|
|
|
45d60a |
- case expr_ns_delete:
|
|
|
45d60a |
- case expr_ns_exists:
|
|
|
45d60a |
- case expr_ns_not_exists:
|
|
|
45d60a |
case expr_not_equal:
|
|
|
45d60a |
case expr_null:
|
|
|
45d60a |
case expr_variable_exists:
|
|
|
45d60a |
@@ -4349,12 +3843,6 @@ int expr_valid_for_context (struct expression *expr,
|
|
|
45d60a |
return 1;
|
|
|
45d60a |
return 0;
|
|
|
45d60a |
|
|
|
45d60a |
- case context_dns:
|
|
|
45d60a |
- if (is_dns_expression (expr)) {
|
|
|
45d60a |
- return 1;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
-
|
|
|
45d60a |
case context_data_or_numeric:
|
|
|
45d60a |
if (is_numeric_expression (expr) ||
|
|
|
45d60a |
is_data_expression (expr)) {
|
|
|
45d60a |
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
|
|
45d60a |
index 1d2bf2c..7e756e0 100644
|
|
|
45d60a |
--- a/includes/dhcpd.h
|
|
|
45d60a |
+++ b/includes/dhcpd.h
|
|
|
45d60a |
@@ -638,6 +638,7 @@ struct lease_state {
|
|
|
45d60a |
#define DDNS_UPDATE_STYLE_NONE 0
|
|
|
45d60a |
#define DDNS_UPDATE_STYLE_AD_HOC 1
|
|
|
45d60a |
#define DDNS_UPDATE_STYLE_INTERIM 2
|
|
|
45d60a |
+#define DDNS_UPDATE_STYLE_STANDARD 3
|
|
|
45d60a |
|
|
|
45d60a |
/* Server option names. */
|
|
|
45d60a |
|
|
|
45d60a |
@@ -1627,6 +1628,9 @@ typedef struct dhcp_ddns_cb {
|
|
|
45d60a |
|
|
|
45d60a |
void *transaction;
|
|
|
45d60a |
void *dataspace;
|
|
|
45d60a |
+
|
|
|
45d60a |
+ dns_rdataclass_t dhcid_class;
|
|
|
45d60a |
+ char *lease_tag;
|
|
|
45d60a |
} dhcp_ddns_cb_t;
|
|
|
45d60a |
|
|
|
45d60a |
extern struct ipv6_pool **pools;
|
|
|
45d60a |
@@ -2047,11 +2051,6 @@ struct expression *parse_domain_list(struct parse *cfile, int);
|
|
|
45d60a |
|
|
|
45d60a |
|
|
|
45d60a |
/* tree.c */
|
|
|
45d60a |
-#if defined (NSUPDATE)
|
|
|
45d60a |
-extern struct __res_state resolver_state;
|
|
|
45d60a |
-extern int resolver_inited;
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
-
|
|
|
45d60a |
extern struct binding_scope *global_scope;
|
|
|
45d60a |
pair cons (caddr_t, pair);
|
|
|
45d60a |
int make_const_option_cache (struct option_cache **, struct buffer **,
|
|
|
45d60a |
@@ -2079,15 +2078,6 @@ int evaluate_expression (struct binding_value **, struct packet *,
|
|
|
45d60a |
struct binding_scope **, struct expression *,
|
|
|
45d60a |
const char *, int);
|
|
|
45d60a |
int binding_value_dereference (struct binding_value **, const char *, int);
|
|
|
45d60a |
-#if defined (NSUPDATE_OLD)
|
|
|
45d60a |
-int evaluate_dns_expression (ns_updrec **, struct packet *,
|
|
|
45d60a |
- struct lease *,
|
|
|
45d60a |
- struct client_state *,
|
|
|
45d60a |
- struct option_state *,
|
|
|
45d60a |
- struct option_state *,
|
|
|
45d60a |
- struct binding_scope **,
|
|
|
45d60a |
- struct expression *);
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
int evaluate_boolean_expression (int *,
|
|
|
45d60a |
struct packet *, struct lease *,
|
|
|
45d60a |
struct client_state *,
|
|
|
45d60a |
@@ -2913,21 +2903,18 @@ int icmp_echorequest (struct iaddr *);
|
|
|
45d60a |
isc_result_t icmp_echoreply (omapi_object_t *);
|
|
|
45d60a |
|
|
|
45d60a |
/* dns.c */
|
|
|
45d60a |
-#if defined (NSUPDATE)
|
|
|
45d60a |
-isc_result_t find_tsig_key (ns_tsig_key **, const char *, struct dns_zone *);
|
|
|
45d60a |
-void tkey_free (ns_tsig_key **);
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
isc_result_t enter_dns_zone (struct dns_zone *);
|
|
|
45d60a |
isc_result_t dns_zone_lookup (struct dns_zone **, const char *);
|
|
|
45d60a |
int dns_zone_dereference (struct dns_zone **, const char *, int);
|
|
|
45d60a |
#if defined (NSUPDATE)
|
|
|
45d60a |
#define FIND_FORWARD 0
|
|
|
45d60a |
#define FIND_REVERSE 1
|
|
|
45d60a |
+isc_result_t find_tsig_key (ns_tsig_key **, const char *, struct dns_zone *);
|
|
|
45d60a |
+void tkey_free (ns_tsig_key **);
|
|
|
45d60a |
isc_result_t find_cached_zone (dhcp_ddns_cb_t *, int);
|
|
|
45d60a |
void forget_zone (struct dns_zone **);
|
|
|
45d60a |
void repudiate_zone (struct dns_zone **);
|
|
|
45d60a |
-//void cache_found_zone (ns_class, char *, struct in_addr *, int);
|
|
|
45d60a |
-int get_dhcid (struct data_string *, int, const u_int8_t *, unsigned);
|
|
|
45d60a |
+int get_dhcid (dhcp_ddns_cb_t *, int, const u_int8_t *, unsigned);
|
|
|
45d60a |
void dhcid_tolease (struct data_string *, struct data_string *);
|
|
|
45d60a |
isc_result_t dhcid_fromlease (struct data_string *, struct data_string *);
|
|
|
45d60a |
isc_result_t ddns_update_fwd(struct data_string *, struct iaddr,
|
|
|
45d60a |
@@ -2937,6 +2924,16 @@ isc_result_t ddns_remove_fwd(struct data_string *,
|
|
|
45d60a |
struct iaddr, struct data_string *);
|
|
|
45d60a |
#endif /* NSUPDATE */
|
|
|
45d60a |
|
|
|
45d60a |
+dhcp_ddns_cb_t *ddns_cb_alloc(const char *file, int line);
|
|
|
45d60a |
+void ddns_cb_free (dhcp_ddns_cb_t *ddns_cb, const char *file, int line);
|
|
|
45d60a |
+void ddns_cb_forget_zone (dhcp_ddns_cb_t *ddns_cb);
|
|
|
45d60a |
+isc_result_t
|
|
|
45d60a |
+ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line);
|
|
|
45d60a |
+isc_result_t
|
|
|
45d60a |
+ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb, const char *file, int line);
|
|
|
45d60a |
+void
|
|
|
45d60a |
+ddns_cancel(dhcp_ddns_cb_t *ddns_cb, const char *file, int line);
|
|
|
45d60a |
+
|
|
|
45d60a |
/* resolv.c */
|
|
|
45d60a |
extern char path_resolv_conf [];
|
|
|
45d60a |
extern struct name_server *name_servers;
|
|
|
45d60a |
@@ -3302,21 +3299,6 @@ void dump_subnets (void);
|
|
|
45d60a |
void free_everything (void);
|
|
|
45d60a |
#endif
|
|
|
45d60a |
|
|
|
45d60a |
-/* nsupdate.c */
|
|
|
45d60a |
-char *ddns_rev_name (struct lease *, struct lease_state *, struct packet *);
|
|
|
45d60a |
-char *ddns_fwd_name (struct lease *, struct lease_state *, struct packet *);
|
|
|
45d60a |
-int nsupdateA (const char *, const unsigned char *, u_int32_t, int);
|
|
|
45d60a |
-int nsupdatePTR (const char *, const unsigned char *, u_int32_t, int);
|
|
|
45d60a |
-void nsupdate (struct lease *, struct lease_state *, struct packet *, int);
|
|
|
45d60a |
-int updateA (const struct data_string *, const struct data_string *,
|
|
|
45d60a |
- unsigned int, struct lease *);
|
|
|
45d60a |
-int updatePTR (const struct data_string *, const struct data_string *,
|
|
|
45d60a |
- unsigned int, struct lease *);
|
|
|
45d60a |
-int deleteA (const struct data_string *, const struct data_string *,
|
|
|
45d60a |
- struct lease *);
|
|
|
45d60a |
-int deletePTR (const struct data_string *, const struct data_string *,
|
|
|
45d60a |
- struct lease *);
|
|
|
45d60a |
-
|
|
|
45d60a |
/* failover.c */
|
|
|
45d60a |
#if defined (FAILOVER_PROTOCOL)
|
|
|
45d60a |
extern dhcp_failover_state_t *failover_states;
|
|
|
45d60a |
@@ -3576,20 +3558,5 @@ void mark_hosts_unavailable(void);
|
|
|
45d60a |
void mark_phosts_unavailable(void);
|
|
|
45d60a |
void mark_interfaces_unavailable(void);
|
|
|
45d60a |
|
|
|
45d60a |
-dhcp_ddns_cb_t *ddns_cb_alloc(const char *file, int line);
|
|
|
45d60a |
-void ddns_cb_free (dhcp_ddns_cb_t *ddns_cb, const char *file, int line);
|
|
|
45d60a |
-void ddns_cb_forget_zone (dhcp_ddns_cb_t *ddns_cb);
|
|
|
45d60a |
-
|
|
|
45d60a |
-//void *key_from_zone(struct dns_zone *zone);
|
|
|
45d60a |
-
|
|
|
45d60a |
-isc_result_t
|
|
|
45d60a |
-ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line);
|
|
|
45d60a |
-
|
|
|
45d60a |
-isc_result_t
|
|
|
45d60a |
-ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb, const char *file, int line);
|
|
|
45d60a |
-
|
|
|
45d60a |
-void
|
|
|
45d60a |
-ddns_cancel(dhcp_ddns_cb_t *ddns_cb, const char *file, int line);
|
|
|
45d60a |
-
|
|
|
45d60a |
#define MAX_ADDRESS_STRING_LEN \
|
|
|
45d60a |
(sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))
|
|
|
45d60a |
diff --git a/includes/dhctoken.h b/includes/dhctoken.h
|
|
|
45d60a |
index 3d9a21d..a75eb97 100644
|
|
|
45d60a |
--- a/includes/dhctoken.h
|
|
|
45d60a |
+++ b/includes/dhctoken.h
|
|
|
45d60a |
@@ -32,6 +32,11 @@
|
|
|
45d60a |
* ``http://www.nominum.com''.
|
|
|
45d60a |
*/
|
|
|
45d60a |
|
|
|
45d60a |
+/*
|
|
|
45d60a |
+ * The following tokens have been deprecated and aren't in use anymore.
|
|
|
45d60a |
+ * They have been left in place to avoid disturbing the code.
|
|
|
45d60a |
+ * DNS_UPDATE, DNS_DELETE, NS_UPDATE, UPDATED_DNS_RR
|
|
|
45d60a |
+ */
|
|
|
45d60a |
enum dhcp_token {
|
|
|
45d60a |
SEMI = ';',
|
|
|
45d60a |
DOT = '.',
|
|
|
45d60a |
diff --git a/includes/site.h b/includes/site.h
|
|
|
45d60a |
index 8ff2834..1c7ec96 100644
|
|
|
45d60a |
--- a/includes/site.h
|
|
|
45d60a |
+++ b/includes/site.h
|
|
|
45d60a |
@@ -281,3 +281,17 @@
|
|
|
45d60a |
limit the number of TCP connections that the server will
|
|
|
45d60a |
allow at one time. A value of 0 means there is no limit.*/
|
|
|
45d60a |
#define MAX_FD_VALUE 200
|
|
|
45d60a |
+
|
|
|
45d60a |
+
|
|
|
45d60a |
+/* Include code to do a slow transition of DDNS records
|
|
|
45d60a |
+ from the interim to the standard version, or backwards.
|
|
|
45d60a |
+ The normal code will handle removing an old style record
|
|
|
45d60a |
+ when the name on a lease is being changed. This adds code
|
|
|
45d60a |
+ to handle the case where the name isn't being changed but
|
|
|
45d60a |
+ the old record should be removed to allow a new record to
|
|
|
45d60a |
+ be added. This is the slow transition as leases are only
|
|
|
45d60a |
+ updated as a client touches them. A fast transition would
|
|
|
45d60a |
+ entail updating all the records at once, probably at start
|
|
|
45d60a |
+ up. */
|
|
|
45d60a |
+#define DDNS_UPDATE_SLOW_TRANSITION
|
|
|
45d60a |
+
|
|
|
45d60a |
diff --git a/includes/tree.h b/includes/tree.h
|
|
|
45d60a |
index 291c0f6..746d31c 100644
|
|
|
45d60a |
--- a/includes/tree.h
|
|
|
45d60a |
+++ b/includes/tree.h
|
|
|
45d60a |
@@ -116,9 +116,6 @@ struct binding_value {
|
|
|
45d60a |
struct data_string data;
|
|
|
45d60a |
unsigned long intval;
|
|
|
45d60a |
int boolean;
|
|
|
45d60a |
-#if defined (NSUPDATE_OLD)
|
|
|
45d60a |
- ns_updrec *dns;
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
struct fundef *fundef;
|
|
|
45d60a |
struct binding_value *bv;
|
|
|
45d60a |
} value;
|
|
|
45d60a |
diff --git a/server/ddns.c b/server/ddns.c
|
|
|
45d60a |
index 2a64bc9..3cf15ce 100644
|
|
|
45d60a |
--- a/server/ddns.c
|
|
|
45d60a |
+++ b/server/ddns.c
|
|
|
45d60a |
@@ -36,6 +36,9 @@
|
|
|
45d60a |
#include "dhcpd.h"
|
|
|
45d60a |
#include <dns/result.h>
|
|
|
45d60a |
|
|
|
45d60a |
+char *ddns_standard_tag = "ddns-dhcid";
|
|
|
45d60a |
+char *ddns_interim_tag = "ddns-txt";
|
|
|
45d60a |
+
|
|
|
45d60a |
#ifdef NSUPDATE
|
|
|
45d60a |
|
|
|
45d60a |
static void ddns_fwd_srv_connector(struct lease *lease,
|
|
|
45d60a |
@@ -71,16 +74,13 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
|
|
|
45d60a |
struct data_string ddns_domainname;
|
|
|
45d60a |
struct data_string old_ddns_fwd_name;
|
|
|
45d60a |
struct data_string ddns_fwd_name;
|
|
|
45d60a |
- //struct data_string ddns_rev_name;
|
|
|
45d60a |
struct data_string ddns_dhcid;
|
|
|
45d60a |
struct binding_scope **scope = NULL;
|
|
|
45d60a |
- //struct iaddr addr;
|
|
|
45d60a |
struct data_string d1;
|
|
|
45d60a |
struct option_cache *oc;
|
|
|
45d60a |
int s1, s2;
|
|
|
45d60a |
int result = 0;
|
|
|
45d60a |
int server_updates_a = 1;
|
|
|
45d60a |
- //int server_updates_ptr = 1;
|
|
|
45d60a |
struct buffer *bp = (struct buffer *)0;
|
|
|
45d60a |
int ignorep = 0, client_ignorep = 0;
|
|
|
45d60a |
int rev_name_len;
|
|
|
45d60a |
@@ -89,8 +89,9 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
|
|
|
45d60a |
dhcp_ddns_cb_t *ddns_cb;
|
|
|
45d60a |
int do_remove = 0;
|
|
|
45d60a |
|
|
|
45d60a |
- if (ddns_update_style != 2)
|
|
|
45d60a |
- return 0;
|
|
|
45d60a |
+ if ((ddns_update_style != DDNS_UPDATE_STYLE_STANDARD) &&
|
|
|
45d60a |
+ (ddns_update_style != DDNS_UPDATE_STYLE_INTERIM))
|
|
|
45d60a |
+ return (0);
|
|
|
45d60a |
|
|
|
45d60a |
/*
|
|
|
45d60a |
* sigh, I want to cancel any previous udpates before we do anything
|
|
|
45d60a |
@@ -149,7 +150,6 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
|
|
|
45d60a |
memset (&ddns_domainname, 0, sizeof (ddns_domainname));
|
|
|
45d60a |
memset (&old_ddns_fwd_name, 0, sizeof (ddns_fwd_name));
|
|
|
45d60a |
memset (&ddns_fwd_name, 0, sizeof (ddns_fwd_name));
|
|
|
45d60a |
- //memset (&ddns_rev_name, 0, sizeof (ddns_rev_name));
|
|
|
45d60a |
memset (&ddns_dhcid, 0, sizeof (ddns_dhcid));
|
|
|
45d60a |
|
|
|
45d60a |
/* If we are allowed to accept the client's update of its own A
|
|
|
45d60a |
@@ -263,31 +263,22 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
|
|
|
45d60a |
goto in;
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
- /* See if there's a DHCID on the lease, and if not
|
|
|
45d60a |
- * then potentially look for 'on events' for ad-hoc ddns.
|
|
|
45d60a |
+#if defined (DDNS_UPDATE_SLOW_TRANSITION)
|
|
|
45d60a |
+ /*
|
|
|
45d60a |
+ * If the slow transition code is enabled check to see
|
|
|
45d60a |
+ * if the stored type (standard or interim doesn't
|
|
|
45d60a |
+ * match the type currently in use. If it doesn't
|
|
|
45d60a |
+ * try to remove and replace the DNS record
|
|
|
45d60a |
*/
|
|
|
45d60a |
- if (!find_bound_string(&ddns_dhcid, *scope, "ddns-txt") &&
|
|
|
45d60a |
- (old != NULL)) {
|
|
|
45d60a |
- /* If there's no DHCID, the update was probably
|
|
|
45d60a |
- done with the old-style ad-hoc DDNS updates.
|
|
|
45d60a |
- So if the expiry and release events look like
|
|
|
45d60a |
- they're the same, run them. This should delete
|
|
|
45d60a |
- the old DDNS data. */
|
|
|
45d60a |
- if (old -> on_expiry == old -> on_release) {
|
|
|
45d60a |
- execute_statements(NULL, NULL, lease, NULL,
|
|
|
45d60a |
- NULL, NULL, scope,
|
|
|
45d60a |
- old->on_expiry);
|
|
|
45d60a |
- if (old -> on_expiry)
|
|
|
45d60a |
- executable_statement_dereference
|
|
|
45d60a |
- (&old -> on_expiry, MDL);
|
|
|
45d60a |
- if (old -> on_release)
|
|
|
45d60a |
- executable_statement_dereference
|
|
|
45d60a |
- (&old -> on_release, MDL);
|
|
|
45d60a |
- /* Now, install the DDNS data the new way. */
|
|
|
45d60a |
- goto in;
|
|
|
45d60a |
- }
|
|
|
45d60a |
- } else
|
|
|
45d60a |
+ if (((ddns_update_style == DDNS_UPDATE_STYLE_STANDARD) &&
|
|
|
45d60a |
+ find_bound_string(&ddns_dhcid, *scope, ddns_interim_tag)) ||
|
|
|
45d60a |
+ ((ddns_update_style == DDNS_UPDATE_STYLE_INTERIM) &&
|
|
|
45d60a |
+ find_bound_string(&ddns_dhcid, *scope, ddns_standard_tag))) {
|
|
|
45d60a |
data_string_forget(&ddns_dhcid, MDL);
|
|
|
45d60a |
+ do_remove = 1;
|
|
|
45d60a |
+ goto in;
|
|
|
45d60a |
+ }
|
|
|
45d60a |
+#endif
|
|
|
45d60a |
|
|
|
45d60a |
/* See if the administrator wants to do updates even
|
|
|
45d60a |
in cases where the update already appears to have been
|
|
|
45d60a |
@@ -486,22 +477,68 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
/*
|
|
|
45d60a |
+ * copy the string now so we can pass it to the dhcid routines
|
|
|
45d60a |
+ * via the ddns_cb pointer
|
|
|
45d60a |
+ */
|
|
|
45d60a |
+ data_string_copy(&ddns_cb->fwd_name, &ddns_fwd_name, MDL);
|
|
|
45d60a |
+
|
|
|
45d60a |
+ /*
|
|
|
45d60a |
* If we are updating the A record, compute the DHCID value.
|
|
|
45d60a |
+ * We have two options for computing the DHCID value, the older
|
|
|
45d60a |
+ * interim version and the newer standard version. The interim
|
|
|
45d60a |
+ * has some issues but is left as is to avoid compatibility issues.
|
|
|
45d60a |
+ *
|
|
|
45d60a |
+ * We select the type of DHCID to construct and the information to
|
|
|
45d60a |
+ * use for the digest based on 4701 section 3.3
|
|
|
45d60a |
*/
|
|
|
45d60a |
if ((ddns_cb->flags & DDNS_UPDATE_ADDR) != 0) {
|
|
|
45d60a |
- if (lease6 != NULL)
|
|
|
45d60a |
- result = get_dhcid(&ddns_cb->dhcid, 2,
|
|
|
45d60a |
- lease6->ia->iaid_duid.data,
|
|
|
45d60a |
- lease6->ia->iaid_duid.len);
|
|
|
45d60a |
- else if ((lease != NULL) && (lease->uid != NULL) &&
|
|
|
45d60a |
- (lease->uid_len != 0))
|
|
|
45d60a |
- result = get_dhcid (&ddns_cb->dhcid,
|
|
|
45d60a |
- DHO_DHCP_CLIENT_IDENTIFIER,
|
|
|
45d60a |
- lease -> uid, lease -> uid_len);
|
|
|
45d60a |
- else if (lease != NULL)
|
|
|
45d60a |
- result = get_dhcid (&ddns_cb->dhcid, 0,
|
|
|
45d60a |
- lease -> hardware_addr.hbuf,
|
|
|
45d60a |
- lease -> hardware_addr.hlen);
|
|
|
45d60a |
+ int ddns_type;
|
|
|
45d60a |
+ int ddns_len;
|
|
|
45d60a |
+ if (ddns_update_style == DDNS_UPDATE_STYLE_STANDARD) {
|
|
|
45d60a |
+ /* The standard style */
|
|
|
45d60a |
+ ddns_cb->lease_tag = ddns_standard_tag;
|
|
|
45d60a |
+ ddns_cb->dhcid_class = dns_rdatatype_dhcid;
|
|
|
45d60a |
+ ddns_type = 1;
|
|
|
45d60a |
+ ddns_len = 4;
|
|
|
45d60a |
+ } else {
|
|
|
45d60a |
+ /* The older interim style */
|
|
|
45d60a |
+ ddns_cb->lease_tag = ddns_interim_tag;
|
|
|
45d60a |
+ ddns_cb->dhcid_class = dns_rdatatype_txt;
|
|
|
45d60a |
+ /* for backwards compatibility */
|
|
|
45d60a |
+ ddns_type = DHO_DHCP_CLIENT_IDENTIFIER;
|
|
|
45d60a |
+ /* IAID incorrectly included */
|
|
|
45d60a |
+ ddns_len = 0;
|
|
|
45d60a |
+ }
|
|
|
45d60a |
+
|
|
|
45d60a |
+
|
|
|
45d60a |
+ if (lease6 != NULL) {
|
|
|
45d60a |
+ if (lease6->ia->iaid_duid.len < ddns_len)
|
|
|
45d60a |
+ goto badfqdn;
|
|
|
45d60a |
+ result = get_dhcid(ddns_cb, 2,
|
|
|
45d60a |
+ lease6->ia->iaid_duid.data + ddns_len,
|
|
|
45d60a |
+ lease6->ia->iaid_duid.len - ddns_len);
|
|
|
45d60a |
+ } else if ((lease != NULL) &&
|
|
|
45d60a |
+ (lease->uid != NULL) &&
|
|
|
45d60a |
+ (lease->uid_len != 0)) {
|
|
|
45d60a |
+ /* If this is standard check for an RFC 4361
|
|
|
45d60a |
+ * compliant client identifier
|
|
|
45d60a |
+ */
|
|
|
45d60a |
+ if ((ddns_update_style == DDNS_UPDATE_STYLE_STANDARD) &&
|
|
|
45d60a |
+ (lease->uid[0] == 255)) {
|
|
|
45d60a |
+ if (lease->uid_len < 5)
|
|
|
45d60a |
+ goto badfqdn;
|
|
|
45d60a |
+ result = get_dhcid(ddns_cb, 2,
|
|
|
45d60a |
+ lease->uid + 5,
|
|
|
45d60a |
+ lease->uid_len - 5);
|
|
|
45d60a |
+ } else {
|
|
|
45d60a |
+ result = get_dhcid(ddns_cb, ddns_type,
|
|
|
45d60a |
+ lease->uid,
|
|
|
45d60a |
+ lease->uid_len);
|
|
|
45d60a |
+ }
|
|
|
45d60a |
+ } else if (lease != NULL)
|
|
|
45d60a |
+ result = get_dhcid(ddns_cb, 0,
|
|
|
45d60a |
+ lease->hardware_addr.hbuf,
|
|
|
45d60a |
+ lease->hardware_addr.hlen);
|
|
|
45d60a |
else
|
|
|
45d60a |
log_fatal("Impossible condition at %s:%d.", MDL);
|
|
|
45d60a |
|
|
|
45d60a |
@@ -513,8 +550,6 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
|
|
|
45d60a |
* Perform updates.
|
|
|
45d60a |
*/
|
|
|
45d60a |
|
|
|
45d60a |
- data_string_copy(&ddns_cb->fwd_name, &ddns_fwd_name, MDL);
|
|
|
45d60a |
-
|
|
|
45d60a |
if (ddns_cb->flags && DDNS_UPDATE_ADDR) {
|
|
|
45d60a |
oc = lookup_option(&server_universe, options,
|
|
|
45d60a |
SV_DDNS_CONFLICT_DETECT);
|
|
|
45d60a |
@@ -707,8 +742,6 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
|
|
|
45d60a |
data_string_forget(&ddns_domainname, MDL);
|
|
|
45d60a |
data_string_forget(&old_ddns_fwd_name, MDL);
|
|
|
45d60a |
data_string_forget(&ddns_fwd_name, MDL);
|
|
|
45d60a |
- //data_string_forget(&ddns_rev_name, MDL);
|
|
|
45d60a |
- //data_string_forget(&ddns_dhcid, MDL);
|
|
|
45d60a |
if (bp)
|
|
|
45d60a |
buffer_dereference(&bp, MDL);
|
|
|
45d60a |
|
|
|
45d60a |
@@ -822,18 +855,21 @@ ddns_update_lease_text(dhcp_ddns_cb_t *ddns_cb,
|
|
|
45d60a |
case DDNS_STATE_ADD_FW_NXDOMAIN:
|
|
|
45d60a |
bind_ds_value(scope, "ddns-fwd-name", &ddns_cb->fwd_name);
|
|
|
45d60a |
|
|
|
45d60a |
- /* convert from dns version to lease version of dhcid */
|
|
|
45d60a |
- memset(&lease_dhcid, 0, sizeof(lease_dhcid));
|
|
|
45d60a |
- dhcid_tolease(&ddns_cb->dhcid, &lease_dhcid);
|
|
|
45d60a |
- bind_ds_value(scope, "ddns-txt", &lease_dhcid);
|
|
|
45d60a |
- data_string_forget(&lease_dhcid, MDL);
|
|
|
45d60a |
-
|
|
|
45d60a |
+ if (ddns_cb->lease_tag == ddns_standard_tag) {
|
|
|
45d60a |
+ bind_ds_value(scope, ddns_standard_tag, &ddns_cb->dhcid);
|
|
|
45d60a |
+ } else {
|
|
|
45d60a |
+ /* convert from dns version to lease version of dhcid */
|
|
|
45d60a |
+ memset(&lease_dhcid, 0, sizeof(lease_dhcid));
|
|
|
45d60a |
+ dhcid_tolease(&ddns_cb->dhcid, &lease_dhcid);
|
|
|
45d60a |
+ bind_ds_value(scope, ddns_interim_tag, &lease_dhcid);
|
|
|
45d60a |
+ data_string_forget(&lease_dhcid, MDL);
|
|
|
45d60a |
+ }
|
|
|
45d60a |
break;
|
|
|
45d60a |
|
|
|
45d60a |
case DDNS_STATE_REM_FW_NXRR:
|
|
|
45d60a |
case DDNS_STATE_REM_FW_YXDHCID:
|
|
|
45d60a |
unset(*scope, "ddns-fwd-name");
|
|
|
45d60a |
- unset(*scope, "ddns-txt");
|
|
|
45d60a |
+ unset(*scope, ddns_cb->lease_tag);
|
|
|
45d60a |
break;
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
@@ -1791,7 +1827,8 @@ ddns_removals(struct lease *lease,
|
|
|
45d60a |
if (*scope == NULL)
|
|
|
45d60a |
goto cleanup;
|
|
|
45d60a |
|
|
|
45d60a |
- if (ddns_update_style != 2)
|
|
|
45d60a |
+ if ((ddns_update_style != DDNS_UPDATE_STYLE_STANDARD) &&
|
|
|
45d60a |
+ (ddns_update_style != DDNS_UPDATE_STYLE_INTERIM))
|
|
|
45d60a |
goto cleanup;
|
|
|
45d60a |
|
|
|
45d60a |
/* Assume that we are removing both records */
|
|
|
45d60a |
@@ -1823,15 +1860,22 @@ ddns_removals(struct lease *lease,
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
/*
|
|
|
45d60a |
- * Find the ptr name and copy it to the control block. If we don't
|
|
|
45d60a |
- * have it this isn't an interim or rfc3??? record so we can't delete
|
|
|
45d60a |
+ * Find the txt or dhcid tag and copy it to the control block. If we don't
|
|
|
45d60a |
+ * have one this isn't an interim or standard record so we can't delete
|
|
|
45d60a |
* the A record using this mechanism but we can delete the ptr record.
|
|
|
45d60a |
* In this case we will attempt to do any requested next step.
|
|
|
45d60a |
*/
|
|
|
45d60a |
memset(&leaseid, 0, sizeof(leaseid));
|
|
|
45d60a |
- if (!find_bound_string (&leaseid, *scope, "ddns-txt")) {
|
|
|
45d60a |
- ddns_cb->flags &= ~DDNS_UPDATE_ADDR;
|
|
|
45d60a |
- } else {
|
|
|
45d60a |
+ if (find_bound_string (&leaseid, *scope, ddns_standard_tag)) {
|
|
|
45d60a |
+ /* We have a standard tag */
|
|
|
45d60a |
+ ddns_cb->lease_tag = ddns_standard_tag;
|
|
|
45d60a |
+ ddns_cb->dhcid_class = dns_rdatatype_dhcid;
|
|
|
45d60a |
+ data_string_copy(&ddns_cb->dhcid, &leaseid, MDL);
|
|
|
45d60a |
+ data_string_forget(&leaseid, MDL);
|
|
|
45d60a |
+ } else if (find_bound_string (&leaseid, *scope, ddns_interim_tag)) {
|
|
|
45d60a |
+ /* we have an interim tag */
|
|
|
45d60a |
+ ddns_cb->lease_tag = ddns_interim_tag;
|
|
|
45d60a |
+ ddns_cb->dhcid_class = dns_rdatatype_txt;
|
|
|
45d60a |
if (dhcid_fromlease(&ddns_cb->dhcid, &leaseid) !=
|
|
|
45d60a |
ISC_R_SUCCESS) {
|
|
|
45d60a |
/* We couldn't convert the dhcid from the lease
|
|
|
45d60a |
@@ -1841,7 +1885,9 @@ ddns_removals(struct lease *lease,
|
|
|
45d60a |
ddns_cb->flags &= ~DDNS_UPDATE_ADDR;
|
|
|
45d60a |
}
|
|
|
45d60a |
data_string_forget(&leaseid, MDL);
|
|
|
45d60a |
- }
|
|
|
45d60a |
+ } else {
|
|
|
45d60a |
+ ddns_cb->flags &= ~DDNS_UPDATE_ADDR;
|
|
|
45d60a |
+ }
|
|
|
45d60a |
|
|
|
45d60a |
/*
|
|
|
45d60a |
* Find the rev name and copy it to the control block. If we don't
|
|
|
45d60a |
@@ -1888,7 +1934,7 @@ ddns_removals(struct lease *lease,
|
|
|
45d60a |
else {
|
|
|
45d60a |
/*remove info from scope */
|
|
|
45d60a |
unset(*scope, "ddns-fwd-name");
|
|
|
45d60a |
- unset(*scope, "ddns-txt");
|
|
|
45d60a |
+ unset(*scope, ddns_cb->lease_tag);
|
|
|
45d60a |
}
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
diff --git a/server/dhcpd.c b/server/dhcpd.c
|
|
|
45d60a |
index 67fec83..9617d75 100644
|
|
|
45d60a |
--- a/server/dhcpd.c
|
|
|
45d60a |
+++ b/server/dhcpd.c
|
|
|
45d60a |
@@ -82,86 +82,6 @@ option server.ddns-hostname = \n\
|
|
|
45d60a |
option server.ddns-domainname = config-option domain-name; \n\
|
|
|
45d60a |
option server.ddns-rev-domainname = \"in-addr.arpa.\";";
|
|
|
45d60a |
|
|
|
45d60a |
-/* This is the old-style name service updater that is executed
|
|
|
45d60a |
- whenever a lease is committed. It does not follow the DHCP-DNS
|
|
|
45d60a |
- draft at all. */
|
|
|
45d60a |
-
|
|
|
45d60a |
-char old_nsupdate [] = " \n\
|
|
|
45d60a |
-on commit { \n\
|
|
|
45d60a |
- if (not static and \n\
|
|
|
45d60a |
- ((config-option server.ddns-updates = null) or \n\
|
|
|
45d60a |
- (config-option server.ddns-updates != 0))) { \n\
|
|
|
45d60a |
- set new-ddns-fwd-name = \n\
|
|
|
45d60a |
- concat (pick (config-option server.ddns-hostname, \n\
|
|
|
45d60a |
- option host-name), \".\", \n\
|
|
|
45d60a |
- pick (config-option server.ddns-domainname, \n\
|
|
|
45d60a |
- config-option domain-name)); \n\
|
|
|
45d60a |
- if (defined (ddns-fwd-name) and ddns-fwd-name != new-ddns-fwd-name) { \n\
|
|
|
45d60a |
- switch (ns-update (delete (IN, A, ddns-fwd-name, leased-address))) { \n\
|
|
|
45d60a |
- case NOERROR: \n\
|
|
|
45d60a |
- unset ddns-fwd-name; \n\
|
|
|
45d60a |
- on expiry or release { \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- \n\
|
|
|
45d60a |
- if (not defined (ddns-fwd-name)) { \n\
|
|
|
45d60a |
- set ddns-fwd-name = new-ddns-fwd-name; \n\
|
|
|
45d60a |
- if defined (ddns-fwd-name) { \n\
|
|
|
45d60a |
- switch (ns-update (not exists (IN, A, ddns-fwd-name, null), \n\
|
|
|
45d60a |
- add (IN, A, ddns-fwd-name, leased-address, \n\
|
|
|
45d60a |
- lease-time / 2))) { \n\
|
|
|
45d60a |
- default: \n\
|
|
|
45d60a |
- unset ddns-fwd-name; \n\
|
|
|
45d60a |
- break; \n\
|
|
|
45d60a |
- \n\
|
|
|
45d60a |
- case NOERROR: \n\
|
|
|
45d60a |
- set ddns-rev-name = \n\
|
|
|
45d60a |
- concat (binary-to-ascii (10, 8, \".\", \n\
|
|
|
45d60a |
- reverse (1, \n\
|
|
|
45d60a |
- leased-address)), \".\", \n\
|
|
|
45d60a |
- pick (config-option server.ddns-rev-domainname, \n\
|
|
|
45d60a |
- \"in-addr.arpa.\")); \n\
|
|
|
45d60a |
- switch (ns-update (delete (IN, PTR, ddns-rev-name, null), \n\
|
|
|
45d60a |
- add (IN, PTR, ddns-rev-name, ddns-fwd-name, \n\
|
|
|
45d60a |
- lease-time / 2))) \n\
|
|
|
45d60a |
- { \n\
|
|
|
45d60a |
- default: \n\
|
|
|
45d60a |
- unset ddns-rev-name; \n\
|
|
|
45d60a |
- on release or expiry { \n\
|
|
|
45d60a |
- switch (ns-update (delete (IN, A, ddns-fwd-name, \n\
|
|
|
45d60a |
- leased-address))) { \n\
|
|
|
45d60a |
- case NOERROR: \n\
|
|
|
45d60a |
- unset ddns-fwd-name; \n\
|
|
|
45d60a |
- break; \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- on release or expiry; \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- break; \n\
|
|
|
45d60a |
- \n\
|
|
|
45d60a |
- case NOERROR: \n\
|
|
|
45d60a |
- on release or expiry { \n\
|
|
|
45d60a |
- switch (ns-update (delete (IN, PTR, ddns-rev-name, null))) {\n\
|
|
|
45d60a |
- case NOERROR: \n\
|
|
|
45d60a |
- unset ddns-rev-name; \n\
|
|
|
45d60a |
- break; \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- switch (ns-update (delete (IN, A, ddns-fwd-name, \n\
|
|
|
45d60a |
- leased-address))) { \n\
|
|
|
45d60a |
- case NOERROR: \n\
|
|
|
45d60a |
- unset ddns-fwd-name; \n\
|
|
|
45d60a |
- break; \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- on release or expiry; \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
- unset new-ddns-fwd-name; \n\
|
|
|
45d60a |
- } \n\
|
|
|
45d60a |
-}";
|
|
|
45d60a |
-
|
|
|
45d60a |
#endif /* NSUPDATE */
|
|
|
45d60a |
int ddns_update_style;
|
|
|
45d60a |
|
|
|
45d60a |
@@ -897,9 +817,6 @@ void postconf_initialization (int quiet)
|
|
|
45d60a |
struct option_cache *oc;
|
|
|
45d60a |
char *s;
|
|
|
45d60a |
isc_result_t result;
|
|
|
45d60a |
-#if defined (NSUPDATE)
|
|
|
45d60a |
- struct parse *parse;
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
int tmp;
|
|
|
45d60a |
|
|
|
45d60a |
/* Now try to get the lease file name. */
|
|
|
45d60a |
@@ -1160,49 +1077,6 @@ void postconf_initialization (int quiet)
|
|
|
45d60a |
|
|
|
45d60a |
/* Don't need the options anymore. */
|
|
|
45d60a |
option_state_dereference (&options, MDL);
|
|
|
45d60a |
-
|
|
|
45d60a |
-#if defined (NSUPDATE)
|
|
|
45d60a |
- /* If old-style ddns updates have been requested, parse the
|
|
|
45d60a |
- old-style ddns updater. */
|
|
|
45d60a |
- if (ddns_update_style == 1) {
|
|
|
45d60a |
- struct executable_statement **e, *s;
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (root_group -> statements) {
|
|
|
45d60a |
- s = (struct executable_statement *)0;
|
|
|
45d60a |
- if (!executable_statement_allocate (&s, MDL))
|
|
|
45d60a |
- log_fatal ("no memory for ddns updater");
|
|
|
45d60a |
- executable_statement_reference
|
|
|
45d60a |
- (&s -> next, root_group -> statements, MDL);
|
|
|
45d60a |
- executable_statement_dereference
|
|
|
45d60a |
- (&root_group -> statements, MDL);
|
|
|
45d60a |
- executable_statement_reference
|
|
|
45d60a |
- (&root_group -> statements, s, MDL);
|
|
|
45d60a |
- s -> op = statements_statement;
|
|
|
45d60a |
- e = &s -> data.statements;
|
|
|
45d60a |
- executable_statement_dereference (&s, MDL);
|
|
|
45d60a |
- } else {
|
|
|
45d60a |
- e = &root_group -> statements;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-
|
|
|
45d60a |
- /* Set up the standard name service updater routine. */
|
|
|
45d60a |
- parse = NULL;
|
|
|
45d60a |
- result = new_parse(&parse, -1, old_nsupdate,
|
|
|
45d60a |
- sizeof(old_nsupdate) - 1,
|
|
|
45d60a |
- "old name service update routine", 0);
|
|
|
45d60a |
- if (result != ISC_R_SUCCESS)
|
|
|
45d60a |
- log_fatal ("can't begin parsing old ddns updater!");
|
|
|
45d60a |
-
|
|
|
45d60a |
- if (parse != NULL) {
|
|
|
45d60a |
- tmp = 0;
|
|
|
45d60a |
- if (!(parse_executable_statements(e, parse, &tmp,
|
|
|
45d60a |
- context_any))) {
|
|
|
45d60a |
- end_parse(&parse;;
|
|
|
45d60a |
- log_fatal("can't parse standard ddns updater!");
|
|
|
45d60a |
- }
|
|
|
45d60a |
- }
|
|
|
45d60a |
- end_parse(&parse;;
|
|
|
45d60a |
- }
|
|
|
45d60a |
-#endif
|
|
|
45d60a |
}
|
|
|
45d60a |
|
|
|
45d60a |
void postdb_startup (void)
|
|
|
45d60a |
diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
|
|
|
45d60a |
index 74393c2..2351e21 100644
|
|
|
45d60a |
--- a/server/dhcpd.conf.5
|
|
|
45d60a |
+++ b/server/dhcpd.conf.5
|
|
|
45d60a |
@@ -1076,115 +1076,24 @@ the Domain Name System to be updated. These updates are RFC 2136
|
|
|
45d60a |
compliant so any DNS server supporting RFC 2136 should be able to
|
|
|
45d60a |
accept updates from the DHCP server.
|
|
|
45d60a |
.PP
|
|
|
45d60a |
-Two DNS update schemes are currently implemented, and another is
|
|
|
45d60a |
-planned. The two that are currently implemented are the ad-hoc DNS
|
|
|
45d60a |
-update mode and the interim DHCP-DNS interaction draft update mode.
|
|
|
45d60a |
-In the future we plan to add a third mode which will be the standard
|
|
|
45d60a |
-DNS update method based on the RFCS for DHCP-DNS interaction and DHCID
|
|
|
45d60a |
-The DHCP server must be configured to use one of the two
|
|
|
45d60a |
-currently-supported methods, or not to do dns updates.
|
|
|
45d60a |
-This can be done with the
|
|
|
45d60a |
+There are two DNS schemes implemented. The interim option is
|
|
|
45d60a |
+based on draft revisions of the DDNS documents while the standard
|
|
|
45d60a |
+option is based on the RFCs for DHCP-DNS interaction and DHCIDs.
|
|
|
45d60a |
+A third option, ad-hoc, was deprecated and has now been removed
|
|
|
45d60a |
+from the code base. The DHCP server must be configured to use
|
|
|
45d60a |
+one of the two currently-supported methods, or not to do DNS updates.
|
|
|
45d60a |
+.PP
|
|
|
45d60a |
+New installations should use the standard option. Older
|
|
|
45d60a |
+installations may want to continue using the interim option for
|
|
|
45d60a |
+backwards compatibility with the DNS database until the database
|
|
|
45d60a |
+can be updated. This can be done with the
|
|
|
45d60a |
.I ddns-update-style
|
|
|
45d60a |
configuration parameter.
|
|
|
45d60a |
-.SH THE AD-HOC DNS UPDATE SCHEME
|
|
|
45d60a |
-The ad-hoc Dynamic DNS update scheme is
|
|
|
45d60a |
-.B now deprecated
|
|
|
45d60a |
-and
|
|
|
45d60a |
-.B
|
|
|
45d60a |
-does not work.
|
|
|
45d60a |
-In future releases of the ISC DHCP server, this scheme will not likely be
|
|
|
45d60a |
-available. The interim scheme works, allows for failover, and should now be
|
|
|
45d60a |
-used. The following description is left here for informational purposes
|
|
|
45d60a |
-only.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-The ad-hoc Dynamic DNS update scheme implemented in this version of
|
|
|
45d60a |
-the ISC DHCP server is a prototype design, which does not
|
|
|
45d60a |
-have much to do with the standard update method that is being
|
|
|
45d60a |
-standardized in the IETF DHC working group, but rather implements some
|
|
|
45d60a |
-very basic, yet useful, update capabilities. This mode
|
|
|
45d60a |
-.B does not work
|
|
|
45d60a |
-with the
|
|
|
45d60a |
-.I failover protocol
|
|
|
45d60a |
-because it does not account for the possibility of two different DHCP
|
|
|
45d60a |
-servers updating the same set of DNS records.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-For the ad-hoc DNS update method, the client's FQDN is derived in two
|
|
|
45d60a |
-parts. First, the hostname is determined. Then, the domain name is
|
|
|
45d60a |
-determined, and appended to the hostname.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-The DHCP server determines the client's hostname by first looking for
|
|
|
45d60a |
-a \fIddns-hostname\fR configuration option, and using that if it is
|
|
|
45d60a |
-present. If no such option is present, the server looks for a
|
|
|
45d60a |
-valid hostname in the FQDN option sent by the client. If one is
|
|
|
45d60a |
-found, it is used; otherwise, if the client sent a host-name option,
|
|
|
45d60a |
-that is used. Otherwise, if there is a host declaration that applies
|
|
|
45d60a |
-to the client, the name from that declaration will be used. If none
|
|
|
45d60a |
-of these applies, the server will not have a hostname for the client,
|
|
|
45d60a |
-and will not be able to do a DNS update.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-The domain name is determined from the
|
|
|
45d60a |
-.I ddns-domainname
|
|
|
45d60a |
-configuration option. The default configuration for this option is:
|
|
|
45d60a |
-.nf
|
|
|
45d60a |
-.sp 1
|
|
|
45d60a |
- option server.ddns-domainname = config-option domain-name;
|
|
|
45d60a |
-
|
|
|
45d60a |
-.fi
|
|
|
45d60a |
-So if this configuration option is not configured to a different
|
|
|
45d60a |
-value (over-riding the above default), or if a domain-name option
|
|
|
45d60a |
-has not been configured for the client's scope, then the server will
|
|
|
45d60a |
-not attempt to perform a DNS update.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-The client's fully-qualified domain name, derived as we have
|
|
|
45d60a |
-described, is used as the name on which an "A" record will be stored.
|
|
|
45d60a |
-The A record will contain the IP address that the client was assigned
|
|
|
45d60a |
-in its lease. If there is already an A record with the same name in
|
|
|
45d60a |
-the DNS server, no update of either the A or PTR records will occur -
|
|
|
45d60a |
-this prevents a client from claiming that its hostname is the name of
|
|
|
45d60a |
-some network server. For example, if you have a fileserver called
|
|
|
45d60a |
-"fs.sneedville.edu", and the client claims its hostname is "fs", no
|
|
|
45d60a |
-DNS update will be done for that client, and an error message will be
|
|
|
45d60a |
-logged.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-If the A record update succeeds, a PTR record update for the assigned
|
|
|
45d60a |
-IP address will be done, pointing to the A record. This update is
|
|
|
45d60a |
-unconditional - it will be done even if another PTR record of the same
|
|
|
45d60a |
-name exists. Since the IP address has been assigned to the DHCP
|
|
|
45d60a |
-server, this should be safe.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-Please note that the current implementation assumes clients only have
|
|
|
45d60a |
-a single network interface. A client with two network interfaces
|
|
|
45d60a |
-will see unpredictable behavior. This is considered a bug, and will
|
|
|
45d60a |
-be fixed in a later release. It may be helpful to enable the
|
|
|
45d60a |
-.I one-lease-per-client
|
|
|
45d60a |
-parameter so that roaming clients do not trigger this same behavior.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-The DHCP protocol normally involves a four-packet exchange - first the
|
|
|
45d60a |
-client sends a DHCPDISCOVER message, then the server sends a
|
|
|
45d60a |
-DHCPOFFER, then the client sends a DHCPREQUEST, then the server sends
|
|
|
45d60a |
-a DHCPACK. In the current version of the server, the server will do
|
|
|
45d60a |
-a DNS update after it has received the DHCPREQUEST, and before it has
|
|
|
45d60a |
-sent the DHCPACK. It only sends the DNS update if it has not sent
|
|
|
45d60a |
-one for the client's address before, in order to minimize the impact
|
|
|
45d60a |
-on the DHCP server.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-When the client's lease expires, the DHCP server (if it is operating
|
|
|
45d60a |
-at the time, or when next it operates) will remove the client's A and
|
|
|
45d60a |
-PTR records from the DNS database. If the client releases its lease
|
|
|
45d60a |
-by sending a DHCPRELEASE message, the server will likewise remove the
|
|
|
45d60a |
-A and PTR records.
|
|
|
45d60a |
-.SH THE INTERIM DNS UPDATE SCHEME
|
|
|
45d60a |
-The interim DNS update scheme operates mostly according to several
|
|
|
45d60a |
-drafts considered by the IETF. While the drafts have since become
|
|
|
45d60a |
-RFCs the code was written before they were finalized and there are
|
|
|
45d60a |
-some differences between our code and the final RFCs. We plan to
|
|
|
45d60a |
-update our code, probably adding a standard DNS update option, at
|
|
|
45d60a |
-some time. The basic framework is similar with the main material
|
|
|
45d60a |
-difference being that a DHCID RR was assigned in the RFCs whereas
|
|
|
45d60a |
-our code continues to use an experimental TXT record. The format
|
|
|
45d60a |
-of the TXT record bears a resemblance to the DHCID RR but it is not
|
|
|
45d60a |
-equivalent (MD5 vs SHA1, field length differences etc).
|
|
|
45d60a |
-The standard RFCs are:
|
|
|
45d60a |
+.SH THE DNS UPDATE SCHEME
|
|
|
45d60a |
+the interim and standard DNS update schemes operate mostly according
|
|
|
45d60a |
+to work from the IETF. The interim version was based on the drafts
|
|
|
45d60a |
+in progress at the time while the standard is based on the completed
|
|
|
45d60a |
+RFCs. The standard RFCs are:
|
|
|
45d60a |
.PP
|
|
|
45d60a |
.nf
|
|
|
45d60a |
.ce 3
|
|
|
45d60a |
@@ -1202,15 +1111,17 @@ draft-ietf-dhc-fqdn-option-??.txt
|
|
|
45d60a |
draft-ietf-dhc-ddns-resolution-??.txt
|
|
|
45d60a |
.fi
|
|
|
45d60a |
.PP
|
|
|
45d60a |
-Because our implementation is slightly different than the standard, we
|
|
|
45d60a |
-will briefly document the operation of this update style here.
|
|
|
45d60a |
+The basic framework for the two schemes is similar with the main
|
|
|
45d60a |
+material difference being that a DHCID RR is used in the standard
|
|
|
45d60a |
+version while the interim versions uses a TXT RR. The format
|
|
|
45d60a |
+of the TXT record bears a resemblance to the DHCID RR but it is not
|
|
|
45d60a |
+equivalent (MD5 vs SHA2, field length differences etc).
|
|
|
45d60a |
.PP
|
|
|
45d60a |
-The first point to understand about this style of DNS update is that
|
|
|
45d60a |
-unlike the ad-hoc style, the DHCP server does not necessarily
|
|
|
45d60a |
+In these two schemes the DHCP server does not necessarily
|
|
|
45d60a |
always update both the A and the PTR records. The FQDN option
|
|
|
45d60a |
includes a flag which, when sent by the client, indicates that the
|
|
|
45d60a |
client wishes to update its own A record. In that case, the server
|
|
|
45d60a |
-can be configured either to honor the client's intentions or ignore
|
|
|
45d60a |
+can be configured either to honor the client\'s intentions or ignore
|
|
|
45d60a |
them. This is done with the statement \fIallow client-updates;\fR or
|
|
|
45d60a |
the statement \fIignore client-updates;\fR. By default, client
|
|
|
45d60a |
updates are allowed.
|
|
|
45d60a |
@@ -1230,15 +1141,14 @@ IP address, it can update its own A record, assuming that the
|
|
|
45d60a |
"radish.org" DNS server will allow it to do so.
|
|
|
45d60a |
.PP
|
|
|
45d60a |
If the server is configured not to allow client updates, or if the
|
|
|
45d60a |
-client doesn't want to do its own update, the server will simply
|
|
|
45d60a |
+client doesn\'t want to do its own update, the server will simply
|
|
|
45d60a |
choose a name for the client from either the fqdn option (if present)
|
|
|
45d60a |
or the hostname option (if present). It will use its own
|
|
|
45d60a |
-domain name for the client, just as in the ad-hoc update scheme.
|
|
|
45d60a |
-It will then update both the A and PTR record, using the name that it
|
|
|
45d60a |
-chose for the client. If the client sends a fully-qualified domain
|
|
|
45d60a |
-name in the fqdn option, the server uses only the leftmost part of the
|
|
|
45d60a |
-domain name - in the example above, "jschmoe" instead of
|
|
|
45d60a |
-"jschmoe.radish.org".
|
|
|
45d60a |
+domain name for the client. It will then update both the A and PTR
|
|
|
45d60a |
+record, using the name that it chose for the client. If the client
|
|
|
45d60a |
+sends a fully-qualified domain name in the \fBfqdn\fR option, the
|
|
|
45d60a |
+server uses only the leftmost part of the domain name - in the
|
|
|
45d60a |
+example above, "jschmoe" instead of "jschmoe.radish.org".
|
|
|
45d60a |
.PP
|
|
|
45d60a |
Further, if the \fIignore client-updates;\fR directive is used, then
|
|
|
45d60a |
the server will in addition send a response in the DHCP packet, using
|
|
|
45d60a |
@@ -1248,49 +1158,41 @@ response is sent which indicates the client may not perform updates.
|
|
|
45d60a |
.PP
|
|
|
45d60a |
Also, if the
|
|
|
45d60a |
.I use-host-decl-names
|
|
|
45d60a |
-configuration option is enabled, then the host declaration's
|
|
|
45d60a |
+configuration option is enabled, then the host declaration\'s
|
|
|
45d60a |
.I hostname
|
|
|
45d60a |
will be used in place of the
|
|
|
45d60a |
.I hostname
|
|
|
45d60a |
option, and the same rules will apply as described above.
|
|
|
45d60a |
.PP
|
|
|
45d60a |
-The other difference between the ad-hoc scheme and the interim
|
|
|
45d60a |
-scheme is that with the interim scheme, a method is used that
|
|
|
45d60a |
-allows more than one DHCP server to update the DNS database without
|
|
|
45d60a |
-accidentally deleting A records that shouldn't be deleted nor failing
|
|
|
45d60a |
-to add A records that should be added. The scheme works as follows:
|
|
|
45d60a |
+Both the standard and interim options also include a method to
|
|
|
45d60a |
+allow more than one DHCP server to update the DNS database without
|
|
|
45d60a |
+accidentally deleting A records that shouldn\'t be deleted nor failing
|
|
|
45d60a |
+to add A records that should be added. For the standard option the
|
|
|
45d60a |
+method works as follows:
|
|
|
45d60a |
.PP
|
|
|
45d60a |
When the DHCP server issues a client a new lease, it creates a text
|
|
|
45d60a |
-string that is an MD5 hash over the DHCP client's identification (see
|
|
|
45d60a |
-draft-ietf-dnsext-dhcid-rr-??.txt for details). The update adds an A
|
|
|
45d60a |
-record with the name the server chose and a TXT record containing the
|
|
|
45d60a |
+string that is an SHA hash over the DHCP client\'s identification (see
|
|
|
45d60a |
+RFCs 4701 & 4702 for details). The update attempts to add an A
|
|
|
45d60a |
+record with the name the server chose and a DHCID record containing the
|
|
|
45d60a |
hashed identifier string (hashid). If this update succeeds, the
|
|
|
45d60a |
server is done.
|
|
|
45d60a |
.PP
|
|
|
45d60a |
If the update fails because the A record already exists, then the DHCP
|
|
|
45d60a |
server attempts to add the A record with the prerequisite that there
|
|
|
45d60a |
-must be a TXT record in the same name as the new A record, and that
|
|
|
45d60a |
-TXT record's contents must be equal to hashid. If this update
|
|
|
45d60a |
+must be a DHCID record in the same name as the new A record, and that
|
|
|
45d60a |
+DHCID record\'s contents must be equal to hashid. If this update
|
|
|
45d60a |
succeeds, then the client has its A record and PTR record. If it
|
|
|
45d60a |
fails, then the name the client has been assigned (or requested) is in
|
|
|
45d60a |
-use, and can't be used by the client. At this point the DHCP server
|
|
|
45d60a |
+use, and can\'t be used by the client. At this point the DHCP server
|
|
|
45d60a |
gives up trying to do a DNS update for the client until the client
|
|
|
45d60a |
chooses a new name.
|
|
|
45d60a |
.PP
|
|
|
45d60a |
-The interim DNS update scheme is called interim for two reasons.
|
|
|
45d60a |
-First, it does not quite follow the RFCs. The RFCs call for a
|
|
|
45d60a |
-new DHCID RRtype while he interim DNS update scheme uses a TXT record.
|
|
|
45d60a |
-The ddns-resolution draft called for the DHCP server to put a DHCID RR
|
|
|
45d60a |
-on the PTR record, but the \fIinterim\fR update method does not do this.
|
|
|
45d60a |
-In the final RFC this requirement was relaxed such that a server may
|
|
|
45d60a |
-add a DHCID RR to the PTR record.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-In addition to these differences, the server also does not update very
|
|
|
45d60a |
-aggressively. Because each DNS update involves a round trip to the
|
|
|
45d60a |
-DNS server, there is a cost associated with doing updates even if they
|
|
|
45d60a |
-do not actually modify the DNS database. So the DHCP server tracks
|
|
|
45d60a |
-whether or not it has updated the record in the past (this information
|
|
|
45d60a |
-is stored on the lease) and does not attempt to update records that it
|
|
|
45d60a |
+The server also does not update very aggressively. Because each
|
|
|
45d60a |
+DNS update involves a round trip to the DNS server, there is a cost
|
|
|
45d60a |
+associated with doing updates even if they do not actually modify
|
|
|
45d60a |
+the DNS database. So the DHCP server tracks whether or not it has
|
|
|
45d60a |
+updated the record in the past (this information is stored on the
|
|
|
45d60a |
+lease) and does not attempt to update records that it
|
|
|
45d60a |
thinks it has already updated.
|
|
|
45d60a |
.PP
|
|
|
45d60a |
This can lead to cases where the DHCP server adds a record, and then
|
|
|
45d60a |
@@ -1299,6 +1201,15 @@ never again updates the DNS because it thinks the data is already
|
|
|
45d60a |
there. In this case the data can be removed from the lease through
|
|
|
45d60a |
operator intervention, and once this has been done, the DNS will be
|
|
|
45d60a |
updated the next time the client renews.
|
|
|
45d60a |
+.PP
|
|
|
45d60a |
+The interim DNS update scheme was written before the RFCs were finalized
|
|
|
45d60a |
+and does not quite follow them. The RFCs call for a new DHCID RRtype
|
|
|
45d60a |
+while he interim DNS update scheme uses a TXT record. In addition
|
|
|
45d60a |
+the ddns-resolution draft called for the DHCP server to put a DHCID RR
|
|
|
45d60a |
+on the PTR record, but the \fIinterim\fR update method does not do this.
|
|
|
45d60a |
+In the final RFC this requirement was relaxed such that a server may
|
|
|
45d60a |
+add a DHCID RR to the PTR record.
|
|
|
45d60a |
+.PP
|
|
|
45d60a |
.SH DYNAMIC DNS UPDATE SECURITY
|
|
|
45d60a |
.PP
|
|
|
45d60a |
When you set your DNS server up to allow updates from the DHCP server,
|
|
|
45d60a |
@@ -1380,24 +1291,15 @@ Also keep in mind that zone names in your DHCP configuration should end in a
|
|
|
45d60a |
configuration, zone names are not encapsulated in quotes where there are in
|
|
|
45d60a |
the DNS configuration.
|
|
|
45d60a |
.PP
|
|
|
45d60a |
-You should choose your own secret key, of course. The ISC BIND 8 and
|
|
|
45d60a |
-9 distributions come with a program for generating secret keys called
|
|
|
45d60a |
-dnssec-keygen. The version that comes with BIND 9 is likely to produce a
|
|
|
45d60a |
-substantially more random key, so we recommend you use that one even
|
|
|
45d60a |
-if you are not using BIND 9 as your DNS server. If you are using BIND 9's
|
|
|
45d60a |
+You should choose your own secret key, of course. The ISC BIND 9
|
|
|
45d60a |
+distribution comes with a program for generating secret keys called
|
|
|
45d60a |
+dnssec-keygen. If you are using BIND 9\'s
|
|
|
45d60a |
dnssec-keygen, the above key would be created as follows:
|
|
|
45d60a |
.PP
|
|
|
45d60a |
.nf
|
|
|
45d60a |
dnssec-keygen -a HMAC-MD5 -b 128 -n USER DHCP_UPDATER
|
|
|
45d60a |
.fi
|
|
|
45d60a |
.PP
|
|
|
45d60a |
-If you are using the BIND 8 dnskeygen program, the following command will
|
|
|
45d60a |
-generate a key as seen above:
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-.nf
|
|
|
45d60a |
- dnskeygen -H 128 -u -c -n DHCP_UPDATER
|
|
|
45d60a |
-.fi
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
The key name, algorithm, and secret must match that being used by the DNS
|
|
|
45d60a |
server. The DHCP server currently supports the following algorithms:
|
|
|
45d60a |
.nf
|
|
|
45d60a |
@@ -1451,15 +1353,7 @@ and the expiry event, when the commitment expires.
|
|
|
45d60a |
To declare a set of statements to execute when an event happens, you
|
|
|
45d60a |
must use the \fBon\fR statement, followed by the name of the event,
|
|
|
45d60a |
followed by a series of statements to execute when the event happens,
|
|
|
45d60a |
-enclosed in braces. Events are used to implement DNS
|
|
|
45d60a |
-updates, so you should not define your own event handlers if you are
|
|
|
45d60a |
-using the built-in DNS update mechanism.
|
|
|
45d60a |
-.PP
|
|
|
45d60a |
-The built-in version of the DNS update mechanism is in a text
|
|
|
45d60a |
-string towards the top of server/dhcpd.c. If you want to use events
|
|
|
45d60a |
-for things other than DNS updates, and you also want DNS updates, you
|
|
|
45d60a |
-will have to start out by copying this code into your dhcpd.conf file
|
|
|
45d60a |
-and modifying it.
|
|
|
45d60a |
+enclosed in braces.
|
|
|
45d60a |
.SH REFERENCE: DECLARATIONS
|
|
|
45d60a |
.PP
|
|
|
45d60a |
.B The
|
|
|
45d60a |
@@ -2109,7 +2003,7 @@ The \fIddns-update-style\fR parameter
|
|
|
45d60a |
.PP
|
|
|
45d60a |
The
|
|
|
45d60a |
.I style
|
|
|
45d60a |
-parameter must be one of \fBad-hoc\fR, \fBinterim\fR or \fBnone\fR.
|
|
|
45d60a |
+parameter must be one of \fBstandard\fR, \fBinterim\fR or \fBnone\fR.
|
|
|
45d60a |
The \fIddns-update-style\fR statement is only meaningful in the outer
|
|
|
45d60a |
scope - it is evaluated once after reading the dhcpd.conf file, rather
|
|
|
45d60a |
than each time a client is assigned an IP address, so there is no way
|
|
|
45d60a |
@@ -2186,16 +2080,15 @@ statement
|
|
|
45d60a |
.B do-forward-updates \fIflag\fB;\fR
|
|
|
45d60a |
.PP
|
|
|
45d60a |
The \fIdo-forward-updates\fR statement instructs the DHCP server as
|
|
|
45d60a |
-to whether it should attempt to update a DHCP client's A record
|
|
|
45d60a |
+to whether it should attempt to update a DHCP client\'s A record
|
|
|
45d60a |
when the client acquires or renews a lease. This statement has no
|
|
|
45d60a |
-effect unless DNS updates are enabled and \fBddns-update-style\fR is
|
|
|
45d60a |
-set to \fBinterim\fR. Forward updates are enabled by default. If
|
|
|
45d60a |
-this statement is used to disable forward updates, the DHCP server
|
|
|
45d60a |
-will never attempt to update the client's A record, and will only ever
|
|
|
45d60a |
-attempt to update the client's PTR record if the client supplies an
|
|
|
45d60a |
-FQDN that should be placed in the PTR record using the fqdn option.
|
|
|
45d60a |
-If forward updates are enabled, the DHCP server will still honor the
|
|
|
45d60a |
-setting of the \fBclient-updates\fR flag.
|
|
|
45d60a |
+effect unless DNS updates are enabled. Forward updates are enabled
|
|
|
45d60a |
+by default. If this statement is used to disable forward updates,
|
|
|
45d60a |
+the DHCP server will never attempt to update the client\'s A record,
|
|
|
45d60a |
+and will only ever attempt to update the client\'s PTR record if the
|
|
|
45d60a |
+client supplies an FQDN that should be placed in the PTR record using
|
|
|
45d60a |
+the \fBfqdn\fR option. If forward updates are enabled, the DHCP server
|
|
|
45d60a |
+will still honor the setting of the \fBclient-updates\fR flag.
|
|
|
45d60a |
.RE
|
|
|
45d60a |
.PP
|
|
|
45d60a |
The
|
|
|
45d60a |
@@ -2747,7 +2640,7 @@ on which the request arrived.
|
|
|
45d60a |
The usual case where the
|
|
|
45d60a |
\fIserver-identifier\fR statement needs to be sent is when a physical
|
|
|
45d60a |
interface has more than one IP address, and the one being sent by default
|
|
|
45d60a |
-isn't appropriate for some or all clients served by that interface.
|
|
|
45d60a |
+isn\'t appropriate for some or all clients served by that interface.
|
|
|
45d60a |
Another common case is when an alias is defined for the purpose of
|
|
|
45d60a |
having a consistent IP address for the DHCP server, and it is desired
|
|
|
45d60a |
that the clients use this IP address when contacting the server.
|
|
|
45d60a |
diff --git a/server/stables.c b/server/stables.c
|
|
|
45d60a |
index 6a900c8..8ef8bf2 100644
|
|
|
45d60a |
--- a/server/stables.c
|
|
|
45d60a |
+++ b/server/stables.c
|
|
|
45d60a |
@@ -3,7 +3,7 @@
|
|
|
45d60a |
Tables of information only used by server... */
|
|
|
45d60a |
|
|
|
45d60a |
/*
|
|
|
45d60a |
- * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC")
|
|
|
45d60a |
+ * Copyright (c) 2004-2011,2013 by Internet Systems Consortium, Inc. ("ISC")
|
|
|
45d60a |
* Copyright (c) 1995-2003 by Internet Software Consortium
|
|
|
45d60a |
*
|
|
|
45d60a |
* Permission to use, copy, modify, and distribute this software for any
|
|
|
45d60a |
@@ -330,6 +330,7 @@ struct enumeration_value ddns_styles_values [] = {
|
|
|
45d60a |
{ "none", 0 },
|
|
|
45d60a |
{ "ad-hoc", 1 },
|
|
|
45d60a |
{ "interim", 2 },
|
|
|
45d60a |
+ { "standard", 3 },
|
|
|
45d60a |
{ (char *)0, 0 }
|
|
|
45d60a |
};
|
|
|
45d60a |
|