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
);
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
);
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_make_schema_global(PyObject
*self
, PyObject
*args
)
448 struct ldb_context
*ldb
;
450 if (!PyArg_ParseTuple(args
, "O", &py_ldb
))
453 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
455 dsdb_make_schema_global(ldb
);
460 static PyObject
*py_dsdb_load_partition_usn(PyObject
*self
, PyObject
*args
)
462 PyObject
*py_dn
, *py_ldb
, *result
;
464 uint64_t highest_uSN
, urgent_uSN
;
465 struct ldb_context
*ldb
;
469 mem_ctx
= talloc_new(NULL
);
470 if (mem_ctx
== NULL
) {
475 if (!PyArg_ParseTuple(args
, "OO", &py_ldb
, &py_dn
)) {
476 talloc_free(mem_ctx
);
480 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
482 if (!PyObject_AsDn(mem_ctx
, py_dn
, ldb
, &dn
)) {
483 talloc_free(mem_ctx
);
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
);
495 talloc_free(mem_ctx
);
497 result
= PyDict_New();
499 PyDict_SetItemString(result
, "uSNHighest", PyInt_FromLong((uint64_t)highest_uSN
));
500 PyDict_SetItemString(result
, "uSNUrgent", PyInt_FromLong((uint64_t)urgent_uSN
));
509 static PyObject
*py_samdb_ntds_invocation_id(PyObject
*self
, PyObject
*args
)
511 PyObject
*py_ldb
, *result
;
512 struct ldb_context
*ldb
;
514 const struct GUID
*guid
;
516 mem_ctx
= talloc_new(NULL
);
517 if (mem_ctx
== NULL
) {
522 if (!PyArg_ParseTuple(args
, "O", &py_ldb
)) {
523 talloc_free(mem_ctx
);
527 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
529 guid
= samdb_ntds_invocation_id(ldb
);
531 PyErr_SetStringError("Failed to find NTDS invocation ID");
532 talloc_free(mem_ctx
);
536 result
= PyString_FromString(GUID_string(mem_ctx
, guid
));
537 talloc_free(mem_ctx
);
542 static PyObject
*py_samdb_ntds_objectGUID(PyObject
*self
, PyObject
*args
)
544 PyObject
*py_ldb
, *result
;
545 struct ldb_context
*ldb
;
547 const struct GUID
*guid
;
549 mem_ctx
= talloc_new(NULL
);
550 if (mem_ctx
== NULL
) {
555 if (!PyArg_ParseTuple(args
, "O", &py_ldb
)) {
556 talloc_free(mem_ctx
);
560 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
562 guid
= samdb_ntds_objectGUID(ldb
);
564 PyErr_SetStringError("Failed to find NTDS GUID");
565 talloc_free(mem_ctx
);
569 result
= PyString_FromString(GUID_string(mem_ctx
, guid
));
570 talloc_free(mem_ctx
);
575 static PyObject
*py_samdb_server_site_name(PyObject
*self
, PyObject
*args
)
577 PyObject
*py_ldb
, *result
;
578 struct ldb_context
*ldb
;
580 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
582 if (!PyArg_ParseTuple(args
, "O", &py_ldb
)) {
583 talloc_free(mem_ctx
);
587 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
589 site
= samdb_server_site_name(ldb
, mem_ctx
);
591 PyErr_SetStringError("Failed to find server site");
592 talloc_free(mem_ctx
);
596 result
= PyString_FromString(site
);
597 talloc_free(mem_ctx
);
603 return the list of interface IPs we have configured
604 takes an loadparm context, returns a list of IPs in string form
606 Does not return addresses on 127.0.0.0/8
608 static PyObject
*py_interface_ips(PyObject
*self
, PyObject
*args
)
614 struct loadparm_context
*lp_ctx
;
615 struct interface
*ifaces
;
619 if (!PyArg_ParseTuple(args
, "Oi", &py_lp_ctx
, &all_interfaces
))
622 lp_ctx
= lp_from_py_object(py_lp_ctx
);
623 if (lp_ctx
== NULL
) {
624 PyErr_SetString(PyExc_TypeError
, "Expected loadparm object");
628 tmp_ctx
= talloc_new(NULL
);
630 load_interfaces(tmp_ctx
, lp_interfaces(lp_ctx
), &ifaces
);
632 count
= iface_count(ifaces
);
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"))) {
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
));
650 talloc_free(tmp_ctx
);
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
,
687 { "dsdb_set_opaque_integer", (PyCFunction
)py_dsdb_set_opaque_integer
, METH_VARARGS
,
689 { "dsdb_set_global_schema", (PyCFunction
)py_dsdb_set_global_schema
, METH_VARARGS
,
691 { "dsdb_set_schema_from_ldif", (PyCFunction
)py_dsdb_set_schema_from_ldif
, METH_VARARGS
,
693 { "dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction
)py_dsdb_write_prefixes_from_schema_to_ldb
, METH_VARARGS
,
695 { "dsdb_set_schema_from_ldb", (PyCFunction
)py_dsdb_set_schema_from_ldb
, METH_VARARGS
,
697 { "dsdb_convert_schema_to_openldap", (PyCFunction
)py_dsdb_convert_schema_to_openldap
, METH_VARARGS
,
699 { "dsdb_make_schema_global", (PyCFunction
)py_dsdb_make_schema_global
, METH_VARARGS
,
701 { "set_debug_level", (PyCFunction
)py_set_debug_level
, METH_VARARGS
,
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"},
720 m
= Py_InitModule3("glue", py_misc_methods
,
721 "Python bindings for miscellaneous Samba functions.");
725 PyModule_AddObject(m
, "version", PyString_FromString(SAMBA_VERSION_STRING
));
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
));
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
));
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
));
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
));
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
));
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
));
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
783 signal(SIGINT
, SIG_DFL
);