summaryrefslogtreecommitdiff
path: root/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/rpc_server/dnsserver/dcerpc_dnsserver.c')
-rw-r--r--source4/rpc_server/dnsserver/dcerpc_dnsserver.c110
1 files changed, 51 insertions, 59 deletions
diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
index 93f315b857..fd0c97795a 100644
--- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
+++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
@@ -1429,7 +1429,7 @@ static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
for (i=0; i<res->count; i++) {
status = dns_fill_records_array(tmp_ctx, NULL, record_type,
select_flag, NULL,
- res->msgs[i], recs,
+ res->msgs[i], 0, recs,
&add_names, &add_count);
if (!W_ERROR_IS_OK(status)) {
talloc_free(tmp_ctx);
@@ -1457,7 +1457,7 @@ static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
}
status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
select_flag, rname,
- res->msgs[0], recs,
+ res->msgs[0], 0, recs,
NULL, NULL);
talloc_free(rname);
talloc_free(res);
@@ -1487,16 +1487,16 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
struct DNS_RPC_RECORDS_ARRAY **buffer)
{
TALLOC_CTX *tmp_ctx;
- char *name, *branch_name;
+ char *name;
const char * const attrs[] = { "name", "dnsRecord", NULL };
struct ldb_result *res;
struct DNS_RPC_RECORDS_ARRAY *recs;
char **add_names = NULL;
- const char *ptr;
char *rname;
int add_count = 0;
int i, ret, len;
WERROR status;
+ struct dns_tree *tree, *base, *node;
tmp_ctx = talloc_new(mem_ctx);
W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
@@ -1530,81 +1530,73 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
(ldb_qsort_cmp_fn_t)dns_name_compare);
- /* Add the parent record with blank name */
- ptr = ldb_msg_find_attr_as_string(res->msgs[0], "name", NULL);
- if (strcmp(ptr, name) == 0 || strcmp(ptr, "@") == 0) {
- /* parent record found */
- if (select_flag & DNS_RPC_VIEW_ONLY_CHILDREN) {
- status = WERR_OK;
- } else {
- status = dns_fill_records_array(tmp_ctx, z, record_type,
- select_flag, NULL,
- res->msgs[0], recs,
- &add_names, &add_count);
- }
- i = 1;
+ /* Build a tree of name components from dns name */
+ if (strcmp(name, z->name) == 0) {
+ tree = dns_build_tree(tmp_ctx, "@", res);
} else {
- /* parent record not in the search */
- if (select_flag & DNS_RPC_VIEW_ONLY_CHILDREN) {
- status = WERR_OK;
- } else {
- status = dns_fill_records_array(tmp_ctx, z, record_type,
- select_flag, NULL,
- NULL, recs,
- &add_names, &add_count);
- }
- i = 0;
+ tree = dns_build_tree(tmp_ctx, name, res);
}
+ W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
- if (!W_ERROR_IS_OK(status)) {
- talloc_free(tmp_ctx);
- return status;
+ /* Find the parent record in the tree */
+ base = tree;
+ while (base->level != -1) {
+ base = base->children[0];
+ }
+
+ /* Add the parent record with blank name */
+ if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
+ status = dns_fill_records_array(tmp_ctx, z, record_type,
+ select_flag, NULL,
+ base->data, 0,
+ recs, &add_names, &add_count);
+ if (!W_ERROR_IS_OK(status)) {
+ talloc_free(tmp_ctx);
+ return status;
+ }
}
/* Add all the children records */
if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
- for ( ; i<res->count; i++) {
- char *name2;
- const char *tmp_str;
-
- ptr = ldb_msg_find_attr_as_string(res->msgs[i], "name", NULL);
- name2 = dns_split_node_name(tmp_ctx, ptr, name);
- tmp_str = strrchr(name2, '.');
- if (tmp_str == NULL) {
- branch_name = talloc_strdup(tmp_ctx, name2);
- } else {
- /* Skip '.' */
- branch_name = talloc_strdup(tmp_ctx, &tmp_str[1]);
- }
- talloc_free(name2);
+ for (i=0; i<base->num_children; i++) {
+ node = base->children[i];
status = dns_fill_records_array(tmp_ctx, z, record_type,
- select_flag, branch_name,
- res->msgs[i], recs,
- &add_names, &add_count);
+ select_flag, node->name,
+ node->data, node->num_children,
+ recs, &add_names, &add_count);
if (!W_ERROR_IS_OK(status)) {
talloc_free(tmp_ctx);
return status;
}
-
- talloc_free(branch_name);
}
}
- talloc_free(res);
+ talloc_free(res);
+ talloc_free(tree);
talloc_free(name);
/* Add any additional records */
if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
for (i=0; i<add_count; i++) {
- name = dns_split_node_name(tmp_ctx, add_names[i], z->name);
- ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
- LDB_SCOPE_ONELEVEL, attrs,
- "(&(objectClass=dnsNode)(name=%s))", name);
- talloc_free(name);
- if (ret != LDB_SUCCESS || res->count == 0) {
- talloc_free(res);
- continue;
+ struct dnsserver_zone *z2;
+
+ /* Search all the available zones for additional name */
+ for (z2 = dsstate->zones; z2; z2 = z2->next) {
+ name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
+ ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
+ LDB_SCOPE_ONELEVEL, attrs,
+ "(&(objectClass=dnsNode)(name=%s))", name);
+ talloc_free(name);
+ if (ret != LDB_SUCCESS) {
+ continue;
+ }
+ if (res->count == 1) {
+ break;
+ } else {
+ talloc_free(res);
+ continue;
+ }
}
len = strlen(add_names[i]);
@@ -1615,7 +1607,7 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
}
status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
select_flag, rname,
- res->msgs[0], recs,
+ res->msgs[0], 0, recs,
NULL, NULL);
talloc_free(rname);
talloc_free(res);