#212 Initial support for BIND 9.18 support
Merged 2 years ago by abbra. Opened 2 years ago by pemensik.
pemensik/bind-dyndb-ldap bind-9.18-support  into  master

file modified
+33 -1
@@ -53,6 +53,18 @@ 

  [CFLAGS="$SAVED_CFLAGS"

   AC_MSG_RESULT([no])])

  

+ # Check if build chain supports -std=gnu11

+ AC_MSG_CHECKING([for -std=gnu11 compiler flag])

+ SAVED_CFLAGS="$CFLAGS"

+ CFLAGS="-std=gnu11 -Werror"

+ AC_TRY_COMPILE([

+ 	extern int fdef(void);

+ ],[],

+ [AC_MSG_RESULT([yes])

+  CFLAGS="$SAVED_CFLAGS -std=gnu11"],

+ [CFLAGS="$SAVED_CFLAGS"

+  AC_MSG_RESULT([no])])

+ 

  # Get CFLAGS from isc-config.sh

  AC_ARG_VAR([BIND9_CFLAGS],

             [C compiler flags for bind9, overriding isc-config.sh])
@@ -98,6 +110,7 @@ 

  #include <dns/version.h>

  ],[ printf("%d\n", dns_libinterface) ])], [

      LIBDNS_VERSION_MAJOR=`./conftest$ac_exeext`

+     AC_MSG_RESULT([$LIBDNS_VERSION_MAJOR])

      AC_DEFINE_UNQUOTED([LIBDNS_VERSION_MAJOR], [$LIBDNS_VERSION_MAJOR],

      [Define libdns version])], [

      AC_RUN_IFELSE([AC_LANG_PROGRAM([[
@@ -111,9 +124,24 @@ 

  	return !(scanned == 3 && major == 9);

      ]])], [

      LIBDNS_VERSION_MAJOR=`./conftest$ac_exeext`

+     AC_MSG_RESULT([$LIBDNS_VERSION_MAJOR])

      AC_DEFINE_UNQUOTED([LIBDNS_VERSION_MAJOR], [$LIBDNS_VERSION_MAJOR],

      [Define libdns version])],

-     [AC_MSG_ERROR([Can't obtain libdns version.])])

+     [

+ 	LIBDNS_PATH="${libdir}/libdns.so"

+ 	if test -L "$LIBDNS_PATH" ; then

+ 		LIBDNS_VERSION_MAJOR=$(ls -l "$LIBDNS_PATH" | sed -e 's/^.*->\s*libdns-9\.\([[0-9]]\+\)\.\([[0-9]]\+\).*\.so/\1 \2/' -e t -e d | xargs printf "%02d%02d")

+ 	else

+ 		AC_MSG_ERROR([Can't obtain libdns version1.])

+ 	fi

+ 	if test -z "$LIBDNS_VERSION_MAJOR" || test "$LIBDNS_VERSION_MAJOR" -lt 1200; then

+ 		AC_MSG_ERROR([Can't obtain libdns version ($LIBDNS_VERSION_MAJOR).])

+ 	else

+ 		AC_DEFINE_UNQUOTED([LIBDNS_VERSION_MAJOR], [$LIBDNS_VERSION_MAJOR],

+     			[Define libdns version])

+ 		AC_MSG_RESULT([$LIBDNS_VERSION_MAJOR])

+ 	fi

+     ])

  ], [AC_MSG_ERROR([Cross compiling is not supported.])]

  )

  
@@ -137,6 +165,10 @@ 

    [AC_DEFINE([HAVE_DNS_SERVESTALE], 1, [Define if dns library provides dns_db_setservestalettl])]

  )

  

+ AC_CHECK_LIB([dns], [dns_result_totext],

+   [AC_DEFINE([HAVE_DNS_RESULT_TOTEXT], 1, [Define if dns library provides dns_result_totext])]

+ )

+ 

  dnl Older autoconf (2.59, for example) doesn't define docdir

  [[ ! -n "$docdir" ]] && docdir='${datadir}/doc/${PACKAGE_TARNAME}'

  AC_SUBST([docdir])

file modified
+33 -6
@@ -66,6 +66,10 @@ 

  		}							\

  	} while (0)

  

+ #if LIBDNS_VERSION_MAJOR < 1700

+ typedef dns_rdatatype_t dns_ssuruletype_t;

+ #endif

+ 

  static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT

  get_mode(const cfg_obj_t *obj, bool *value)

  {
@@ -184,14 +188,14 @@ 

  }

  

  static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT

- get_types(isc_mem_t *mctx, const cfg_obj_t *obj, dns_rdatatype_t **typesp,

+ get_types(isc_mem_t *mctx, const cfg_obj_t *obj, dns_ssuruletype_t **typesp,

  	  unsigned int *np)

  {

  	isc_result_t result = ISC_R_SUCCESS;

  	unsigned int i;

  	unsigned int n = 0;

  	const cfg_listelt_t *el;

- 	dns_rdatatype_t *types = NULL;

+ 	dns_ssuruletype_t *types = NULL;

  

  	REQUIRE(obj != NULL);

  	REQUIRE(typesp != NULL && *typesp == NULL);
@@ -201,7 +205,7 @@ 

  

  	n = count_list_elements(obj);

  	if (n > 0) {

- 		types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t));

+ 		types = isc_mem_get(mctx, n * sizeof(dns_ssuruletype_t));

  	}

  	i = 0;

  	for (el = cfg_list_first(obj); el != NULL; el = cfg_list_next(el)) {
@@ -216,7 +220,12 @@ 

  		DE_CONST(str, r.base);

  		r.length = strlen(str);

  

+ #if LIBDNS_VERSION_MAJOR < 1700

  		result = dns_rdatatype_fromtext(&types[i++], &r);

+ #else

+ 		types[i].max = 0;

+ 		result = dns_rdatatype_fromtext(&types[i++].type, &r);

+ #endif

  		if (result != ISC_R_SUCCESS) {

  			log_error("'%s' is not a valid type", str);

  			goto cleanup;
@@ -229,7 +238,7 @@ 

  	return result;

  

  cleanup:

- 	SAFE_MEM_PUT(mctx, types, n * sizeof(dns_rdatatype_t));

+ 	SAFE_MEM_PUT(mctx, types, n * sizeof(dns_ssuruletype_t));

  

  	return result;

  }
@@ -281,14 +290,18 @@ 

  		goto cleanup;

  	}

  

+ #if LIBDNS_VERSION_MAJOR >= 1700

+ 	dns_ssutable_create(mctx, &table);

+ #else

  	CHECK(dns_ssutable_create(mctx, &table));

+ #endif

  

  	for (el = cfg_list_first(policy); el != NULL; el = cfg_list_next(el)) {

  		const cfg_obj_t *stmt;

  		bool grant;

  		unsigned int match_type;

  		dns_fixedname_t fname, fident;

- 		dns_rdatatype_t *types;

+ 		dns_ssuruletype_t *types;

  		unsigned int n;

  

  		types = NULL;
@@ -303,9 +316,14 @@ 

  		result = get_fixed_name(stmt, "name", &fname);

  		if (result == ISC_R_NOTFOUND &&

  		    match_type == dns_ssumatchtype_subdomain) {

+ #if LIBDNS_VERSION_MAJOR >= 1700

+ 			dns_name_copy(dns_zone_getorigin(zone),

+ 				      dns_fixedname_initname(&fname));

+ #else

  			CHECK(dns_name_copy(dns_zone_getorigin(zone),

  					    dns_fixedname_initname(&fname),

  					    &fname.buffer));

+ #endif

  		}

  		else if (result != ISC_R_SUCCESS)

  			goto cleanup;
@@ -324,13 +342,22 @@ 

  			CLEANUP_WITH(DNS_R_BADNAME);

  		}

  

+ #if LIBDNS_VERSION_MAJOR >= 1700

+ 		result = ISC_R_SUCCESS;

+ 		dns_ssutable_addrule(table, grant,

+ 				     dns_fixedname_name(&fident),

+ 				     match_type,

+ 				     dns_fixedname_name(&fname),

+ 				     n, types);

+ #else

  		result = dns_ssutable_addrule(table, grant,

  					      dns_fixedname_name(&fident),

  					      match_type,

  					      dns_fixedname_name(&fname),

  					      n, types);

+ #endif

  

- 		SAFE_MEM_PUT(mctx, types, n * sizeof(dns_rdatatype_t));

+ 		SAFE_MEM_PUT(mctx, types, n * sizeof(dns_ssuruletype_t));

  		if (result != ISC_R_SUCCESS)

  			goto cleanup;

  

file modified
-4
@@ -13,10 +13,6 @@ 

  #include "util.h"

  #include "zone_register.h"

  

- #if LIBDNS_VERSION_MAJOR < 1600

- #define dns_name_copynf(src, dst) dns_name_copy((src), (dst), NULL)

- #endif

- 

  /**

   * These zones should not leak onto the Internet.

   * The list matches BIND commit 8f20f6c9d7ce5a0f0af6ee4c5361832d97b1c5d4

file modified
-4
@@ -27,10 +27,6 @@ 

  #include "util.h"

  #include "zone_register.h"

  

- #if LIBDNS_VERSION_MAJOR < 1600

- #define dns_name_copynf(src, dst) dns_name_copy((src), (dst), NULL)

- #endif

- 

  /**

   * Convert LDAP DN to absolute DNS names.

   *

file modified
+21 -3
@@ -11,11 +11,13 @@ 

  #include <isc/buffer.h>

  #include <isc/commandline.h>

  #include <isc/hash.h>

- #include <isc/lib.h>

  #include <isc/mem.h>

  #include <isc/once.h>

  #include <isc/refcount.h>

  #include <isc/util.h>

+ #if LIBDNS_VERSION_MAJOR < 1617

+ #include <isc/lib.h>

+ #endif

  

  #include <dns/db.h>

  #include <dns/diff.h>
@@ -238,6 +240,7 @@ 

  	return ISC_R_SUCCESS;

  }

  

+ #if LIBDNS_VERSION_MAJOR < 1719

  static isc_result_t

  serialize(dns_db_t *db, dns_dbversion_t *version, FILE *file)

  {
@@ -247,6 +250,7 @@ 

  

  	return dns_db_serialize(ldapdb->rbtdb, version, file);

  }

+ #endif

  

  /* !!! This could be required for optimizations (like on-disk cache). */

  static isc_result_t
@@ -635,6 +639,7 @@ 

  	return dns_db_issecure(ldapdb->rbtdb);

  }

  

+ #if LIBDNS_VERSION_MAJOR < 1721

  static unsigned int

  nodecount(dns_db_t *db)

  {
@@ -644,6 +649,17 @@ 

  

  	return dns_db_nodecount(ldapdb->rbtdb);

  }

+ #else

+ static unsigned int

+ nodecount(dns_db_t *db, dns_dbtree_t tree)

+ {

+ 	ldapdb_t *ldapdb = (ldapdb_t *) db;

+ 

+ 	REQUIRE(VALID_LDAPDB(ldapdb));

+ 

+ 	return dns_db_nodecount(ldapdb->rbtdb, tree);

+ }

+ #endif

  

  /**

   * Return TRUE, because database does not need to be loaded from disk
@@ -896,7 +912,7 @@ 

  }

  #endif

  

- #if LIBDNS_VERSION_MAJOR >= 1606

+ #if LIBDNS_VERSION_MAJOR >= 1606 && LIBDNS_VERSION_MAJOR < 1720

  /* Used for cache size adjustments, called by dns_cache_setcachesize.

   * Just proxy to rbtdb implementation. */

  static isc_result_t
@@ -914,7 +930,9 @@ 

  	detach,

  	beginload,

  	endload,

+ #if LIBDNS_VERSION_MAJOR < 1719

  	serialize, /* see dns_db_serialize(), implementation is not mandatory */

+ #endif

  	dump,

  	currentversion,

  	newversion,
@@ -966,7 +984,7 @@ 

  #if LIBDNS_VERSION_MAJOR >= 1600

  	NULL, /* setgluecachestats */

  #endif

- #if LIBDNS_VERSION_MAJOR >= 1606

+ #if LIBDNS_VERSION_MAJOR >= 1606 && LIBDNS_VERSION_MAJOR < 1720

  	adjusthashsize, /* adjusthashsize */

  #endif

  };

file modified
+2 -1
@@ -5,6 +5,7 @@ 

  #include "dyndb-config.h"

  #define HAVE_TLS 1

  #define HAVE_THREAD_LOCAL 1

+ #include <threads.h>

  

  #include <dns/dyndb.h>

  #include <dns/diff.h>
@@ -3760,7 +3761,7 @@ 

  update_zone(isc_task_t *task, isc_event_t *event)

  {

  	ldap_syncreplevent_t *pevent = (ldap_syncreplevent_t *)event;

- 	isc_result_t result ;

+ 	isc_result_t result = ISC_R_SUCCESS;

  	ldap_instance_t *inst = pevent->inst;

  	isc_mem_t *mctx;

  	dns_name_t prevname;

file modified
+1 -2
@@ -30,7 +30,6 @@ 

  #include "dyndb-config.h"

  

  #if LIBDNS_VERSION_MAJOR < 1600

- #define dns_name_copynf(src, dst) dns_name_copy((src), (dst), NULL)

  #define REFCOUNT_CAST(n) ((typeof(((isc_refcount_t *)0)->refs)) (n))

  

  /* Static assert is not provided yet, copy from 9.16 */
@@ -495,7 +494,7 @@ 

  	isc_result_t result;

  	dns_dbnode_t *rbt_node = NULL;

  	metadb_iter_t *iter = NULL;

- 	uint32_t node_generation;

+ 	uint32_t node_generation = 0;

  	uint32_t cur_generation;

  	metadb_node_t metadb_node;

  	DECLARE_BUFFERED_NAME(name);

file modified
+1 -1
@@ -17,7 +17,7 @@ 

  #define _STR_MEM_FLARG_PASS	, file, line

  #else

  #define _STR_MEM_FILELINE

- #define _STR_MEM_FLAG

+ #define _STR_MEM_FLARG

  #define _STR_MEM_FLARG_PASS

  #endif

  

file modified
-4
@@ -32,10 +32,6 @@ 

  #define SYNCPTR_FMTPRE  SYNCPTR_PREF "(%s) for '%s A/AAAA %s' "

  #define SYNCPTR_FMTPOST ldap_modop_str(mod_op), a_name_str, ip_str

  

- #if LIBDNS_VERSION_MAJOR < 1600

- #define dns_name_copynf(src, dst) dns_name_copy((src), (dst), NULL)

- #endif

- 

  /*

   * Event for asynchronous PTR record synchronization.

   */

file modified
+3 -3
@@ -129,7 +129,7 @@ 

  finish(isc_task_t *task, isc_event_t *event) {

  	isc_result_t result = ISC_R_SUCCESS;

  	sync_barrierev_t *bev = NULL;

- 	sync_state_t new_state;

+ 	sync_state_t new_state = sync_configinit;

  

  	REQUIRE(event != NULL);

  	UNUSED(task);
@@ -496,8 +496,8 @@ 

  sync_barrier_wait(sync_ctx_t *sctx, ldap_instance_t *inst) {

  	isc_event_t *ev = NULL;

  	sync_barrierev_t *bev = NULL;

- 	sync_state_t barrier_state;

- 	sync_state_t final_state;

+ 	sync_state_t barrier_state = sync_configinit;

+ 	sync_state_t final_state = sync_configinit;

  	task_element_t *taskel = NULL;

  	task_element_t *next_taskel = NULL;

  

file modified
+11
@@ -15,9 +15,20 @@ 

  #include <dns/result.h>

  

  #include "log.h"

+ #include "dyndb-config.h"

  

  extern bool verbose_checks; /* from settings.c */

  

+ #ifndef HAVE_DNS_RESULT_TOTEXT

+ #define dns_result_totext isc_result_totext

+ #endif

+ 

+ #if LIBDNS_VERSION_MAJOR < 1600

+ #define dns_name_copynf(src, dst) dns_name_copy((src), (dst), NULL)

+ #elif LIBDNS_VERSION_MAJOR >= 1714

+ #define dns_name_copynf(src, dst) dns_name_copy((src), (dst))

+ #endif

+ 

  #define CLEANUP_WITH(result_code)				\

  	do {							\

  		result = (result_code);				\

Some changes needed to build with the most recent BIND9 release. It does
not yet provide complete support for new release.

Detects version of libdns just from libdns.so symlink. It requires
--libdir= explicitly set for this part to work.

Leaves unsolved issue with dns_ssutable, which I am not sure which solution would be the best. dns_rdatatype_t is replaced by structure containing type and maximum count for it:

typedef struct dns_ssuruletype {
        dns_rdatatype_t type; /* type allowed */
        unsigned int    max;  /* maximum number of records allowed. */
} dns_ssuruletype_t;
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..    -Wall -Wextra -Werror -std=gnu99 -O2 -I/usr/include/bind9 -I/usr/include/bind9 -g -O2 -fvisibility=hidden -fno-delete-null-pointer-checks -std=gnu11 -fvisibility=hidden -fno-delete-null-pointer-checks -std=gnu11 -MT ldap_la-acl.lo -MD -MP -MF .deps/ldap_la-acl.Tpo -c -o ldap_la-acl.lo `test -f 'acl.c' || echo './'`acl.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -Wall -Wextra -Werror -std=gnu99 -O2 -I/usr/include/bind9 -I/usr/include/bind9 -g -O2 -fvisibility=hidden -fno-delete-null-pointer-checks -std=gnu11 -fvisibility=hidden -fno-delete-null-pointer-checks -std=gnu11 -MT ldap_la-acl.lo -MD -MP -MF .deps/ldap_la-acl.Tpo -c acl.c  -fPIC -DPIC -o .libs/ldap_la-acl.o
acl.c: In function ‘acl_configure_zone_ssutable’:
acl.c:340:50: error: passing argument 7 of ‘dns_ssutable_addrule’ from incompatible pointer type [-Werror=incompatible-pointer-types]
  340 |                                               n, types);
      |                                                  ^~~~~
      |                                                  |
      |                                                  dns_rdatatype_t * {aka short unsigned int *}
In file included from acl.c:22:
/usr/include/bind9/dns/ssu.h:114:41: note: expected ‘dns_ssuruletype_t *’ {aka ‘struct dns_ssuruletype *’} but argument is of type ‘dns_rdatatype_t *’ {aka ‘short unsigned int *’}
  114 |                      dns_ssuruletype_t *types);
      |                      ~~~~~~~~~~~~~~~~~~~^~~~~
acl.c:336:24: error: void value not ignored as it ought to be
  336 |                 result = dns_ssutable_addrule(table, grant,
      |                        ^
cc1: all warnings being treated as errors

Test build of bind 9.18 is available at: https://copr.fedorainfracloud.org/coprs/pemensik/bind/

It seems we may ask bind upstream to provide public method alternative of internal function, which does something similar to implemented again by bind-dyndb-ldap. It seems unnecessary to parse update-policy again in plugin. Do we want to limit supported update policies? Is it required to reimplement existing code in bind?

static isc_result_t
configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,         const char *zname);

This is implemented in bin/named/zoneconf.c, function configure_zone_ssutable.

I don't think we want to limit update-policy, indeed. The original issue was and still is that configure_zone_ssutable is static and is called from named_zone_configure which is called from a static configure_zone. This does not work well with updates coming from LDAP where we basically need to reconfigure the existing zone.

What's the planned schedule here? Debian moved to 9.18 already last month.

2 new commits added

  • Support for 9.18 and 9.17 support
  • Add basic support of dns_ssuruletype_t
2 years ago

Updated support, it already compiles under 9.18. Do not know how much it would work.

seems to build, although Debian/Ubuntu for some reason rename the libs to look like this:

bind9-libs: /usr/lib/x86_64-linux-gnu/libbind9-9.18.0-2ubuntu1-Ubuntu.so

so I've just hardcoded the version instead

It would be nice, if we found generally working way to detect correct names for libraries used. Working on all distributions. Different directory should not matter. This configure time check is intended to work with bind9-dev package, not with bind9-libs itself. I attempted to make it universal and it should work also on debian or ubuntu, but I did not test it myself.

It may work if ./configure --libdir=/usr/lib/x86_64-linux-gnu were used, can you @tjaalton test it with bind9-dev installed? I don't know Debian packaging enough to know whether some variable has correct libdir. I would expect that. I have used libdir this way, because our RPM %configure macro always passes it to built packages.

Is Debian bind-dyndb-ldap packaging setting libdir correctly? bind9 package uses different value, which might work better.

https://salsa.debian.org/freeipa-team/bind-dyndb-ldap/-/blob/master/debian/rules:
dh_auto_configure --    --libdir=/usr/lib

https://salsa.debian.org/dns-team/bind9/-/blob/debian/main/debian/rules:
dh_auto_configure --    --libdir=/usr/lib/$(DEB_HOST_MULTIARCH)

That libdir scan were intended to be used on development package, which provides symlink to actual library, whatever it is. I think you should replace bind9-libs with bind9-dev in your packaging and it might work the way I have prepared it.

that was hardcoded so that freeipa wouldn't have to worry about multiarch paths, but that can be changed now

but the thing is that bind9-dev doesn't ship headers that the maintainer thinks are non-public, so dns/version.h is not available:

conftest.c:38:10: fatal error: dns/version.h: No such file or directory

actually, I can't find dns/version.h in upstream sources either

Sure, separate versions of each libraries were removed. dns/version.h include is no longer available and version built into libdns binary as well. That is the reason I fiddle with symlink path of libdns.so library. I could think only of named -V first line to provide exact version of named, including any extra version used. That is where I attempt to extract version from libdns.so symlink of devel package. That should work with just bind9-dev package, without bind9 package itself. If you know a better way, please share.

But that requires ${libdir}/libdns.so symlink to exist. Which would not in case of libdir=/usr/lib. I am sure that detection can be adjusted by downstream patch however.

1 new commit added

  • Move common dns_name_copynf compatibility macros to header
2 years ago

Could be this change tested together with bind 9.18.0 build from COPR repository pemensik/bind? Basic test worked. It seems to be ready for new Rawhide. What do you think?

Are there any tasks needed to move this PR along that could be contributed to? This is a critical component of getting the FreeIPA server working on Debian, as @tjaalton previously mentioned.

I'd be happy to pitch in, provided I knew what needed to be done x)

We wanted to run the whole set of FreeIPA tests on both Fedora and RHEL before merging. @pemensik created a COPR repo but sadly it did not have consistent state when we tried couple weeks so packages weren't installable. We can retry next week.

Sounds good :smile: Give us a shout if we can do anything to help out from the Debian side of things!

Bind 9.17+ support was merged to FreeIPA. We are going to release FreeIPA 4.9.10 and 4.10.0 which will have this support, so I think we can merge this pull request and do a new bind-dyndb-ldap release.

@pemensik is this PR a final one?

@abbra Yes, I don't have anything more to add now.

Thanks. We tested this extensively as a part of FreeIPA 4.9.10 integration testing.

Pull-Request has been merged by abbra

2 years ago

Great! Glad to hear that

@pemensik @tjaalton I have released bind-dyndb-ldap-11.10 which supports bind 9.17+.

@pemensik I pushed the update to Rawhide dist-git but haven't built the package aside from building a scratch one: https://koji.fedoraproject.org/koji/taskinfo?taskID=88530266. Feel free to create a side-tag and rebuild bind and bind-dyndb-ldap there in Rawhide.