s4-python: Move samdb_server_site_name to dsdb module.
[samba.git] / source4 / scripting / python / pyglue.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
4    Copyright (C) Matthias Dieter Wallnöfer          2009
5    
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.
10    
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.
15    
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/>.
18 */
19
20 #include <Python.h>
21 #include "includes.h"
22 #include "ldb.h"
23 #include "ldb_errors.h"
24 #include "ldb_wrap.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"
30 #include "version.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"
39
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"); \
45                 return NULL; \
46         } */\
47         ldb = PyLdb_AsLdbContext(py_ldb);
48
49 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
50 {
51         if (ret == LDB_ERR_PYTHON_EXCEPTION)
52                 return; /* Python exception should already be set, just keep that */
53
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)));
57 }
58
59 static PyObject *py_ldb_get_exception(void)
60 {
61         PyObject *mod = PyImport_ImportModule("ldb");
62         if (mod == NULL)
63                 return NULL;
64
65         return PyObject_GetAttrString(mod, "LdbError");
66 }
67
68 static PyObject *py_generate_random_str(PyObject *self, PyObject *args)
69 {
70         int len;
71         PyObject *ret;
72         char *retstr;
73         if (!PyArg_ParseTuple(args, "i", &len))
74                 return NULL;
75
76         retstr = generate_random_str(NULL, len);
77         ret = PyString_FromString(retstr);
78         talloc_free(retstr);
79         return ret;
80 }
81
82 static PyObject *py_generate_random_password(PyObject *self, PyObject *args)
83 {
84         int min, max;
85         PyObject *ret;
86         char *retstr;
87         if (!PyArg_ParseTuple(args, "ii", &min, &max))
88                 return NULL;
89
90         retstr = generate_random_password(NULL, min, max);
91         if (retstr == NULL) {
92                 return NULL;
93         }
94         ret = PyString_FromString(retstr);
95         talloc_free(retstr);
96         return ret;
97 }
98
99 static PyObject *py_unix2nttime(PyObject *self, PyObject *args)
100 {
101         time_t t;
102         NTTIME nt;
103         if (!PyArg_ParseTuple(args, "I", &t))
104                 return NULL;
105
106         unix_to_nt_time(&nt, t);
107
108         return PyInt_FromLong((uint64_t)nt);
109 }
110
111 static PyObject *py_set_debug_level(PyObject *self, PyObject *args)
112 {
113         unsigned level;
114         if (!PyArg_ParseTuple(args, "I", &level))
115                 return NULL;
116         (DEBUGLEVEL) = level;
117         Py_RETURN_NONE;
118 }
119
120 static PyObject *py_ldb_set_session_info(PyObject *self, PyObject *args)
121 {
122         PyObject *py_session_info, *py_ldb;
123         struct auth_session_info *info;
124         struct ldb_context *ldb;
125         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_session_info))
126                 return NULL;
127
128         PyErr_LDB_OR_RAISE(py_ldb, ldb);
129         /*if (!PyAuthSession_Check(py_session_info)) {
130                 PyErr_SetString(PyExc_TypeError, "Expected session info object");
131                 return NULL;
132         }*/
133
134         info = PyAuthSession_AsSession(py_session_info);
135
136         ldb_set_opaque(ldb, "sessionInfo", info);
137
138         Py_RETURN_NONE;
139 }
140
141 static PyObject *py_ldb_set_credentials(PyObject *self, PyObject *args)
142 {
143         PyObject *py_creds, *py_ldb;
144         struct cli_credentials *creds;
145         struct ldb_context *ldb;
146         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_creds))
147                 return NULL;
148
149         PyErr_LDB_OR_RAISE(py_ldb, ldb);
150         
151         creds = cli_credentials_from_py_object(py_creds);
152         if (creds == NULL) {
153                 PyErr_SetString(PyExc_TypeError, "Expected credentials object");
154                 return NULL;
155         }
156
157         ldb_set_opaque(ldb, "credentials", creds);
158
159         Py_RETURN_NONE;
160 }
161
162 static PyObject *py_ldb_set_loadparm(PyObject *self, PyObject *args)
163 {
164         PyObject *py_lp_ctx, *py_ldb;
165         struct loadparm_context *lp_ctx;
166         struct ldb_context *ldb;
167         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_lp_ctx))
168                 return NULL;
169
170         PyErr_LDB_OR_RAISE(py_ldb, ldb);
171
172         lp_ctx = lp_from_py_object(py_lp_ctx);
173         if (lp_ctx == NULL) {
174                 PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
175                 return NULL;
176         }
177
178         ldb_set_opaque(ldb, "loadparm", lp_ctx);
179
180         Py_RETURN_NONE;
181 }
182
183 static PyObject *py_ldb_set_utf8_casefold(PyObject *self, PyObject *args)
184 {
185         PyObject *py_ldb;
186         struct ldb_context *ldb;
187
188         if (!PyArg_ParseTuple(args, "O", &py_ldb))
189                 return NULL;
190
191         PyErr_LDB_OR_RAISE(py_ldb, ldb);
192
193         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
194
195         Py_RETURN_NONE;
196 }
197
198 static PyObject *py_samdb_set_domain_sid(PyLdbObject *self, PyObject *args)
199
200         PyObject *py_ldb, *py_sid;
201         struct ldb_context *ldb;
202         struct dom_sid *sid;
203         bool ret;
204
205         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_sid))
206                 return NULL;
207         
208         PyErr_LDB_OR_RAISE(py_ldb, ldb);
209
210         sid = dom_sid_parse_talloc(NULL, PyString_AsString(py_sid));
211
212         ret = samdb_set_domain_sid(ldb, sid);
213         if (!ret) {
214                 PyErr_SetString(PyExc_RuntimeError, "set_domain_sid failed");
215                 return NULL;
216         } 
217         Py_RETURN_NONE;
218 }
219
220 static PyObject *py_samdb_get_domain_sid(PyLdbObject *self, PyObject *args)
221
222         PyObject *py_ldb;
223         struct ldb_context *ldb;
224         const struct dom_sid *sid;
225         PyObject *ret;
226         char *retstr;
227
228         if (!PyArg_ParseTuple(args, "O", &py_ldb))
229                 return NULL;
230         
231         PyErr_LDB_OR_RAISE(py_ldb, ldb);
232
233         sid = samdb_domain_sid(ldb);
234         if (!sid) {
235                 PyErr_SetString(PyExc_RuntimeError, "samdb_domain_sid failed");
236                 return NULL;
237         } 
238         retstr = dom_sid_string(NULL, sid);
239         ret = PyString_FromString(retstr);
240         talloc_free(retstr);
241         return ret;
242 }
243
244 static PyObject *py_ldb_register_samba_handlers(PyObject *self, PyObject *args)
245 {
246         PyObject *py_ldb;
247         struct ldb_context *ldb;
248         int ret;
249
250         if (!PyArg_ParseTuple(args, "O", &py_ldb))
251                 return NULL;
252
253         PyErr_LDB_OR_RAISE(py_ldb, ldb);
254         ret = ldb_register_samba_handlers(ldb);
255
256         PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
257         Py_RETURN_NONE;
258 }
259
260 static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
261 {
262         PyObject *py_ldb, *py_guid;
263         bool ret;
264         struct GUID guid;
265         struct ldb_context *ldb;
266         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_guid))
267                 return NULL;
268
269         PyErr_LDB_OR_RAISE(py_ldb, ldb);
270         GUID_from_string(PyString_AsString(py_guid), &guid);
271
272         ret = samdb_set_ntds_invocation_id(ldb, &guid);
273         if (!ret) {
274                 PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id failed");
275                 return NULL;
276         }
277         Py_RETURN_NONE;
278 }
279
280 static PyObject *py_dsdb_set_opaque_integer(PyObject *self, PyObject *args)
281 {
282         PyObject *py_ldb;
283         int value;
284         int *old_val, *new_val;
285         char *py_opaque_name, *opaque_name_talloc;
286         struct ldb_context *ldb;
287         TALLOC_CTX *tmp_ctx;
288
289         if (!PyArg_ParseTuple(args, "Osi", &py_ldb, &py_opaque_name, &value))
290                 return NULL;
291
292         PyErr_LDB_OR_RAISE(py_ldb, ldb);
293
294         /* see if we have a cached copy */
295         old_val = (int *)ldb_get_opaque(ldb, 
296                                         py_opaque_name);
297
298         if (old_val) {
299                 *old_val = value;
300                 Py_RETURN_NONE;
301         } 
302
303         tmp_ctx = talloc_new(ldb);
304         if (tmp_ctx == NULL) {
305                 goto failed;
306         }
307         
308         new_val = talloc(tmp_ctx, int);
309         if (!new_val) {
310                 goto failed;
311         }
312         
313         opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name);
314         if (!opaque_name_talloc) {
315                 goto failed;
316         }
317         
318         *new_val = value;
319
320         /* cache the domain_sid in the ldb */
321         if (ldb_set_opaque(ldb, opaque_name_talloc, new_val) != LDB_SUCCESS) {
322                 goto failed;
323         }
324
325         talloc_steal(ldb, new_val);
326         talloc_steal(ldb, opaque_name_talloc);
327         talloc_free(tmp_ctx);
328
329         Py_RETURN_NONE;
330
331 failed:
332         talloc_free(tmp_ctx);
333         PyErr_SetString(PyExc_RuntimeError, "Failed to set opaque integer into the ldb!\n");
334         return NULL;
335 }
336
337 static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args)
338 {
339         PyObject *py_ldb;
340         struct ldb_context *ldb;
341         int ret;
342         if (!PyArg_ParseTuple(args, "O", &py_ldb))
343                 return NULL;
344
345         PyErr_LDB_OR_RAISE(py_ldb, ldb);
346
347         ret = dsdb_set_global_schema(ldb);
348         PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
349
350         Py_RETURN_NONE;
351 }
352
353 static PyObject *py_dsdb_set_schema_from_ldif(PyObject *self, PyObject *args)
354 {
355         WERROR result;
356         char *pf, *df;
357         PyObject *py_ldb;
358         struct ldb_context *ldb;
359
360         if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &pf, &df))
361                 return NULL;
362
363         PyErr_LDB_OR_RAISE(py_ldb, ldb);
364
365         result = dsdb_set_schema_from_ldif(ldb, pf, df);
366         PyErr_WERROR_IS_ERR_RAISE(result);
367
368         Py_RETURN_NONE;
369 }
370
371 static PyObject *py_dsdb_convert_schema_to_openldap(PyObject *self, PyObject *args)
372 {
373         char *target_str, *mapping;
374         PyObject *py_ldb;
375         struct ldb_context *ldb;
376         PyObject *ret;
377         char *retstr;
378
379         if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &target_str, &mapping))
380                 return NULL;
381
382         PyErr_LDB_OR_RAISE(py_ldb, ldb);
383
384         retstr = dsdb_convert_schema_to_openldap(ldb, target_str, mapping);
385         if (!retstr) {
386                 PyErr_SetString(PyExc_RuntimeError, "dsdb_convert_schema_to_openldap failed");
387                 return NULL;
388         } 
389         ret = PyString_FromString(retstr);
390         talloc_free(retstr);
391         return ret;
392 }
393
394 static PyObject *py_dsdb_write_prefixes_from_schema_to_ldb(PyObject *self, PyObject *args)
395 {
396         PyObject *py_ldb;
397         struct ldb_context *ldb;
398         WERROR result;
399         struct dsdb_schema *schema;
400
401         if (!PyArg_ParseTuple(args, "O", &py_ldb))
402                 return NULL;
403
404         PyErr_LDB_OR_RAISE(py_ldb, ldb);
405
406         schema = dsdb_get_schema(ldb, NULL);
407         if (!schema) {
408                 PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on ldb!\n");
409                 return NULL;
410         }
411
412         result = dsdb_write_prefixes_from_schema_to_ldb(NULL, ldb, schema);
413         PyErr_WERROR_IS_ERR_RAISE(result);
414
415         Py_RETURN_NONE;
416 }
417
418 static PyObject *py_dsdb_set_schema_from_ldb(PyObject *self, PyObject *args)
419 {
420         PyObject *py_ldb;
421         struct ldb_context *ldb;
422         PyObject *py_from_ldb;
423         struct ldb_context *from_ldb;
424         struct dsdb_schema *schema;
425         int ret;
426         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_from_ldb))
427                 return NULL;
428
429         PyErr_LDB_OR_RAISE(py_ldb, ldb);
430
431         PyErr_LDB_OR_RAISE(py_from_ldb, from_ldb);
432
433         schema = dsdb_get_schema(from_ldb, NULL);
434         if (!schema) {
435                 PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on 'from' ldb!\n");
436                 return NULL;
437         }
438
439         ret = dsdb_reference_schema(ldb, schema, true);
440         PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
441
442         Py_RETURN_NONE;
443 }
444
445 static PyObject *py_dsdb_load_partition_usn(PyObject *self, PyObject *args)
446 {
447         PyObject *py_dn, *py_ldb, *result;
448         struct ldb_dn *dn;
449         uint64_t highest_uSN, urgent_uSN;
450         struct ldb_context *ldb;
451         TALLOC_CTX *mem_ctx;
452         int ret;
453
454         mem_ctx = talloc_new(NULL);
455         if (mem_ctx == NULL) {
456            PyErr_NoMemory();
457            return NULL;
458         }
459
460         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_dn)) {
461            talloc_free(mem_ctx);
462            return NULL;
463         }
464
465         PyErr_LDB_OR_RAISE(py_ldb, ldb);
466
467         if (!PyObject_AsDn(mem_ctx, py_dn, ldb, &dn)) {
468            talloc_free(mem_ctx);
469            return NULL;
470         }
471
472         ret = dsdb_load_partition_usn(ldb, dn, &highest_uSN, &urgent_uSN);
473         if (ret != LDB_SUCCESS) {
474            char *errstr = talloc_asprintf(mem_ctx, "Failed to load partition uSN - %s", ldb_errstring(ldb));
475            PyErr_SetString(PyExc_RuntimeError, errstr);
476            talloc_free(mem_ctx);
477            return NULL;
478         }
479
480         talloc_free(mem_ctx);
481
482         result = PyDict_New();
483
484         PyDict_SetItemString(result, "uSNHighest", PyInt_FromLong((uint64_t)highest_uSN));
485         PyDict_SetItemString(result, "uSNUrgent", PyInt_FromLong((uint64_t)urgent_uSN));
486
487
488         return result;
489
490 }
491
492
493
494 static PyObject *py_samdb_ntds_invocation_id(PyObject *self, PyObject *args)
495 {
496         PyObject *py_ldb, *result;
497         struct ldb_context *ldb;
498         TALLOC_CTX *mem_ctx;
499         const struct GUID *guid;
500
501         mem_ctx = talloc_new(NULL);
502         if (mem_ctx == NULL) {
503                 PyErr_NoMemory();
504                 return NULL;
505         }
506
507         if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
508                 talloc_free(mem_ctx);
509                 return NULL;
510         }
511
512         PyErr_LDB_OR_RAISE(py_ldb, ldb);
513
514         guid = samdb_ntds_invocation_id(ldb);
515         if (guid == NULL) {
516                 PyErr_SetStringError("Failed to find NTDS invocation ID");
517                 talloc_free(mem_ctx);
518                 return NULL;
519         }
520
521         result = PyString_FromString(GUID_string(mem_ctx, guid));
522         talloc_free(mem_ctx);
523         return result;
524 }
525
526
527 static PyObject *py_samdb_ntds_objectGUID(PyObject *self, PyObject *args)
528 {
529         PyObject *py_ldb, *result;
530         struct ldb_context *ldb;
531         TALLOC_CTX *mem_ctx;
532         const struct GUID *guid;
533
534         mem_ctx = talloc_new(NULL);
535         if (mem_ctx == NULL) {
536                 PyErr_NoMemory();
537                 return NULL;
538         }
539
540         if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
541                 talloc_free(mem_ctx);
542                 return NULL;
543         }
544
545         PyErr_LDB_OR_RAISE(py_ldb, ldb);
546
547         guid = samdb_ntds_objectGUID(ldb);
548         if (guid == NULL) {
549                 PyErr_SetStringError("Failed to find NTDS GUID");
550                 talloc_free(mem_ctx);
551                 return NULL;
552         }
553
554         result = PyString_FromString(GUID_string(mem_ctx, guid));
555         talloc_free(mem_ctx);
556         return result;
557 }
558
559
560 /*
561   return the list of interface IPs we have configured
562   takes an loadparm context, returns a list of IPs in string form
563
564   Does not return addresses on 127.0.0.0/8
565  */
566 static PyObject *py_interface_ips(PyObject *self, PyObject *args)
567 {
568         PyObject *pylist;
569         int count;
570         TALLOC_CTX *tmp_ctx;
571         PyObject *py_lp_ctx;
572         struct loadparm_context *lp_ctx;
573         struct interface *ifaces;
574         int i, ifcount;
575         int all_interfaces;
576
577         if (!PyArg_ParseTuple(args, "Oi", &py_lp_ctx, &all_interfaces))
578                 return NULL;
579
580         lp_ctx = lp_from_py_object(py_lp_ctx);
581         if (lp_ctx == NULL) {
582                 PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
583                 return NULL;
584         }
585
586         tmp_ctx = talloc_new(NULL);
587
588         load_interfaces(tmp_ctx, lp_interfaces(lp_ctx), &ifaces);
589
590         count = iface_count(ifaces);
591
592         /* first count how many are not loopback addresses */
593         for (ifcount = i = 0; i<count; i++) {
594                 const char *ip = iface_n_ip(ifaces, i);
595                 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
596                         ifcount++;
597                 }
598         }
599
600         pylist = PyList_New(ifcount);
601         for (ifcount = i = 0; i<count; i++) {
602                 const char *ip = iface_n_ip(ifaces, i);
603                 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
604                         PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
605                         ifcount++;
606                 }
607         }
608         talloc_free(tmp_ctx);
609         return pylist;
610 }
611
612
613 static PyMethodDef py_misc_methods[] = {
614         { "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS,
615                 "generate_random_str(len) -> string\n"
616                 "Generate random string with specified length." },
617         { "generate_random_password", (PyCFunction)py_generate_random_password, METH_VARARGS,
618                 "generate_random_password(min, max) -> string\n"
619                 "Generate random password with a length >= min and <= max." },
620         { "unix2nttime", (PyCFunction)py_unix2nttime, METH_VARARGS,
621                 "unix2nttime(timestamp) -> nttime" },
622         { "ldb_set_session_info", (PyCFunction)py_ldb_set_session_info, METH_VARARGS,
623                 "ldb_set_session_info(ldb, session_info)\n"
624                 "Set session info to use when connecting." },
625         { "ldb_set_credentials", (PyCFunction)py_ldb_set_credentials, METH_VARARGS,
626                 "ldb_set_credentials(ldb, credentials)\n"
627                 "Set credentials to use when connecting." },
628         { "ldb_set_loadparm", (PyCFunction)py_ldb_set_loadparm, METH_VARARGS,
629                 "ldb_set_loadparm(ldb, session_info)\n"
630                 "Set loadparm context to use when connecting." },
631         { "samdb_set_domain_sid", (PyCFunction)py_samdb_set_domain_sid, METH_VARARGS,
632                 "samdb_set_domain_sid(samdb, sid)\n"
633                 "Set SID of domain to use." },
634         { "samdb_get_domain_sid", (PyCFunction)py_samdb_get_domain_sid, METH_VARARGS,
635                 "samdb_get_domain_sid(samdb)\n"
636                 "Get SID of domain in use." },
637         { "ldb_register_samba_handlers", (PyCFunction)py_ldb_register_samba_handlers, METH_VARARGS,
638                 "ldb_register_samba_handlers(ldb)\n"
639                 "Register Samba-specific LDB modules and schemas." },
640         { "ldb_set_utf8_casefold", (PyCFunction)py_ldb_set_utf8_casefold, METH_VARARGS,
641                 "ldb_set_utf8_casefold(ldb)\n"
642                 "Set the right Samba casefolding function for UTF8 charset." },
643         { "dsdb_set_ntds_invocation_id", (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
644                 NULL },
645         { "dsdb_set_opaque_integer", (PyCFunction)py_dsdb_set_opaque_integer, METH_VARARGS,
646                 NULL },
647         { "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
648                 NULL },
649         { "dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS,
650                 NULL },
651         { "dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction)py_dsdb_write_prefixes_from_schema_to_ldb, METH_VARARGS,
652                 NULL },
653         { "dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS,
654                 NULL },
655         { "dsdb_convert_schema_to_openldap", (PyCFunction)py_dsdb_convert_schema_to_openldap, METH_VARARGS,
656                 NULL },
657         { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS,
658                 "set debug level" },
659         { "dsdb_load_partition_usn", (PyCFunction)py_dsdb_load_partition_usn, METH_VARARGS,
660                 "get uSNHighest and uSNUrgent from the partition @REPLCHANGED"},
661         { "samdb_ntds_invocation_id", (PyCFunction)py_samdb_ntds_invocation_id, METH_VARARGS,
662                 "get the NTDS invocation ID GUID as a string"},
663         { "samdb_ntds_objectGUID", (PyCFunction)py_samdb_ntds_objectGUID, METH_VARARGS,
664                 "get the NTDS objectGUID as a string"},
665         { "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS,
666                 "get interface IP address list"},
667         { NULL }
668 };
669
670 void initglue(void)
671 {
672         PyObject *m;
673
674         debug_setup_talloc_log();
675
676         m = Py_InitModule3("glue", py_misc_methods, 
677                            "Python bindings for miscellaneous Samba functions.");
678         if (m == NULL)
679                 return;
680
681         PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
682
683         /* one of the most annoying things about python scripts is
684            that they don't die when you hit control-C. This fixes that
685            sillyness. As we do all database operations using
686            transactions, this is also safe. In fact, not dying
687            immediately is unsafe as we could end up treating the
688            control-C exception as a different error and try to modify
689            as database incorrectly 
690         */
691         signal(SIGINT, SIG_DFL);
692 }
693