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_dsdb_set_global_schema(PyObject *self, PyObject *args)
123 struct ldb_context *ldb;
125 if (!PyArg_ParseTuple(args, "O", &py_ldb))
128 PyErr_LDB_OR_RAISE(py_ldb, ldb);
130 ret = dsdb_set_global_schema(ldb);
131 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
136 static PyObject *py_dsdb_set_schema_from_ldif(PyObject *self, PyObject *args)
141 struct ldb_context *ldb;
143 if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &pf, &df))
146 PyErr_LDB_OR_RAISE(py_ldb, ldb);
148 result = dsdb_set_schema_from_ldif(ldb, pf, df);
149 PyErr_WERROR_IS_ERR_RAISE(result);
154 static PyObject *py_dsdb_write_prefixes_from_schema_to_ldb(PyObject *self, PyObject *args)
157 struct ldb_context *ldb;
159 struct dsdb_schema *schema;
161 if (!PyArg_ParseTuple(args, "O", &py_ldb))
164 PyErr_LDB_OR_RAISE(py_ldb, ldb);
166 schema = dsdb_get_schema(ldb, NULL);
168 PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on ldb!\n");
172 result = dsdb_write_prefixes_from_schema_to_ldb(NULL, ldb, schema);
173 PyErr_WERROR_IS_ERR_RAISE(result);
178 static PyObject *py_dsdb_set_schema_from_ldb(PyObject *self, PyObject *args)
181 struct ldb_context *ldb;
182 PyObject *py_from_ldb;
183 struct ldb_context *from_ldb;
184 struct dsdb_schema *schema;
186 if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_from_ldb))
189 PyErr_LDB_OR_RAISE(py_ldb, ldb);
191 PyErr_LDB_OR_RAISE(py_from_ldb, from_ldb);
193 schema = dsdb_get_schema(from_ldb, NULL);
195 PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on 'from' ldb!\n");
199 ret = dsdb_reference_schema(ldb, schema, true);
200 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
205 static PyObject *py_dsdb_load_partition_usn(PyObject *self, PyObject *args)
207 PyObject *py_dn, *py_ldb, *result;
209 uint64_t highest_uSN, urgent_uSN;
210 struct ldb_context *ldb;
214 mem_ctx = talloc_new(NULL);
215 if (mem_ctx == NULL) {
220 if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_dn)) {
221 talloc_free(mem_ctx);
225 PyErr_LDB_OR_RAISE(py_ldb, ldb);
227 if (!PyObject_AsDn(mem_ctx, py_dn, ldb, &dn)) {
228 talloc_free(mem_ctx);
232 ret = dsdb_load_partition_usn(ldb, dn, &highest_uSN, &urgent_uSN);
233 if (ret != LDB_SUCCESS) {
234 char *errstr = talloc_asprintf(mem_ctx, "Failed to load partition uSN - %s", ldb_errstring(ldb));
235 PyErr_SetString(PyExc_RuntimeError, errstr);
236 talloc_free(mem_ctx);
240 talloc_free(mem_ctx);
242 result = PyDict_New();
244 PyDict_SetItemString(result, "uSNHighest", PyInt_FromLong((uint64_t)highest_uSN));
245 PyDict_SetItemString(result, "uSNUrgent", PyInt_FromLong((uint64_t)urgent_uSN));
252 return the list of interface IPs we have configured
253 takes an loadparm context, returns a list of IPs in string form
255 Does not return addresses on 127.0.0.0/8
257 static PyObject *py_interface_ips(PyObject *self, PyObject *args)
263 struct loadparm_context *lp_ctx;
264 struct interface *ifaces;
268 if (!PyArg_ParseTuple(args, "Oi", &py_lp_ctx, &all_interfaces))
271 lp_ctx = lp_from_py_object(py_lp_ctx);
272 if (lp_ctx == NULL) {
273 PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
277 tmp_ctx = talloc_new(NULL);
279 load_interfaces(tmp_ctx, lp_interfaces(lp_ctx), &ifaces);
281 count = iface_count(ifaces);
283 /* first count how many are not loopback addresses */
284 for (ifcount = i = 0; i<count; i++) {
285 const char *ip = iface_n_ip(ifaces, i);
286 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
291 pylist = PyList_New(ifcount);
292 for (ifcount = i = 0; i<count; i++) {
293 const char *ip = iface_n_ip(ifaces, i);
294 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
295 PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
299 talloc_free(tmp_ctx);
304 static PyMethodDef py_misc_methods[] = {
305 { "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS,
306 "generate_random_str(len) -> string\n"
307 "Generate random string with specified length." },
308 { "generate_random_password", (PyCFunction)py_generate_random_password, METH_VARARGS,
309 "generate_random_password(min, max) -> string\n"
310 "Generate random password with a length >= min and <= max." },
311 { "unix2nttime", (PyCFunction)py_unix2nttime, METH_VARARGS,
312 "unix2nttime(timestamp) -> nttime" },
313 { "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
315 { "dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS,
317 { "dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction)py_dsdb_write_prefixes_from_schema_to_ldb, METH_VARARGS,
319 { "dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS,
321 { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS,
323 { "dsdb_load_partition_usn", (PyCFunction)py_dsdb_load_partition_usn, METH_VARARGS,
324 "get uSNHighest and uSNUrgent from the partition @REPLCHANGED"},
325 { "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS,
326 "get interface IP address list"},
334 debug_setup_talloc_log();
336 m = Py_InitModule3("glue", py_misc_methods,
337 "Python bindings for miscellaneous Samba functions.");
341 PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
343 /* one of the most annoying things about python scripts is
344 that they don't die when you hit control-C. This fixes that
345 sillyness. As we do all database operations using
346 transactions, this is also safe. In fact, not dying
347 immediately is unsafe as we could end up treating the
348 control-C exception as a different error and try to modify
349 as database incorrectly
351 signal(SIGINT, SIG_DFL);