diff options
author | Martin Nagy <mnagy@redhat.com> | 2009-07-28 16:04:28 +0200 |
---|---|---|
committer | Martin Nagy <mnagy@redhat.com> | 2009-08-04 16:50:53 +0200 |
commit | 01827e38817bb7bf1e848a6c627406209c2fe551 (patch) | |
tree | 9428a8fbbca97753ade74e23abf543f3439eeabd | |
parent | f1d0bfb02e771b748e76ca6425a480a6315721ad (diff) | |
download | ldap_driver-01827e38817bb7bf1e848a6c627406209c2fe551.tar.gz ldap_driver-01827e38817bb7bf1e848a6c627406209c2fe551.tar.xz ldap_driver-01827e38817bb7bf1e848a6c627406209c2fe551.zip |
Allow updating of the SOA record
Since the SOA record is special for us, as we store it in multiple LDAP
attributes, it was ignored until now. This is now fixed, but we only
allow changes to the numeric attributes: serial, refresh, retry, expire
and minimum.
Resolves ticket #5
-rw-r--r-- | src/ldap_helper.c | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/src/ldap_helper.c b/src/ldap_helper.c index a85c568..ba774ff 100644 --- a/src/ldap_helper.c +++ b/src/ldap_helper.c @@ -1928,32 +1928,70 @@ cleanup: } /* - * TODO: Handle updating of the SOA record, use the settings to determine if - * this is allowed. + * Modify the SOA record of a zone, where DN of the zone is 'zone_dn'. + * The SOA record is a special case because we need to update serial, + * refresh, retry, expire and minimum attributes for each SOA record. */ static isc_result_t +modify_soa_record(ldap_connection_t *ldap_conn, const char *zone_dn, + dns_rdata_t *rdata) +{ + isc_mem_t *mctx = ldap_conn->database->mctx; + dns_rdata_soa_t soa; + LDAPMod change[5]; + LDAPMod *changep[6] = { + &change[0], &change[1], &change[2], &change[3], &change[4], + NULL + }; + +#define SET_LDAP_MOD(index, name) \ + change[index].mod_op = LDAP_MOD_REPLACE; \ + change[index].mod_type = "idnsSOA" #name; \ + change[index].mod_values = alloca(2 * sizeof(char *)); \ + change[index].mod_values[0] = alloca(sizeof(soa.name) + 1); \ + change[index].mod_values[1] = NULL; \ + snprintf(change[index].mod_values[0], sizeof(soa.name) + 1, "%d", soa.name) + + dns_rdata_tostruct(rdata, (void *)&soa, mctx); + + SET_LDAP_MOD(0, serial); + SET_LDAP_MOD(1, refresh); + SET_LDAP_MOD(2, retry); + SET_LDAP_MOD(3, expire); + SET_LDAP_MOD(4, minimum); + + dns_rdata_freestruct((void *)&soa); + + return ldap_modify_do(ldap_conn, zone_dn, changep); + +#undef SET_LDAP_MOD +} + +static isc_result_t modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst, dns_rdatalist_t *rdlist, int mod_op) { isc_result_t result; - isc_mem_t *mctx; + isc_mem_t *mctx = ldap_inst->mctx; ldap_connection_t *ldap_conn = NULL; ld_string_t *owner_dn = NULL; - LDAPMod *change[3] = { NULL, NULL, NULL }; - - mctx = ldap_inst->mctx; + LDAPMod *change[3] = { NULL }; - if (rdlist->type == dns_rdatatype_soa) { - result = ISC_R_SUCCESS; - goto cleanup; - } + if (rdlist->type == dns_rdatatype_soa && mod_op == LDAP_MOD_DELETE) + return ISC_R_SUCCESS; ldap_conn = get_connection(ldap_inst); CHECK(str_new(mctx, &owner_dn)); CHECK(dnsname_to_dn(ldap_inst, owner, owner_dn)); - CHECK(ldap_rdatalist_to_ldapmod(mctx, rdlist, &change[0], mod_op)); + if (rdlist->type == dns_rdatatype_soa) { + result = modify_soa_record(ldap_conn, str_buf(owner_dn), + HEAD(rdlist->rdata)); + goto cleanup; + } + + CHECK(ldap_rdatalist_to_ldapmod(mctx, rdlist, &change[0], mod_op)); if (mod_op == LDAP_MOD_ADD) { /* for now always replace the ttl on add */ CHECK(ldap_rdttl_to_ldapmod(mctx, rdlist, &change[1])); |