mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-04 00:05:30 +00:00
- Fix the DDNS update code to correctly send a client FQDN option, to not
do the update if it seems unnecessary, and to handle client updates if configured to do so.
This commit is contained in:
385
server/ddns.c
385
server/ddns.c
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
static char copyright[] =
|
||||||
"$Id: ddns.c,v 1.5 2001/01/06 21:37:21 mellon Exp $ Copyright (c) 2000-2001 The Internet Software Consortium. All rights reserved.\n";
|
"$Id: ddns.c,v 1.6 2001/01/08 17:24:45 mellon Exp $ Copyright (c) 2000-2001 The Internet Software Consortium. All rights reserved.\n";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -216,7 +216,7 @@ static int find_bound_string (struct data_string *value,
|
|||||||
binding -> value -> value.data.data,
|
binding -> value -> value.data.data,
|
||||||
binding -> value -> value.data.len);
|
binding -> value -> value.data.len);
|
||||||
value -> data = value -> buffer -> data;
|
value -> data = value -> buffer -> data;
|
||||||
value -> len = binding -> value -> value.data.len;
|
value -> len = binding -> value -> value.data.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -273,12 +273,13 @@ static ns_rcode ddns_update_a (struct data_string *ddns_fwd_name,
|
|||||||
/*
|
/*
|
||||||
* A RR does not exist.
|
* A RR does not exist.
|
||||||
*/
|
*/
|
||||||
updrec = minires_mkupdrec (S_PREREQ, ddns_fwd_name -> data,
|
updrec = minires_mkupdrec (S_PREREQ,
|
||||||
|
(const char *)ddns_fwd_name -> data,
|
||||||
C_IN, T_A, 0);
|
C_IN, T_A, 0);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
updrec -> r_data = (unsigned char *)0;
|
updrec -> r_data = (unsigned char *)0;
|
||||||
updrec -> r_size = 0;
|
updrec -> r_size = 0;
|
||||||
updrec -> r_opcode = NXDOMAIN;
|
updrec -> r_opcode = NXDOMAIN;
|
||||||
|
|
||||||
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
||||||
@@ -287,11 +288,12 @@ static ns_rcode ddns_update_a (struct data_string *ddns_fwd_name,
|
|||||||
/*
|
/*
|
||||||
* Add A RR.
|
* Add A RR.
|
||||||
*/
|
*/
|
||||||
updrec = minires_mkupdrec (S_UPDATE, ddns_fwd_name -> data,
|
updrec = minires_mkupdrec (S_UPDATE,
|
||||||
|
(const char *)ddns_fwd_name -> data,
|
||||||
C_IN, T_A, ttl);
|
C_IN, T_A, ttl);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
updrec -> r_data = ddns_address;
|
updrec -> r_data = (unsigned char *)ddns_address;
|
||||||
updrec -> r_size = strlen (ddns_address);
|
updrec -> r_size = strlen (ddns_address);
|
||||||
updrec -> r_opcode = ADD;
|
updrec -> r_opcode = ADD;
|
||||||
|
|
||||||
@@ -301,7 +303,8 @@ static ns_rcode ddns_update_a (struct data_string *ddns_fwd_name,
|
|||||||
/*
|
/*
|
||||||
* Add DHCID RR.
|
* Add DHCID RR.
|
||||||
*/
|
*/
|
||||||
updrec = minires_mkupdrec (S_UPDATE, ddns_fwd_name -> data,
|
updrec = minires_mkupdrec (S_UPDATE,
|
||||||
|
(const char *)ddns_fwd_name -> data,
|
||||||
C_IN, T_DHCID, ttl);
|
C_IN, T_DHCID, ttl);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
@@ -358,7 +361,8 @@ static ns_rcode ddns_update_a (struct data_string *ddns_fwd_name,
|
|||||||
/*
|
/*
|
||||||
* DHCID RR exists, and matches client identity.
|
* DHCID RR exists, and matches client identity.
|
||||||
*/
|
*/
|
||||||
updrec = minires_mkupdrec (S_PREREQ, ddns_fwd_name -> data,
|
updrec = minires_mkupdrec (S_PREREQ,
|
||||||
|
(const char *)ddns_fwd_name -> data,
|
||||||
C_IN, T_DHCID, 0);
|
C_IN, T_DHCID, 0);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
@@ -372,7 +376,8 @@ static ns_rcode ddns_update_a (struct data_string *ddns_fwd_name,
|
|||||||
/*
|
/*
|
||||||
* Delete A RRset.
|
* Delete A RRset.
|
||||||
*/
|
*/
|
||||||
updrec = minires_mkupdrec (S_UPDATE, ddns_fwd_name -> data,
|
updrec = minires_mkupdrec (S_UPDATE,
|
||||||
|
(const char *)ddns_fwd_name -> data,
|
||||||
C_IN, T_A, 0);
|
C_IN, T_A, 0);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
@@ -386,11 +391,12 @@ static ns_rcode ddns_update_a (struct data_string *ddns_fwd_name,
|
|||||||
/*
|
/*
|
||||||
* Add A RR.
|
* Add A RR.
|
||||||
*/
|
*/
|
||||||
updrec = minires_mkupdrec (S_UPDATE, ddns_fwd_name -> data,
|
updrec = minires_mkupdrec (S_UPDATE,
|
||||||
|
(const char *)ddns_fwd_name -> data,
|
||||||
C_IN, T_A, ttl);
|
C_IN, T_A, ttl);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
updrec -> r_data = ddns_address;
|
updrec -> r_data = (unsigned char *)ddns_address;
|
||||||
updrec -> r_size = strlen (ddns_address);
|
updrec -> r_size = strlen (ddns_address);
|
||||||
updrec -> r_opcode = ADD;
|
updrec -> r_opcode = ADD;
|
||||||
|
|
||||||
@@ -474,12 +480,13 @@ static ns_rcode ddns_update_ptr (struct data_string *ddns_fwd_name,
|
|||||||
/*
|
/*
|
||||||
* Delete all PTR RRs.
|
* Delete all PTR RRs.
|
||||||
*/
|
*/
|
||||||
updrec = minires_mkupdrec (S_UPDATE, ddns_rev_name -> data,
|
updrec = minires_mkupdrec (S_UPDATE,
|
||||||
|
(const char *)ddns_rev_name -> data,
|
||||||
C_IN, T_PTR, 0);
|
C_IN, T_PTR, 0);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
updrec -> r_data = (unsigned char *)0;
|
updrec -> r_data = (unsigned char *)0;
|
||||||
updrec -> r_size = 0;
|
updrec -> r_size = 0;
|
||||||
updrec -> r_opcode = DELETE;
|
updrec -> r_opcode = DELETE;
|
||||||
|
|
||||||
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
||||||
@@ -487,12 +494,13 @@ static ns_rcode ddns_update_ptr (struct data_string *ddns_fwd_name,
|
|||||||
/*
|
/*
|
||||||
* Add PTR RR.
|
* Add PTR RR.
|
||||||
*/
|
*/
|
||||||
updrec = minires_mkupdrec (S_UPDATE, ddns_rev_name -> data,
|
updrec = minires_mkupdrec (S_UPDATE,
|
||||||
|
(const char *)ddns_rev_name -> data,
|
||||||
C_IN, T_PTR, ttl);
|
C_IN, T_PTR, ttl);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
updrec -> r_data = ddns_fwd_name -> buffer -> data;
|
updrec -> r_data = (char *)ddns_fwd_name -> buffer -> data;
|
||||||
updrec -> r_size = ddns_fwd_name -> len;
|
updrec -> r_size = ddns_fwd_name -> len;
|
||||||
updrec -> r_opcode = ADD;
|
updrec -> r_opcode = ADD;
|
||||||
|
|
||||||
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
||||||
@@ -590,8 +598,8 @@ static ns_rcode ddns_remove_a (struct data_string *ddns_fwd_name,
|
|||||||
C_IN, T_A, 0);
|
C_IN, T_A, 0);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
updrec -> r_data = ddns_address;
|
updrec -> r_data = ddns_address;
|
||||||
updrec -> r_size = strlen (ddns_address);
|
updrec -> r_size = strlen (ddns_address);
|
||||||
updrec -> r_opcode = DELETE;
|
updrec -> r_opcode = DELETE;
|
||||||
|
|
||||||
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
||||||
@@ -638,7 +646,7 @@ static ns_rcode ddns_remove_a (struct data_string *ddns_fwd_name,
|
|||||||
C_IN, T_A, 0);
|
C_IN, T_A, 0);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
updrec -> r_data = (char *)0;
|
updrec -> r_data = (unsigned char *)0;
|
||||||
updrec -> r_size = 0;
|
updrec -> r_size = 0;
|
||||||
updrec -> r_opcode = NXRRSET;
|
updrec -> r_opcode = NXRRSET;
|
||||||
|
|
||||||
@@ -652,8 +660,8 @@ static ns_rcode ddns_remove_a (struct data_string *ddns_fwd_name,
|
|||||||
if (!updrec)
|
if (!updrec)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
updrec -> r_data = ddns_dhcid -> buffer -> data;
|
updrec -> r_data = ddns_dhcid -> buffer -> data;
|
||||||
updrec -> r_size = ddns_dhcid -> len;
|
updrec -> r_size = ddns_dhcid -> len;
|
||||||
updrec -> r_opcode = DELETE;
|
updrec -> r_opcode = DELETE;
|
||||||
|
|
||||||
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
||||||
@@ -698,12 +706,13 @@ static ns_rcode ddns_remove_ptr (struct data_string *ddns_fwd_name,
|
|||||||
/*
|
/*
|
||||||
* Delete appropriate PTR RR.
|
* Delete appropriate PTR RR.
|
||||||
*/
|
*/
|
||||||
updrec = minires_mkupdrec (S_UPDATE, ddns_rev_name -> data,
|
updrec = minires_mkupdrec (S_UPDATE,
|
||||||
|
(const char *)ddns_rev_name -> data,
|
||||||
C_IN, T_PTR, 0);
|
C_IN, T_PTR, 0);
|
||||||
if (!updrec) goto error;
|
if (!updrec) goto error;
|
||||||
|
|
||||||
updrec -> r_data = ddns_fwd_name -> buffer -> data;
|
updrec -> r_data = ddns_fwd_name -> buffer -> data;
|
||||||
updrec -> r_size = ddns_fwd_name -> len;
|
updrec -> r_size = ddns_fwd_name -> len;
|
||||||
updrec -> r_opcode = DELETE;
|
updrec -> r_opcode = DELETE;
|
||||||
|
|
||||||
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
ISC_LIST_APPEND (updqueue, updrec, r_link);
|
||||||
@@ -734,6 +743,7 @@ int ddns_updates (struct packet *packet,
|
|||||||
unsigned long ddns_ttl = DEFAULT_DDNS_TTL;
|
unsigned long ddns_ttl = DEFAULT_DDNS_TTL;
|
||||||
struct data_string ddns_hostname;
|
struct data_string ddns_hostname;
|
||||||
struct data_string ddns_domainname;
|
struct data_string ddns_domainname;
|
||||||
|
struct data_string old_ddns_fwd_name;
|
||||||
struct data_string ddns_fwd_name;
|
struct data_string ddns_fwd_name;
|
||||||
struct data_string ddns_rev_name;
|
struct data_string ddns_rev_name;
|
||||||
struct data_string ddns_dhcid;
|
struct data_string ddns_dhcid;
|
||||||
@@ -742,7 +752,10 @@ int ddns_updates (struct packet *packet,
|
|||||||
struct option_cache *oc;
|
struct option_cache *oc;
|
||||||
int s1, s2;
|
int s1, s2;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
ns_rcode rcode1, rcode2;
|
ns_rcode rcode1 = NOERROR, rcode2 = NOERROR;
|
||||||
|
int server_updates_a = 1;
|
||||||
|
struct buffer *bp = (struct buffer *)0;
|
||||||
|
int ignorep = 0;
|
||||||
|
|
||||||
if (ddns_update_style != 2)
|
if (ddns_update_style != 2)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -751,35 +764,47 @@ int ddns_updates (struct packet *packet,
|
|||||||
if (lease -> ip_addr . len != 4)
|
if (lease -> ip_addr . len != 4)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
memset (&ddns_hostname, 0, sizeof (ddns_hostname));
|
memset (&ddns_hostname, 0, sizeof (ddns_hostname));
|
||||||
memset (&ddns_domainname, 0, sizeof (ddns_domainname));
|
memset (&ddns_domainname, 0, sizeof (ddns_domainname));
|
||||||
|
memset (&old_ddns_fwd_name, 0, sizeof (ddns_fwd_name));
|
||||||
memset (&ddns_fwd_name, 0, sizeof (ddns_fwd_name));
|
memset (&ddns_fwd_name, 0, sizeof (ddns_fwd_name));
|
||||||
memset (&ddns_rev_name, 0, sizeof (ddns_rev_name));
|
memset (&ddns_rev_name, 0, sizeof (ddns_rev_name));
|
||||||
memset (&ddns_dhcid, 0, sizeof (ddns_dhcid));
|
memset (&ddns_dhcid, 0, sizeof (ddns_dhcid));
|
||||||
|
|
||||||
|
/* If we are allowed to accept the client's update of its own A
|
||||||
/*
|
record, see if the client wants to update its own A record. */
|
||||||
* Look up the RR TTL.
|
if (!(oc = lookup_option (&server_universe, state -> options,
|
||||||
*/
|
SV_ALLOW_CLIENT_UPDATES)) ||
|
||||||
ddns_ttl = DEFAULT_DDNS_TTL;
|
evaluate_boolean_option_cache (&ignorep, packet, lease,
|
||||||
memset (&d1, 0, sizeof d1);
|
|
||||||
if ((oc = lookup_option (&server_universe, state -> options,
|
|
||||||
SV_DDNS_TTL))) {
|
|
||||||
if (evaluate_option_cache (&d1, packet, lease,
|
|
||||||
(struct client_state *)0,
|
(struct client_state *)0,
|
||||||
packet -> options,
|
packet -> options,
|
||||||
state -> options,
|
state -> options,
|
||||||
&lease -> scope, oc, MDL)) {
|
&lease -> scope, oc, MDL)) {
|
||||||
if (d1.len == sizeof (u_int32_t))
|
/* If there's no fqdn.no-client-update or if it's
|
||||||
ddns_ttl = getULong (d1.data);
|
nonzero, don't try to use the client-supplied
|
||||||
data_string_forget (&d1, MDL);
|
XXX */
|
||||||
}
|
if (!(oc = lookup_option (&fqdn_universe, state -> options,
|
||||||
|
FQDN_NO_CLIENT_UPDATE)) ||
|
||||||
|
evaluate_boolean_option_cache (&ignorep, packet, lease,
|
||||||
|
(struct client_state *)0,
|
||||||
|
packet -> options,
|
||||||
|
state -> options,
|
||||||
|
&lease -> scope, oc, MDL))
|
||||||
|
goto noclient;
|
||||||
|
if (!(oc = lookup_option (&fqdn_universe, state -> options,
|
||||||
|
FQDN_FQDN)) ||
|
||||||
|
evaluate_option_cache (&ddns_fwd_name, packet, lease,
|
||||||
|
(struct client_state *)0,
|
||||||
|
packet -> options, state -> options,
|
||||||
|
&lease -> scope, oc, MDL))
|
||||||
|
goto noclient;
|
||||||
|
server_updates_a = 0;
|
||||||
|
goto client_updates;
|
||||||
}
|
}
|
||||||
|
noclient:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up the lease FQDN.
|
* Compute the name for the A record.
|
||||||
*/
|
*/
|
||||||
s1 = s2 = 0;
|
s1 = s2 = 0;
|
||||||
|
|
||||||
@@ -815,9 +840,96 @@ int ddns_updates (struct packet *packet,
|
|||||||
ddns_fwd_name.terminated = 1;
|
ddns_fwd_name.terminated = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
client_updates:
|
||||||
|
|
||||||
|
/* See if there's a name already stored on the lease. */
|
||||||
|
if (find_bound_string (&old_ddns_fwd_name,
|
||||||
|
lease -> scope, "ddns-fwd-name")) {
|
||||||
|
/* If there is, see if it's different. */
|
||||||
|
if (old_ddns_fwd_name.len != ddns_fwd_name.len ||
|
||||||
|
memcmp (old_ddns_fwd_name.data, ddns_fwd_name.data,
|
||||||
|
old_ddns_fwd_name.len)) {
|
||||||
|
/* If the name is different, try to delete
|
||||||
|
the old A record. */
|
||||||
|
if (!ddns_removals (lease))
|
||||||
|
goto out;
|
||||||
|
/* If the delete succeeded, go install the new
|
||||||
|
record. */
|
||||||
|
goto in;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if there's a DHCID on the lease. */
|
||||||
|
if (!find_bound_string (&ddns_dhcid,
|
||||||
|
lease -> scope, "ddns-txt")) {
|
||||||
|
/* If there's no DHCID, the update was probably
|
||||||
|
done with the old-style ad-hoc DDNS updates.
|
||||||
|
So if the expiry and release events look like
|
||||||
|
they're the same, run them. This should delete
|
||||||
|
the old DDNS data. */
|
||||||
|
if (lease -> on_expiry == lease -> on_release) {
|
||||||
|
execute_statements ((struct binding_value **)0,
|
||||||
|
(struct packet *)0, lease,
|
||||||
|
(struct client_state *)0,
|
||||||
|
(struct option_state *)0,
|
||||||
|
(struct option_state *)0,
|
||||||
|
&lease -> scope,
|
||||||
|
lease -> on_expiry);
|
||||||
|
if (lease -> on_expiry)
|
||||||
|
executable_statement_dereference
|
||||||
|
(&lease -> on_expiry, MDL);
|
||||||
|
if (lease -> on_release)
|
||||||
|
executable_statement_dereference
|
||||||
|
(&lease -> on_release, MDL);
|
||||||
|
/* Now, install the DDNS data the new way. */
|
||||||
|
goto in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, we probably don't need to do the update.
|
||||||
|
This is sufficiently likely that we in fact don't
|
||||||
|
do it, although technically we should. */
|
||||||
|
result = 1;
|
||||||
|
goto noerror;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there's no ddns-fwd-name on the lease, see if there's
|
||||||
|
a ddns-client-fqdn, indicating a prior client FQDN update.
|
||||||
|
If there is, and if we're still doing the client update,
|
||||||
|
see if the name has changed. If it hasn't, don't do the
|
||||||
|
PTR update. */
|
||||||
|
if (find_bound_string (&old_ddns_fwd_name,
|
||||||
|
lease -> scope, "ddns-client-fqdn")) {
|
||||||
|
if (old_ddns_fwd_name.len != ddns_fwd_name.len ||
|
||||||
|
memcmp (old_ddns_fwd_name.data, ddns_fwd_name.data,
|
||||||
|
old_ddns_fwd_name.len)) {
|
||||||
|
/* If the name is not different, no need to update
|
||||||
|
the PTR record. */
|
||||||
|
goto noerror;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the RR TTL.
|
||||||
|
*/
|
||||||
|
ddns_ttl = DEFAULT_DDNS_TTL;
|
||||||
|
memset (&d1, 0, sizeof d1);
|
||||||
|
if ((oc = lookup_option (&server_universe, state -> options,
|
||||||
|
SV_DDNS_TTL))) {
|
||||||
|
if (evaluate_option_cache (&d1, packet, lease,
|
||||||
|
(struct client_state *)0,
|
||||||
|
packet -> options,
|
||||||
|
state -> options,
|
||||||
|
&lease -> scope, oc, MDL)) {
|
||||||
|
if (d1.len == sizeof (u_int32_t))
|
||||||
|
ddns_ttl = getULong (d1.data);
|
||||||
|
data_string_forget (&d1, MDL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up the reverse IP name.
|
* Compute the reverse IP name.
|
||||||
*/
|
*/
|
||||||
oc = lookup_option (&server_universe, state -> options,
|
oc = lookup_option (&server_universe, state -> options,
|
||||||
SV_DDNS_REV_DOMAIN_NAME);
|
SV_DDNS_REV_DOMAIN_NAME);
|
||||||
@@ -850,7 +962,8 @@ int ddns_updates (struct packet *packet,
|
|||||||
lease -> ip_addr . iabuf[1],
|
lease -> ip_addr . iabuf[1],
|
||||||
lease -> ip_addr . iabuf[0]);
|
lease -> ip_addr . iabuf[0]);
|
||||||
#endif
|
#endif
|
||||||
ddns_rev_name.len = strlen (ddns_rev_name.data);
|
ddns_rev_name.len =
|
||||||
|
strlen ((const char *)ddns_rev_name.data);
|
||||||
data_string_append (&ddns_rev_name, &d1);
|
data_string_append (&ddns_rev_name, &d1);
|
||||||
ddns_rev_name.buffer -> data [ddns_rev_name.len] ='\0';
|
ddns_rev_name.buffer -> data [ddns_rev_name.len] ='\0';
|
||||||
ddns_rev_name.terminated = 1;
|
ddns_rev_name.terminated = 1;
|
||||||
@@ -860,10 +973,12 @@ int ddns_updates (struct packet *packet,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up the DHCID value. (Should this be cached in the lease?)
|
* If we are updating the A record, compute the DHCID value.
|
||||||
*/
|
*/
|
||||||
memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
|
if (server_updates_a) {
|
||||||
get_dhcid (&ddns_dhcid, lease);
|
memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
|
||||||
|
get_dhcid (&ddns_dhcid, lease);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the resolver, if necessary.
|
* Start the resolver, if necessary.
|
||||||
@@ -881,7 +996,7 @@ int ddns_updates (struct packet *packet,
|
|||||||
&ddns_dhcid, ddns_ttl);
|
&ddns_dhcid, ddns_ttl);
|
||||||
|
|
||||||
if (rcode1 == NOERROR) {
|
if (rcode1 == NOERROR) {
|
||||||
if (ddns_fwd_name.len && ddns_rev_name.len && ddns_dhcid.len)
|
if (ddns_fwd_name.len && ddns_rev_name.len)
|
||||||
rcode2 = ddns_update_ptr (&ddns_fwd_name,
|
rcode2 = ddns_update_ptr (&ddns_fwd_name,
|
||||||
&ddns_rev_name, ddns_ttl);
|
&ddns_rev_name, ddns_ttl);
|
||||||
} else
|
} else
|
||||||
@@ -894,9 +1009,11 @@ int ddns_updates (struct packet *packet,
|
|||||||
rcode2 = SERVFAIL;
|
rcode2 = SERVFAIL;
|
||||||
|
|
||||||
if (rcode1 == NOERROR) {
|
if (rcode1 == NOERROR) {
|
||||||
bind_ds_value (&lease -> scope, "ddns-fwd-name",
|
bind_ds_value (&lease -> scope,
|
||||||
|
(server_updates_a
|
||||||
|
? "ddns-fwd-name" : "ddns-client-fqdn"),
|
||||||
&ddns_fwd_name);
|
&ddns_fwd_name);
|
||||||
bind_ds_value (&lease -> scope, "ddns-dhcid",
|
bind_ds_value (&lease -> scope, "ddns-txt",
|
||||||
&ddns_dhcid);
|
&ddns_dhcid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -905,73 +1022,91 @@ int ddns_updates (struct packet *packet,
|
|||||||
&ddns_rev_name);
|
&ddns_rev_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set up the outgoing FQDN option if there was an incoming
|
||||||
/*
|
FQDN option. */
|
||||||
* If the client sent us the FQDN option, respond appropriately.
|
noerror:
|
||||||
*/
|
if ((oc = lookup_option (&dhcp_universe, packet -> options, DHO_FQDN))
|
||||||
oc = lookup_option (&fqdn_universe, packet -> options,
|
&& buffer_allocate (&bp, ddns_fwd_name.len + 5, MDL)) {
|
||||||
FQDN_SERVER_UPDATE);
|
bp -> data [0] = server_updates_a;
|
||||||
if (oc) {
|
if (!save_option_buffer (&fqdn_universe, state -> options,
|
||||||
oc -> data.buffer -> data[0] = 1;
|
bp, &bp -> data [0], 1,
|
||||||
|
&fqdn_options [FQDN_SERVER_UPDATE],
|
||||||
|
0))
|
||||||
|
goto badfqdn;
|
||||||
|
bp -> data [1] = server_updates_a;
|
||||||
|
if (!save_option_buffer (&fqdn_universe, state -> options,
|
||||||
|
bp, &bp -> data [1], 1,
|
||||||
|
&fqdn_options [FQDN_NO_CLIENT_UPDATE],
|
||||||
|
0))
|
||||||
|
goto badfqdn;
|
||||||
|
/* Do the same encoding the client did. */
|
||||||
|
oc = lookup_option (&fqdn_universe, packet -> options,
|
||||||
|
FQDN_ENCODED);
|
||||||
|
if (oc &&
|
||||||
|
evaluate_boolean_option_cache (&ignorep, packet, lease,
|
||||||
|
(struct client_state *)0,
|
||||||
|
packet -> options,
|
||||||
|
state -> options,
|
||||||
|
&lease -> scope, oc, MDL))
|
||||||
|
bp -> data [2] = 1;
|
||||||
|
else
|
||||||
|
bp -> data [2] = 0;
|
||||||
|
if (!save_option_buffer (&fqdn_universe, state -> options,
|
||||||
|
bp, &bp -> data [2], 1,
|
||||||
|
&fqdn_options [FQDN_ENCODED],
|
||||||
|
0))
|
||||||
|
goto badfqdn;
|
||||||
|
bp -> data [3] = rcode1;
|
||||||
|
if (!save_option_buffer (&fqdn_universe, state -> options,
|
||||||
|
bp, &bp -> data [3], 1,
|
||||||
|
&fqdn_options [FQDN_RCODE1],
|
||||||
|
0))
|
||||||
|
goto badfqdn;
|
||||||
|
bp -> data [4] = rcode2;
|
||||||
|
if (!save_option_buffer (&fqdn_universe, state -> options,
|
||||||
|
bp, &bp -> data [4], 1,
|
||||||
|
&fqdn_options [FQDN_RCODE2],
|
||||||
|
0))
|
||||||
|
goto badfqdn;
|
||||||
|
if (ddns_fwd_name.len) {
|
||||||
|
memcpy (&bp -> data [5],
|
||||||
|
ddns_fwd_name.data, ddns_fwd_name.len);
|
||||||
|
if (!save_option_buffer (&fqdn_universe, state -> options,
|
||||||
|
bp, &bp -> data [5],
|
||||||
|
ddns_fwd_name.len,
|
||||||
|
&fqdn_options [FQDN_FQDN],
|
||||||
|
0))
|
||||||
|
goto badfqdn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oc = lookup_option (&fqdn_universe, packet -> options,
|
badfqdn:
|
||||||
FQDN_NO_CLIENT_UPDATE);
|
out:
|
||||||
if (oc) {
|
|
||||||
oc -> data.buffer -> data[0] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
oc = lookup_option (&fqdn_universe, packet -> options,
|
|
||||||
FQDN_RCODE1);
|
|
||||||
if (oc) {
|
|
||||||
oc -> data.buffer -> data[0] = rcode1;
|
|
||||||
}
|
|
||||||
|
|
||||||
oc = lookup_option (&fqdn_universe, packet -> options,
|
|
||||||
FQDN_RCODE2);
|
|
||||||
if (oc) {
|
|
||||||
oc -> data.buffer -> data[0] = rcode2;
|
|
||||||
}
|
|
||||||
|
|
||||||
oc = lookup_option (&fqdn_universe, packet -> options,
|
|
||||||
FQDN_HOSTNAME);
|
|
||||||
if (oc && ddns_hostname.buffer) {
|
|
||||||
data_string_forget (&oc -> data, MDL);
|
|
||||||
data_string_copy (&oc -> data, &ddns_hostname, MDL);
|
|
||||||
}
|
|
||||||
|
|
||||||
oc = lookup_option (&fqdn_universe, packet -> options,
|
|
||||||
FQDN_DOMAINNAME);
|
|
||||||
if (oc && ddns_hostname.buffer) {
|
|
||||||
data_string_forget (&oc -> data, MDL);
|
|
||||||
data_string_copy (&oc -> data, &ddns_domainname, MDL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Final cleanup.
|
* Final cleanup.
|
||||||
*/
|
*/
|
||||||
data_string_forget (&ddns_hostname, MDL);
|
data_string_forget (&ddns_hostname, MDL);
|
||||||
data_string_forget (&ddns_domainname, MDL);
|
data_string_forget (&ddns_domainname, MDL);
|
||||||
|
data_string_forget (&old_ddns_fwd_name, MDL);
|
||||||
data_string_forget (&ddns_fwd_name, MDL);
|
data_string_forget (&ddns_fwd_name, MDL);
|
||||||
data_string_forget (&ddns_rev_name, MDL);
|
data_string_forget (&ddns_rev_name, MDL);
|
||||||
data_string_forget (&ddns_dhcid, MDL);
|
data_string_forget (&ddns_dhcid, MDL);
|
||||||
|
|
||||||
return rcode1 == NOERROR || rcode2 == NOERROR;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ddns_removals (struct lease *lease)
|
||||||
int ddns_removals(struct lease *lease)
|
|
||||||
{
|
{
|
||||||
struct data_string ddns_fwd_name;
|
struct data_string ddns_fwd_name;
|
||||||
struct data_string ddns_rev_name;
|
struct data_string ddns_rev_name;
|
||||||
struct data_string ddns_dhcid;
|
struct data_string ddns_dhcid;
|
||||||
ns_rcode rcode;
|
ns_rcode rcode;
|
||||||
struct binding *binding;
|
struct binding *binding;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
/* No scope implies that DDNS has not been performed for this lease. */
|
/* No scope implies that DDNS has not been performed for this lease. */
|
||||||
if (!lease -> scope)
|
if (!lease -> scope)
|
||||||
return 1;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up stored names.
|
* Look up stored names.
|
||||||
@@ -980,20 +1115,6 @@ int ddns_removals(struct lease *lease)
|
|||||||
memset (&ddns_rev_name, 0, sizeof (ddns_rev_name));
|
memset (&ddns_rev_name, 0, sizeof (ddns_rev_name));
|
||||||
memset (&ddns_dhcid, 0, sizeof (ddns_dhcid));
|
memset (&ddns_dhcid, 0, sizeof (ddns_dhcid));
|
||||||
|
|
||||||
/* If all the bindings aren't there (ddns-dhcid being the crucial
|
|
||||||
one), this isn't an interim or rfc3??? record, so we can't do
|
|
||||||
the delete using this mechanism. */
|
|
||||||
if (!find_bound_string (&ddns_fwd_name,
|
|
||||||
lease -> scope, "ddns-fwd-name") ||
|
|
||||||
!find_bound_string (&ddns_rev_name,
|
|
||||||
lease -> scope, "ddns-rev-name") ||
|
|
||||||
!find_bound_string (&ddns_dhcid, lease -> scope, "ddns-dhcid")) {
|
|
||||||
data_string_forget (&ddns_fwd_name, MDL);
|
|
||||||
data_string_forget (&ddns_rev_name, MDL);
|
|
||||||
data_string_forget (&ddns_dhcid, MDL);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the resolver, if necessary.
|
* Start the resolver, if necessary.
|
||||||
*/
|
*/
|
||||||
@@ -1002,29 +1123,45 @@ int ddns_removals(struct lease *lease)
|
|||||||
resolver_inited = 1;
|
resolver_inited = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We need the fwd name whether we are deleting both records or just
|
||||||
|
the PTR record, so if it's not there, we can't proceed. */
|
||||||
|
if (!find_bound_string (&ddns_fwd_name,
|
||||||
|
lease -> scope, "ddns-fwd-name"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* If the ddns-txt binding isn't there, this isn't an interim
|
||||||
|
or rfc3??? record, so we can't delete the A record using
|
||||||
|
this mechanism, but we can delete the PTR record. */
|
||||||
|
if (!find_bound_string (&ddns_dhcid, lease -> scope, "ddns-txt")) {
|
||||||
|
result = 1;
|
||||||
|
goto try_rev;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform removals.
|
* Perform removals.
|
||||||
*/
|
*/
|
||||||
if (ddns_fwd_name.len && ddns_dhcid.len) {
|
rcode = ddns_remove_a (&ddns_fwd_name, lease -> ip_addr, &ddns_dhcid);
|
||||||
rcode = ddns_remove_a (&ddns_fwd_name, lease -> ip_addr,
|
|
||||||
&ddns_dhcid);
|
|
||||||
}
|
|
||||||
if (rcode != NOERROR &&
|
|
||||||
ddns_fwd_name.len && ddns_rev_name.len) {
|
|
||||||
rcode = ddns_remove_ptr(&ddns_fwd_name, &ddns_rev_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
unset (lease -> scope, "ddns-fwd-name");
|
if (rcode == NOERROR) {
|
||||||
unset (lease -> scope, "ddns-rev-name");
|
result = 1;
|
||||||
unset (lease -> scope, "ddns-dhcid");
|
unset (lease -> scope, "ddns-fwd-name");
|
||||||
|
unset (lease -> scope, "ddns-txt");
|
||||||
|
try_rev:
|
||||||
|
if (find_bound_string (&ddns_rev_name,
|
||||||
|
lease -> scope, "ddns-rev-name")) {
|
||||||
|
if (ddns_remove_ptr(&ddns_fwd_name,
|
||||||
|
&ddns_rev_name) == NOERROR)
|
||||||
|
unset (lease -> scope, "ddns-rev-name");
|
||||||
|
else
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data_string_forget (&ddns_fwd_name, MDL);
|
data_string_forget (&ddns_fwd_name, MDL);
|
||||||
data_string_forget (&ddns_rev_name, MDL);
|
data_string_forget (&ddns_rev_name, MDL);
|
||||||
data_string_forget (&ddns_dhcid, MDL);
|
data_string_forget (&ddns_dhcid, MDL);
|
||||||
|
|
||||||
|
return result;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* NSUPDATE */
|
#endif /* NSUPDATE */
|
||||||
|
Reference in New Issue
Block a user