pydsdb_dns: Allow the partition DN to be specified into py_dsdb_dns_lookup
authorAndrew Bartlett <abartlet@samba.org>
Fri, 9 Jun 2017 04:05:31 +0000 (16:05 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 10 Jun 2017 19:48:20 +0000 (21:48 +0200)
This allows lookups to be confined to one partition, which in turn avoids issues
when running this against MS Windows, which does not match Samba behaviour
for dns_common_zones()

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
python/samba/samdb.py
source4/dns_server/dns_server.c
source4/dns_server/dnsserver_common.c
source4/dns_server/dnsserver_common.h
source4/dns_server/pydns.c

index 719bb8b2d90fe7b65dcdaa4b5cc08be402fc23a3..638fa06ec8a86512f979205f09164afe6e74480c 100644 (file)
@@ -930,9 +930,13 @@ accountExpires: %u
         res = self.search(base="", scope=ldb.SCOPE_BASE, attrs=["serverName"])
         return res[0]["serverName"][0]
 
-    def dns_lookup(self, dns_name):
+    def dns_lookup(self, dns_name, dns_partition=None):
         '''Do a DNS lookup in the database, returns the NDR database structures'''
-        return dsdb_dns.lookup(self, dns_name)
+        if dns_partition is None:
+            return dsdb_dns.lookup(self, dns_name)
+        else:
+            return dsdb_dns.lookup(self, dns_name,
+                                   dns_partition=dns_partition)
 
     def dns_extract(self, el):
         '''Return the NDR database structures from a dnsRecord element'''
index 5e9527d1f72a9488f7cdec1139be5687691031ba..d4f5f27d0bb48a8f8c13a7e7105d766d6fe02793 100644 (file)
@@ -764,7 +764,7 @@ static NTSTATUS dns_server_reload_zones(struct dns_server *dns)
        struct dns_server_zone *new_list = NULL;
        struct dns_server_zone *old_list = NULL;
        struct dns_server_zone *old_zone;
-       status = dns_common_zones(dns->samdb, dns, &new_list);
+       status = dns_common_zones(dns->samdb, dns, NULL, &new_list);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index 7aac7e228559327a37fbb59c769f4ffc97f7721a..fbfa5fa4eaefcdb1222b1511bd96d211932552a0 100644 (file)
@@ -560,6 +560,7 @@ static int dns_common_sort_zones(struct ldb_message **m1, struct ldb_message **m
 
 NTSTATUS dns_common_zones(struct ldb_context *samdb,
                          TALLOC_CTX *mem_ctx,
+                         struct ldb_dn *base_dn,
                          struct dns_server_zone **zones_ret)
 {
        int ret;
@@ -569,9 +570,19 @@ NTSTATUS dns_common_zones(struct ldb_context *samdb,
        struct dns_server_zone *new_list = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
 
-       /* TODO: this search does not work against windows */
-       ret = dsdb_search(samdb, frame, &res, NULL, LDB_SCOPE_SUBTREE,
-                         attrs, DSDB_SEARCH_SEARCH_ALL_PARTITIONS, "(objectClass=dnsZone)");
+       if (base_dn) {
+               /* This search will work against windows */
+               ret = dsdb_search(samdb, frame, &res,
+                                 base_dn, LDB_SCOPE_SUBTREE,
+                                 attrs, 0, "(objectClass=dnsZone)");
+       } else {
+               /* TODO: this search does not work against windows */
+               ret = dsdb_search(samdb, frame, &res, NULL,
+                                 LDB_SCOPE_SUBTREE,
+                                 attrs,
+                                 DSDB_SEARCH_SEARCH_ALL_PARTITIONS,
+                                 "(objectClass=dnsZone)");
+       }
        if (ret != LDB_SUCCESS) {
                TALLOC_FREE(frame);
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
index 57d5d9f3c157b2d5108d43feb3f50b46c8f8d814..293831f0acb3ccc8ab79785cd7af143f8ee70ff7 100644 (file)
@@ -62,7 +62,14 @@ WERROR dns_common_name2dn(struct ldb_context *samdb,
                          TALLOC_CTX *mem_ctx,
                          const char *name,
                          struct ldb_dn **_dn);
+
+/*
+ * For this routine, base_dn is generally NULL.  The exception comes
+ * from the python bindings to support setting ACLs on DNS objects
+ * when joining Windows
+ */
 NTSTATUS dns_common_zones(struct ldb_context *samdb,
                          TALLOC_CTX *mem_ctx,
+                         struct ldb_dn *base_dn,
                          struct dns_server_zone **zones_ret);
 #endif /* __DNSSERVER_COMMON_H__ */
index 7fc8f0c8811fe543ac24cd033328912faecac20f..cb41faa1441213d3078fde536299d5c8de9410ba 100644 (file)
@@ -93,27 +93,40 @@ static int py_dnsp_DnssrvRpcRecord_get_array(PyObject *value,
        return 0;
 }
 
-static PyObject *py_dsdb_dns_lookup(PyObject *self, PyObject *args)
+static PyObject *py_dsdb_dns_lookup(PyObject *self,
+                                   PyObject *args, PyObject *kwargs)
 {
        struct ldb_context *samdb;
        PyObject *py_ldb, *ret, *pydn;
+       PyObject *py_dns_partition = NULL;
        char *dns_name;
        TALLOC_CTX *frame;
        NTSTATUS status;
        WERROR werr;
        struct dns_server_zone *zones_list;
-       struct ldb_dn *dn;
+       struct ldb_dn *dn, *dns_partition = NULL;
        struct dnsp_DnssrvRpcRecord *records;
        uint16_t num_records;
+       const char * const kwnames[] = { "ldb", "dns_name",
+                                        "dns_partition", NULL };
 
-       if (!PyArg_ParseTuple(args, "Os", &py_ldb, &dns_name)) {
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os|O",
+                                        discard_const_p(char *, kwnames),
+                                        &py_ldb, &dns_name,
+                                        &py_dns_partition)) {
                return NULL;
        }
        PyErr_LDB_OR_RAISE(py_ldb, samdb);
 
+       if (py_dns_partition) {
+               PyErr_LDB_DN_OR_RAISE(py_dns_partition,
+                                     dns_partition);
+       }
+
        frame = talloc_stackframe();
 
-       status = dns_common_zones(samdb, frame, &zones_list);
+       status = dns_common_zones(samdb, frame, dns_partition,
+                                 &zones_list);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(frame);
                PyErr_SetNTSTATUS(status);
@@ -210,7 +223,7 @@ static PyObject *py_dsdb_dns_replace(PyObject *self, PyObject *args)
 
        frame = talloc_stackframe();
 
-       status = dns_common_zones(samdb, frame, &zones_list);
+       status = dns_common_zones(samdb, frame, NULL, &zones_list);
        if (!NT_STATUS_IS_OK(status)) {
                PyErr_SetNTSTATUS(status);
                talloc_free(frame);
@@ -305,7 +318,8 @@ static PyObject *py_dsdb_dns_replace_by_dn(PyObject *self, PyObject *args)
 static PyMethodDef py_dsdb_dns_methods[] = {
 
        { "lookup", (PyCFunction)py_dsdb_dns_lookup,
-               METH_VARARGS, "Get the DNS database entries for a DNS name"},
+               METH_VARARGS|METH_KEYWORDS,
+               "Get the DNS database entries for a DNS name"},
        { "replace", (PyCFunction)py_dsdb_dns_replace,
                METH_VARARGS, "Replace the DNS database entries for a DNS name"},
        { "replace_by_dn", (PyCFunction)py_dsdb_dns_replace_by_dn,