s4:dsdb Remove unused 'dsdb_make_schema_global' call from pyglue
[metze/samba/wip.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 static PyObject *py_samdb_server_site_name(PyObject *self, PyObject *args)
561 {
562         PyObject *py_ldb, *result;
563         struct ldb_context *ldb;
564         const char *site;
565         TALLOC_CTX *mem_ctx = talloc_new(NULL);
566
567         if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
568                 talloc_free(mem_ctx);
569                 return NULL;
570         }
571
572         PyErr_LDB_OR_RAISE(py_ldb, ldb);
573
574         site = samdb_server_site_name(ldb, mem_ctx);
575         if (site == NULL) {
576                 PyErr_SetStringError("Failed to find server site");
577                 talloc_free(mem_ctx);
578                 return NULL;
579         }
580
581         result = PyString_FromString(site);
582         talloc_free(mem_ctx);
583         return result;
584 }
585
586
587 /*
588   return the list of interface IPs we have configured
589   takes an loadparm context, returns a list of IPs in string form
590
591   Does not return addresses on 127.0.0.0/8
592  */
593 static PyObject *py_interface_ips(PyObject *self, PyObject *args)
594 {
595         PyObject *pylist;
596         int count;
597         TALLOC_CTX *tmp_ctx;
598         PyObject *py_lp_ctx;
599         struct loadparm_context *lp_ctx;
600         struct interface *ifaces;
601         int i, ifcount;
602         int all_interfaces;
603
604         if (!PyArg_ParseTuple(args, "Oi", &py_lp_ctx, &all_interfaces))
605                 return NULL;
606
607         lp_ctx = lp_from_py_object(py_lp_ctx);
608         if (lp_ctx == NULL) {
609                 PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
610                 return NULL;
611         }
612
613         tmp_ctx = talloc_new(NULL);
614
615         load_interfaces(tmp_ctx, lp_interfaces(lp_ctx), &ifaces);
616
617         count = iface_count(ifaces);
618
619         /* first count how many are not loopback addresses */
620         for (ifcount = i = 0; i<count; i++) {
621                 const char *ip = iface_n_ip(ifaces, i);
622                 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
623                         ifcount++;
624                 }
625         }
626
627         pylist = PyList_New(ifcount);
628         for (ifcount = i = 0; i<count; i++) {
629                 const char *ip = iface_n_ip(ifaces, i);
630                 if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
631                         PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
632                         ifcount++;
633                 }
634         }
635         talloc_free(tmp_ctx);
636         return pylist;
637 }
638
639
640 static PyMethodDef py_misc_methods[] = {
641         { "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS,
642                 "generate_random_str(len) -> string\n"
643                 "Generate random string with specified length." },
644         { "generate_random_password", (PyCFunction)py_generate_random_password, METH_VARARGS,
645                 "generate_random_password(min, max) -> string\n"
646                 "Generate random password with a length >= min and <= max." },
647         { "unix2nttime", (PyCFunction)py_unix2nttime, METH_VARARGS,
648                 "unix2nttime(timestamp) -> nttime" },
649         { "ldb_set_session_info", (PyCFunction)py_ldb_set_session_info, METH_VARARGS,
650                 "ldb_set_session_info(ldb, session_info)\n"
651                 "Set session info to use when connecting." },
652         { "ldb_set_credentials", (PyCFunction)py_ldb_set_credentials, METH_VARARGS,
653                 "ldb_set_credentials(ldb, credentials)\n"
654                 "Set credentials to use when connecting." },
655         { "ldb_set_loadparm", (PyCFunction)py_ldb_set_loadparm, METH_VARARGS,
656                 "ldb_set_loadparm(ldb, session_info)\n"
657                 "Set loadparm context to use when connecting." },
658         { "samdb_set_domain_sid", (PyCFunction)py_samdb_set_domain_sid, METH_VARARGS,
659                 "samdb_set_domain_sid(samdb, sid)\n"
660                 "Set SID of domain to use." },
661         { "samdb_get_domain_sid", (PyCFunction)py_samdb_get_domain_sid, METH_VARARGS,
662                 "samdb_get_domain_sid(samdb)\n"
663                 "Get SID of domain in use." },
664         { "ldb_register_samba_handlers", (PyCFunction)py_ldb_register_samba_handlers, METH_VARARGS,
665                 "ldb_register_samba_handlers(ldb)\n"
666                 "Register Samba-specific LDB modules and schemas." },
667         { "ldb_set_utf8_casefold", (PyCFunction)py_ldb_set_utf8_casefold, METH_VARARGS,
668                 "ldb_set_utf8_casefold(ldb)\n"
669                 "Set the right Samba casefolding function for UTF8 charset." },
670         { "dsdb_set_ntds_invocation_id", (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
671                 NULL },
672         { "dsdb_set_opaque_integer", (PyCFunction)py_dsdb_set_opaque_integer, METH_VARARGS,
673                 NULL },
674         { "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
675                 NULL },
676         { "dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS,
677                 NULL },
678         { "dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction)py_dsdb_write_prefixes_from_schema_to_ldb, METH_VARARGS,
679                 NULL },
680         { "dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS,
681                 NULL },
682         { "dsdb_convert_schema_to_openldap", (PyCFunction)py_dsdb_convert_schema_to_openldap, METH_VARARGS,
683                 NULL },
684         { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS,
685                 "set debug level" },
686         { "dsdb_load_partition_usn", (PyCFunction)py_dsdb_load_partition_usn, METH_VARARGS,
687                 "get uSNHighest and uSNUrgent from the partition @REPLCHANGED"},
688         { "samdb_ntds_invocation_id", (PyCFunction)py_samdb_ntds_invocation_id, METH_VARARGS,
689                 "get the NTDS invocation ID GUID as a string"},
690         { "samdb_ntds_objectGUID", (PyCFunction)py_samdb_ntds_objectGUID, METH_VARARGS,
691                 "get the NTDS objectGUID as a string"},
692         { "samdb_server_site_name", (PyCFunction)py_samdb_server_site_name, METH_VARARGS,
693                 "get the server site name as a string"},
694         { "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS,
695                 "get interface IP address list"},
696         { NULL }
697 };
698
699 void initglue(void)
700 {
701         PyObject *m;
702
703         m = Py_InitModule3("glue", py_misc_methods, 
704                            "Python bindings for miscellaneous Samba functions.");
705         if (m == NULL)
706                 return;
707
708         PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
709
710         /* "userAccountControl" flags */
711         PyModule_AddObject(m, "UF_NORMAL_ACCOUNT", PyInt_FromLong(UF_NORMAL_ACCOUNT));
712         PyModule_AddObject(m, "UF_TEMP_DUPLICATE_ACCOUNT", PyInt_FromLong(UF_TEMP_DUPLICATE_ACCOUNT));
713         PyModule_AddObject(m, "UF_SERVER_TRUST_ACCOUNT", PyInt_FromLong(UF_SERVER_TRUST_ACCOUNT));
714         PyModule_AddObject(m, "UF_WORKSTATION_TRUST_ACCOUNT", PyInt_FromLong(UF_WORKSTATION_TRUST_ACCOUNT));
715         PyModule_AddObject(m, "UF_INTERDOMAIN_TRUST_ACCOUNT", PyInt_FromLong(UF_INTERDOMAIN_TRUST_ACCOUNT));
716         PyModule_AddObject(m, "UF_PASSWD_NOTREQD", PyInt_FromLong(UF_PASSWD_NOTREQD));
717         PyModule_AddObject(m, "UF_ACCOUNTDISABLE", PyInt_FromLong(UF_ACCOUNTDISABLE));
718
719         /* "groupType" flags */
720         PyModule_AddObject(m, "GTYPE_SECURITY_BUILTIN_LOCAL_GROUP", PyInt_FromLong(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP));
721         PyModule_AddObject(m, "GTYPE_SECURITY_GLOBAL_GROUP", PyInt_FromLong(GTYPE_SECURITY_GLOBAL_GROUP));
722         PyModule_AddObject(m, "GTYPE_SECURITY_DOMAIN_LOCAL_GROUP", PyInt_FromLong(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
723         PyModule_AddObject(m, "GTYPE_SECURITY_UNIVERSAL_GROUP", PyInt_FromLong(GTYPE_SECURITY_UNIVERSAL_GROUP));
724         PyModule_AddObject(m, "GTYPE_DISTRIBUTION_GLOBAL_GROUP", PyInt_FromLong(GTYPE_DISTRIBUTION_GLOBAL_GROUP));
725         PyModule_AddObject(m, "GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP", PyInt_FromLong(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP));
726         PyModule_AddObject(m, "GTYPE_DISTRIBUTION_UNIVERSAL_GROUP", PyInt_FromLong(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP));
727
728         /* "sAMAccountType" flags */
729         PyModule_AddObject(m, "ATYPE_NORMAL_ACCOUNT", PyInt_FromLong(ATYPE_NORMAL_ACCOUNT));
730         PyModule_AddObject(m, "ATYPE_WORKSTATION_TRUST", PyInt_FromLong(ATYPE_WORKSTATION_TRUST));
731         PyModule_AddObject(m, "ATYPE_INTERDOMAIN_TRUST", PyInt_FromLong(ATYPE_INTERDOMAIN_TRUST));
732         PyModule_AddObject(m, "ATYPE_SECURITY_GLOBAL_GROUP", PyInt_FromLong(ATYPE_SECURITY_GLOBAL_GROUP));
733         PyModule_AddObject(m, "ATYPE_SECURITY_LOCAL_GROUP", PyInt_FromLong(ATYPE_SECURITY_LOCAL_GROUP));
734         PyModule_AddObject(m, "ATYPE_SECURITY_UNIVERSAL_GROUP", PyInt_FromLong(ATYPE_SECURITY_UNIVERSAL_GROUP));
735         PyModule_AddObject(m, "ATYPE_DISTRIBUTION_GLOBAL_GROUP", PyInt_FromLong(ATYPE_DISTRIBUTION_GLOBAL_GROUP));
736         PyModule_AddObject(m, "ATYPE_DISTRIBUTION_LOCAL_GROUP", PyInt_FromLong(ATYPE_DISTRIBUTION_LOCAL_GROUP));
737         PyModule_AddObject(m, "ATYPE_DISTRIBUTION_UNIVERSAL_GROUP", PyInt_FromLong(ATYPE_DISTRIBUTION_UNIVERSAL_GROUP));
738
739         /* "domainFunctionality", "forestFunctionality" flags in the rootDSE */
740         PyModule_AddObject(m, "DS_DOMAIN_FUNCTION_2000", PyInt_FromLong(DS_DOMAIN_FUNCTION_2000));
741         PyModule_AddObject(m, "DS_DOMAIN_FUNCTION_2003_MIXED", PyInt_FromLong(DS_DOMAIN_FUNCTION_2003_MIXED));
742         PyModule_AddObject(m, "DS_DOMAIN_FUNCTION_2003", PyInt_FromLong(DS_DOMAIN_FUNCTION_2003));
743         PyModule_AddObject(m, "DS_DOMAIN_FUNCTION_2008", PyInt_FromLong(DS_DOMAIN_FUNCTION_2008));
744         PyModule_AddObject(m, "DS_DOMAIN_FUNCTION_2008_R2", PyInt_FromLong(DS_DOMAIN_FUNCTION_2008_R2));
745
746         /* "domainControllerFunctionality" flags in the rootDSE */
747         PyModule_AddObject(m, "DS_DC_FUNCTION_2000", PyInt_FromLong(DS_DC_FUNCTION_2000));
748         PyModule_AddObject(m, "DS_DC_FUNCTION_2003", PyInt_FromLong(DS_DC_FUNCTION_2003));
749         PyModule_AddObject(m, "DS_DC_FUNCTION_2008", PyInt_FromLong(DS_DC_FUNCTION_2008));
750         PyModule_AddObject(m, "DS_DC_FUNCTION_2008_R2", PyInt_FromLong(DS_DC_FUNCTION_2008_R2));
751
752         /* "LDAP_SERVER_SD_FLAGS_OID" */
753         PyModule_AddObject(m, "SECINFO_OWNER", PyInt_FromLong(SECINFO_OWNER));
754         PyModule_AddObject(m, "SECINFO_GROUP", PyInt_FromLong(SECINFO_GROUP));
755         PyModule_AddObject(m, "SECINFO_DACL", PyInt_FromLong(SECINFO_DACL));
756         PyModule_AddObject(m, "SECINFO_SACL", PyInt_FromLong(SECINFO_SACL));
757
758         /* control access rights guids */
759         PyModule_AddObject(m, "GUID_DRS_ALLOCATE_RIDS", PyString_FromString(GUID_DRS_ALLOCATE_RIDS));
760         PyModule_AddObject(m, "GUID_DRS_CHANGE_DOMAIN_MASTER", PyString_FromString(GUID_DRS_CHANGE_DOMAIN_MASTER));
761         PyModule_AddObject(m, "GUID_DRS_CHANGE_INFR_MASTER", PyString_FromString(GUID_DRS_CHANGE_INFR_MASTER));
762         PyModule_AddObject(m, "GUID_DRS_CHANGE_PDC", PyString_FromString(GUID_DRS_CHANGE_PDC));
763         PyModule_AddObject(m, "GUID_DRS_CHANGE_RID_MASTER", PyString_FromString(GUID_DRS_CHANGE_RID_MASTER));
764         PyModule_AddObject(m, "GUID_DRS_CHANGE_SCHEMA_MASTER", PyString_FromString(GUID_DRS_CHANGE_SCHEMA_MASTER));
765         PyModule_AddObject(m, "GUID_DRS_GET_CHANGES", PyString_FromString(GUID_DRS_GET_CHANGES));
766         PyModule_AddObject(m, "GUID_DRS_GET_ALL_CHANGES", PyString_FromString(GUID_DRS_GET_ALL_CHANGES));
767         PyModule_AddObject(m, "GUID_DRS_GET_FILTERED_ATTRIBUTES", PyString_FromString(GUID_DRS_GET_FILTERED_ATTRIBUTES));
768         PyModule_AddObject(m, "GUID_DRS_MANAGE_TOPOLOGY", PyString_FromString(GUID_DRS_MANAGE_TOPOLOGY));
769         PyModule_AddObject(m, "GUID_DRS_MONITOR_TOPOLOGY", PyString_FromString(GUID_DRS_MONITOR_TOPOLOGY));
770         PyModule_AddObject(m, "GUID_DRS_REPL_SYNCRONIZE", PyString_FromString(GUID_DRS_REPL_SYNCRONIZE));
771         PyModule_AddObject(m, "GUID_DRS_RO_REPL_SECRET_SYNC", PyString_FromString(GUID_DRS_RO_REPL_SECRET_SYNC));
772
773         /* one of the most annoying things about python scripts is
774            that they don't die when you hit control-C. This fixes that
775            sillyness. As we do all database operations using
776            transactions, this is also safe. In fact, not dying
777            immediately is unsafe as we could end up treating the
778            control-C exception as a different error and try to modify
779            as database incorrectly 
780         */
781         signal(SIGINT, SIG_DFL);
782 }
783