s4-rpc: dnsserver: dns_name_equal() returns boolean
[samba.git] / source4 / rpc_server / dnsserver / dnsdata.c
index 535996036d312855abdd6f0791fd7fc6e6594454..fb2547ff7ecc4c858e7c477339c3ce97d73a213b 100644 (file)
@@ -204,7 +204,7 @@ char *dns_split_node_name(TALLOC_CTX *tmp_ctx, const char *node_name, const char
                } else {
                        match = 0;
                        for (i=1; i<=zcount; i++) {
-                               if (strcmp(nlist[ncount-i], zlist[zcount-i]) != 0) {
+                               if (strcasecmp(nlist[ncount-i], zlist[zcount-i]) != 0) {
                                        break;
                                }
                                match++;
@@ -236,7 +236,7 @@ char *dns_split_node_name(TALLOC_CTX *tmp_ctx, const char *node_name, const char
 void dnsp_to_dns_copy(TALLOC_CTX *mem_ctx, struct dnsp_DnssrvRpcRecord *dnsp,
                                struct DNS_RPC_RECORD *dns)
 {
-       int len;
+       int i, len;
 
        ZERO_STRUCTP(dns);
 
@@ -323,8 +323,12 @@ void dnsp_to_dns_copy(TALLOC_CTX *mem_ctx, struct dnsp_DnssrvRpcRecord *dnsp,
                break;
 
        case DNS_TYPE_TXT:
-               dns->data.name.len = strlen(dnsp->data.txt);
-               dns->data.name.str = talloc_strdup(mem_ctx, dnsp->data.txt);
+               dns->data.txt.count = dnsp->data.txt.count;
+               dns->data.txt.str = talloc_array(mem_ctx, struct DNS_RPC_NAME, dnsp->data.txt.count);
+               for (i=0; i<dnsp->data.txt.count; i++) {
+                       dns->data.txt.str[i].str = talloc_strdup(mem_ctx, dnsp->data.txt.str[i]);
+                       dns->data.txt.str[i].len = strlen(dnsp->data.txt.str[i]);
+               }
                break;
 
        case DNS_TYPE_AAAA:
@@ -355,7 +359,7 @@ void dnsp_to_dns_copy(TALLOC_CTX *mem_ctx, struct dnsp_DnssrvRpcRecord *dnsp,
 
 struct dnsp_DnssrvRpcRecord *dns_to_dnsp_copy(TALLOC_CTX *mem_ctx, struct DNS_RPC_RECORD *dns)
 {
-       int len;
+       int i, len;
        struct dnsp_DnssrvRpcRecord *dnsp;
 
        dnsp = talloc_zero(mem_ctx, struct dnsp_DnssrvRpcRecord);
@@ -408,9 +412,9 @@ struct dnsp_DnssrvRpcRecord *dns_to_dnsp_copy(TALLOC_CTX *mem_ctx, struct DNS_RP
 
                len = dns->data.soa.NamePrimaryServer.len;
                if (dns->data.soa.NamePrimaryServer.str[len-1] == '.') {
-                       dnsp->data.soa.mname = talloc_strdup(mem_ctx, dns->data.soa.NamePrimaryServer.str);
-               } else {
                        dnsp->data.soa.mname = talloc_strndup(mem_ctx, dns->data.soa.NamePrimaryServer.str, len-1);
+               } else {
+                       dnsp->data.soa.mname = talloc_strdup(mem_ctx, dns->data.soa.NamePrimaryServer.str);
                }
 
                len = dns->data.soa.ZoneAdministratorEmail.len;
@@ -436,7 +440,11 @@ struct dnsp_DnssrvRpcRecord *dns_to_dnsp_copy(TALLOC_CTX *mem_ctx, struct DNS_RP
                break;
 
        case DNS_TYPE_TXT:
-               dnsp->data.txt = talloc_strdup(mem_ctx, dns->data.name.str);
+               dnsp->data.txt.count = dns->data.txt.count;
+               dnsp->data.txt.str = talloc_array(mem_ctx, const char *, dns->data.txt.count);
+               for (i=0; i<dns->data.txt.count; i++) {
+                       dnsp->data.txt.str[i] = talloc_strdup(mem_ctx, dns->data.txt.str[i].str);
+               }
                break;
 
        case DNS_TYPE_AAAA:
@@ -535,7 +543,7 @@ static struct dns_tree *dns_tree_find(struct dns_tree *tree, int ncount, char **
        if (strcmp(tree->name, "@") == 0) {
                start = 0;
        } else {
-               if (strcmp(tree->name, nlist[ncount-1]) != 0) {
+               if (strcasecmp(tree->name, nlist[ncount-1]) != 0) {
                        return NULL;
                }
                start = 1;
@@ -549,7 +557,7 @@ static struct dns_tree *dns_tree_find(struct dns_tree *tree, int ncount, char **
                }
                next = NULL;
                for (j=0; j<node->num_children; j++) {
-                       if (strcmp(nlist[(ncount-1)-i], node->children[j]->name) == 0) {
+                       if (strcasecmp(nlist[(ncount-1)-i], node->children[j]->name) == 0) {
                                next = node->children[j];
                                *match_count = i;
                                break;
@@ -601,7 +609,7 @@ struct dns_tree *dns_build_tree(TALLOC_CTX *mem_ctx, const char *name, struct ld
                if (strcmp(ptr, "@") == 0) {
                        base->data = res->msgs[i];
                        continue;
-               } else if (strcmp(ptr, name) == 0) {
+               } else if (strcasecmp(ptr, name) == 0) {
                        base->data = res->msgs[i];
                        continue;
                }
@@ -617,6 +625,11 @@ struct dns_tree *dns_build_tree(TALLOC_CTX *mem_ctx, const char *name, struct ld
                        goto failed;
                }
 
+               /* If the node is on leaf, then add record data */
+               if (match_count+1 == ncount) {
+                       tree->data = res->msgs[i];
+               }
+
                /* Add missing name components */
                for (level=match_count+1; level<ncount; level++) {
                        if (tree->level == rootcount+1) {
@@ -654,7 +667,7 @@ static void _dns_add_name(TALLOC_CTX *mem_ctx, const char *name, char ***add_nam
        int count = *add_count;
 
        for (i=0; i<count; i++) {
-               if (strcmp(ptr[i], name) == 0) {
+               if (strcasecmp(ptr[i], name) == 0) {
                        return;
                }
        }
@@ -754,6 +767,11 @@ WERROR dns_fill_records_array(TALLOC_CTX *mem_ctx,
                return WERR_OK;
        }
 
+       /* Do not return RR records, if the node has children */
+       if (branch_name != NULL && num_children > 0) {
+               return WERR_OK;
+       }
+
        ptr = ldb_msg_find_attr_as_string(msg, "name", NULL);
        el = ldb_msg_find_element(msg, "dnsRecord");
        if (el == NULL || el->values == 0) {
@@ -850,14 +868,14 @@ int dns_name_compare(const struct ldb_message **m1, const struct ldb_message **m
        if (name1[0] == '@') {
                return -1;
        }
-       if (search_name && strcmp(name1, search_name) == 0) {
+       if (search_name && strcasecmp(name1, search_name) == 0) {
                return -1;
        }
 
        if (name2[0] == '@') {
                return 1;
        }
-       if (search_name && strcmp(name2, search_name) == 0) {
+       if (search_name && strcasecmp(name2, search_name) == 0) {
                return 1;
        }
 
@@ -867,7 +885,7 @@ int dns_name_compare(const struct ldb_message **m1, const struct ldb_message **m
        if (ptr1 == NULL) {
                ptr1 = name1;
        } else {
-               if (search_name && strcmp(ptr1+1, search_name) == 0) {
+               if (search_name && strcasecmp(ptr1+1, search_name) == 0) {
                        ptr1--;
                        while (ptr1 != name1) {
                                ptr1--;
@@ -885,7 +903,7 @@ int dns_name_compare(const struct ldb_message **m1, const struct ldb_message **m
        if (ptr2 == NULL) {
                ptr2 = name2;
        } else {
-               if (search_name && strcmp(ptr2+1, search_name) == 0) {
+               if (search_name && strcasecmp(ptr2+1, search_name) == 0) {
                        ptr2--;
                        while (ptr2 != name2) {
                                ptr2--;
@@ -919,6 +937,9 @@ bool dns_name_equal(const char *name1, const char *name2)
 
 bool dns_record_match(struct dnsp_DnssrvRpcRecord *rec1, struct dnsp_DnssrvRpcRecord *rec2)
 {
+       bool status;
+       int i;
+
        if (rec1->wType != rec2->wType) {
                return false;
        }
@@ -931,14 +952,14 @@ bool dns_record_match(struct dnsp_DnssrvRpcRecord *rec1, struct dnsp_DnssrvRpcRe
                return strcmp(rec1->data.ipv4, rec2->data.ipv4) == 0;
 
        case DNS_TYPE_NS:
-               return dns_name_equal(rec1->data.ns, rec1->data.ns);
+               return dns_name_equal(rec1->data.ns, rec2->data.ns);
 
        case DNS_TYPE_CNAME:
-               return dns_name_equal(rec1->data.cname, rec1->data.cname);
+               return dns_name_equal(rec1->data.cname, rec2->data.cname);
 
        case DNS_TYPE_SOA:
-               return dns_name_equal(rec1->data.soa.mname, rec2->data.soa.mname) == 0 &&
-                       dns_name_equal(rec1->data.soa.rname, rec2->data.soa.rname) == 0 &&
+               return dns_name_equal(rec1->data.soa.mname, rec2->data.soa.mname) &&
+                       dns_name_equal(rec1->data.soa.rname, rec2->data.soa.rname) &&
                        rec1->data.soa.serial == rec2->data.soa.serial &&
                        rec1->data.soa.refresh == rec2->data.soa.refresh &&
                        rec1->data.soa.retry == rec2->data.soa.retry &&
@@ -949,11 +970,19 @@ bool dns_record_match(struct dnsp_DnssrvRpcRecord *rec1, struct dnsp_DnssrvRpcRe
                return dns_name_equal(rec1->data.ptr, rec2->data.ptr);
 
        case DNS_TYPE_MX:
-               return rec1->data.mx.wPriority == rec2->data.srv.wPriority &&
-                       dns_name_equal(rec1->data.mx.nameTarget, rec2->data.srv.nameTarget);
+               return rec1->data.mx.wPriority == rec2->data.mx.wPriority &&
+                       dns_name_equal(rec1->data.mx.nameTarget, rec2->data.mx.nameTarget);
 
        case DNS_TYPE_TXT:
-               return strcmp(rec1->data.txt, rec2->data.txt) == 0;
+               if (rec1->data.txt.count != rec2->data.txt.count) {
+                       return false;
+               }
+               status = true;
+               for (i=0; i<rec1->data.txt.count; i++) {
+                       status = status && (strcmp(rec1->data.txt.str[i],
+                                                  rec2->data.txt.str[i]) == 0);
+               }
+               return status;
 
        case DNS_TYPE_AAAA:
                return strcmp(rec1->data.ipv6, rec2->data.ipv6) == 0;