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_ldb_set_session_info(PyObject *self, PyObject *args)
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))
128 PyErr_LDB_OR_RAISE(py_ldb, ldb);
129 /*if (!PyAuthSession_Check(py_session_info)) {
130 PyErr_SetString(PyExc_TypeError, "Expected session info object");
134 info = PyAuthSession_AsSession(py_session_info);
136 ldb_set_opaque(ldb, "sessionInfo", info);
141 static PyObject *py_ldb_set_credentials(PyObject *self, PyObject *args)
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))
149 PyErr_LDB_OR_RAISE(py_ldb, ldb);
151 creds = cli_credentials_from_py_object(py_creds);
153 PyErr_SetString(PyExc_TypeError, "Expected credentials object");
157 ldb_set_opaque(ldb, "credentials", creds);
162 static PyObject *py_ldb_set_loadparm(PyObject *self, PyObject *args)
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))
170 PyErr_LDB_OR_RAISE(py_ldb, ldb);
172 lp_ctx = lp_from_py_object(py_lp_ctx);
173 if (lp_ctx == NULL) {
174 PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
178 ldb_set_opaque(ldb, "loadparm", lp_ctx);
183 static PyObject *py_ldb_set_utf8_casefold(PyObject *self, PyObject *args)
186 struct ldb_context *ldb;
188 if (!PyArg_ParseTuple(args, "O", &py_ldb))
191 PyErr_LDB_OR_RAISE(py_ldb, ldb);
193 ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
198 static PyObject *py_samdb_set_domain_sid(PyLdbObject *self, PyObject *args)
200 PyObject *py_ldb, *py_sid;
201 struct ldb_context *ldb;
205 if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_sid))
208 PyErr_LDB_OR_RAISE(py_ldb, ldb);
210 sid = dom_sid_parse_talloc(NULL, PyString_AsString(py_sid));
212 ret = samdb_set_domain_sid(ldb, sid);
214 PyErr_SetString(PyExc_RuntimeError, "set_domain_sid failed");
220 static PyObject *py_samdb_get_domain_sid(PyLdbObject *self, PyObject *args)
223 struct ldb_context *ldb;
224 const struct dom_sid *sid;
228 if (!PyArg_ParseTuple(args, "O", &py_ldb))
231 PyErr_LDB_OR_RAISE(py_ldb, ldb);
233 sid = samdb_domain_sid(ldb);
235 PyErr_SetString(PyExc_RuntimeError, "samdb_domain_sid failed");
238 retstr = dom_sid_string(NULL, sid);
239 ret = PyString_FromString(retstr);
244 static PyObject *py_ldb_register_samba_handlers(PyObject *self, PyObject *args)
247 struct ldb_context *ldb;
250 if (!PyArg_ParseTuple(args, "O", &py_ldb))
253 PyErr_LDB_OR_RAISE(py_ldb, ldb);
254 ret = ldb_register_samba_handlers(ldb);
256 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
260 static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
262 PyObject *py_ldb, *py_guid;
265 struct ldb_context *ldb;
266 if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_guid))
269 PyErr_LDB_OR_RAISE(py_ldb, ldb);
270 GUID_from_string(PyString_AsString(py_guid), &guid);
272 ret = samdb_set_ntds_invocation_id(ldb, &guid);
274 PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id failed");
280 static PyObject *py_dsdb_set_opaque_integer(PyObject *self, PyObject *args)
284 int *old_val, *new_val;
285 char *py_opaque_name, *opaque_name_talloc;
286 struct ldb_context *ldb;
289 if (!PyArg_ParseTuple(args, "Osi", &py_ldb, &py_opaque_name, &value))
292 PyErr_LDB_OR_RAISE(py_ldb, ldb);
294 /* see if we have a cached copy */
295 old_val = (int *)ldb_get_opaque(ldb,
303 tmp_ctx = talloc_new(ldb);
304 if (tmp_ctx == NULL) {
308 new_val = talloc(tmp_ctx, int);
313 opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name);
314 if (!opaque_name_talloc) {
320 /* cache the domain_sid in the ldb */
321 if (ldb_set_opaque(ldb, opaque_name_talloc, new_val) != LDB_SUCCESS) {
325 talloc_steal(ldb, new_val);
326 talloc_steal(ldb, opaque_name_talloc);
327 talloc_free(tmp_ctx);
332 talloc_free(tmp_ctx);
333 PyErr_SetString(PyExc_RuntimeError, "Failed to set opaque integer into the ldb!\n");
337 static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args)
340 struct ldb_context *ldb;
342 if (!PyArg_ParseTuple(args, "O", &py_ldb))
345 PyErr_LDB_OR_RAISE(py_ldb, ldb);
347 ret = dsdb_set_global_schema(ldb);
348 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
353 static PyObject *py_dsdb_set_schema_from_ldif(PyObject *self, PyObject *args)
358 struct ldb_context *ldb;
360 if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &pf, &df))
363 PyErr_LDB_OR_RAISE(py_ldb, ldb);
365 result = dsdb_set_schema_from_ldif(ldb, pf, df);
366 PyErr_WERROR_IS_ERR_RAISE(result);
371 static PyObject *py_dsdb_convert_schema_to_openldap(PyObject *self, PyObject *args)
373 char *target_str, *mapping;
375 struct ldb_context *ldb;
379 if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &target_str, &mapping))
382 PyErr_LDB_OR_RAISE(py_ldb, ldb);
384 retstr = dsdb_convert_schema_to_openldap(ldb, target_str, mapping);
386 PyErr_SetString(PyExc_RuntimeError, "dsdb_convert_schema_to_openldap failed");
389 ret = PyString_FromString(retstr);
394 static PyObject *py_dsdb_write_prefixes_from_schema_to_ldb(PyObject *self, PyObject *args)
397 struct ldb_context *ldb;
399 struct dsdb_schema *schema;
401 if (!PyArg_ParseTuple(args, "O", &py_ldb))
404 PyErr_LDB_OR_RAISE(py_ldb, ldb);
406 schema = dsdb_get_schema(ldb, NULL);
408 PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on ldb!\n");
412 result = dsdb_write_prefixes_from_schema_to_ldb(NULL, ldb, schema);
413 PyErr_WERROR_IS_ERR_RAISE(result);
418 static PyObject *py_dsdb_set_schema_from_ldb(PyObject *self, PyObject *args)
421 struct ldb_context *ldb;
422 PyObject *py_from_ldb;
423 struct ldb_context *from_ldb;
424 struct dsdb_schema *schema;
426 if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_from_ldb))
429 PyErr_LDB_OR_RAISE(py_ldb, ldb);
431 PyErr_LDB_OR_RAISE(py_from_ldb, from_ldb);
433 schema = dsdb_get_schema(from_ldb, NULL);
435 PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on 'from' ldb!\n");
439 ret = dsdb_reference_schema(ldb, schema, true);
440 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
445 static PyObject *py_dsdb_load_partition_usn(PyObject *self, PyObject *args)
447 PyObject *py_dn, *py_ldb, *result;
449 uint64_t highest_uSN, urgent_uSN;
450 struct ldb_context *ldb;
454 mem_ctx = talloc_new(NULL);
455 if (mem_ctx == NULL) {
460 if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_dn)) {
461 talloc_free(mem_ctx);
465 PyErr_LDB_OR_RAISE(py_ldb, ldb);
467 if (!PyObject_AsDn(mem_ctx, py_dn, ldb, &dn)) {
468 talloc_free(mem_ctx);
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);
480 talloc_free(mem_ctx);
482 result = PyDict_New();
484 PyDict_SetItemString(result, "uSNHighest", PyInt_FromLong((uint64_t)highest_uSN));
485 PyDict_SetItemString(result, "uSNUrgent", PyInt_FromLong((uint64_t)urgent_uSN));
494 static PyObject *py_samdb_ntds_invocation_id(PyObject *self, PyObject *args)
496 PyObject *py_ldb, *result;
497 struct ldb_context *ldb;
499 const struct GUID *guid;
501 mem_ctx = talloc_new(NULL);
502 if (mem_ctx == NULL) {
507 if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
508 talloc_free(mem_ctx);
512 PyErr_LDB_OR_RAISE(py_ldb, ldb);
514 guid = samdb_ntds_invocation_id(ldb);
516 PyErr_SetStringError("Failed to find NTDS invocation ID");
517 talloc_free(mem_ctx);
521 result = PyString_FromString(GUID_string(mem_ctx, guid));
522 talloc_free(mem_ctx);
527 static PyObject *py_samdb_ntds_objectGUID(PyObject *self, PyObject *args)
529 PyObject *py_ldb, *result;
530 struct ldb_context *ldb;
532 const struct GUID *guid;
534 mem_ctx = talloc_new(NULL);
535 if (mem_ctx == NULL) {
540 if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
541 talloc_free(mem_ctx);
545 PyErr_LDB_OR_RAISE(py_ldb, ldb);
547 guid = samdb_ntds_objectGUID(ldb);
549 PyErr_SetStringError("Failed to find NTDS GUID");
550 talloc_free(mem_ctx);
554 result = PyString_FromString(GUID_string(mem_ctx, guid));
555 talloc_free(mem_ctx);
560 static PyObject *py_samdb_server_site_name(PyObject *self, PyObject *args)
562 PyObject *py_ldb, *result;
563 struct ldb_context *ldb;
565 TALLOC_CTX *mem_ctx = talloc_new(NULL);
567 if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
568 talloc_free(mem_ctx);
572 PyErr_LDB_OR_RAISE(py_ldb, ldb);
574 site = samdb_server_site_name(ldb, mem_ctx);
576 PyErr_SetStringError("Failed to find server site");
577 talloc_free(mem_ctx);
581 result = PyString_FromString(site);
582 talloc_free(mem_ctx);
588 return the list of interface IPs we have configured
589 takes an loadparm context, returns a list of IPs in string form
591 Does not return addresses on 127.0.0.0/8
593 static PyObject *py_interface_ips(PyObject *self, PyObject *args)
599 struct loadparm_context *lp_ctx;
600 struct interface *ifaces;
604 if (!PyArg_ParseTuple(args, "Oi", &py_lp_ctx, &all_interfaces))
607 lp_ctx = lp_from_py_object(py_lp_ctx);
608 if (lp_ctx == NULL) {
609 PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
613 tmp_ctx = talloc_new(NULL);
615 load_interfaces(tmp_ctx, lp_interfaces(lp_ctx), &ifaces);
617 count = iface_count(ifaces);
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"))) {
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));
635 talloc_free(tmp_ctx);
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,
672 { "dsdb_set_opaque_integer", (PyCFunction)py_dsdb_set_opaque_integer, METH_VARARGS,
674 { "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
676 { "dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS,
678 { "dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction)py_dsdb_write_prefixes_from_schema_to_ldb, METH_VARARGS,
680 { "dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS,
682 { "dsdb_convert_schema_to_openldap", (PyCFunction)py_dsdb_convert_schema_to_openldap, METH_VARARGS,
684 { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS,
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"},
703 m = Py_InitModule3("glue", py_misc_methods,
704 "Python bindings for miscellaneous Samba functions.");
708 PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
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));
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));
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));
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));
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));
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));
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));
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
781 signal(SIGINT, SIG_DFL);