SHA256
1
0
forked from pool/dhcp
OBS User unknown 2009-01-19 01:22:10 +00:00 committed by Git OBS Bridge
parent 23138acaa3
commit 839cc33106
7 changed files with 465 additions and 16 deletions

View File

@ -0,0 +1,381 @@
--- 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)))",

View File

@ -0,0 +1,12 @@
--- server/ldap.c
+++ server/ldap.c 2009/01/15 15:47:19
@@ -1750,7 +1750,8 @@ ldap_read_config (void)
(tempstr = ldap_get_values (ld, hostent, "dhcpServiceDN")) == NULL ||
tempstr[0] == NULL)
{
- log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
+ log_error ("Error: No dhcp service is associated with the server %s %s", (hostdn ? "dn" : "name"),
+ (hostdn ? hostdn : (ldap_dhcp_server_cn ? ldap_dhcp_server_cn : unme.nodename)));
if (tempstr != NULL)
ldap_value_free (tempstr);

View File

@ -1,3 +1,22 @@
-------------------------------------------------------------------
Thu Jan 15 16:43:01 CET 2009 - mt@suse.de
- Fix message about missed service/server association (bnc#392354).
- Applied missed patch with support for dhcpFailOverPeer objects
(failover peering definition) by S Kalyanasundaram (fate#303198).
-------------------------------------------------------------------
Thu Jan 15 13:50:01 CET 2009 - mt@suse.de
- Fixed init script to copy nsswitch.conf and all libnss libs to
the chroot jail to fix resolving via /etc/hosts (bnc#462851).
-------------------------------------------------------------------
Tue Dec 16 11:37:00 CET 2008 - mt@suse.de
- Fixed init scripts Required-Start/Stop tags to require network-
remotefs script, so all interfaces are up while start.
-------------------------------------------------------------------
Wed Nov 26 08:05:01 CET 2008 - coolo@suse.de

View File

@ -1,7 +1,7 @@
#
# spec file for package dhcp (Version 3.1.1)
#
# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany.
# Copyright (c) 2009 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -31,7 +31,7 @@ License: BSD 3-Clause
Group: Productivity/Networking/Boot/Servers
AutoReqProv: on
Version: 3.1.1
Release: 6
Release: 7
Summary: Common Files Used by ISC DHCP Software
Url: http://www.isc.org/isc/dhcp.html
Source0: http://ftp.isc.org/isc/dhcp/dhcp-%{version}.tar.gz
@ -73,6 +73,8 @@ Patch12: dhcp-3.0.5-ldap-patch_server_dn.dif
Patch13: dhcp-3.0.5-ldap-patch_host_brace.dif
Patch14: dhcp-3.0.6-ldap-patch_hwaddr-icase.dif
Patch15: dhcp-3.0.6-ldap-patch_external-dn.diff
Patch16: dhcp-3.1.1-ldap-patch_failover-obj.dif
Patch17: dhcp-3.1.1-ldap-patch_service-assoc-msg.dif
%endif
%if %{?suse_version:%suse_version}%{?!suse_version:99999} > 930
Patch30: dhcp-3.1.1-pie.dif
@ -204,6 +206,8 @@ Authors:
%patch13 -p0
%patch14 -p0
%patch15 -p0
%patch16 -p0
%patch17 -p0
%endif
%if %{?suse_version:%suse_version}%{?!suse_version:99999} > 930
%patch30 -p0
@ -486,6 +490,16 @@ if ! test -f /.buildenv; then rm -rf $RPM_BUILD_ROOT; fi
%doc %{_mandir}/man3/dhcpctl.3.gz
%changelog
* Thu Jan 15 2009 mt@suse.de
- Fix message about missed service/server association (bnc#392354).
- Applied missed patch with support for dhcpFailOverPeer objects
(failover peering definition) by S Kalyanasundaram (fate#303198).
* Thu Jan 15 2009 mt@suse.de
- Fixed init script to copy nsswitch.conf and all libnss libs to
the chroot jail to fix resolving via /etc/hosts (bnc#462851).
* Tue Dec 16 2008 mt@suse.de
- Fixed init scripts Required-Start/Stop tags to require network-
remotefs script, so all interfaces are up while start.
* Wed Nov 26 2008 coolo@suse.de
- prereq sysconfig to avoid warnings about missing
/etc/sysconfig/dhcp

View File

@ -1,4 +1,4 @@
#! /bin/sh
#! /bin/bash
# Copyright (c) 1996, 1997, 1998 S.u.S.E. GmbH
# Copyright (c) 1998, 1999, 2000, 2001 SuSE GmbH
# Copyright (c) 2002, 2003 SuSE Linux AG
@ -12,9 +12,9 @@
#
### BEGIN INIT INFO
# Provides: dhcpd
# Required-Start: $remote_fs $network
# Required-Start: $network $remote_fs network-remotefs
# Should-Start: $named $syslog $time ldap ndsd
# Required-Stop: $remote_fs $network
# Required-Stop: $network $remote_fs network-remotefs
# Should-Stop: $named $syslog ldap ndsd
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
@ -160,15 +160,37 @@ case "$1" in
fi
done
rm -f $CHROOT_PREFIX/dev/urandom
for i in $DAEMON_CONF $DHCPD_CONF_INCLUDE_FILES $LDAP_CONF /etc/{resolv.conf,host.conf,hosts,localtime} /dev/urandom; do
for i in $DAEMON_CONF $DHCPD_CONF_INCLUDE_FILES $LDAP_CONF /etc/{gai.conf,nsswitch.conf,resolv.conf,host.conf,hosts,localtime} /dev/urandom; do
if ! test -e "$i"; then continue; fi # neither of them is absolutely necessary
cp -aL "$i" "${CHROOT_PREFIX}/${i%/*}/" &>/dev/null \
|| { echo "...$0:$LINENO: could not copy $i to chroot jail"; rc_failed; rc_status -v1; exit 6; }
done
libdir=/$(basename $(echo /var/lib/dhcp/lib*))
for i in /$libdir/{libresolv.so.2,libnss_dns{,6}.so.2} \
/$libdir/{libpthread.so.0,libdl.so.2} ; do
if [ -s "$i" ]; then
libdir=$(basename $(echo /var/lib/dhcp/lib*))
if test -x /usr/bin/ldd ; then
get_ldd_deps()
{
ldd_wl="\/${libdir}\/lib"
ldd_bl="\/${libdir}\/libc\."
while read -sr a b c d ; do
[ -n "$c" ] || continue
[[ $c =~ $ldd_wl ]] || continue
[[ $c =~ $ldd_bl ]] && continue
echo $c
done < <(/usr/bin/ldd "$1")
}
else
get_ldd_deps() { :; }
fi
cplibs=`for i in /$libdir/{libresolv.so.*,libnss_*.so.*} \
/$libdir/{libpthread.so.0,libdl.so.2} ;
do
if [ -s "$i" ] ; then
echo "$i"
get_ldd_deps "$i"
fi
done | sort -u`
for i in $cplibs ; do
if [ -s "$i" ]; then
cp -pL "$i" "/var/lib/dhcp/$libdir/" \
|| { echo "...$0:$LINENO: could not copy $i to chroot jail"; rc_failed; rc_status -v1; exit 6; }
fi

View File

@ -11,9 +11,9 @@
#
### BEGIN INIT INFO
# Provides: dhcrelay
# Required-Start: $remote_fs $network
# Should-Start: $named $syslog
# Required-Stop: $remote_fs $network
# Required-Start: $network $remote_fs network-remotefs
# Should-Start: $named $syslog $time
# Required-Stop: $network $remote_fs network-remotefs
# Should-Stop: $named $syslog
# Default-Start: 3 5
# Default-Stop: 0 1 2 6

View File

@ -26,9 +26,10 @@ DHCPD_INTERFACE=""
# be copied to /var/lib/dhcp/etc/.
#
# Some files that are important for hostname to IP address resolution
# (/etc/{hosts,host.conf,resolv.conf,localtime}, /lib/libnss_dns.so.2,
# /lib/libresolv.so.2) will also be copied to the chroot jail by the
# init script when you start it (about 100kB altogether).
# (/etc/{gai.conf,nsswitch.conf,resolv.conf,host.conf,hosts,localtime},
# /lib/lib{resolv.so.*,libnss_*.so.*,libpthread.so.0,libdl.so.2}) will
# also be copied to the chroot jail by the init script when you start
# it (less than 1MB altogether).
#
# The pid file will be in /var/lib/dhcp/var/run/dhcpd.pid.
#