diff options
author | Martin Nagy <mnagy@redhat.com> | 2009-02-10 18:55:56 +0100 |
---|---|---|
committer | Martin Nagy <mnagy@redhat.com> | 2009-02-12 15:39:48 +0100 |
commit | c0aff53501ad45dba1425951a8cc2cd3d1697a8d (patch) | |
tree | 623ee09c1e754517f786aaa43a9eb2c42de36480 | |
parent | a6935806d2330ad86915a76f6807328d445d63f3 (diff) | |
download | ldap_driver-c0aff53501ad45dba1425951a8cc2cd3d1697a8d.tar.gz ldap_driver-c0aff53501ad45dba1425951a8cc2cd3d1697a8d.tar.xz ldap_driver-c0aff53501ad45dba1425951a8cc2cd3d1697a8d.zip |
Add helper functions for LDAP related conversions.
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | ldap_convert.c | 180 | ||||
-rw-r--r-- | ldap_convert.h | 31 |
3 files changed, 213 insertions, 1 deletions
@@ -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_ */ |