2 Unix SMB/CIFS implementation.
3 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
4 Copyright (C) Matthias Dieter Wallnöfer 2009
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "ldb_errors.h"
25 #include "param/param.h"
26 #include "auth/credentials/credentials.h"
27 #include "dsdb/samdb/samdb.h"
28 #include "lib/ldb-samba/ldif_handlers.h"
29 #include "librpc/ndr/libndr.h"
31 #include "lib/ldb/pyldb.h"
32 #include "libcli/util/pyerrors.h"
33 #include "libcli/security/security.h"
34 #include "auth/pyauth.h"
35 #include "param/pyparam.h"
36 #include "auth/credentials/pycredentials.h"
37 #include "lib/socket/netif.h"
38 #include "lib/socket/netif_proto.h"
40 /* FIXME: These should be in a header file somewhere, once we finish moving
41 * away from SWIG .. */
42 #define PyErr_LDB_OR_RAISE(py_ldb, ldb) \
43 /* if (!PyLdb_Check(py_ldb)) { \
44 PyErr_SetString(py_ldb_get_exception(), "Ldb connection object required"); \
47 ldb = PyLdb_AsLdbContext(py_ldb);
49 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
51 if (ret == LDB_ERR_PYTHON_EXCEPTION)
52 return; /* Python exception should already be set, just keep that */
54 PyErr_SetObject(error,
55 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
56 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
59 static PyObject *py_ldb_get_exception(void)
61 PyObject *mod = PyImport_ImportModule("ldb");
65 return PyObject_GetAttrString(mod, "LdbError");
68 static PyObject *py_generate_random_str(PyObject *self, PyObject *args)
73 if (!PyArg_ParseTuple(args, "i", &len))
76 retstr = generate_random_str(NULL, len);
77 ret = PyString_FromString(retstr);
82 static PyObject *py_generate_random_password(PyObject *self, PyObject *args)
87 if (!PyArg_ParseTuple(args, "ii", &min, &max))
90 retstr = generate_random_password(NULL, min, max);
94 ret = PyString_FromString(retstr);
99 static PyObject *py_unix2nttime(PyObject *self, PyObject *args)
103 if (!PyArg_ParseTuple(args, "I", &t))
106 unix_to_nt_time(&nt, t);
108 return PyInt_FromLong((uint64_t)nt);
111 static PyObject *py_set_debug_level(PyObject *self, PyObject *args)
114 if (!PyArg_ParseTuple(args, "I", &level))
116 (DEBUGLEVEL) = level;
120 static PyObject *py_samdb_set_domain_sid(PyLdbObject *self, PyObject *args)
122 PyObject *py_ldb, *py_sid;
123 struct ldb_context *ldb;
127 if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_sid))
130 PyErr_LDB_OR_RAISE(py_ldb, ldb);
132 sid = dom_sid_parse_talloc(NULL, PyString_AsString(py_sid));
134 ret = samdb_set_domain_sid(ldb, sid);
136 PyErr_SetString(PyExc_RuntimeError, "set_domain_sid failed");
142 static PyObject *py_samdb_get_domain_sid(PyLdbObject *self, PyObject *args)
145 struct ldb_context *ldb;
146 const struct dom_sid *sid;
150 if (!PyArg_ParseTuple(args, "O", &py_ldb))
153 PyErr_LDB_OR_RAISE(py_ldb, ldb);
155 sid = samdb_domain_sid(ldb);
157 PyErr_SetString(PyExc_RuntimeError, "samdb_domain_sid failed");
160 retstr = dom_sid_string(NULL, sid);
161 ret = PyString_FromString(retstr);
166 static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
168 PyObject *py_ldb, *py_guid;
171 struct ldb_context *ldb;
172 if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_guid))
175 PyErr_LDB_OR_RAISE(py_ldb, ldb);
176 GUID_from_string(PyString_AsString(py_guid), &guid);
178 ret = samdb_set_ntds_invocation_id(ldb, &guid);
180 PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id failed");
186 static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args)
189 struct ldb_context *ldb;
191 if (!PyArg_ParseTuple(args, "O", &py_ldb))
194 PyErr_LDB_OR_RAISE(py_ldb, ldb);
196 ret = dsdb_set_global_schema(ldb);
197 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
202 static PyObject *py_dsdb_set_schema_from_ldif(PyObject *self, PyObject *args)
207 struct ldb_context *ldb;
209 if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &pf, &df))
212 PyErr_LDB_OR_RAISE(py_ldb, ldb);
214 result = dsdb_set_schema_from_ldif(ldb, pf, df);
215 PyErr_WERROR_IS_ERR_RAISE(result);
220 static PyObject *py_dsdb_write_prefixes_from_schema_to_ldb(PyObject *self, PyObject *args)
223 struct ldb_context *ldb;
225 struct dsdb_schema *schema;
227 if (!PyArg_ParseTuple(args, "O", &py_ldb))
230 PyErr_LDB_OR_RAISE(py_ldb, ldb);
232 schema = dsdb_get_schema(ldb, NULL);
234 PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on ldb!\n");
238 result = dsdb_write_prefixes_from_schema_to_ldb(NULL, ldb, schema);
239 PyErr_WERROR_IS_ERR_RAISE(result);
244 static PyObject *py_dsdb_set_schema_from_ldb(PyObject *self, PyObject *args)
247 struct ldb_context *ldb;
248 PyObject *py_from_ldb;
249 struct ldb_context *from_ldb;
250 struct dsdb_schema *schema;
252 if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_from_ldb))
255 PyErr_LDB_OR_RAISE(py_ldb, ldb);
257 PyErr_LDB_OR_RAISE(py_from_ldb, from_ldb);
259 schema = dsdb_get_schema(from_ldb, NULL);
261 PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on 'from' ldb!\n");
265 ret = dsdb_reference_schema(ldb, schema, true);
266 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
271 static PyObject *py_dsdb_load_partition_usn(PyObject *self, PyObject *args)
273 PyObject *py_dn, *py_ldb, *result;
275 uint64_t highest_uSN, urgent_uSN;
276 struct ldb_context *ldb;
280 mem_ctx = talloc_new(NULL);
281 if (mem_ctx == NULL) {
286 if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_dn)) {
287 talloc_free(mem_ctx);
291 PyErr_LDB_OR_RAISE(py_ldb, ldb);
293 if (!PyObject_AsDn(mem_ctx, py_dn, ldb, &dn)) {
294 talloc_free(mem_ctx);
298 ret = dsdb_load_partition_usn(ldb, dn, &highest_uSN, &urgent_uSN);
299 if (ret != LDB_SUCCESS) {
300 char *errstr = talloc_asprintf(mem_ctx, "Failed to load partition uSN - %s", ldb_errstring(ldb));
301 PyErr_SetString(PyExc_RuntimeError, errstr);
302 talloc_free(mem_ctx);
306 talloc_free(mem_ctx);
308 result = PyDict_New();
310 PyDict_SetItemString(result, "uSNHighest", PyInt_FromLong((uint64_t)highest_uSN));
311 PyDict_SetItemString(result, "uSNUrgent", PyInt_FromLong((uint64_t)urgent_uSN));
317 static PyObject *py_samdb_ntds_invocation_id(PyObject *self, PyObject *args)
319 PyObject *py_ldb, *result;
320 struct ldb_context *ldb;
322 const struct GUID *guid;
324 mem_ctx = talloc_new(NULL);
325 if (mem_ctx == NULL) {
330 if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
331 talloc_free(mem_ctx);
335 PyErr_LDB_OR_RAISE(py_ldb, ldb);
337 guid = samdb_ntds_invocation_id(ldb);
339 PyErr_SetString(PyExc_RuntimeError, "Failed to find NTDS invocation ID");
340 talloc_free(mem_ctx);
344 result = PyString_FromString(GUID_string(mem_ctx, guid));
345 talloc_free(mem_ctx);
350 static PyObject *py_samdb_ntds_objectGUID(PyObject *self, PyObject *args)
352 PyObject *py_ldb, *result;
353 struct ldb_context *ldb;
355 const struct GUID *guid;
357 mem_ctx = talloc_new(NULL);
358 if (mem_ctx == NULL) {
363 if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
364 talloc_free(mem_ctx);
368 PyErr_LDB_OR_RAISE(py_ldb, ldb);
370 guid = samdb_ntds_objectGUID(ldb);
372 PyErr_SetString(PyExc_RuntimeError, "Failed to find NTDS GUID");
373 talloc_free(mem_ctx);
377 result = PyString_FromString(GUID_string(mem_ctx, guid));
378 talloc_free(mem_ctx);
384 return the list of interface IPs we have configured
385 takes an loadparm context, returns a list of IPs in string form
387 Does not return addresses on 127.0.0.0/8
389 static PyObject *py_interface_ips(PyObject *self, PyObject *args)
395 struct loadparm_context *lp_ctx;
396 struct interface *ifaces;
400 if (!PyArg_ParseTuple(args, "Oi", &py_lp_ctx, &all_interfaces))
403 lp_ctx = lp_from_py_object(py_lp_ctx);
404 if (lp_ctx == NULL) {
405 PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
409 tmp_ctx = talloc_new(NULL);
411 load_interfaces(tmp_ctx, lp_interfaces(lp_ctx), &ifaces);
413 count = iface_count(ifaces);
415 /* first count how many are not loopback addresses */
416 for (ifcount = i = 0; i<count; i++) {
417 const char *ip = iface_n_ip(ifaces, i);
418 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
423 pylist = PyList_New(ifcount);
424 for (ifcount = i = 0; i<count; i++) {
425 const char *ip = iface_n_ip(ifaces, i);
426 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
427 PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
431 talloc_free(tmp_ctx);
436 static PyMethodDef py_misc_methods[] = {
437 { "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS,
438 "generate_random_str(len) -> string\n"
439 "Generate random string with specified length." },
440 { "generate_random_password", (PyCFunction)py_generate_random_password, METH_VARARGS,
441 "generate_random_password(min, max) -> string\n"
442 "Generate random password with a length >= min and <= max." },
443 { "unix2nttime", (PyCFunction)py_unix2nttime, METH_VARARGS,
444 "unix2nttime(timestamp) -> nttime" },
445 { "samdb_set_domain_sid", (PyCFunction)py_samdb_set_domain_sid, METH_VARARGS,
446 "samdb_set_domain_sid(samdb, sid)\n"
447 "Set SID of domain to use." },
448 { "samdb_get_domain_sid", (PyCFunction)py_samdb_get_domain_sid, METH_VARARGS,
449 "samdb_get_domain_sid(samdb)\n"
450 "Get SID of domain in use." },
451 { "dsdb_set_ntds_invocation_id", (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
453 { "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
455 { "dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS,
457 { "dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction)py_dsdb_write_prefixes_from_schema_to_ldb, METH_VARARGS,
459 { "dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS,
461 { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS,
463 { "dsdb_load_partition_usn", (PyCFunction)py_dsdb_load_partition_usn, METH_VARARGS,
464 "get uSNHighest and uSNUrgent from the partition @REPLCHANGED"},
465 { "samdb_ntds_invocation_id", (PyCFunction)py_samdb_ntds_invocation_id, METH_VARARGS,
466 "get the NTDS invocation ID GUID as a string"},
467 { "samdb_ntds_objectGUID", (PyCFunction)py_samdb_ntds_objectGUID, METH_VARARGS,
468 "get the NTDS objectGUID as a string"},
469 { "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS,
470 "get interface IP address list"},
478 debug_setup_talloc_log();
480 m = Py_InitModule3("glue", py_misc_methods,
481 "Python bindings for miscellaneous Samba functions.");
485 PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
487 /* one of the most annoying things about python scripts is
488 that they don't die when you hit control-C. This fixes that
489 sillyness. As we do all database operations using
490 transactions, this is also safe. In fact, not dying
491 immediately is unsafe as we could end up treating the
492 control-C exception as a different error and try to modify
493 as database incorrectly
495 signal(SIGINT, SIG_DFL);