SHA256
1
0
forked from pool/dhcp
dhcp/dhcp-3.1.1-ldap-patch_failover-obj.dif

382 lines
12 KiB
Plaintext

--- server/ldap.c
+++ server/ldap.c 2009/01/15 15:42:21
@@ -106,6 +106,106 @@ x_strxform(char *dst, const char *src, s
return NULL;
}
+static int
+get_host_entry(char *fqdnname, size_t fqdnname_size,
+ char *hostaddr, size_t hostaddr_size)
+{
+#if defined(MAXHOSTNAMELEN)
+ char hname[MAXHOSTNAMELEN+1];
+#else
+ char hname[65];
+#endif
+ struct hostent *hp;
+
+ if (NULL == fqdnname || 1 >= fqdnname_size)
+ return -1;
+
+ memset(hname, 0, sizeof(hname));
+ if (gethostname(hname, sizeof(hname)-1))
+ return -1;
+
+ if (NULL == (hp = gethostbyname(hname)))
+ return -1;
+
+ strncpy(fqdnname, hp->h_name, fqdnname_size-1);
+ fqdnname[fqdnname_size-1] = '\0';
+
+ if (hostaddr != NULL)
+ {
+ if (hp->h_addr != NULL)
+ {
+ struct in_addr *aptr = (struct in_addr *)hp->h_addr;
+#if defined(HAVE_INET_NTOP)
+ if (hostaddr_size >= INET_ADDRSTRLEN &&
+ inet_ntop(AF_INET, aptr, hostaddr, hostaddr_size) != NULL)
+ {
+ return 0;
+ }
+#else
+ char *astr = inet_ntoa(*aptr);
+ size_t alen = strlen(astr);
+ if (astr && alen > 0 && hostaddr_size > alen)
+ {
+ strncpy(hostaddr, astr, hostaddr_size-1);
+ hostaddr[hostaddr_size-1] = '\0';
+ return 0;
+ }
+#endif
+ }
+ return -1;
+ }
+ return 0;
+}
+
+static int
+get_host_address(const char *hostname, char *hostaddr, size_t hostaddr_size)
+{
+ if (hostname && *hostname && hostaddr && hostaddr_size)
+ {
+ struct in_addr addr;
+
+#if defined(HAVE_INET_PTON)
+ if (inet_pton(AF_INET, hostname, &addr) == 0)
+#else
+ if (inet_aton(hostname, &addr) == 0)
+#endif
+ {
+ /* it is already IP address string */
+ if(strlen(hostname) < hostaddr_size)
+ {
+ strncpy(hostaddr, hostname, hostaddr_size-1);
+ hostaddr[hostaddr_size-1] = '\0';
+ return 0;
+ }
+ }
+ else
+ {
+ struct hostent *hp;
+ if ((hp = gethostbyname(hostname)) != NULL && hp->h_addr != NULL)
+ {
+ struct in_addr *aptr = (struct in_addr *)hp->h_addr;
+#if defined(HAVE_INET_NTOP)
+ if (hostaddr_size >= INET_ADDRSTRLEN &&
+ inet_ntop(AF_INET, aptr, hostaddr, hostaddr_size) != NULL)
+ {
+ return 0;
+ }
+#else
+ char *astr = inet_ntoa(*aptr);
+ size_t alen = strlen(astr);
+ if (astr && alen > 0 && alen < hostaddr_size)
+ {
+ strncpy(hostaddr, astr, hostaddr_size-1);
+ hostaddr[hostaddr_size-1] = '\0';
+ return 0;
+ }
+#endif
+ }
+ }
+ }
+ return -1;
+}
+
static void
ldap_parse_class (struct ldap_config_stack *item, struct parse *cfile)
{
@@ -447,6 +547,220 @@ add_to_config_stack (LDAPMessage * res,
ldap_stack = ns;
}
+static void
+ldap_parse_failover (struct ldap_config_stack *item, struct parse *cfile)
+{
+ char **tempstr;
+ char nodename[257]="\0", fqdnname[257]="\0", fqdnaddr[64]="\0";
+ char srvaddr[2][64] = {"\0", "\0"};
+ int primary, split = 0;
+ struct utsname unme;
+
+ if(uname(&unme) == 0)
+ {
+ snprintf(nodename, sizeof(nodename), "%s", unme.nodename);
+ }
+ if (get_host_entry (fqdnname, sizeof(fqdnname), fqdnaddr, sizeof(fqdnaddr)))
+ {
+ log_info("Could not get fqdn and the IP address of the host");
+ return;
+ }
+
+ /*
+ ** when dhcpFailOverPrimaryServer or dhcpFailOverSecondaryServer
+ ** matches our IP address, the following valiables are set:
+ ** - primary is 1 when we are primary or 0 when we are secondary
+ ** - srvaddr[0] contains ip address of the primary
+ ** - srvaddr[1] contains ip address of the secondary
+ */
+ primary = -1;
+ if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpFailOverPrimaryServer")) != NULL)
+ {
+ if (strcasecmp (tempstr[0], fqdnaddr) == 0 ||
+ strcasecmp (tempstr[0], fqdnname) == 0 ||
+ strcasecmp (tempstr[0], nodename) == 0)
+ {
+ /* we are the primary */
+ primary = 1;
+ /* write primary address */
+ strncpy(srvaddr[0], fqdnaddr, sizeof(srvaddr[0])-1);
+ srvaddr[0][sizeof(srvaddr[0])-1] = '\0';
+ }
+ else
+ {
+ /* no match => don't set primary flag */
+ /* write primary address */
+ if (get_host_address (tempstr[0], srvaddr[0], sizeof(srvaddr[0])) != 0)
+ {
+ log_info("Can't resolve address of the primary failover server %s",
+ tempstr[0]);
+ ldap_value_free (tempstr);
+ return;
+ }
+ }
+ ldap_value_free (tempstr);
+ }
+
+ if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpFailOverSecondaryServer")) != NULL)
+ {
+ if (strcasecmp (tempstr[0], fqdnaddr) == 0 ||
+ strcasecmp (tempstr[0], fqdnname) == 0 ||
+ strcasecmp (tempstr[0], nodename) == 0)
+ {
+ if (primary == 1)
+ {
+ log_info("Both, primary and secondary failover server"
+ " attribute matches our hostname/address");
+ ldap_value_free (tempstr);
+ return;
+ }
+ /* we are the secondary */
+ primary = 0;
+ /* write secondary address */
+ strncpy(srvaddr[1], fqdnaddr, sizeof(srvaddr[1])-1);
+ srvaddr[1][sizeof(srvaddr[1])-1] = '\0';
+ }
+ else
+ {
+ /* no match => don't set primary flag */
+ /* write secondary address */
+ if (get_host_address (tempstr[0], srvaddr[1], sizeof(srvaddr[1])) != 0)
+ {
+ log_info("Can't resolve address of the secondary failover server %s",
+ tempstr[0]);
+ ldap_value_free (tempstr);
+ return;
+ }
+ }
+ ldap_value_free (tempstr);
+ }
+
+ if (primary == -1 || srvaddr[0] == '\0' || srvaddr[1] == '\0')
+ {
+ log_error("Could not decide if the server type is primary"
+ " or secondary for failover peering.");
+ return;
+ }
+
+ if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) != NULL)
+ {
+ x_strncat (cfile->inbuf, "failover peer \"", LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
+ ldap_value_free (tempstr);
+ }
+ else
+ {
+ // ldap with disabled schema checks? fail to avoid syntax error.
+ log_error("Unable to find mandatory failover peering name attribute");
+ return;
+ }
+
+ if (primary)
+ x_strncat (cfile->inbuf, "primary;\n", LDAP_BUFFER_SIZE);
+ else
+ x_strncat (cfile->inbuf, "secondary;\n", LDAP_BUFFER_SIZE);
+
+ x_strncat (cfile->inbuf, "address ", LDAP_BUFFER_SIZE);
+ if (primary)
+ x_strncat (cfile->inbuf, srvaddr[0], LDAP_BUFFER_SIZE);
+ else
+ x_strncat (cfile->inbuf, srvaddr[1], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+
+ x_strncat (cfile->inbuf, "peer address ", LDAP_BUFFER_SIZE);
+ if (primary)
+ x_strncat (cfile->inbuf, srvaddr[1], LDAP_BUFFER_SIZE);
+ else
+ x_strncat (cfile->inbuf, srvaddr[0], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+
+ if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpFailOverPrimaryPort")) != NULL)
+ {
+ if (primary)
+ x_strncat (cfile->inbuf, "port ", LDAP_BUFFER_SIZE);
+ else
+ x_strncat (cfile->inbuf, "peer port ", LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ ldap_value_free (tempstr);
+ }
+ if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpFailOverSecondaryPort")) != NULL)
+ {
+ if (primary)
+ x_strncat (cfile->inbuf, "peer port ", LDAP_BUFFER_SIZE);
+ else
+ x_strncat (cfile->inbuf, "port ", LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ ldap_value_free (tempstr);
+ }
+
+ if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpFailOverResponseDelay")) != NULL)
+ {
+ x_strncat (cfile->inbuf, "max-response-delay ", LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ ldap_value_free (tempstr);
+ }
+
+ if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpFailOverUnackedUpdates")) != NULL)
+ {
+ x_strncat (cfile->inbuf, "max-unacked-updates ", LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ ldap_value_free (tempstr);
+ }
+
+ if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpFailOverLoadBalanceTime")) != NULL)
+ {
+ x_strncat (cfile->inbuf, "load balance max seconds ", LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ ldap_value_free (tempstr);
+ }
+
+ if (primary &&
+ (tempstr = ldap_get_values (ld, item->ldent, "dhcpMaxClientLeadTime")) != NULL)
+ {
+ x_strncat (cfile->inbuf, "mclt ", LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ ldap_value_free (tempstr);
+ }
+
+ if (primary &&
+ (tempstr = ldap_get_values (ld, item->ldent, "dhcpFailOverSplit")) != NULL)
+ {
+ x_strncat (cfile->inbuf, "split ", LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ split = 1;
+ ldap_value_free (tempstr);
+ }
+
+ if (primary && !split &&
+ (tempstr = ldap_get_values (ld, item->ldent, "dhcpFailOverHashBucketAssignment")) != NULL)
+ {
+ x_strncat (cfile->inbuf, "hba ", LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ ldap_value_free (tempstr);
+ }
+
+ /*
+ ** Are there any other options can come here? If yes then we need to enable
+ ** dhcpStatements in the schema and apply them here as well.
+ **
+ if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpStatements")) != NULL)
+ {
+ ...
+ ldap_value_free (tempstr);
+ }
+ */
+
+ item->close_brace = 1;
+}
static void
ldap_stop()
@@ -1171,6 +1485,8 @@ ldap_generate_config_string (struct pars
ldap_parse_key (entry, cfile);
else if (strcasecmp (objectClass[i], "dhcpDnsZone") == 0)
ldap_parse_zone (entry, cfile);
+ else if (strcasecmp (objectClass[i], "dhcpFailOverPeer") == 0)
+ ldap_parse_failover (entry, cfile);
else if (strcasecmp (objectClass[i], "dhcpHost") == 0)
{
if (ldap_method == LDAP_METHOD_STATIC)
@@ -1356,32 +1672,6 @@ ldap_get_host_name (LDAPMessage * ent)
}
-static int
-getfqhostname(char *fqhost, size_t size)
-{
-#if defined(MAXHOSTNAMELEN)
- char hname[MAXHOSTNAMELEN];
-#else
- char hname[65];
-#endif
- struct hostent *hp;
-
- if(NULL == fqhost || 1 >= size)
- return -1;
-
- memset(hname, 0, sizeof(hname));
- if( gethostname(hname, sizeof(hname)-1))
- return -1;
-
- if(NULL == (hp = gethostbyname(hname)))
- return -1;
-
- strncpy(fqhost, hp->h_name, size-1);
- fqhost[size-1] = '\0';
- return 0;
-}
-
-
isc_result_t
ldap_read_config (void)
{
@@ -1417,7 +1707,7 @@ ldap_read_config (void)
}
else
{
- if(0 == getfqhostname(fqdn, sizeof(fqdn)))
+ if(0 == get_host_entry(fqdn, sizeof(fqdn), NULL, 0))
{
snprintf (hfilter, sizeof (hfilter),
"(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))",