mirror of
https://github.com/samba-team/samba.git
synced 2025-02-23 09:57:40 +03:00
dns_server: Add a python module directly accessing DNS records in sam.ldb
Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz>
This commit is contained in:
parent
0504065948
commit
87cd68c1dc
@ -27,7 +27,7 @@ import ldb
|
||||
import time
|
||||
import base64
|
||||
import os
|
||||
from samba import dsdb
|
||||
from samba import dsdb, dsdb_dns
|
||||
from samba.ndr import ndr_unpack, ndr_pack
|
||||
from samba.dcerpc import drsblobs, misc
|
||||
from samba.common import normalise_int32
|
||||
@ -921,3 +921,11 @@ accountExpires: %u
|
||||
'''get the server DN from the rootDSE'''
|
||||
res = self.search(base="", scope=ldb.SCOPE_BASE, attrs=["serverName"])
|
||||
return res[0]["serverName"][0]
|
||||
|
||||
def dns_lookup(self, dns_name):
|
||||
'''Do a DNS lookup in the database, returns the NDR database structures'''
|
||||
return dsdb_dns.lookup(self, dns_name)
|
||||
|
||||
def dns_replace(self, dns_name, new_records):
|
||||
'''Do a DNS modification on the database, sets the NDR database structures'''
|
||||
return dsdb_dns.replace(self, dns_name, new_records)
|
||||
|
225
source4/dns_server/pydns.c
Normal file
225
source4/dns_server/pydns.c
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Python DNS server wrapper
|
||||
|
||||
Copyright (C) 2015 Andrew Bartlett
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include "includes.h"
|
||||
#include <pyldb.h>
|
||||
#include <pytalloc.h>
|
||||
#include "dns_server/dnsserver_common.h"
|
||||
#include "dsdb/samdb/samdb.h"
|
||||
#include "dsdb/common/util.h"
|
||||
#include "librpc/gen_ndr/ndr_dnsp.h"
|
||||
#include "librpc/rpc/pyrpc_util.h"
|
||||
|
||||
/* FIXME: These should be in a header file somewhere */
|
||||
#define PyErr_LDB_OR_RAISE(py_ldb, ldb) \
|
||||
if (!py_check_dcerpc_type(py_ldb, "ldb", "Ldb")) { \
|
||||
PyErr_SetString(py_ldb_get_exception(), "Ldb connection object required"); \
|
||||
return NULL; \
|
||||
} \
|
||||
ldb = pyldb_Ldb_AsLdbContext(py_ldb);
|
||||
|
||||
static PyObject *py_ldb_get_exception(void)
|
||||
{
|
||||
PyObject *mod = PyImport_ImportModule("ldb");
|
||||
if (mod == NULL)
|
||||
return NULL;
|
||||
|
||||
return PyObject_GetAttrString(mod, "LdbError");
|
||||
}
|
||||
|
||||
static PyObject *py_dnsp_DnssrvRpcRecord_get_list(struct dnsp_DnssrvRpcRecord *records,
|
||||
uint16_t num_records)
|
||||
{
|
||||
PyObject *py_dns_list;
|
||||
int i;
|
||||
py_dns_list = PyList_New(num_records);
|
||||
if (py_dns_list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < num_records; i++) {
|
||||
PyObject *py_dns_record;
|
||||
py_dns_record = py_return_ndr_struct("samba.dcerpc.dnsp", "DnssrvRpcRecord", records, &records[i]);
|
||||
PyList_SetItem(py_dns_list, i, py_dns_record);
|
||||
}
|
||||
return py_dns_list;
|
||||
}
|
||||
|
||||
static int py_dnsp_DnssrvRpcRecord_get_array(PyObject *value,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct dnsp_DnssrvRpcRecord **records,
|
||||
uint16_t *num_records)
|
||||
{
|
||||
int i;
|
||||
struct dnsp_DnssrvRpcRecord *recs;
|
||||
PY_CHECK_TYPE(&PyList_Type, value, return -1;);
|
||||
recs = talloc_array(mem_ctx, struct dnsp_DnssrvRpcRecord,
|
||||
PyList_GET_SIZE(value));
|
||||
if (recs == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < PyList_GET_SIZE(value); i++) {
|
||||
bool type_correct;
|
||||
PyObject *item = PyList_GET_ITEM(value, i);
|
||||
type_correct = py_check_dcerpc_type(item, "samba.dcerpc.dnsp", "DnssrvRpcRecord");
|
||||
if (type_correct == false) {
|
||||
return -1;
|
||||
}
|
||||
if (talloc_reference(mem_ctx, pytalloc_get_mem_ctx(item)) == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
recs[i] = *(struct dnsp_DnssrvRpcRecord *)pytalloc_get_ptr(item);
|
||||
}
|
||||
*records = recs;
|
||||
*num_records = PyList_GET_SIZE(value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *py_dsdb_dns_lookup(PyObject *self, PyObject *args)
|
||||
{
|
||||
struct ldb_context *samdb;
|
||||
PyObject *py_ldb;
|
||||
char *dns_name;
|
||||
TALLOC_CTX *frame;
|
||||
NTSTATUS status;
|
||||
WERROR werr;
|
||||
struct dns_server_zone *zones_list;
|
||||
struct ldb_dn *dn;
|
||||
struct dnsp_DnssrvRpcRecord *records;
|
||||
uint16_t num_records;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "Os", &py_ldb, &dns_name)) {
|
||||
return NULL;
|
||||
}
|
||||
PyErr_LDB_OR_RAISE(py_ldb, samdb);
|
||||
|
||||
frame = talloc_stackframe();
|
||||
|
||||
status = dns_common_zones(samdb, frame, &zones_list);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
PyErr_SetNTSTATUS(status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
werr = dns_common_name2dn(samdb, zones_list, frame, dns_name, &dn);
|
||||
if (!W_ERROR_IS_OK(werr)) {
|
||||
PyErr_SetWERROR(werr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
werr = dns_common_lookup(samdb,
|
||||
frame,
|
||||
dn,
|
||||
&records,
|
||||
&num_records,
|
||||
NULL);
|
||||
if (!W_ERROR_IS_OK(werr)) {
|
||||
PyErr_SetWERROR(werr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return py_dnsp_DnssrvRpcRecord_get_list(records, num_records);
|
||||
}
|
||||
|
||||
static PyObject *py_dsdb_dns_replace(PyObject *self, PyObject *args)
|
||||
{
|
||||
struct ldb_context *samdb;
|
||||
PyObject *py_ldb, *py_dns_records;
|
||||
char *dns_name;
|
||||
TALLOC_CTX *frame;
|
||||
NTSTATUS status;
|
||||
WERROR werr;
|
||||
int ret;
|
||||
struct dns_server_zone *zones_list;
|
||||
struct ldb_dn *dn;
|
||||
struct dnsp_DnssrvRpcRecord *records;
|
||||
uint16_t num_records;
|
||||
|
||||
/*
|
||||
* TODO: This is a shocking abuse, but matches what the
|
||||
* internal DNS server does, it should be pushed into
|
||||
* dns_common_replace()
|
||||
*/
|
||||
static const int serial = 110;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OsO", &py_ldb, &dns_name, &py_dns_records)) {
|
||||
return NULL;
|
||||
}
|
||||
PyErr_LDB_OR_RAISE(py_ldb, samdb);
|
||||
|
||||
frame = talloc_stackframe();
|
||||
|
||||
status = dns_common_zones(samdb, frame, &zones_list);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
PyErr_SetNTSTATUS(status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
werr = dns_common_name2dn(samdb, zones_list, frame, dns_name, &dn);
|
||||
if (!W_ERROR_IS_OK(werr)) {
|
||||
PyErr_SetWERROR(werr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = py_dnsp_DnssrvRpcRecord_get_array(py_dns_records,
|
||||
frame,
|
||||
&records, &num_records);
|
||||
if (ret != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
werr = dns_common_replace(samdb,
|
||||
frame,
|
||||
dn,
|
||||
false, /* Not adding a record */
|
||||
serial,
|
||||
records,
|
||||
num_records);
|
||||
if (!W_ERROR_IS_OK(werr)) {
|
||||
PyErr_SetWERROR(werr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef py_dsdb_dns_methods[] = {
|
||||
|
||||
{ "lookup", (PyCFunction)py_dsdb_dns_lookup,
|
||||
METH_VARARGS, "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"},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
void initdsdb_dns(void);
|
||||
|
||||
void initdsdb_dns(void)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
m = Py_InitModule3("dsdb_dns", py_dsdb_dns_methods,
|
||||
"Python bindings for the DNS objects in the directory service databases.");
|
||||
if (m == NULL)
|
||||
return;
|
||||
}
|
@ -53,3 +53,9 @@ bld.SAMBA_LIBRARY('dlz_bind9_for_torture',
|
||||
private_library=True,
|
||||
deps='samba-hostconfig samdb-common gensec popt dnsserver_common',
|
||||
enabled=bld.AD_DC_BUILD_IS_ENABLED())
|
||||
|
||||
|
||||
bld.SAMBA_PYTHON('python_dsdb_dns',
|
||||
source='pydns.c',
|
||||
deps='samdb pyldb-util pyrpc_util dnsserver_common',
|
||||
realname='samba/dsdb_dns.so')
|
||||
|
Loading…
x
Reference in New Issue
Block a user