The branch, master has been updated
       via  a6ed907 dsdb: Handle the case when extended rights string is NULL
       via  c8ac367 s4-drepl: Search for application partitions in addition to 
main ones
       via  4a6410d s4-dnsserver: Check the raised exception with assertRaises
       via  8dca18a s4-dnsserver: Handle the case when the dns name is NULL
       via  6e800bf s4-dnsserver: Build a dns name tree for correct enumeration
       via  0d3aff7 s4-dnsserver: List dns zones matching the search filter
       via  c1b45af s4-dnsserver: Compare two dns names using last uncommon 
name components
       via  c651b4e s4-dnsserver: Set DNS_DP_AUTOCREATED flag for the zone 
information
       via  9abfaa3 samba-tool: Improve the description of dns subcommands.
       via  66121dc samba-tool: Enable comparison of DNS naming contexts in 
ldapcmp
      from  cde73e2 Remove opendir() VFS code from ACL modules.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit a6ed9071b9aa75ff6f3ca2c3b24e6060c4d3f389
Author: Amitay Isaacs <ami...@gmail.com>
Date:   Wed Nov 2 14:34:41 2011 +1100

    dsdb: Handle the case when extended rights string is NULL
    
    Pair-Programmed-With: Andrew Tridgell <tri...@samba.org>
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>
    
    Autobuild-User: Andrew Tridgell <tri...@samba.org>
    Autobuild-Date: Wed Nov  2 07:03:40 CET 2011 on sn-devel-104

commit c8ac3678ad98bc27cf08f3d14bae2aa52318c48d
Author: Amitay Isaacs <ami...@gmail.com>
Date:   Tue Oct 25 15:06:07 2011 +1100

    s4-drepl: Search for application partitions in addition to main ones
    
    To replicate application partitions (e.g. DNS partitions) consult
    msDs-hasMasterNCs attribute as well. Also, make sure we don't add
    same partition twice in the list. hasMasterNCs and msDs-hasMasterNCs
    have domain, configuration and schema partitions common.
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>

commit 4a6410df54fdbc8fb08b104c47010db507443def
Author: Amitay Isaacs <ami...@gmail.com>
Date:   Mon Oct 24 17:37:24 2011 +1100

    s4-dnsserver: Check the raised exception with assertRaises
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>

commit 8dca18a71a813719e1c20b1ff909ed3aae32cf40
Author: Amitay Isaacs <ami...@gmail.com>
Date:   Mon Oct 24 17:22:21 2011 +1100

    s4-dnsserver: Handle the case when the dns name is NULL
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>

commit 6e800bfba708124077defab3c9379db201f4c43c
Author: Amitay Isaacs <ami...@gmail.com>
Date:   Mon Oct 24 17:20:46 2011 +1100

    s4-dnsserver: Build a dns name tree for correct enumeration
    
    The result of EnumRecords/EnumRecords2 RPC calls, is a list of
    dns records that are one level below in the name hierarchy starting
    from the search name. This patch builds a tree of names to get
    the list of records one level below the search names and correctly
    count the number of child records for each of those.
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>

commit 0d3aff732483cf1a48cb9ea6af16537fc11be547
Author: Amitay Isaacs <ami...@gmail.com>
Date:   Mon Oct 24 17:15:27 2011 +1100

    s4-dnsserver: List dns zones matching the search filter
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>

commit c1b45afcf254ed0bbb36b125e440a2731c253e63
Author: Amitay Isaacs <ami...@gmail.com>
Date:   Mon Oct 24 17:07:45 2011 +1100

    s4-dnsserver: Compare two dns names using last uncommon name components
    
    When search_name is not NULL, use the second last component of name
    instead of the last name.
    
    e.g. To compare following two names,
       _ldap._tcp.gc, and
       _ldap._tcp.Default-First-Site-Name._sites.gc
    
    with search_name=NULL, it is gc and gc
    with search_name=gc, it is _tcp and _sites
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>

commit c651b4e99b8bd70eb3be7b3d416c329b4d506f76
Author: Amitay Isaacs <ami...@gmail.com>
Date:   Mon Oct 24 16:54:16 2011 +1100

    s4-dnsserver: Set DNS_DP_AUTOCREATED flag for the zone information
    
    This make the zone information similar to windows (W2K8r2).
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>

commit 9abfaa3bbb45f5217b326d41aca1b68a49ca12ea
Author: Amitay Isaacs <ami...@gmail.com>
Date:   Fri Oct 21 11:27:28 2011 +1100

    samba-tool: Improve the description of dns subcommands.
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>

commit 66121dc89677b4b6e91f8b4cac893d709ab63544
Author: Amitay Isaacs <ami...@gmail.com>
Date:   Tue Sep 20 17:31:24 2011 +1000

    samba-tool: Enable comparison of DNS naming contexts in ldapcmp
    
    Signed-off-by: Andrew Tridgell <tri...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/common/dsdb_access.c                  |   11 +-
 source4/dsdb/repl/drepl_partitions.c               |   19 +-
 source4/rpc_server/dnsserver/dcerpc_dnsserver.c    |  232 ++++++++++------
 source4/rpc_server/dnsserver/dnsdata.c             |  306 ++++++++++++++++----
 source4/rpc_server/dnsserver/dnsserver.h           |   12 +-
 source4/rpc_server/dnsserver/dnsutils.c            |    2 +-
 source4/scripting/python/samba/netcmd/dns.py       |   20 +-
 source4/scripting/python/samba/netcmd/ldapcmp.py   |   11 +-
 .../python/samba/tests/dcerpc/dnsserver.py         |   24 +-
 9 files changed, 458 insertions(+), 179 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/common/dsdb_access.c 
b/source4/dsdb/common/dsdb_access.c
index b8784fc..fd75e77 100644
--- a/source4/dsdb/common/dsdb_access.c
+++ b/source4/dsdb/common/dsdb_access.c
@@ -152,9 +152,12 @@ int dsdb_check_access_on_dn(struct ldb_context *ldb,
                "objectSid",
                NULL
        };
-       NTSTATUS status = GUID_from_string(ext_right, &guid);
-       if (!NT_STATUS_IS_OK(status)) {
-               return LDB_ERR_OPERATIONS_ERROR;
+
+       if (ext_right != NULL) {
+               NTSTATUS status = GUID_from_string(ext_right, &guid);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
        }
 
        ret = dsdb_search_dn(ldb, mem_ctx, &acl_res, dn, acl_attrs, 
DSDB_SEARCH_SHOW_DELETED);
@@ -168,6 +171,6 @@ int dsdb_check_access_on_dn(struct ldb_context *ldb,
                                                token,
                                                dn,
                                                access_mask,
-                                               &guid);
+                                               ext_right ? &guid : NULL);
 }
 
diff --git a/source4/dsdb/repl/drepl_partitions.c 
b/source4/dsdb/repl/drepl_partitions.c
index f2d4b13..70f9971 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -41,7 +41,7 @@
 WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 {
        WERROR status;
-       static const char *attrs[] = { "hasMasterNCs", "hasPartialReplicaNCs", 
"msDS-HasFullReplicaNCs", NULL };
+       static const char *attrs[] = { "hasMasterNCs", "msDs-hasMasterNCs", 
"hasPartialReplicaNCs", "msDS-HasFullReplicaNCs", NULL };
        unsigned int a;
        int ret;
        TALLOC_CTX *tmp_ctx;
@@ -75,7 +75,8 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
                }
                for (i=0; i<el->num_values; i++) {
                        struct ldb_dn *pdn;
-                       struct dreplsrv_partition *p;
+                       struct dreplsrv_partition *p, *tp;
+                       bool found;
 
                        pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, 
&el->values[i]);
                        if (pdn == NULL) {
@@ -98,8 +99,20 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
                                p->rodc_replica = true;
                        }
 
-                       DLIST_ADD(s->partitions, p);
+                       /* Do not add partitions more than once */
+                       found = false;
+                       for (tp = s->partitions; tp; tp = tp->next) {
+                               if (ldb_dn_compare(tp->dn, p->dn) == 0) {
+                                       found = true;
+                                       break;
+                               }
+                       }
+                       if (found) {
+                               talloc_free(p);
+                               continue;
+                       }
 
+                       DLIST_ADD(s->partitions, p);
                        DEBUG(2, ("dreplsrv_partition[%s] loaded\n", 
ldb_dn_get_linearized(p->dn)));
                }
        }
diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c 
b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
index 66162c5..fd0c977 100644
--- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
+++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
@@ -1103,8 +1103,9 @@ static WERROR dnsserver_complex_operate_server(struct 
dnsserver_state *dsstate,
                                        union DNSSRV_RPC_UNION *rout)
 {
        int valid_operation = 0;
-       struct dnsserver_zone *z;
-       bool list_zones;
+       struct dnsserver_zone *z, **zlist;
+       int zcount;
+       bool found;
        int i;
 
        if (strcasecmp(operation, "QueryDwordProperty") == 0) {
@@ -1119,45 +1120,112 @@ static WERROR dnsserver_complex_operate_server(struct 
dnsserver_state *dsstate,
                if (typeid_in != DNSSRV_TYPEID_DWORD) {
                        return WERR_DNS_ERROR_INVALID_PROPERTY;
                }
-               if ((rin->Dword & (DNS_ZONE_REQUEST_PRIMARY |
-                                       DNS_ZONE_REQUEST_FORWARD |
-                                       DNS_ZONE_REQUEST_DS)) > 0) {
-                       list_zones = true;
-               } else {
-                       list_zones = false;
+
+               zcount = 0;
+               zlist = talloc_zero_array(mem_ctx, struct dnsserver_zone *, 0);
+               for (z = dsstate->zones; z; z = z->next) {
+                       found = false;
+                       if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
+                               if (z->zoneinfo->dwZoneType & 
DNS_ZONE_TYPE_PRIMARY) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
+                               if (z->zoneinfo->dwZoneType & 
DNS_ZONE_TYPE_SECONDARY) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
+                               if (z->zoneinfo->dwZoneType & 
DNS_ZONE_TYPE_CACHE) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
+                               if (z->zoneinfo->fAutoCreated || 
z->zoneinfo->dwDpFlags & DNS_DP_AUTOCREATED) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
+                               if (!(z->zoneinfo->Flags & 
DNS_RPC_ZONE_REVERSE)) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
+                               if (z->zoneinfo->Flags & DNS_RPC_ZONE_REVERSE) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
+                               if (z->zoneinfo->dwZoneType & 
DNS_ZONE_TYPE_FORWARDER) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
+                               if (z->zoneinfo->dwZoneType & 
DNS_ZONE_TYPE_STUB) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_DS) {
+                               if (z->zoneinfo->Flags & 
DNS_RPC_ZONE_DSINTEGRATED) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
+                               if (!(z->zoneinfo->Flags & 
DNS_RPC_ZONE_DSINTEGRATED)) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
+                               if (z->zoneinfo->dwDpFlags & 
DNS_DP_DOMAIN_DEFAULT) {
+                                       found = true;
+                               }
+                       }
+                       if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
+                               if (z->zoneinfo->dwDpFlags & 
DNS_DP_FOREST_DEFAULT) {
+                                       found = true;
+                               }
+                       }
+
+                       if (found) {
+                               zlist = talloc_realloc(mem_ctx, zlist, struct 
dnsserver_zone *, zcount+1);
+                               zlist[zcount] = z;
+                               zcount++;
+                       }
+
                }
 
                if (client_version == DNS_CLIENT_VERSION_W2K) {
                        *typeid_out = DNSSRV_TYPEID_ZONE_LIST_W2K;
                        rout->ZoneListW2K = talloc_zero(mem_ctx, struct 
DNS_RPC_ZONE_LIST_W2K);
 
-                       if (!list_zones) {
+                       if (zcount == 0) {
                                rout->ZoneListW2K->dwZoneCount = 0;
                                rout->ZoneListW2K->ZoneArray = NULL;
 
                                return WERR_OK;
                        }
 
-                       rout->ZoneListW2K->ZoneArray = 
talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, dsstate->zones_count);
+                       rout->ZoneListW2K->ZoneArray = 
talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, zcount);
                        if (rout->ZoneListW2K->ZoneArray == NULL) {
+                               talloc_free(zlist);
                                return WERR_NOMEM;
                        }
 
-                       for (z = dsstate->zones, i=0; z; z = z->next, i++) {
+                       for (i=0; i<zcount; i++) {
                                rout->ZoneListW2K->ZoneArray[i] = 
talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
 
-                               rout->ZoneListW2K->ZoneArray[i]->pszZoneName = 
talloc_strdup(mem_ctx, z->name);
-                               rout->ZoneListW2K->ZoneArray[i]->Flags = 
z->zoneinfo->Flags;
-                               rout->ZoneListW2K->ZoneArray[i]->ZoneType = 
z->zoneinfo->dwZoneType;
-                               rout->ZoneListW2K->ZoneArray[i]->Version = 
z->zoneinfo->Version;
+                               rout->ZoneListW2K->ZoneArray[i]->pszZoneName = 
talloc_strdup(mem_ctx, zlist[i]->name);
+                               rout->ZoneListW2K->ZoneArray[i]->Flags = 
zlist[i]->zoneinfo->Flags;
+                               rout->ZoneListW2K->ZoneArray[i]->ZoneType = 
zlist[i]->zoneinfo->dwZoneType;
+                               rout->ZoneListW2K->ZoneArray[i]->Version = 
zlist[i]->zoneinfo->Version;
                        }
-                       rout->ZoneListW2K->dwZoneCount = dsstate->zones_count;
+                       rout->ZoneListW2K->dwZoneCount = zcount;
 
                } else {
                        *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
                        rout->ZoneList = talloc_zero(mem_ctx, struct 
DNS_RPC_ZONE_LIST_DOTNET);
 
-                       if (!list_zones) {
+                       if (zcount == 0) {
                                rout->ZoneList->dwRpcStructureVersion = 1;
                                rout->ZoneList->dwZoneCount = 0;
                                rout->ZoneList->ZoneArray = NULL;
@@ -1165,25 +1233,27 @@ static WERROR dnsserver_complex_operate_server(struct 
dnsserver_state *dsstate,
                                return WERR_OK;
                        }
 
-                       rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, 
struct DNS_RPC_ZONE_DOTNET *, dsstate->zones_count);
+                       rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, 
struct DNS_RPC_ZONE_DOTNET *, zcount);
                        if (rout->ZoneList->ZoneArray == NULL) {
+                               talloc_free(zlist);
                                return WERR_NOMEM;
                        }
 
-                       for (z = dsstate->zones, i=0; z; z = z->next, i++) {
+                       for (i=0; i<zcount; i++) {
                                rout->ZoneList->ZoneArray[i] = 
talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
 
                                
rout->ZoneList->ZoneArray[i]->dwRpcStructureVersion = 1;
-                               rout->ZoneList->ZoneArray[i]->pszZoneName = 
talloc_strdup(mem_ctx, z->name);
-                               rout->ZoneList->ZoneArray[i]->Flags = 
z->zoneinfo->Flags;
-                               rout->ZoneList->ZoneArray[i]->ZoneType = 
z->zoneinfo->dwZoneType;
-                               rout->ZoneList->ZoneArray[i]->Version = 
z->zoneinfo->Version;
-                               rout->ZoneList->ZoneArray[i]->dwDpFlags = 
z->zoneinfo->dwDpFlags;
-                               rout->ZoneList->ZoneArray[i]->pszDpFqdn = 
talloc_strdup(mem_ctx, z->zoneinfo->pszDpFqdn);
+                               rout->ZoneList->ZoneArray[i]->pszZoneName = 
talloc_strdup(mem_ctx, zlist[i]->name);
+                               rout->ZoneList->ZoneArray[i]->Flags = 
zlist[i]->zoneinfo->Flags;
+                               rout->ZoneList->ZoneArray[i]->ZoneType = 
zlist[i]->zoneinfo->dwZoneType;
+                               rout->ZoneList->ZoneArray[i]->Version = 
zlist[i]->zoneinfo->Version;
+                               rout->ZoneList->ZoneArray[i]->dwDpFlags = 
zlist[i]->zoneinfo->dwDpFlags;
+                               rout->ZoneList->ZoneArray[i]->pszDpFqdn = 
talloc_strdup(mem_ctx, zlist[i]->zoneinfo->pszDpFqdn);
                        }
                        rout->ZoneList->dwRpcStructureVersion = 1;
-                       rout->ZoneList->dwZoneCount = dsstate->zones_count;
+                       rout->ZoneList->dwZoneCount = zcount;
                }
+               talloc_free(zlist);
                return WERR_OK;
        } else if (strcasecmp(operation, "EnumZones2") == 0) {
                valid_operation = true;
@@ -1359,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);
@@ -1387,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);
@@ -1417,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);
@@ -1460,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]);
@@ -1545,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);
diff --git a/source4/rpc_server/dnsserver/dnsdata.c 
b/source4/rpc_server/dnsserver/dnsdata.c
index 486290d..d9e708f 100644
--- a/source4/rpc_server/dnsserver/dnsdata.c
+++ b/source4/rpc_server/dnsserver/dnsdata.c
@@ -128,6 +128,10 @@ int dns_split_name_components(TALLOC_CTX *tmp_ctx, const 
char *name, char ***com
        char *str = NULL, *ptr, **list;
        int count = 0;
 
+       if (name == NULL) {
+               return 0;
+       }
+
        str = talloc_strdup(tmp_ctx, name);
        if (!str) {
                goto failed;
@@ -462,6 +466,187 @@ struct dnsp_DnssrvRpcRecord *dns_to_dnsp_copy(TALLOC_CTX 
*mem_ctx, struct DNS_RP
 }
 
 
+/* Intialize tree with given name as the root */
+static struct dns_tree *dns_tree_init(TALLOC_CTX *mem_ctx, const char *name, 
void *data)
+{
+       struct dns_tree *tree;
+
+       tree = talloc_zero(mem_ctx, struct dns_tree);
+       if (tree == NULL) {
+               return NULL;
+       }
+
+       tree->name = talloc_strdup(tree, name);
+       if (tree->name == NULL) {
+               talloc_free(tree);
+               return NULL;
+       }
+
+       tree->data = data;
+
+       return tree;
+}
+
+
+/* Add a child one level below */
+static struct dns_tree *dns_tree_add(struct dns_tree *tree, const char *name, 
void *data)
+{
+       struct dns_tree *node;
+
+       node = talloc_zero(tree, struct dns_tree);
+       if (node == NULL) {
+               return NULL;
+       }
+
+       node->name = talloc_strdup(tree, name);
+       if (node->name == NULL) {
+               talloc_free(node);
+               return NULL;
+       }
+       node->level = tree->level + 1;
+       node->num_children = 0;
+       node->children = NULL;
+       node->data = data;
+
+       if (tree->num_children == 0) {
+               tree->children = talloc_zero(tree, struct dns_tree *);
+       } else {
+               tree->children = talloc_realloc(tree, tree->children, struct 
dns_tree *,
+                                               tree->num_children+1);
+       }
+       if (tree->children == NULL) {
+               talloc_free(node);
+               return NULL;
+       }
+       tree->children[tree->num_children] = node;


-- 
Samba Shared Repository

Reply via email to