summaryrefslogtreecommitdiffstats
path: root/ldap_helper.c
diff options
context:
space:
mode:
authorMartin Nagy <mnagy@redhat.com>2009-02-10 18:56:23 +0100
committerMartin Nagy <mnagy@redhat.com>2009-02-12 15:39:48 +0100
commit1167840b16883acdc4ab47b1ef8c69d8ed7a33d8 (patch)
tree6262f4797ed514d2069bbfe71f7410219bd0e1ad /ldap_helper.c
parentc0aff53501ad45dba1425951a8cc2cd3d1697a8d (diff)
downloadldap_driver_testing-1167840b16883acdc4ab47b1ef8c69d8ed7a33d8.tar.gz
ldap_driver_testing-1167840b16883acdc4ab47b1ef8c69d8ed7a33d8.tar.xz
ldap_driver_testing-1167840b16883acdc4ab47b1ef8c69d8ed7a33d8.zip
Add zone manager.
Zone manager will take care of periodical checks for new zones and will add them when they appear. For now, zones are only added at start time, no periodical checks yet.
Diffstat (limited to 'ldap_helper.c')
-rw-r--r--ldap_helper.c200
1 files changed, 156 insertions, 44 deletions
diff --git a/ldap_helper.c b/ldap_helper.c
index 011ab96..d5561c8 100644
--- a/ldap_helper.c
+++ b/ldap_helper.c
@@ -1,7 +1,7 @@
/* Authors: Martin Nagy <mnagy@redhat.com>
* Adam Tkac <atkac@redhat.com>
*
- * Copyright (C) 2008 Red Hat
+ * Copyright (C) 2008, 2009 Red Hat
* see file 'COPYING' for use and warranty information
*
* This program is free software; you can redistribute it and/or
@@ -24,6 +24,8 @@
#include <dns/rdatatype.h>
#include <dns/result.h>
#include <dns/ttl.h>
+#include <dns/view.h>
+#include <dns/zone.h>
#include <isc/buffer.h>
#include <isc/lex.h>
@@ -38,6 +40,7 @@
#include <string.h>
#include <strings.h>
+#include "ldap_convert.h"
#include "ldap_helper.h"
#include "log.h"
#include "semaphore.h"
@@ -69,9 +72,12 @@ struct ldap_auth_pair {
/* These are typedefed in ldap_helper.h */
struct ldap_db {
isc_mem_t *mctx;
+ dns_view_t *view;
+
/* List of LDAP connections. */
semaphore_t conn_semaphore;
LIST(ldap_instance_t) conn_list;
+
/* Settings. */
ld_string_t *host;
ld_string_t *base;
@@ -88,16 +94,21 @@ struct ldap_instance {
LDAP *handle;
LDAPMessage *result;
+
+ /* Temporary stuff. */
LDAPMessage *entry;
BerElement *ber;
char *attribute;
char **values;
+ char *dn;
};
/*
* Constants.
*/
+extern const char *ldapdb_impname;
+
/* Supported authentication types. */
const ldap_auth_pair_t supported_ldap_auth[] = {
{ AUTH_NONE, "none" },
@@ -115,6 +126,8 @@ const ldap_auth_pair_t supported_ldap_auth[] = {
static isc_result_t new_ldap_instance(ldap_db_t *ldap_db,
ldap_instance_t **ldap_instp);
static void destroy_ldap_instance(ldap_instance_t **ldap_instp);
+static isc_result_t add_or_modify_zone(ldap_db_t *ldap_db, const char *dn,
+ const char *db_name, dns_zonemgr_t *zmgr);
static ldap_instance_t * get_connection(ldap_db_t *ldap_db);
static void put_connection(ldap_instance_t *ldap_inst);
static isc_result_t ldap_connect(ldap_instance_t *ldap_inst);
@@ -125,9 +138,11 @@ static const LDAPMessage *next_entry(ldap_instance_t *inst);
static const char *next_attribute(ldap_instance_t *inst);
static const char *get_attribute(ldap_instance_t *inst);
static char **get_values(ldap_instance_t *inst);
+static const char *get_dn(ldap_instance_t *inst);
isc_result_t
-new_ldap_db(isc_mem_t *mctx, ldap_db_t **ldap_dbp, const char * const *argv)
+new_ldap_db(isc_mem_t *mctx, dns_view_t *view, ldap_db_t **ldap_dbp,
+ const char * const *argv)
{
unsigned int i;
isc_result_t result;
@@ -141,6 +156,7 @@ new_ldap_db(isc_mem_t *mctx, ldap_db_t **ldap_dbp, const char * const *argv)
};
REQUIRE(mctx != NULL);
+ REQUIRE(view != NULL);
REQUIRE(ldap_dbp != NULL && *ldap_dbp == NULL);
ldap_db = isc_mem_get(mctx, sizeof(ldap_db_t));
@@ -148,9 +164,11 @@ new_ldap_db(isc_mem_t *mctx, ldap_db_t **ldap_dbp, const char * const *argv)
return ISC_R_NOMEMORY;
ZERO_PTR(ldap_db);
- memset(ldap_db, 0, sizeof(ldap_db_t));
isc_mem_attach(mctx, &ldap_db->mctx);
+ ldap_db->view = view;
+ /* commented out for now, cause named to hang */
+ //dns_view_attach(view, &ldap_db->view);
INIT_LIST(ldap_db->conn_list);
ldap_db->auth_method = AUTH_NONE; /* todo: should be in settings */
@@ -211,6 +229,9 @@ destroy_ldap_db(ldap_db_t **ldap_dbp)
str_destroy(&ldap_db->base);
semaphore_destroy(&ldap_db->conn_semaphore);
+ /* commented out for now, causes named to hang */
+ //dns_view_detach(&ldap_db->view);
+
isc_mem_putanddetach(&ldap_db->mctx, ldap_db, sizeof(ldap_db_t));
*ldap_dbp = NULL;
@@ -230,7 +251,6 @@ new_ldap_instance(ldap_db_t *ldap_db, ldap_instance_t **ldap_instp)
return ISC_R_NOMEMORY;
ZERO_PTR(ldap_inst);
- memset(ldap_inst, 0, sizeof(ldap_instance_t));
ldap_inst->database = ldap_db;
INIT_LINK(ldap_inst, link);
@@ -272,6 +292,102 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
*ldap_instp = NULL;
}
+/* TODO: Delete old zones. */
+isc_result_t
+refresh_zones_from_ldap(ldap_db_t *ldap_db, const char *name,
+ dns_zonemgr_t *zmgr)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ ldap_instance_t *ldap_inst;
+ char *attrs[] = {
+ "idnsName", NULL
+ };
+
+ REQUIRE(ldap_db != NULL);
+ REQUIRE(name != NULL);
+
+ log_debug(2, "refreshing list of zones");
+
+ ldap_inst = get_connection(ldap_db);
+
+ ldap_query(ldap_inst, LDAP_SCOPE_SUBTREE, attrs, 0,
+ "(objectClass=idnsZone)");
+
+ while (next_entry(ldap_inst))
+ CHECK(add_or_modify_zone(ldap_db, get_dn(ldap_inst), name, zmgr));
+
+cleanup:
+ put_connection(ldap_inst);
+
+ log_debug(2, "finished refreshing list of zones");
+
+ return result;
+}
+
+static isc_result_t
+add_or_modify_zone(ldap_db_t *ldap_db, const char *dn, const char *db_name,
+ dns_zonemgr_t *zmgr)
+{
+ isc_result_t result;
+ dns_zone_t *zone;
+ dns_name_t name;
+ const char *argv[2];
+
+ REQUIRE(ldap_db != NULL);
+ REQUIRE(dn != NULL);
+ REQUIRE(db_name != NULL);
+
+ log_func_enter();
+
+ argv[0] = ldapdb_impname;
+ argv[1] = db_name;
+
+ zone = NULL;
+ dns_name_init(&name, NULL);
+
+ CHECK(dn_to_dnsname(ldap_db->mctx, dn, str_buf(ldap_db->base), &name));
+
+ /* If the zone doesn't exist, create it. */
+ result = dns_view_findzone(ldap_db->view, &name, &zone);
+ if (result == ISC_R_NOTFOUND) {
+ CHECK(dns_zone_create(&zone, ldap_db->mctx));
+ dns_zone_setview(zone, ldap_db->view);
+ CHECK(dns_zone_setorigin(zone, &name));
+ dns_zone_setclass(zone, dns_rdataclass_in);
+ dns_zone_settype(zone, dns_zone_master);
+ CHECK(dns_zone_setdbtype(zone, 2, argv));
+ log_func_va("adding zone %s", dn);
+ CHECK(dns_zonemgr_managezone(zmgr, zone));
+ CHECK(dns_view_addzone(ldap_db->view, zone));
+ } else if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
+
+ /*
+ * ACLs:
+ * dns_zone_setqueryacl()
+ * dns_zone_setqueryonacl()
+ * dns_zone_setupdateacl()
+ * dns_zone_setforwardacl()
+ * dns_zone_setxfracl()
+ */
+
+ /*
+ * maybe?
+ * dns_zone_setnotifytype()
+ * dns_zone_setalsonotify()
+ */
+
+cleanup:
+ dns_name_free(&name, ldap_db->mctx);
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+
+ log_func_exit_result(result);
+
+ return result;
+}
+
isc_result_t
ldapdb_rdatalist_findrdatatype(ldapdb_rdatalist_t *rdatalist,
dns_rdatatype_t rdtype,
@@ -322,7 +438,7 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, dns_name_t *name,
/* Max type length definitions, from lib/dns/master.c */
#define MINTSIZ (65535 - 12 - 1 - 2 - 2 - 4 - 2)
- #define TOKENSIZ (8*1024)
+ #define TOKENSIZ (8*1024) /* Could be smaller */
isc_lex_t *lex = NULL;
isc_result_t result;
@@ -340,6 +456,8 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, dns_name_t *name,
REQUIRE(name != NULL);
REQUIRE(rdatalist != NULL);
+ log_func_enter();
+
/*
* Get info from ldap - name, type, class, TTL + value. Try avoid
* ENOMEM as much as possible, if nothing found return ISC_R_NOTFOUND
@@ -357,7 +475,7 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, dns_name_t *name,
INIT_LIST(*rdatalist);
- for (;0;) {
+ for (int i = 0; i < 1; i++) {
/*
* Note: if rdclass_text and rdtype_text are ttl_text are allocated
* free() them correctly before break and before next iteration!
@@ -373,7 +491,8 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, dns_name_t *name,
/* Everything else than IN class is pretty bad */
INSIST(rdclass == dns_rdataclass_in);
- rdtype_text.base = "a";
+ //rdtype_text.base = "a";
+ rdtype_text.base = "ns";
rdtype_text.length = strlen(rdtype_text.base);
result = dns_rdatatype_fromtext(&rdtype, &rdtype_text);
if (result != ISC_R_SUCCESS) {
@@ -391,7 +510,8 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, dns_name_t *name,
}
/* put record in master file format here */
- rdata_text.base = "192.168.1.1";
+ //rdata_text.base = "192.168.1.1";
+ rdata_text.base = "wolverine.englab.brq.redhat.com.";
rdata_text.length = strlen(rdata_text.base);
isc_buffer_init(&lexbuffer, rdata_text.base, rdata_text.length);
@@ -429,6 +549,7 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, dns_name_t *name,
rdata = isc_mem_get(mctx, sizeof(*rdata));
if (rdata == NULL)
goto for_cleanup1;
+ dns_rdata_init(rdata);
rdatamem.length = isc_buffer_usedlength(&target);
rdatamem.base = isc_mem_get(mctx, rdatamem.length);
@@ -452,6 +573,7 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, dns_name_t *name,
rdlist->type = rdtype;
rdlist->ttl = ttl;
APPEND(*rdatalist, rdlist, link);
+ result = ISC_R_SUCCESS;
} else {
/*
* Use strong condition here, we are not allowing
@@ -481,40 +603,11 @@ cleanup:
isc_mem_put(mctx, targetmem, MINTSIZ);
isc_lex_destroy(&lex);
+ log_func_exit_result(result);
+
return result;
}
-void
-get_zone_list(ldap_db_t *ldap_db)
-{
- ldap_instance_t *ldap_inst;
- int i;
- char **vals;
- char *attrs[] = {
- "idnsName", "idnsSOAmName", "idnsSOArName", "idnsSOAserial",
- "idnsSOArefresh", "idnsSOAretry", "idnsSOAexpire",
- "idnsSOAminimum", NULL
- };
- ldap_inst = get_connection(ldap_db);
-
- ldap_query(ldap_inst, LDAP_SCOPE_SUBTREE, attrs, 0,
- "(objectClass=idnsZone)");
-
- log_error("list of ldap values:");
- while (next_entry(ldap_inst)) {
- while (next_attribute(ldap_inst)) {
- vals = get_values(ldap_inst);
- for (i = 0; vals[i] != NULL; i++) {
- log_error("attribute %s: %s",
- get_attribute(ldap_inst),
- vals[i]);
- }
- }
- }
- log_error("end of ldap values");
-
- put_connection(ldap_inst);
-}
static ldap_instance_t *
get_connection(ldap_db_t *ldap_db)
@@ -531,7 +624,7 @@ get_connection(ldap_db_t *ldap_db)
RUNTIME_CHECK(ldap_inst != NULL);
- /* todo: find a clever way to not really require this */
+ /* TODO: find a clever way to not really require this */
str_copy(ldap_inst->base, ldap_db->base);
return ldap_inst;
@@ -540,6 +633,10 @@ get_connection(ldap_db_t *ldap_db)
static void
put_connection(ldap_instance_t *ldap_inst)
{
+ if (ldap_inst->dn) {
+ ldap_memfree(ldap_inst->dn);
+ ldap_inst->dn = NULL;
+ }
if (ldap_inst->values) {
ldap_value_free(ldap_inst->values);
ldap_inst->values = NULL;
@@ -573,16 +670,16 @@ ldap_query(ldap_instance_t *ldap_inst, int scope, char **attrs,
str_vsprintf(ldap_inst->query_string, filter, ap);
va_end(ap);
- log_error("Querying '%s' with '%s'", str_buf(ldap_inst->base),
- str_buf(ldap_inst->query_string));
+ log_debug(2, "querying '%s' with '%s'", str_buf(ldap_inst->base),
+ str_buf(ldap_inst->query_string));
ret = ldap_search_ext_s(ldap_inst->handle, str_buf(ldap_inst->base),
scope, str_buf(ldap_inst->query_string), attrs,
attrsonly, NULL, NULL, NULL, LDAP_NO_LIMIT,
&ldap_inst->result);
- log_error("Result: %d", ldap_count_entries(ldap_inst->handle,
- ldap_inst->result));
+ log_debug(2, "entry count: %d", ldap_count_entries(ldap_inst->handle,
+ ldap_inst->result));
return ISC_R_SUCCESS;
}
@@ -644,6 +741,21 @@ get_values(ldap_instance_t *inst)
return inst->values;
}
+static const char *
+get_dn(ldap_instance_t *inst)
+{
+ if (inst->dn) {
+ ldap_memfree(inst->dn);
+ inst->dn = NULL;
+ }
+
+ if (inst->handle && inst->entry)
+ inst->dn = ldap_get_dn(inst->handle, inst->entry);
+
+ return inst->dn;
+
+}
+
#if 0
static const char *
next_value(ldap_instance_t *inst)