NULL
};
+/*
+ * Get a printable string representation of an isc_result_t
+ */
+static const char *isc_result_str( const isc_result_t result) {
+ switch (result) {
+ case ISC_R_SUCCESS:
+ return "ISC_R_SUCCESS";
+ case ISC_R_NOMEMORY:
+ return "ISC_R_NOMEMORY";
+ case ISC_R_NOPERM:
+ return "ISC_R_NOPERM";
+ case ISC_R_NOSPACE:
+ return "ISC_R_NOSPACE";
+ case ISC_R_NOTFOUND:
+ return "ISC_R_NOTFOUND";
+ case ISC_R_FAILURE:
+ return "ISC_R_FAILURE";
+ case ISC_R_NOTIMPLEMENTED:
+ return "ISC_R_NOTIMPLEMENTED";
+ case ISC_R_NOMORE:
+ return "ISC_R_NOMORE";
+ case ISC_R_INVALIDFILE:
+ return "ISC_R_INVALIDFILE";
+ case ISC_R_UNEXPECTED:
+ return "ISC_R_UNEXPECTED";
+ case ISC_R_FILENOTFOUND:
+ return "ISC_R_FILENOTFOUND";
+ default:
+ return "UNKNOWN";
+ }
+}
+
/*
return the version of the API
*/
#define DNS_PARSE_UINT(ret, str, sep, saveptr) do { \
char *istr = strtok_r(str, sep, &saveptr); \
+ int error = 0;\
if ((istr) == NULL) return false; \
- (ret) = strtoul(istr, NULL, 10); \
+ (ret) = strtoul_err(istr, NULL, 10, &error); \
+ if (error != 0) {\
+ return false;\
+ }\
} while (0)
/*
char *errstring = NULL;
if (dlz_bind9_state != NULL) {
+ dlz_bind9_state->log(ISC_LOG_ERROR,
+ "samba_dlz: dlz_create ignored, #refs=%d",
+ dlz_bind9_state_ref_count);
*dbdata = dlz_bind9_state;
dlz_bind9_state_ref_count++;
return ISC_R_SUCCESS;
return ISC_R_SUCCESS;
failed:
+ state->log(ISC_LOG_INFO,
+ "samba_dlz: FAILED dlz_create call result=%d #refs=%d",
+ result,
+ dlz_bind9_state_ref_count);
talloc_free(state);
return result;
}
_PUBLIC_ void dlz_destroy(void *dbdata)
{
struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
- state->log(ISC_LOG_INFO, "samba_dlz: shutting down");
dlz_bind9_state_ref_count--;
if (dlz_bind9_state_ref_count == 0) {
+ state->log(ISC_LOG_INFO, "samba_dlz: shutting down");
talloc_unlink(state, state->samdb);
talloc_free(state);
dlz_bind9_state = NULL;
+ } else {
+ state->log(ISC_LOG_INFO,
+ "samba_dlz: dlz_destroy called. %d refs remaining.",
+ dlz_bind9_state_ref_count);
}
}
int i;
for (i=0; zone_prefixes[i]; i++) {
+ const char *casefold;
struct ldb_dn *dn;
struct ldb_result *res;
+ struct ldb_val zone_name_val
+ = data_blob_string_const(zone_name);
dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->samdb));
if (dn == NULL) {
return ISC_R_NOMEMORY;
}
- if (!ldb_dn_add_child_fmt(dn, "DC=%s,%s", zone_name, zone_prefixes[i])) {
+ /*
+ * This dance ensures that it is not possible to put
+ * (eg) an extra DC=x, into the DNS name being
+ * queried
+ */
+
+ if (!ldb_dn_add_child_fmt(dn,
+ "DC=X,%s",
+ zone_prefixes[i])) {
talloc_free(tmp_ctx);
return ISC_R_NOMEMORY;
}
+ ret = ldb_dn_set_component(dn,
+ 0,
+ "DC",
+ zone_name_val);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ISC_R_NOMEMORY;
+ }
+
+ /*
+ * Check if this is a plausibly valid DN early
+ * (time spent here will be saved during the
+ * search due to an internal cache)
+ */
+ casefold = ldb_dn_get_casefold(dn);
+
+ if (casefold == NULL) {
+ talloc_free(tmp_ctx);
+ return ISC_R_NOTFOUND;
+ }
+
ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, "objectClass=dnsZone");
if (ret == LDB_SUCCESS) {
if (zone_dn != NULL) {
isc_result_t result;
result = b9_find_zone_dn(state, p, mem_ctx, dn);
if (result == ISC_R_SUCCESS) {
+ const char *casefold;
+
/* we found a zone, now extend the DN to get
* the full DN
*/
bool ret;
if (p == name) {
ret = ldb_dn_add_child_fmt(*dn, "DC=@");
+ if (ret == false) {
+ talloc_free(*dn);
+ return ISC_R_NOMEMORY;
+ }
} else {
- ret = ldb_dn_add_child_fmt(*dn, "DC=%.*s", (int)(p-name)-1, name);
+ struct ldb_val name_val
+ = data_blob_const(name,
+ (int)(p-name)-1);
+
+ if (!ldb_dn_add_child_val(*dn,
+ "DC",
+ name_val)) {
+ talloc_free(*dn);
+ return ISC_R_NOMEMORY;
+ }
}
- if (!ret) {
- talloc_free(*dn);
- return ISC_R_NOMEMORY;
+
+ /*
+ * Check if this is a plausibly valid DN early
+ * (time spent here will be saved during the
+ * search due to an internal cache)
+ */
+ casefold = ldb_dn_get_casefold(*dn);
+
+ if (casefold == NULL) {
+ return ISC_R_NOTFOUND;
}
+
return ISC_R_SUCCESS;
}
p = strchr(p, '.');
dns_clientinfo_t *clientinfo)
#endif
{
+ struct timeval start = timeval_current();
struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
- return b9_find_zone_dn(state, name, NULL, NULL);
+ isc_result_t result = ISC_R_SUCCESS;
+
+ result = b9_find_zone_dn(state, name, NULL, NULL);
+ DNS_COMMON_LOG_OPERATION(
+ isc_result_str(result),
+ &start,
+ NULL,
+ name,
+ NULL);
+ return result;
}
WERROR werr = WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
struct dnsp_DnssrvRpcRecord *records = NULL;
uint16_t num_records = 0, i;
+ struct ldb_val zone_name_val
+ = data_blob_string_const(zone);
+ struct ldb_val name_val
+ = data_blob_string_const(name);
for (i=0; zone_prefixes[i]; i++) {
+ int ret;
+ const char *casefold;
dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->samdb));
if (dn == NULL) {
talloc_free(tmp_ctx);
return ISC_R_NOMEMORY;
}
- if (!ldb_dn_add_child_fmt(dn, "DC=%s,DC=%s,%s", name, zone, zone_prefixes[i])) {
+ /*
+ * This dance ensures that it is not possible to put
+ * (eg) an extra DC=x, into the DNS name being
+ * queried
+ */
+
+ if (!ldb_dn_add_child_fmt(dn,
+ "DC=X,DC=X,%s",
+ zone_prefixes[i])) {
+ talloc_free(tmp_ctx);
+ return ISC_R_NOMEMORY;
+ }
+
+ ret = ldb_dn_set_component(dn,
+ 1,
+ "DC",
+ zone_name_val);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ISC_R_NOMEMORY;
+ }
+
+ ret = ldb_dn_set_component(dn,
+ 0,
+ "DC",
+ name_val);
+ if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return ISC_R_NOMEMORY;
}
+ /*
+ * Check if this is a plausibly valid DN early
+ * (time spent here will be saved during the
+ * search due to an internal cache)
+ */
+ casefold = ldb_dn_get_casefold(dn);
+
+ if (casefold == NULL) {
+ talloc_free(tmp_ctx);
+ return ISC_R_NOTFOUND;
+ }
+
werr = dns_common_wildcard_lookup(state->samdb, tmp_ctx, dn,
&records, &num_records);
if (W_ERROR_IS_OK(werr)) {
#endif
{
struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
- return dlz_lookup_types(state, zone, name, lookup, NULL);
+ isc_result_t result = ISC_R_SUCCESS;
+ struct timeval start = timeval_current();
+
+ result = dlz_lookup_types(state, zone, name, lookup, NULL);
+ DNS_COMMON_LOG_OPERATION(
+ isc_result_str(result),
+ &start,
+ zone,
+ name,
+ NULL);
+
+ return result;
}
_PUBLIC_ isc_result_t dlz_allnodes(const char *zone, void *dbdata,
dns_sdlzallnodes_t *allnodes)
{
+ struct timeval start = timeval_current();
struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
const char *attrs[] = { "dnsRecord", NULL };
- int ret = LDB_SUCCESS, i, j;
- struct ldb_dn *dn;
+ int ret = LDB_ERR_NO_SUCH_OBJECT;
+ size_t i, j;
+ struct ldb_dn *dn = NULL;
struct ldb_result *res;
TALLOC_CTX *tmp_ctx = talloc_new(state);
+ struct ldb_val zone_name_val = data_blob_string_const(zone);
+ isc_result_t result = ISC_R_SUCCESS;
for (i=0; zone_prefixes[i]; i++) {
+ const char *casefold;
+
dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->samdb));
if (dn == NULL) {
talloc_free(tmp_ctx);
- return ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
+ goto exit;
}
- if (!ldb_dn_add_child_fmt(dn, "DC=%s,%s", zone, zone_prefixes[i])) {
+ /*
+ * This dance ensures that it is not possible to put
+ * (eg) an extra DC=x, into the DNS name being
+ * queried
+ */
+
+ if (!ldb_dn_add_child_fmt(dn,
+ "DC=X,%s",
+ zone_prefixes[i])) {
talloc_free(tmp_ctx);
- return ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
+ goto exit;
+ }
+
+ ret = ldb_dn_set_component(dn,
+ 0,
+ "DC",
+ zone_name_val);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ result = ISC_R_NOMEMORY;
+ goto exit;
+ }
+
+ /*
+ * Check if this is a plausibly valid DN early
+ * (time spent here will be saved during the
+ * search due to an internal cache)
+ */
+ casefold = ldb_dn_get_casefold(dn);
+
+ if (casefold == NULL) {
+ result = ISC_R_NOTFOUND;
+ goto exit;
}
ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE,
break;
}
}
- if (ret != LDB_SUCCESS) {
+ if (ret != LDB_SUCCESS || dn == NULL) {
talloc_free(tmp_ctx);
- return ISC_R_NOTFOUND;
+ result = ISC_R_NOTFOUND;
+ goto exit;
}
for (i=0; i<res->count; i++) {
rdn = talloc_strndup(el_ctx, (char *)v->data, v->length);
if (rdn == NULL) {
talloc_free(tmp_ctx);
- return ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
+ goto exit;
}
if (strcmp(rdn, "@") == 0) {
name = b9_format_fqdn(el_ctx, name);
if (name == NULL) {
talloc_free(tmp_ctx);
- return ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
+ goto exit;
}
werr = dns_common_extract(state->samdb, el, el_ctx, &recs, &num_recs);
}
for (j=0; j < num_recs; j++) {
- isc_result_t result;
+ isc_result_t rc;
- result = b9_putnamedrr(state, allnodes, name, &recs[j]);
- if (result != ISC_R_SUCCESS) {
+ rc = b9_putnamedrr(state, allnodes, name, &recs[j]);
+ if (rc != ISC_R_SUCCESS) {
continue;
}
}
}
talloc_free(tmp_ctx);
-
- return ISC_R_SUCCESS;
+exit:
+ DNS_COMMON_LOG_OPERATION(
+ isc_result_str(result),
+ &start,
+ zone,
+ NULL,
+ NULL);
+ return result;
}
*/
_PUBLIC_ isc_result_t dlz_newversion(const char *zone, void *dbdata, void **versionp)
{
+ struct timeval start = timeval_current();
struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
+ isc_result_t result = ISC_R_SUCCESS;
state->log(ISC_LOG_INFO, "samba_dlz: starting transaction on zone %s", zone);
if (state->transaction_token != NULL) {
state->log(ISC_LOG_INFO, "samba_dlz: transaction already started for zone %s", zone);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
state->transaction_token = talloc_zero(state, int);
if (state->transaction_token == NULL) {
- return ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
+ goto exit;
}
if (ldb_transaction_start(state->samdb) != LDB_SUCCESS) {
state->log(ISC_LOG_INFO, "samba_dlz: failed to start a transaction for zone %s", zone);
talloc_free(state->transaction_token);
state->transaction_token = NULL;
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
*versionp = (void *)state->transaction_token;
-
- return ISC_R_SUCCESS;
+exit:
+ DNS_COMMON_LOG_OPERATION(
+ isc_result_str(result),
+ &start,
+ zone,
+ NULL,
+ NULL);
+ return result;
}
/*
_PUBLIC_ void dlz_closeversion(const char *zone, isc_boolean_t commit,
void *dbdata, void **versionp)
{
+ struct timeval start = timeval_current();
struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
+ const char *data = NULL;
+
+ data = commit ? "commit" : "cancel";
if (state->transaction_token != (int *)*versionp) {
state->log(ISC_LOG_INFO, "samba_dlz: transaction not started for zone %s", zone);
- return;
+ goto exit;
}
if (commit) {
if (ldb_transaction_commit(state->samdb) != LDB_SUCCESS) {
state->log(ISC_LOG_INFO, "samba_dlz: failed to commit a transaction for zone %s", zone);
- return;
+ goto exit;
}
state->log(ISC_LOG_INFO, "samba_dlz: committed transaction on zone %s", zone);
} else {
if (ldb_transaction_cancel(state->samdb) != LDB_SUCCESS) {
state->log(ISC_LOG_INFO, "samba_dlz: failed to cancel a transaction for zone %s", zone);
- return;
+ goto exit;
}
state->log(ISC_LOG_INFO, "samba_dlz: cancelling transaction on zone %s", zone);
}
talloc_free(state->transaction_token);
state->transaction_token = NULL;
*versionp = NULL;
+
+exit:
+ DNS_COMMON_LOG_OPERATION(
+ isc_result_str(ISC_R_SUCCESS),
+ &start,
+ zone,
+ NULL,
+ data);
}
WERROR werr;
struct dnsp_DnssrvRpcRecord *records = NULL;
uint16_t num_records = 0, i;
+ struct ldb_val zone_name_val
+ = data_blob_string_const(zone);
- if (!ldb_dn_add_child_fmt(dn, "DC=@,DC=%s", zone)) {
+ /*
+ * This dance ensures that it is not possible to put
+ * (eg) an extra DC=x, into the DNS name being
+ * queried
+ */
+
+ if (!ldb_dn_add_child_val(dn,
+ "DC",
+ zone_name_val)) {
+ talloc_free(tmp_ctx);
+ return false;
+ }
+
+ /*
+ * The SOA record is alwas stored under DC=@,DC=zonename
+ * This can probably be removed when dns_common_lookup makes a fallback
+ * lookup on @ pseudo record
+ */
+
+ if (!ldb_dn_add_child_fmt(dn,"DC=@")) {
talloc_free(tmp_ctx);
return false;
}
const char *type, const char *key, uint32_t keydatalen, uint8_t *keydata,
void *dbdata)
{
+ struct timeval start = timeval_current();
struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
TALLOC_CTX *tmp_ctx;
DATA_BLOB ap_req;
struct gensec_security *gensec_ctx;
struct auth_session_info *session_info;
struct ldb_dn *dn;
- isc_result_t result;
+ isc_result_t rc;
struct ldb_result *res;
const char * attrs[] = { NULL };
uint32_t access_mask;
struct gensec_settings *settings = NULL;
const struct gensec_security_ops **backends = NULL;
size_t idx = 0;
+ isc_boolean_t result = ISC_FALSE;
/* Remove cached credentials, if any */
if (state->session_info) {
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
state->log(ISC_LOG_ERROR, "samba_dlz: no memory");
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
ap_req = data_blob_const(keydata, keydatalen);
if (!server_credentials) {
state->log(ISC_LOG_ERROR, "samba_dlz: failed to init server credentials");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
cli_credentials_set_krb5_context(server_credentials, state->smb_krb5_ctx);
if (keytab_file == NULL) {
state->log(ISC_LOG_ERROR, "samba_dlz: Out of memory!");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
if (!file_exist(keytab_file)) {
if (keytab_file == NULL) {
state->log(ISC_LOG_ERROR, "samba_dlz: Out of memory!");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
}
if (keytab_name == NULL) {
state->log(ISC_LOG_ERROR, "samba_dlz: Out of memory!");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
ret = cli_credentials_set_keytab_name(server_credentials, state->lp, keytab_name,
state->log(ISC_LOG_ERROR, "samba_dlz: failed to obtain server credentials from %s",
keytab_name);
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
talloc_free(keytab_name);
if (settings == NULL) {
state->log(ISC_LOG_ERROR, "samba_dlz: lpcfg_gensec_settings failed");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
backends = talloc_zero_array(settings,
const struct gensec_security_ops *, 3);
if (backends == NULL) {
state->log(ISC_LOG_ERROR, "samba_dlz: talloc_zero_array gensec_security_ops failed");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
settings->backends = backends;
if (!NT_STATUS_IS_OK(nt_status)) {
state->log(ISC_LOG_ERROR, "samba_dlz: failed to start gensec server");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
gensec_set_credentials(gensec_ctx, server_credentials);
if (!NT_STATUS_IS_OK(nt_status)) {
state->log(ISC_LOG_ERROR, "samba_dlz: failed to start spnego");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
/*
if (!NT_STATUS_IS_OK(nt_status)) {
state->log(ISC_LOG_ERROR, "samba_dlz: spnego update failed");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
nt_status = gensec_session_info(gensec_ctx, tmp_ctx, &session_info);
if (!NT_STATUS_IS_OK(nt_status)) {
state->log(ISC_LOG_ERROR, "samba_dlz: failed to create session info");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
/* Get the DN from name */
- result = b9_find_name_dn(state, name, tmp_ctx, &dn);
- if (result != ISC_R_SUCCESS) {
+ rc = b9_find_name_dn(state, name, tmp_ctx, &dn);
+ if (rc != ISC_R_SUCCESS) {
state->log(ISC_LOG_ERROR, "samba_dlz: failed to find name %s", name);
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
/* make sure the dn exists, or find parent dn in case new object is being added */
talloc_free(res);
} else {
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
/* Do ACL check */
"samba_dlz: disallowing update of signer=%s name=%s type=%s error=%s",
signer, name, type, ldb_strerror(ldb_ret));
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
/* Cache session_info, so it can be used in the actual add/delete operation */
if (state->update_name == NULL) {
state->log(ISC_LOG_ERROR, "samba_dlz: memory allocation error");
talloc_free(tmp_ctx);
- return ISC_FALSE;
+ result = ISC_FALSE;
+ goto exit;
}
state->session_info = talloc_steal(state, session_info);
signer, name, tcpaddr, type, key);
talloc_free(tmp_ctx);
- return ISC_TRUE;
+ result = ISC_TRUE;
+exit:
+ DNS_COMMON_LOG_OPERATION(
+ isc_result_str(result),
+ &start,
+ NULL,
+ name,
+ NULL);
+ return result;
}
/*
*/
_PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, void *dbdata, void *version)
{
+ struct timeval start = timeval_current();
struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
struct dnsp_DnssrvRpcRecord *rec;
struct ldb_dn *dn;
- isc_result_t result;
+ isc_result_t result = ISC_R_SUCCESS;
bool tombstoned = false;
bool needs_add = false;
struct dnsp_DnssrvRpcRecord *recs = NULL;
if (state->transaction_token != (void*)version) {
state->log(ISC_LOG_INFO, "samba_dlz: bad transaction version");
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
rec = talloc_zero(state, struct dnsp_DnssrvRpcRecord);
if (rec == NULL) {
- return ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
+ goto exit;
}
- unix_to_nt_time(&t, time(NULL));
- /*
- * convert to seconds (NT time is in 100ns units)
- */
- t /= 10 * 1000 * 1000;
- /*
- * convert to hours
- */
- t /= 3600;
-
rec->rank = DNS_RANK_ZONE;
- rec->dwTimeStamp = (uint32_t)t;
if (!b9_parse(state, rdatastr, rec)) {
state->log(ISC_LOG_INFO, "samba_dlz: failed to parse rdataset '%s'", rdatastr);
talloc_free(rec);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
/* find the DN of the record */
result = b9_find_name_dn(state, name, rec, &dn);
if (result != ISC_R_SUCCESS) {
talloc_free(rec);
- return result;
+ goto exit;
}
/* get any existing records */
state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s",
ldb_dn_get_linearized(dn), win_errstr(werr));
talloc_free(rec);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
if (tombstoned) {
state->log(ISC_LOG_ERROR, "samba_dlz: failed to already %u dnsRecord values for %s",
i, ldb_dn_get_linearized(dn));
talloc_free(rec);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
if (i == num_recs) {
num_recs + 1);
if (recs == NULL) {
talloc_free(rec);
- return ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
+ goto exit;
}
num_recs++;
+
+ if (dns_name_is_static(recs, num_recs)) {
+ rec->dwTimeStamp = 0;
+ } else {
+ unix_to_nt_time(&t, time(NULL));
+ t /= 10 * 1000 * 1000; /* convert to seconds */
+ t /= 3600; /* convert to hours */
+ rec->dwTimeStamp = (uint32_t)t;
+ }
}
recs[i] = *rec;
if (!b9_set_session_info(state, name)) {
talloc_free(rec);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
/* modify the record */
needs_add ? "add" : "modify",
ldb_dn_get_linearized(dn), win_errstr(werr));
talloc_free(rec);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
state->log(ISC_LOG_INFO, "samba_dlz: added rdataset %s '%s'", name, rdatastr);
talloc_free(rec);
- return ISC_R_SUCCESS;
+exit:
+ DNS_COMMON_LOG_OPERATION(
+ isc_result_str(result),
+ &start,
+ NULL,
+ name,
+ rdatastr);
+ return result;
}
/*
*/
_PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, void *dbdata, void *version)
{
+ struct timeval start = timeval_current();
struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
struct dnsp_DnssrvRpcRecord *rec;
struct ldb_dn *dn;
- isc_result_t result;
+ isc_result_t result = ISC_R_SUCCESS;
struct dnsp_DnssrvRpcRecord *recs = NULL;
uint16_t num_recs = 0;
uint16_t i;
if (state->transaction_token != (void*)version) {
state->log(ISC_LOG_ERROR, "samba_dlz: bad transaction version");
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
rec = talloc_zero(state, struct dnsp_DnssrvRpcRecord);
if (rec == NULL) {
- return ISC_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
+ goto exit;
}
if (!b9_parse(state, rdatastr, rec)) {
state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse rdataset '%s'", rdatastr);
talloc_free(rec);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
/* find the DN of the record */
result = b9_find_name_dn(state, name, rec, &dn);
if (result != ISC_R_SUCCESS) {
talloc_free(rec);
- return result;
+ goto exit;
}
/* get the existing records */
&recs, &num_recs, NULL);
if (!W_ERROR_IS_OK(werr)) {
talloc_free(rec);
- return ISC_R_NOTFOUND;
+ result = ISC_R_NOTFOUND;
+ goto exit;
}
for (i=0; i < num_recs; i++) {
}
if (i == num_recs) {
talloc_free(rec);
- return ISC_R_NOTFOUND;
+ result = ISC_R_NOTFOUND;
+ goto exit;
}
if (!b9_set_session_info(state, name)) {
talloc_free(rec);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
/* modify the record */
state->log(ISC_LOG_ERROR, "samba_dlz: failed to modify %s - %s",
ldb_dn_get_linearized(dn), win_errstr(werr));
talloc_free(rec);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
state->log(ISC_LOG_INFO, "samba_dlz: subtracted rdataset %s '%s'", name, rdatastr);
talloc_free(rec);
- return ISC_R_SUCCESS;
+exit:
+ DNS_COMMON_LOG_OPERATION(
+ isc_result_str(result),
+ &start,
+ NULL,
+ name,
+ rdatastr);
+ return result;
}
*/
_PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void *dbdata, void *version)
{
+ struct timeval start = timeval_current();
struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
TALLOC_CTX *tmp_ctx;
struct ldb_dn *dn;
- isc_result_t result;
+ isc_result_t result = ISC_R_SUCCESS;
enum dns_record_type dns_type;
bool found = false;
struct dnsp_DnssrvRpcRecord *recs = NULL;
if (state->transaction_token != (void*)version) {
state->log(ISC_LOG_ERROR, "samba_dlz: bad transaction version");
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
if (!b9_dns_type(type, &dns_type)) {
state->log(ISC_LOG_ERROR, "samba_dlz: bad dns type %s in delete", type);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
tmp_ctx = talloc_new(state);
result = b9_find_name_dn(state, name, tmp_ctx, &dn);
if (result != ISC_R_SUCCESS) {
talloc_free(tmp_ctx);
- return result;
+ goto exit;
}
/* get the existing records */
&recs, &num_recs, NULL);
if (!W_ERROR_IS_OK(werr)) {
talloc_free(tmp_ctx);
- return ISC_R_NOTFOUND;
+ result = ISC_R_NOTFOUND;
+ goto exit;
}
for (ri=0; ri < num_recs; ri++) {
if (!found) {
talloc_free(tmp_ctx);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
if (!b9_set_session_info(state, name)) {
talloc_free(tmp_ctx);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
/* modify the record */
state->log(ISC_LOG_ERROR, "samba_dlz: failed to modify %s - %s",
ldb_dn_get_linearized(dn), win_errstr(werr));
talloc_free(tmp_ctx);
- return ISC_R_FAILURE;
+ result = ISC_R_FAILURE;
+ goto exit;
}
state->log(ISC_LOG_INFO, "samba_dlz: deleted rdataset %s of type %s", name, type);
talloc_free(tmp_ctx);
- return ISC_R_SUCCESS;
+exit:
+ DNS_COMMON_LOG_OPERATION(
+ isc_result_str(result),
+ &start,
+ NULL,
+ name,
+ type);
+ return result;
}