s4:dsdb Change dsdb_get_schema() callers to use new talloc argument
[idra/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_make_schema_global(PyObject *self, PyObject *args)
446 {
447         PyObject *py_ldb;
448         struct ldb_context *ldb;
449
450         if (!PyArg_ParseTuple(args, "O", &py_ldb))
451                 return NULL;
452
453         PyErr_LDB_OR_RAISE(py_ldb, ldb);
454
455         dsdb_make_schema_global(ldb);
456
457         Py_RETURN_NONE;
458 }
459
460 static PyObject *py_dsdb_load_partition_usn(PyObject *self, PyObject *args)
461 {
462         PyObject *py_dn, *py_ldb, *result;
463         struct ldb_dn *dn;
464         uint64_t highest_uSN, urgent_uSN;
465         struct ldb_context *ldb;
466         TALLOC_CTX *mem_ctx;
467         int ret;
468
469         mem_ctx = talloc_new(NULL);
470         if (mem_ctx == NULL) {
471            PyErr_NoMemory();
472            return NULL;
473         }
474
475         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_dn)) {
476            talloc_free(mem_ctx);
477            return NULL;
478         }
479
480         PyErr_LDB_OR_RAISE(py_ldb, ldb);
481
482         if (!PyObject_AsDn(mem_ctx, py_dn, ldb, &dn)) {
483            talloc_free(mem_ctx);
484            return NULL;
485         }
486
487         ret = dsdb_load_partition_usn(ldb, dn, &highest_uSN, &urgent_uSN);
488         if (ret != LDB_SUCCESS) {
489            char *errstr = talloc_asprintf(mem_ctx, "Failed to load partition uSN - %s", ldb_errstring(ldb));
490            PyErr_SetString(PyExc_RuntimeError, errstr);
491            talloc_free(mem_ctx);
492            return NULL;
493         }
494
495         talloc_free(mem_ctx);
496
497         result = PyDict_New();
498
499         PyDict_SetItemString(result, "uSNHighest", PyInt_FromLong((uint64_t)highest_uSN));
500         PyDict_SetItemString(result, "uSNUrgent", PyInt_FromLong((uint64_t)urgent_uSN));
501
502
503         return result;
504
505 }
506
507
508
509 static PyObject *py_samdb_ntds_invocation_id(PyObject *self, PyObject *args)
510 {
511         PyObject *py_ldb, *result;
512         struct ldb_context *ldb;
513         TALLOC_CTX *mem_ctx;
514         const struct GUID *guid;
515
516         mem_ctx = talloc_new(NULL);
517         if (mem_ctx == NULL) {
518                 PyErr_NoMemory();
519                 return NULL;
520         }
521
522         if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
523                 talloc_free(mem_ctx);
524                 return NULL;
525         }
526
527         PyErr_LDB_OR_RAISE(py_ldb, ldb);
528
529         guid = samdb_ntds_invocation_id(ldb);
530         if (guid == NULL) {
531                 PyErr_SetStringError("Failed to find NTDS invocation ID");
532                 talloc_free(mem_ctx);
533                 return NULL;
534         }
535
536         result = PyString_FromString(GUID_string(mem_ctx, guid));
537         talloc_free(mem_ctx);
538         return result;
539 }
540
541
542 static PyObject *py_samdb_ntds_objectGUID(PyObject *self, PyObject *args)
543 {
544         PyObject *py_ldb, *result;
545         struct ldb_context *ldb;
546         TALLOC_CTX *mem_ctx;
547         const struct GUID *guid;
548
549         mem_ctx = talloc_new(NULL);
550         if (mem_ctx == NULL) {
551                 PyErr_NoMemory();
552                 return NULL;
553         }
554
555         if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
556                 talloc_free(mem_ctx);
557                 return NULL;
558         }
559
560         PyErr_LDB_OR_RAISE(py_ldb, ldb);
561
562         guid = samdb_ntds_objectGUID(ldb);
563         if (guid == NULL) {
564                 PyErr_SetStringError("Failed to find NTDS GUID");
565                 talloc_free(mem_ctx);
566                 return NULL;
567         }
568
569         result = PyString_FromString(GUID_string(mem_ctx, guid));
570         talloc_free(mem_ctx);
571         return result;
572 }
573
574
575 static PyObject *py_samdb_server_site_name(PyObject *self, PyObject *args)
576 {
577         PyObject *py_ldb, *result;
578         struct ldb_context *ldb;
579         const char *site;
580         TALLOC_CTX *mem_ctx = talloc_new(NULL);
581
582         if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
583                 talloc_free(mem_ctx);
584                 return NULL;
585         }
586
587         PyErr_LDB_OR_RAISE(py_ldb, ldb);
588
589         site = samdb_server_site_name(ldb, mem_ctx);
590         if (site == NULL) {
591                 PyErr_SetStringError("Failed to find server site");
592                 talloc_free(mem_ctx);
593                 return NULL;
594         }
595
596         result = PyString_FromString(site);
597         talloc_free(mem_ctx);
598         return result;
599 }
600
601
602 /*
603   return the list of interface IPs we have configured
604   takes an loadparm context, returns a list of IPs in string form
605
606   Does not return addresses on 127.0.0.0/8
607  */
608 static PyObject *py_interface_ips(PyObject *self, PyObject *args)
609 {
610         PyObject *pylist;
611         int count;
612         TALLOC_CTX *tmp_ctx;
613         PyObject *py_lp_ctx;
614         struct loadparm_context *lp_ctx;
615         struct interface *ifaces;
616         int i, ifcount;
617         int all_interfaces;
618
619         if (!PyArg_ParseTuple(args, "Oi", &py_lp_ctx, &all_interfaces))
620                 return NULL;
621
622         lp_ctx = lp_from_py_object(py_lp_ctx);
623         if (lp_ctx == NULL) {
624                 PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
625                 return NULL;
626         }
627
628         tmp_ctx = talloc_new(NULL);
629
630         load_interfaces(tmp_ctx, lp_interfaces(lp_ctx), &ifaces);
631
632         count = iface_count(ifaces);
633
634         /* first count how many are not loopback addresses */
635         for (ifcount = i = 0; i<count; i++) {
636                 const char *ip = iface_n_ip(ifaces, i);
637                 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
638                         ifcount++;
639                 }
640         }
641
642         pylist = PyList_New(ifcount);
643         for (ifcount = i = 0; i<count; i++) {
644                 const char *ip = iface_n_ip(ifaces, i);
645                 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
646                         PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
647                         ifcount++;
648                 }
649         }
650         talloc_free(tmp_ctx);
651         return pylist;
652 }
653
654
655 static PyMethodDef py_misc_methods[] = {
656         { "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS,
657                 "generate_random_str(len) -> string\n"
658                 "Generate random string with specified length." },
659         { "generate_random_password", (PyCFunction)py_generate_random_password, METH_VARARGS,
660                 "generate_random_password(min, max) -> string\n"
661                 "Generate random password with a length >= min and <= max." },
662         { "unix2nttime", (PyCFunction)py_unix2nttime, METH_VARARGS,
663                 "unix2nttime(timestamp) -> nttime" },
664         { "ldb_set_session_info", (PyCFunction)py_ldb_set_session_info, METH_VARARGS,
665                 "ldb_set_session_info(ldb, session_info)\n"
666                 "Set session info to use when connecting." },
667         { "ldb_set_credentials", (PyCFunction)py_ldb_set_credentials, METH_VARARGS,
668                 "ldb_set_credentials(ldb, credentials)\n"
669                 "Set credentials to use when connecting." },
670         { "ldb_set_loadparm", (PyCFunction)py_ldb_set_loadparm, METH_VARARGS,
671                 "ldb_set_loadparm(ldb, session_info)\n"
672                 "Set loadparm context to use when connecting." },
673         { "samdb_set_domain_sid", (PyCFunction)py_samdb_set_domain_sid, METH_VARARGS,
674                 "samdb_set_domain_sid(samdb, sid)\n"
675                 "Set SID of domain to use." },
676         { "samdb_get_domain_sid", (PyCFunction)py_samdb_get_domain_sid, METH_VARARGS,
677                 "samdb_get_domain_sid(samdb)\n"
678                 "Get SID of domain in use." },
679         { "ldb_register_samba_handlers", (PyCFunction)py_ldb_register_samba_handlers, METH_VARARGS,
680                 "ldb_register_samba_handlers(ldb)\n"
681                 "Register Samba-specific LDB modules and schemas." },
682         { "ldb_set_utf8_casefold", (PyCFunction)py_ldb_set_utf8_casefold, METH_VARARGS,
683                 "ldb_set_utf8_casefold(ldb)\n"
684                 "Set the right Samba casefolding function for UTF8 charset." },
685         { "dsdb_set_ntds_invocation_id", (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
686                 NULL },
687         { "dsdb_set_opaque_integer", (PyCFunction)py_dsdb_set_opaque_integer, METH_VARARGS,
688                 NULL },
689         { "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
690                 NULL },
691         { "dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS,
692                 NULL },
693         { "dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction)py_dsdb_write_prefixes_from_schema_to_ldb, METH_VARARGS,
694                 NULL },
695         { "dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS,
696                 NULL },
697         { "dsdb_convert_schema_to_openldap", (PyCFunction)py_dsdb_convert_schema_to_openldap, METH_VARARGS,
698                 NULL },
699         { "dsdb_make_schema_global", (PyCFunction)py_dsdb_make_schema_global, METH_VARARGS,
700                 NULL },
701         { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS,
702                 "set debug level" },
703         { "dsdb_load_partition_usn", (PyCFunction)py_dsdb_load_partition_usn, METH_VARARGS,
704                 "get uSNHighest and uSNUrgent from the partition @REPLCHANGED"},
705         { "samdb_ntds_invocation_id", (PyCFunction)py_samdb_ntds_invocation_id, METH_VARARGS,
706                 "get the NTDS invocation ID GUID as a string"},
707         { "samdb_ntds_objectGUID", (PyCFunction)py_samdb_ntds_objectGUID, METH_VARARGS,
708                 "get the NTDS objectGUID as a string"},
709         { "samdb_server_site_name", (PyCFunction)py_samdb_server_site_name, METH_VARARGS,
710                 "get the server site name as a string"},
711         { "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS,
712                 "get interface IP address list"},
713         { NULL }
714 };
715
716 void initglue(void)
717 {
718         PyObject *m;
719
720         m = Py_InitModule3("glue", py_misc_methods, 
721                            "Python bindings for miscellaneous Samba functions.");
722         if (m == NULL)
723                 return;
724
725         PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
726
727         /* "userAccountControl" flags */
728         PyModule_AddObject(m, "UF_NORMAL_ACCOUNT", PyInt_FromLong(UF_NORMAL_ACCOUNT));
729         PyModule_AddObject(m, "UF_TEMP_DUPLICATE_ACCOUNT", PyInt_FromLong(UF_TEMP_DUPLICATE_ACCOUNT));
730         PyModule_AddObject(m, "UF_SERVER_TRUST_ACCOUNT", PyInt_FromLong(UF_SERVER_TRUST_ACCOUNT));
731         PyModule_AddObject(m, "UF_WORKSTATION_TRUST_ACCOUNT", PyInt_FromLong(UF_WORKSTATION_TRUST_ACCOUNT));
732         PyModule_AddObject(m, "UF_INTERDOMAIN_TRUST_ACCOUNT", PyInt_FromLong(UF_INTERDOMAIN_TRUST_ACCOUNT));
733         PyModule_AddObject(m, "UF_PASSWD_NOTREQD", PyInt_FromLong(UF_PASSWD_NOTREQD));
734         PyModule_AddObject(m, "UF_ACCOUNTDISABLE", PyInt_FromLong(UF_ACCOUNTDISABLE));
735
736         /* "groupType" flags */
737         PyModule_AddObject(m, "GTYPE_SECURITY_BUILTIN_LOCAL_GROUP", PyInt_FromLong(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP));
738         PyModule_AddObject(m, "GTYPE_SECURITY_GLOBAL_GROUP", PyInt_FromLong(GTYPE_SECURITY_GLOBAL_GROUP));
739         PyModule_AddObject(m, "GTYPE_SECURITY_DOMAIN_LOCAL_GROUP", PyInt_FromLong(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
740         PyModule_AddObject(m, "GTYPE_SECURITY_UNIVERSAL_GROUP", PyInt_FromLong(GTYPE_SECURITY_UNIVERSAL_GROUP));
741         PyModule_AddObject(m, "GTYPE_DISTRIBUTION_GLOBAL_GROUP", PyInt_FromLong(GTYPE_DISTRIBUTION_GLOBAL_GROUP));
742         PyModule_AddObject(m, "GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP", PyInt_FromLong(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP));
743         PyModule_AddObject(m, "GTYPE_DISTRIBUTION_UNIVERSAL_GROUP", PyInt_FromLong(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP));
744
745         /* "sAMAccountType" flags */
746         PyModule_AddObject(m, "ATYPE_NORMAL_ACCOUNT", PyInt_FromLong(ATYPE_NORMAL_ACCOUNT));
747         PyModule_AddObject(m, "ATYPE_WORKSTATION_TRUST", PyInt_FromLong(ATYPE_WORKSTATION_TRUST));
748         PyModule_AddObject(m, "ATYPE_INTERDOMAIN_TRUST", PyInt_FromLong(ATYPE_INTERDOMAIN_TRUST));
749         PyModule_AddObject(m, "ATYPE_SECURITY_GLOBAL_GROUP", PyInt_FromLong(ATYPE_SECURITY_GLOBAL_GROUP));
750         PyModule_AddObject(m, "ATYPE_SECURITY_LOCAL_GROUP", PyInt_FromLong(ATYPE_SECURITY_LOCAL_GROUP));
751         PyModule_AddObject(m, "ATYPE_SECURITY_UNIVERSAL_GROUP", PyInt_FromLong(ATYPE_SECURITY_UNIVERSAL_GROUP));
752         PyModule_AddObject(m, "ATYPE_DISTRIBUTION_GLOBAL_GROUP", PyInt_FromLong(ATYPE_DISTRIBUTION_GLOBAL_GROUP));
753         PyModule_AddObject(m, "ATYPE_DISTRIBUTION_LOCAL_GROUP", PyInt_FromLong(ATYPE_DISTRIBUTION_LOCAL_GROUP));
754         PyModule_AddObject(m, "ATYPE_DISTRIBUTION_UNIVERSAL_GROUP", PyInt_FromLong(ATYPE_DISTRIBUTION_UNIVERSAL_GROUP));
755
756         /* "domainFunctionality", "forestFunctionality" flags in the rootDSE */
757         PyModule_AddObject(m, "DS_DOMAIN_FUNCTION_2000", PyInt_FromLong(DS_DOMAIN_FUNCTION_2000));
758         PyModule_AddObject(m, "DS_DOMAIN_FUNCTION_2003_MIXED", PyInt_FromLong(DS_DOMAIN_FUNCTION_2003_MIXED));
759         PyModule_AddObject(m, "DS_DOMAIN_FUNCTION_2003", PyInt_FromLong(DS_DOMAIN_FUNCTION_2003));
760         PyModule_AddObject(m, "DS_DOMAIN_FUNCTION_2008", PyInt_FromLong(DS_DOMAIN_FUNCTION_2008));
761         PyModule_AddObject(m, "DS_DOMAIN_FUNCTION_2008_R2", PyInt_FromLong(DS_DOMAIN_FUNCTION_2008_R2));
762
763         /* "domainControllerFunctionality" flags in the rootDSE */
764         PyModule_AddObject(m, "DS_DC_FUNCTION_2000", PyInt_FromLong(DS_DC_FUNCTION_2000));
765         PyModule_AddObject(m, "DS_DC_FUNCTION_2003", PyInt_FromLong(DS_DC_FUNCTION_2003));
766         PyModule_AddObject(m, "DS_DC_FUNCTION_2008", PyInt_FromLong(DS_DC_FUNCTION_2008));
767         PyModule_AddObject(m, "DS_DC_FUNCTION_2008_R2", PyInt_FromLong(DS_DC_FUNCTION_2008_R2));
768
769         /* "LDAP_SERVER_SD_FLAGS_OID" */
770         PyModule_AddObject(m, "SECINFO_OWNER", PyInt_FromLong(SECINFO_OWNER));
771         PyModule_AddObject(m, "SECINFO_GROUP", PyInt_FromLong(SECINFO_GROUP));
772         PyModule_AddObject(m, "SECINFO_DACL", PyInt_FromLong(SECINFO_DACL));
773         PyModule_AddObject(m, "SECINFO_SACL", PyInt_FromLong(SECINFO_SACL));
774
775         /* one of the most annoying things about python scripts is
776            that they don't die when you hit control-C. This fixes that
777            sillyness. As we do all database operations using
778            transactions, this is also safe. In fact, not dying
779            immediately is unsafe as we could end up treating the
780            control-C exception as a different error and try to modify
781            as database incorrectly 
782         */
783         signal(SIGINT, SIG_DFL);
784 }
785