summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Nagy <mnagy@redhat.com>2009-02-10 18:55:56 +0100
committerMartin Nagy <mnagy@redhat.com>2009-02-12 15:39:48 +0100
commitc0aff53501ad45dba1425951a8cc2cd3d1697a8d (patch)
tree623ee09c1e754517f786aaa43a9eb2c42de36480
parenta6935806d2330ad86915a76f6807328d445d63f3 (diff)
downloadldap_driver-c0aff53501ad45dba1425951a8cc2cd3d1697a8d.tar.gz
ldap_driver-c0aff53501ad45dba1425951a8cc2cd3d1697a8d.tar.xz
ldap_driver-c0aff53501ad45dba1425951a8cc2cd3d1697a8d.zip
Add helper functions for LDAP related conversions.
-rw-r--r--Makefile3
-rw-r--r--ldap_convert.c180
-rw-r--r--ldap_convert.h31
3 files changed, 213 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index d020153..c22c3ea 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,8 @@ LIBMINOR = 0
LIBNAME = libdnsldap.so.$(LIBMAJOR).$(LIBMINOR).0
LIBSONAME = libdnsldap.so.$(LIBMAJOR)
-OBJS = ldap_driver.o semaphore.o ldap_helper.o log.o settings.o str.o
+OBJS = ldap_driver.o semaphore.o ldap_convert.o ldap_helper.o log.o settings.o
+OBJS += str.o
CFLAGS := -Wall -Wextra -pedantic -std=c99 -g -fPIC $(CFLAGS)
diff --git a/ldap_convert.c b/ldap_convert.c
new file mode 100644
index 0000000..41d0474
--- /dev/null
+++ b/ldap_convert.c
@@ -0,0 +1,180 @@
+/* Authors: Martin Nagy <mnagy@redhat.com>
+ *
+ * Copyright (C) 2009 Red Hat
+ * see file 'COPYING' for use and warranty information
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 only
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <isc/buffer.h>
+#include <isc/mem.h>
+#include <isc/result.h>
+#include <isc/util.h>
+
+#include <dns/name.h>
+
+#include <errno.h>
+#define LDAP_DEPRECATED 1
+#include <ldap.h>
+
+#include "str.h"
+#include "ldap_convert.h"
+#include "log.h"
+#include "util.h"
+
+
+static isc_result_t dn_to_text(const char *dn, const char *root_dn,
+ ld_string_t *target);
+static isc_result_t explode_dn(const char *dn, char ***explodedp, int notypes);
+static unsigned int count_rdns(char **exploded);
+
+
+isc_result_t
+dn_to_dnsname(isc_mem_t *mctx, const char *dn, const char *root_dn,
+ dns_name_t *target)
+{
+ isc_result_t result;
+ ld_string_t *str;
+ isc_buffer_t source_buffer;
+ isc_buffer_t target_buffer;
+ dns_name_t tmp_name;
+ unsigned char target_base[DNS_NAME_MAXWIRE];
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(dn != NULL);
+
+ str = NULL;
+ result = ISC_R_SUCCESS;
+
+ /* Convert the DN into a DNS name. */
+ CHECK(str_new(mctx, &str));
+ CHECK(dn_to_text(dn, root_dn, str));
+
+ /* TODO: fix this */
+ isc_buffer_init(&source_buffer, str_buf(str), str_len(str) - 1);
+ isc_buffer_add(&source_buffer, str_len(str) - 1);
+ isc_buffer_init(&target_buffer, target_base, sizeof(target_base));
+
+ /* Now create a dns_name_t struct. */
+ dns_name_init(&tmp_name, NULL);
+ dns_name_setbuffer(&tmp_name, &target_buffer);
+
+ dns_name_fromtext(&tmp_name, &source_buffer, dns_rootname, 0, NULL);
+
+cleanup:
+ if (result != ISC_R_FAILURE)
+ result = dns_name_dupwithoffsets(&tmp_name, mctx, target);
+
+ str_destroy(&str);
+
+ return result;
+}
+
+/*
+ * Convert LDAP dn to DNS name. If root_dn is not NULL then count how much RNDs
+ * it contains and ignore that much trailing RNDs from dn.
+ *
+ * Example:
+ * dn = "idnsName=foo, idnsName=bar, idnsName=example.org, cn=dns,"
+ * "dc=example, dc=org"
+ * root_dn = "cn=dns, dc=example, dc=org"
+ *
+ * The resulting string will be "foo.bar.example.org."
+ */
+static isc_result_t
+dn_to_text(const char *dn, const char *root_dn, ld_string_t *target)
+{
+ isc_result_t result;
+ unsigned int count;
+ char **exploded_dn = NULL;
+ char **exploded_root = NULL;
+
+ REQUIRE(dn != NULL);
+ REQUIRE(target != NULL);
+
+ result = ISC_R_SUCCESS;
+
+ CHECK(explode_dn(dn, &exploded_dn, 1));
+ count = count_rdns(exploded_dn);
+
+ if (root_dn != NULL) {
+ unsigned int count_root;
+
+ CHECK(explode_dn(root_dn, &exploded_root, 1));
+ count_root = count_rdns(exploded_root);
+ if (exploded_root > exploded_dn) {
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+ count -= count_root;
+ }
+
+ str_init_char(target, "");
+ for (unsigned int i = 0; exploded_dn[i] != NULL && i < count; i++) {
+ str_cat_char(target, exploded_dn[i]);
+ str_cat_char(target, ".");
+ }
+
+ if (str_len(target) == 0)
+ str_init_char(target, ".");
+
+cleanup:
+ if (exploded_dn != NULL)
+ ldap_value_free(exploded_dn);
+ if (exploded_root != NULL)
+ ldap_value_free(exploded_root);
+
+ return result;
+}
+
+static isc_result_t
+explode_dn(const char *dn, char ***explodedp, int notypes)
+{
+ isc_result_t result;
+ char **exploded;
+
+ REQUIRE(dn != NULL);
+ REQUIRE(explodedp != NULL && *explodedp == NULL);
+
+ result = ISC_R_SUCCESS;
+
+ exploded = ldap_explode_dn(dn, notypes);
+ if (exploded == NULL) {
+ if (errno == ENOMEM) {
+ return ISC_R_NOMEMORY;
+ } else {
+ log_error("ldap_explode_dn(\"%s\") failed, error code %d",
+ dn, errno);
+ return ISC_R_FAILURE;
+ }
+ }
+
+ *explodedp = exploded;
+
+ return ISC_R_SUCCESS;
+}
+
+static unsigned int
+count_rdns(char **exploded)
+{
+ unsigned int ret;
+
+ REQUIRE(exploded != NULL);
+
+ ret = 0;
+ while (exploded[ret] != NULL)
+ ret++;
+
+ return ret;
+}
diff --git a/ldap_convert.h b/ldap_convert.h
new file mode 100644
index 0000000..1fb77e4
--- /dev/null
+++ b/ldap_convert.h
@@ -0,0 +1,31 @@
+/* Authors: Martin Nagy <mnagy@redhat.com>
+ *
+ * Copyright (C) 2009 Red Hat
+ * see file 'COPYING' for use and warranty information
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 only
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LD_LDAP_CONVERT_H_
+#define _LD_LDAP_CONVERT_H_
+
+/*
+ * Convert LDAP DN 'dn', to dns_name_t 'target'. 'target' needs to be
+ * initialized with dns_name_init() before the call and freed by the caller
+ * after it using dns_name_free().
+ */
+isc_result_t dn_to_dnsname(isc_mem_t *mctx, const char *dn, const char *root_dn,
+ dns_name_t *target);
+
+#endif /* !_LD_LDAP_CONVERT_H_ */