From 970fdfae6a18bf11d423a72973c0f7b589e6f92a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Jun 2017 16:05:31 +1200 Subject: pydsdb_dns: Allow the partition DN to be specified into py_dsdb_dns_lookup 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 Reviewed-by: Garming Sam --- python/samba/samdb.py | 8 ++++++-- source4/dns_server/dns_server.c | 2 +- source4/dns_server/dnsserver_common.c | 17 ++++++++++++++--- source4/dns_server/dnsserver_common.h | 7 +++++++ source4/dns_server/pydns.c | 26 ++++++++++++++++++++------ 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/python/samba/samdb.py b/python/samba/samdb.py index 719bb8b2d90..638fa06ec8a 100644 --- a/python/samba/samdb.py +++ b/python/samba/samdb.py @@ -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''' diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c index 5e9527d1f72..d4f5f27d0bb 100644 --- a/source4/dns_server/dns_server.c +++ b/source4/dns_server/dns_server.c @@ -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; } diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c index 7aac7e22855..fbfa5fa4eae 100644 --- a/source4/dns_server/dnsserver_common.c +++ b/source4/dns_server/dnsserver_common.c @@ -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; diff --git a/source4/dns_server/dnsserver_common.h b/source4/dns_server/dnsserver_common.h index 57d5d9f3c15..293831f0acb 100644 --- a/source4/dns_server/dnsserver_common.h +++ b/source4/dns_server/dnsserver_common.h @@ -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__ */ diff --git a/source4/dns_server/pydns.c b/source4/dns_server/pydns.c index 7fc8f0c8811..cb41faa1441 100644 --- a/source4/dns_server/pydns.c +++ b/source4/dns_server/pydns.c @@ -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, -- cgit v1.2.1