2 Unix SMB/CIFS implementation.
3 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2010
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/>.
24 #include "dsdb/samdb/samdb.h"
25 #include "libcli/security/security.h"
26 #include "librpc/ndr/libndr.h"
27 #include "system/kerberos.h"
28 #include "auth/kerberos/kerberos.h"
29 #include "librpc/rpc/pyrpc_util.h"
30 #include "lib/policy/policy.h"
31 #include "param/pyparam.h"
32 #include "lib/util/dlinklist.h"
33 #include "dsdb/kcc/garbage_collect_tombstones.h"
37 /* FIXME: These should be in a header file somewhere */
38 #define PyErr_LDB_OR_RAISE(py_ldb, ldb) \
39 if (!py_check_dcerpc_type(py_ldb, "ldb", "Ldb")) { \
40 PyErr_SetString(PyExc_TypeError, "Ldb connection object required"); \
43 ldb = pyldb_Ldb_AsLdbContext(py_ldb);
45 #define PyErr_LDB_DN_OR_RAISE(py_ldb_dn, dn) \
46 if (!py_check_dcerpc_type(py_ldb_dn, "ldb", "Dn")) { \
47 PyErr_SetString(PyExc_TypeError, "ldb Dn object required"); \
50 dn = pyldb_Dn_AsDn(py_ldb_dn);
52 static PyObject
*py_ldb_get_exception(void)
54 PyObject
*mod
= PyImport_ImportModule("ldb");
58 return PyObject_GetAttrString(mod
, "LdbError");
61 static void PyErr_SetLdbError(PyObject
*error
, int ret
, struct ldb_context
*ldb_ctx
)
63 if (ret
== LDB_ERR_PYTHON_EXCEPTION
)
64 return; /* Python exception should already be set, just keep that */
66 PyErr_SetObject(error
,
67 Py_BuildValue(discard_const_p(char, "(i,s)"), ret
,
68 ldb_ctx
== NULL
?ldb_strerror(ret
):ldb_errstring(ldb_ctx
)));
71 static PyObject
*py_samdb_server_site_name(PyObject
*self
, PyObject
*args
)
73 PyObject
*py_ldb
, *result
;
74 struct ldb_context
*ldb
;
78 if (!PyArg_ParseTuple(args
, "O", &py_ldb
))
81 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
83 mem_ctx
= talloc_new(NULL
);
84 if (mem_ctx
== NULL
) {
89 site
= samdb_server_site_name(ldb
, mem_ctx
);
91 PyErr_SetString(PyExc_RuntimeError
, "Failed to find server site");
96 result
= PyString_FromString(site
);
101 static PyObject
*py_dsdb_convert_schema_to_openldap(PyObject
*self
,
104 char *target_str
, *mapping
;
106 struct ldb_context
*ldb
;
110 if (!PyArg_ParseTuple(args
, "Oss", &py_ldb
, &target_str
, &mapping
))
113 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
115 retstr
= dsdb_convert_schema_to_openldap(ldb
, target_str
, mapping
);
116 if (retstr
== NULL
) {
117 PyErr_SetString(PyExc_RuntimeError
,
118 "dsdb_convert_schema_to_openldap failed");
122 ret
= PyString_FromString(retstr
);
127 static PyObject
*py_samdb_set_domain_sid(PyLdbObject
*self
, PyObject
*args
)
129 PyObject
*py_ldb
, *py_sid
;
130 struct ldb_context
*ldb
;
134 if (!PyArg_ParseTuple(args
, "OO", &py_ldb
, &py_sid
))
137 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
139 sid
= dom_sid_parse_talloc(NULL
, PyString_AsString(py_sid
));
145 ret
= samdb_set_domain_sid(ldb
, sid
);
148 PyErr_SetString(PyExc_RuntimeError
, "set_domain_sid failed");
154 static PyObject
*py_samdb_set_ntds_settings_dn(PyLdbObject
*self
, PyObject
*args
)
156 PyObject
*py_ldb
, *py_ntds_settings_dn
;
157 struct ldb_context
*ldb
;
158 struct ldb_dn
*ntds_settings_dn
;
162 if (!PyArg_ParseTuple(args
, "OO", &py_ldb
, &py_ntds_settings_dn
))
165 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
167 tmp_ctx
= talloc_new(NULL
);
168 if (tmp_ctx
== NULL
) {
173 if (!pyldb_Object_AsDn(tmp_ctx
, py_ntds_settings_dn
, ldb
, &ntds_settings_dn
)) {
174 /* exception thrown by "pyldb_Object_AsDn" */
175 talloc_free(tmp_ctx
);
179 ret
= samdb_set_ntds_settings_dn(ldb
, ntds_settings_dn
);
180 talloc_free(tmp_ctx
);
182 PyErr_SetString(PyExc_RuntimeError
, "set_ntds_settings_dn failed");
188 static PyObject
*py_samdb_get_domain_sid(PyLdbObject
*self
, PyObject
*args
)
191 struct ldb_context
*ldb
;
192 const struct dom_sid
*sid
;
196 if (!PyArg_ParseTuple(args
, "O", &py_ldb
))
199 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
201 sid
= samdb_domain_sid(ldb
);
203 PyErr_SetString(PyExc_RuntimeError
, "samdb_domain_sid failed");
207 retstr
= dom_sid_string(NULL
, sid
);
208 if (retstr
== NULL
) {
212 ret
= PyString_FromString(retstr
);
217 static PyObject
*py_samdb_ntds_invocation_id(PyObject
*self
, PyObject
*args
)
219 PyObject
*py_ldb
, *result
;
220 struct ldb_context
*ldb
;
221 const struct GUID
*guid
;
224 if (!PyArg_ParseTuple(args
, "O", &py_ldb
)) {
228 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
230 guid
= samdb_ntds_invocation_id(ldb
);
232 PyErr_SetString(PyExc_RuntimeError
,
233 "Failed to find NTDS invocation ID");
237 retstr
= GUID_string(NULL
, guid
);
238 if (retstr
== NULL
) {
242 result
= PyString_FromString(retstr
);
247 static PyObject
*py_dsdb_get_oid_from_attid(PyObject
*self
, PyObject
*args
)
250 struct ldb_context
*ldb
;
252 struct dsdb_schema
*schema
;
258 if (!PyArg_ParseTuple(args
, "OI", &py_ldb
, &attid
))
261 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
263 mem_ctx
= talloc_new(NULL
);
269 schema
= dsdb_get_schema(ldb
, mem_ctx
);
271 PyErr_SetString(PyExc_RuntimeError
, "Failed to find a schema from ldb \n");
272 talloc_free(mem_ctx
);
276 status
= dsdb_schema_pfm_oid_from_attid(schema
->prefixmap
, attid
,
278 if (!W_ERROR_IS_OK(status
)) {
279 PyErr_SetWERROR(status
);
280 talloc_free(mem_ctx
);
284 ret
= PyString_FromString(oid
);
286 talloc_free(mem_ctx
);
292 static PyObject
*py_dsdb_get_attid_from_lDAPDisplayName(PyObject
*self
, PyObject
*args
)
294 PyObject
*py_ldb
, *is_schema_nc
;
295 struct ldb_context
*ldb
;
296 struct dsdb_schema
*schema
;
297 const char *ldap_display_name
;
298 bool schema_nc
= false;
299 const struct dsdb_attribute
*a
;
302 if (!PyArg_ParseTuple(args
, "OsO", &py_ldb
, &ldap_display_name
, &is_schema_nc
))
305 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
308 if (!PyBool_Check(is_schema_nc
)) {
309 PyErr_SetString(PyExc_TypeError
, "Expected boolean is_schema_nc");
312 if (is_schema_nc
== Py_True
) {
317 schema
= dsdb_get_schema(ldb
, NULL
);
320 PyErr_SetString(PyExc_RuntimeError
, "Failed to find a schema from ldb");
324 a
= dsdb_attribute_by_lDAPDisplayName(schema
, ldap_display_name
);
326 PyErr_Format(PyExc_KeyError
, "Failed to find attribute '%s'", ldap_display_name
);
330 attid
= dsdb_attribute_get_attid(a
, schema_nc
);
332 return PyLong_FromUnsignedLong(attid
);
336 return the systemFlags as int from the attribute name
338 static PyObject
*py_dsdb_get_systemFlags_from_lDAPDisplayName(PyObject
*self
, PyObject
*args
)
341 struct ldb_context
*ldb
;
342 struct dsdb_schema
*schema
;
343 const char *ldap_display_name
;
344 const struct dsdb_attribute
*attribute
;
346 if (!PyArg_ParseTuple(args
, "Os", &py_ldb
, &ldap_display_name
))
349 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
351 schema
= dsdb_get_schema(ldb
, NULL
);
354 PyErr_SetString(PyExc_RuntimeError
, "Failed to find a schema from ldb");
358 attribute
= dsdb_attribute_by_lDAPDisplayName(schema
, ldap_display_name
);
359 if (attribute
== NULL
) {
360 PyErr_Format(PyExc_KeyError
, "Failed to find attribute '%s'", ldap_display_name
);
364 return PyInt_FromLong(attribute
->systemFlags
);
368 return the linkID from the attribute name
370 static PyObject
*py_dsdb_get_linkId_from_lDAPDisplayName(PyObject
*self
, PyObject
*args
)
373 struct ldb_context
*ldb
;
374 struct dsdb_schema
*schema
;
375 const char *ldap_display_name
;
376 const struct dsdb_attribute
*attribute
;
378 if (!PyArg_ParseTuple(args
, "Os", &py_ldb
, &ldap_display_name
))
381 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
383 schema
= dsdb_get_schema(ldb
, NULL
);
386 PyErr_SetString(PyExc_RuntimeError
, "Failed to find a schema from ldb");
390 attribute
= dsdb_attribute_by_lDAPDisplayName(schema
, ldap_display_name
);
391 if (attribute
== NULL
) {
392 PyErr_Format(PyExc_KeyError
, "Failed to find attribute '%s'", ldap_display_name
);
396 return PyInt_FromLong(attribute
->linkID
);
400 return the backlink attribute name (if any) for an attribute
402 static PyObject
*py_dsdb_get_backlink_from_lDAPDisplayName(PyObject
*self
, PyObject
*args
)
405 struct ldb_context
*ldb
;
406 struct dsdb_schema
*schema
;
407 const char *ldap_display_name
;
408 const struct dsdb_attribute
*attribute
, *target_attr
;
410 if (!PyArg_ParseTuple(args
, "Os", &py_ldb
, &ldap_display_name
))
413 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
415 schema
= dsdb_get_schema(ldb
, NULL
);
418 PyErr_SetString(PyExc_RuntimeError
, "Failed to find a schema from ldb");
422 attribute
= dsdb_attribute_by_lDAPDisplayName(schema
, ldap_display_name
);
423 if (attribute
== NULL
) {
424 PyErr_Format(PyExc_KeyError
, "Failed to find attribute '%s'", ldap_display_name
);
428 if (attribute
->linkID
== 0) {
432 target_attr
= dsdb_attribute_by_linkID(schema
, attribute
->linkID
^ 1);
433 if (target_attr
== NULL
) {
434 /* when we add pseudo-backlinks we'll need to handle
439 return PyString_FromString(target_attr
->lDAPDisplayName
);
443 static PyObject
*py_dsdb_get_lDAPDisplayName_by_attid(PyObject
*self
, PyObject
*args
)
446 struct ldb_context
*ldb
;
447 struct dsdb_schema
*schema
;
448 const struct dsdb_attribute
*a
;
451 if (!PyArg_ParseTuple(args
, "OI", &py_ldb
, &attid
))
454 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
456 schema
= dsdb_get_schema(ldb
, NULL
);
459 PyErr_SetString(PyExc_RuntimeError
, "Failed to find a schema from ldb");
463 a
= dsdb_attribute_by_attributeID_id(schema
, attid
);
465 PyErr_Format(PyExc_KeyError
, "Failed to find attribute '0x%08x'", attid
);
469 return PyString_FromString(a
->lDAPDisplayName
);
474 return the attribute syntax oid as a string from the attribute name
476 static PyObject
*py_dsdb_get_syntax_oid_from_lDAPDisplayName(PyObject
*self
, PyObject
*args
)
479 struct ldb_context
*ldb
;
480 struct dsdb_schema
*schema
;
481 const char *ldap_display_name
;
482 const struct dsdb_attribute
*attribute
;
484 if (!PyArg_ParseTuple(args
, "Os", &py_ldb
, &ldap_display_name
))
487 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
489 schema
= dsdb_get_schema(ldb
, NULL
);
492 PyErr_SetString(PyExc_RuntimeError
, "Failed to find a schema from ldb");
496 attribute
= dsdb_attribute_by_lDAPDisplayName(schema
, ldap_display_name
);
497 if (attribute
== NULL
) {
498 PyErr_Format(PyExc_KeyError
, "Failed to find attribute '%s'", ldap_display_name
);
502 return PyString_FromString(attribute
->syntax
->ldap_oid
);
506 convert a python string to a DRSUAPI drsuapi_DsReplicaAttribute attribute
508 static PyObject
*py_dsdb_DsReplicaAttribute(PyObject
*self
, PyObject
*args
)
510 PyObject
*py_ldb
, *el_list
, *ret
;
511 struct ldb_context
*ldb
;
512 char *ldap_display_name
;
513 const struct dsdb_attribute
*a
;
514 struct dsdb_schema
*schema
;
515 struct dsdb_syntax_ctx syntax_ctx
;
516 struct ldb_message_element
*el
;
517 struct drsuapi_DsReplicaAttribute
*attr
;
522 if (!PyArg_ParseTuple(args
, "OsO", &py_ldb
, &ldap_display_name
, &el_list
)) {
526 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
528 schema
= dsdb_get_schema(ldb
, NULL
);
530 PyErr_SetString(PyExc_RuntimeError
, "Failed to find a schema from ldb");
534 a
= dsdb_attribute_by_lDAPDisplayName(schema
, ldap_display_name
);
536 PyErr_Format(PyExc_KeyError
, "Failed to find attribute '%s'", ldap_display_name
);
540 dsdb_syntax_ctx_init(&syntax_ctx
, ldb
, schema
);
541 syntax_ctx
.is_schema_nc
= false;
543 tmp_ctx
= talloc_new(ldb
);
544 if (tmp_ctx
== NULL
) {
549 /* If we were not given an LdbMessageElement */
550 if (!PyList_Check(el_list
)) {
551 if (!py_check_dcerpc_type(el_list
, "ldb", "MessageElement")) {
552 PyErr_SetString(py_ldb_get_exception(),
553 "list of strings or ldb MessageElement object required");
558 * el may not be a valid talloc context, it
559 * could be part of an array
561 el
= pyldb_MessageElement_AsMessageElement(el_list
);
563 el
= talloc_zero(tmp_ctx
, struct ldb_message_element
);
566 talloc_free(tmp_ctx
);
570 el
->name
= ldap_display_name
;
571 el
->num_values
= PyList_Size(el_list
);
573 el
->values
= talloc_array(el
, struct ldb_val
, el
->num_values
);
574 if (el
->values
== NULL
) {
576 talloc_free(tmp_ctx
);
580 for (i
= 0; i
< el
->num_values
; i
++) {
581 PyObject
*item
= PyList_GetItem(el_list
, i
);
582 if (!PyString_Check(item
)) {
583 PyErr_Format(PyExc_TypeError
, "ldif_elements should be strings");
584 talloc_free(tmp_ctx
);
587 el
->values
[i
].data
= (uint8_t *)PyString_AsString(item
);
588 el
->values
[i
].length
= PyString_Size(item
);
592 attr
= talloc_zero(tmp_ctx
, struct drsuapi_DsReplicaAttribute
);
595 talloc_free(tmp_ctx
);
599 werr
= a
->syntax
->ldb_to_drsuapi(&syntax_ctx
, a
, el
, attr
, attr
);
600 PyErr_WERROR_NOT_OK_RAISE(werr
);
602 ret
= py_return_ndr_struct("samba.dcerpc.drsuapi", "DsReplicaAttribute", attr
, attr
);
604 talloc_free(tmp_ctx
);
611 normalise a ldb attribute list
613 static PyObject
*py_dsdb_normalise_attributes(PyObject
*self
, PyObject
*args
)
615 PyObject
*py_ldb
, *el_list
, *py_ret
;
616 struct ldb_context
*ldb
;
617 char *ldap_display_name
;
618 const struct dsdb_attribute
*a
;
619 struct dsdb_schema
*schema
;
620 struct dsdb_syntax_ctx syntax_ctx
;
621 struct ldb_message_element
*el
, *new_el
;
622 struct drsuapi_DsReplicaAttribute
*attr
;
623 PyLdbMessageElementObject
*ret
;
627 PyTypeObject
*py_type
= NULL
;
628 PyObject
*module
= NULL
;
630 if (!PyArg_ParseTuple(args
, "OsO", &py_ldb
, &ldap_display_name
, &el_list
)) {
634 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
636 schema
= dsdb_get_schema(ldb
, NULL
);
638 PyErr_SetString(PyExc_RuntimeError
, "Failed to find a schema from ldb");
642 a
= dsdb_attribute_by_lDAPDisplayName(schema
, ldap_display_name
);
644 PyErr_Format(PyExc_KeyError
, "Failed to find attribute '%s'", ldap_display_name
);
648 dsdb_syntax_ctx_init(&syntax_ctx
, ldb
, schema
);
649 syntax_ctx
.is_schema_nc
= false;
651 tmp_ctx
= talloc_new(ldb
);
652 if (tmp_ctx
== NULL
) {
657 if (!PyList_Check(el_list
)) {
658 if (!py_check_dcerpc_type(el_list
, "ldb", "MessageElement")) {
659 PyErr_SetString(py_ldb_get_exception(),
660 "list of strings or ldb MessageElement object required");
665 * el may not be a valid talloc context, it
666 * could be part of an array
668 el
= pyldb_MessageElement_AsMessageElement(el_list
);
670 el
= talloc_zero(tmp_ctx
, struct ldb_message_element
);
673 talloc_free(tmp_ctx
);
677 el
->name
= ldap_display_name
;
678 el
->num_values
= PyList_Size(el_list
);
680 el
->values
= talloc_array(el
, struct ldb_val
, el
->num_values
);
681 if (el
->values
== NULL
) {
683 talloc_free(tmp_ctx
);
687 for (i
= 0; i
< el
->num_values
; i
++) {
688 PyObject
*item
= PyList_GetItem(el_list
, i
);
689 if (!PyString_Check(item
)) {
690 PyErr_Format(PyExc_TypeError
, "ldif_elements should be strings");
691 talloc_free(tmp_ctx
);
694 el
->values
[i
].data
= (uint8_t *)PyString_AsString(item
);
695 el
->values
[i
].length
= PyString_Size(item
);
699 new_el
= talloc_zero(tmp_ctx
, struct ldb_message_element
);
700 if (new_el
== NULL
) {
702 talloc_free(tmp_ctx
);
706 /* Normalise "objectClass" attribute if needed */
707 if (ldb_attr_cmp(a
->lDAPDisplayName
, "objectClass") == 0) {
709 iret
= dsdb_sort_objectClass_attr(ldb
, schema
, el
, new_el
, new_el
);
710 if (iret
!= LDB_SUCCESS
) {
711 PyErr_SetString(PyExc_RuntimeError
, ldb_errstring(ldb
));
712 talloc_free(tmp_ctx
);
717 /* first run ldb_to_drsuapi, then convert back again. This has
718 * the effect of normalising the attributes
721 attr
= talloc_zero(tmp_ctx
, struct drsuapi_DsReplicaAttribute
);
724 talloc_free(tmp_ctx
);
728 werr
= a
->syntax
->ldb_to_drsuapi(&syntax_ctx
, a
, el
, attr
, attr
);
729 PyErr_WERROR_NOT_OK_RAISE(werr
);
731 /* now convert back again */
732 werr
= a
->syntax
->drsuapi_to_ldb(&syntax_ctx
, a
, attr
, new_el
, new_el
);
733 PyErr_WERROR_NOT_OK_RAISE(werr
);
735 module
= PyImport_ImportModule("ldb");
736 if (module
== NULL
) {
740 py_type
= (PyTypeObject
*)PyObject_GetAttrString(module
, "MessageElement");
741 if (py_type
== NULL
) {
744 py_ret
= py_type
->tp_alloc(py_type
, 0);
745 ret
= (PyLdbMessageElementObject
*)py_ret
;
747 ret
->mem_ctx
= talloc_new(NULL
);
748 if (talloc_reference(ret
->mem_ctx
, new_el
) == NULL
) {
754 talloc_free(tmp_ctx
);
760 static PyObject
*py_dsdb_set_ntds_invocation_id(PyObject
*self
, PyObject
*args
)
762 PyObject
*py_ldb
, *py_guid
;
765 struct ldb_context
*ldb
;
766 if (!PyArg_ParseTuple(args
, "OO", &py_ldb
, &py_guid
))
769 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
770 GUID_from_string(PyString_AsString(py_guid
), &guid
);
772 if (GUID_all_zero(&guid
)) {
773 PyErr_SetString(PyExc_RuntimeError
, "set_ntds_invocation_id rejected due to all-zero invocation ID");
777 ret
= samdb_set_ntds_invocation_id(ldb
, &guid
);
779 PyErr_SetString(PyExc_RuntimeError
, "set_ntds_invocation_id failed");
785 static PyObject
*py_samdb_ntds_objectGUID(PyObject
*self
, PyObject
*args
)
787 PyObject
*py_ldb
, *result
;
788 struct ldb_context
*ldb
;
789 const struct GUID
*guid
;
792 if (!PyArg_ParseTuple(args
, "O", &py_ldb
)) {
796 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
798 guid
= samdb_ntds_objectGUID(ldb
);
800 PyErr_SetString(PyExc_RuntimeError
, "Failed to find NTDS GUID");
804 retstr
= GUID_string(NULL
, guid
);
805 if (retstr
== NULL
) {
809 result
= PyString_FromString(retstr
);
814 static PyObject
*py_dsdb_set_global_schema(PyObject
*self
, PyObject
*args
)
817 struct ldb_context
*ldb
;
819 if (!PyArg_ParseTuple(args
, "O", &py_ldb
))
822 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
824 ret
= dsdb_set_global_schema(ldb
);
825 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret
, ldb
);
830 static PyObject
*py_dsdb_load_partition_usn(PyObject
*self
, PyObject
*args
)
832 PyObject
*py_dn
, *py_ldb
, *result
;
834 uint64_t highest_uSN
, urgent_uSN
;
835 struct ldb_context
*ldb
;
839 if (!PyArg_ParseTuple(args
, "OO", &py_ldb
, &py_dn
)) {
843 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
845 mem_ctx
= talloc_new(NULL
);
846 if (mem_ctx
== NULL
) {
851 if (!pyldb_Object_AsDn(mem_ctx
, py_dn
, ldb
, &dn
)) {
852 talloc_free(mem_ctx
);
856 ret
= dsdb_load_partition_usn(ldb
, dn
, &highest_uSN
, &urgent_uSN
);
857 if (ret
!= LDB_SUCCESS
) {
858 PyErr_Format(PyExc_RuntimeError
,
859 "Failed to load partition [%s] uSN - %s",
860 ldb_dn_get_linearized(dn
),
862 talloc_free(mem_ctx
);
866 talloc_free(mem_ctx
);
868 result
= PyDict_New();
870 PyDict_SetItemString(result
, "uSNHighest", PyInt_FromLong((uint64_t)highest_uSN
));
871 PyDict_SetItemString(result
, "uSNUrgent", PyInt_FromLong((uint64_t)urgent_uSN
));
877 static PyObject
*py_dsdb_set_am_rodc(PyObject
*self
, PyObject
*args
)
881 struct ldb_context
*ldb
;
884 if (!PyArg_ParseTuple(args
, "Oi", &py_ldb
, &py_val
))
887 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
888 ret
= samdb_set_am_rodc(ldb
, (bool)py_val
);
890 PyErr_SetString(PyExc_RuntimeError
, "set_am_rodc failed");
896 static PyObject
*py_dsdb_set_schema_from_ldif(PyObject
*self
, PyObject
*args
)
901 struct ldb_context
*ldb
;
903 if (!PyArg_ParseTuple(args
, "Osss", &py_ldb
, &pf
, &df
, &dn
))
906 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
908 result
= dsdb_set_schema_from_ldif(ldb
, pf
, df
, dn
);
909 PyErr_WERROR_NOT_OK_RAISE(result
);
914 static PyObject
*py_dsdb_set_schema_from_ldb(PyObject
*self
, PyObject
*args
)
917 struct ldb_context
*ldb
;
918 PyObject
*py_from_ldb
;
919 struct ldb_context
*from_ldb
;
920 struct dsdb_schema
*schema
;
922 char write_indices_and_attributes
= true;
923 if (!PyArg_ParseTuple(args
, "OO|b",
924 &py_ldb
, &py_from_ldb
, &write_indices_and_attributes
))
927 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
929 PyErr_LDB_OR_RAISE(py_from_ldb
, from_ldb
);
931 schema
= dsdb_get_schema(from_ldb
, NULL
);
933 PyErr_SetString(PyExc_RuntimeError
, "Failed to set find a schema on 'from' ldb!\n");
937 ret
= dsdb_reference_schema(ldb
, schema
, write_indices_and_attributes
);
938 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret
, ldb
);
943 static PyObject
*py_dsdb_write_prefixes_from_schema_to_ldb(PyObject
*self
, PyObject
*args
)
946 struct ldb_context
*ldb
;
948 struct dsdb_schema
*schema
;
950 if (!PyArg_ParseTuple(args
, "O", &py_ldb
))
953 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
955 schema
= dsdb_get_schema(ldb
, NULL
);
957 PyErr_SetString(PyExc_RuntimeError
, "Failed to set find a schema on ldb!\n");
961 result
= dsdb_write_prefixes_from_schema_to_ldb(NULL
, ldb
, schema
);
962 PyErr_WERROR_NOT_OK_RAISE(result
);
968 static PyObject
*py_dsdb_get_partitions_dn(PyObject
*self
, PyObject
*args
)
970 struct ldb_context
*ldb
;
972 PyObject
*py_ldb
, *ret
;
974 if (!PyArg_ParseTuple(args
, "O", &py_ldb
))
977 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
979 dn
= samdb_partitions_dn(ldb
, NULL
);
984 ret
= pyldb_Dn_FromDn(dn
);
990 static PyObject
*py_dsdb_get_nc_root(PyObject
*self
, PyObject
*args
)
992 struct ldb_context
*ldb
;
993 struct ldb_dn
*dn
, *nc_root
;
994 PyObject
*py_ldb
, *py_ldb_dn
, *py_nc_root
;
997 if (!PyArg_ParseTuple(args
, "OO", &py_ldb
, &py_ldb_dn
))
1000 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
1001 PyErr_LDB_DN_OR_RAISE(py_ldb_dn
, dn
);
1003 ret
= dsdb_find_nc_root(ldb
, ldb
, dn
, &nc_root
);
1004 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret
, ldb
);
1006 py_nc_root
= pyldb_Dn_FromDn(nc_root
);
1007 talloc_unlink(ldb
, nc_root
);
1011 static PyObject
*py_dsdb_get_wellknown_dn(PyObject
*self
, PyObject
*args
)
1013 struct ldb_context
*ldb
;
1014 struct ldb_dn
*nc_dn
, *wk_dn
;
1016 PyObject
*py_ldb
, *py_nc_dn
, *py_wk_dn
;
1019 if (!PyArg_ParseTuple(args
, "OOs", &py_ldb
, &py_nc_dn
, &wkguid
))
1022 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
1023 PyErr_LDB_DN_OR_RAISE(py_nc_dn
, nc_dn
);
1025 ret
= dsdb_wellknown_dn(ldb
, ldb
, nc_dn
, wkguid
, &wk_dn
);
1026 if (ret
== LDB_ERR_NO_SUCH_OBJECT
) {
1027 PyErr_Format(PyExc_KeyError
, "Failed to find well known DN for GUID %s", wkguid
);
1031 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret
, ldb
);
1033 py_wk_dn
= pyldb_Dn_FromDn(wk_dn
);
1034 talloc_unlink(ldb
, wk_dn
);
1040 call into samdb_rodc()
1042 static PyObject
*py_dsdb_am_rodc(PyObject
*self
, PyObject
*args
)
1045 struct ldb_context
*ldb
;
1049 if (!PyArg_ParseTuple(args
, "O", &py_ldb
))
1052 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
1054 ret
= samdb_rodc(ldb
, &am_rodc
);
1055 if (ret
!= LDB_SUCCESS
) {
1056 PyErr_SetString(PyExc_RuntimeError
, ldb_errstring(ldb
));
1060 return PyBool_FromLong(am_rodc
);
1064 call into samdb_is_pdc()
1066 static PyObject
*py_dsdb_am_pdc(PyObject
*self
, PyObject
*args
)
1069 struct ldb_context
*ldb
;
1072 if (!PyArg_ParseTuple(args
, "O", &py_ldb
))
1075 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
1077 am_pdc
= samdb_is_pdc(ldb
);
1078 return PyBool_FromLong(am_pdc
);
1082 call DSDB_EXTENDED_CREATE_OWN_RID_SET to get a new RID set for this server
1084 static PyObject
*py_dsdb_create_own_rid_set(PyObject
*self
, PyObject
*args
)
1087 struct ldb_context
*ldb
;
1089 struct ldb_result
*ext_res
;
1091 if (!PyArg_ParseTuple(args
, "O", &py_ldb
))
1094 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
1097 * Run DSDB_EXTENDED_CREATE_OWN_RID_SET to get a RID set
1100 ret
= ldb_extended(ldb
, DSDB_EXTENDED_CREATE_OWN_RID_SET
, NULL
, &ext_res
);
1102 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret
, ldb
);
1104 TALLOC_FREE(ext_res
);
1110 call DSDB_EXTENDED_ALLOCATE_RID to get a new RID set for this server
1112 static PyObject
*py_dsdb_allocate_rid(PyObject
*self
, PyObject
*args
)
1115 struct ldb_context
*ldb
;
1118 struct ldb_result
*ext_res
= NULL
;
1119 struct dsdb_extended_allocate_rid
*rid_return
= NULL
;
1120 if (!PyArg_ParseTuple(args
, "O", &py_ldb
)) {
1124 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
1126 rid_return
= talloc_zero(ldb
, struct dsdb_extended_allocate_rid
);
1127 if (rid_return
== NULL
) {
1128 return PyErr_NoMemory();
1132 * Run DSDB_EXTENDED_ALLOCATE_RID to get a new RID
1135 ret
= ldb_extended(ldb
, DSDB_EXTENDED_ALLOCATE_RID
, rid_return
, &ext_res
);
1136 if (ret
!= LDB_SUCCESS
) {
1137 TALLOC_FREE(rid_return
);
1138 TALLOC_FREE(ext_res
);
1139 PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret
, ldb
);
1142 rid
= rid_return
->rid
;
1143 TALLOC_FREE(rid_return
);
1144 TALLOC_FREE(ext_res
);
1146 return PyInt_FromLong(rid
);
1149 static PyObject
*py_dsdb_garbage_collect_tombstones(PyObject
*self
, PyObject
*args
)
1151 PyObject
*py_ldb
, *py_list_dn
;
1152 struct ldb_context
*ldb
= NULL
;
1155 long long _current_time
, _tombstone_lifetime
= LLONG_MAX
;
1156 uint32_t tombstone_lifetime32
;
1157 struct dsdb_ldb_dn_list_node
*part
= NULL
;
1158 time_t current_time
, tombstone_lifetime
;
1159 TALLOC_CTX
*mem_ctx
= NULL
;
1161 unsigned int num_objects_removed
= 0;
1162 unsigned int num_links_removed
= 0;
1163 char *error_string
= NULL
;
1165 if (!PyArg_ParseTuple(args
, "OOL|L", &py_ldb
,
1166 &py_list_dn
, &_current_time
, &_tombstone_lifetime
)) {
1171 PyErr_LDB_OR_RAISE(py_ldb
, ldb
);
1173 mem_ctx
= talloc_new(ldb
);
1174 if (mem_ctx
== NULL
) {
1175 return PyErr_NoMemory();
1178 current_time
= _current_time
;
1180 if (_tombstone_lifetime
== LLONG_MAX
) {
1181 int ret
= dsdb_tombstone_lifetime(ldb
, &tombstone_lifetime32
);
1182 if (ret
!= LDB_SUCCESS
) {
1183 PyErr_Format(PyExc_RuntimeError
,
1184 "Failed to get tombstone lifetime: %s",
1185 ldb_errstring(ldb
));
1186 TALLOC_FREE(mem_ctx
);
1189 tombstone_lifetime
= tombstone_lifetime32
;
1191 tombstone_lifetime
= _tombstone_lifetime
;
1194 if (!PyList_Check(py_list_dn
)) {
1195 PyErr_SetString(PyExc_TypeError
, "A list of DNs were expected");
1196 TALLOC_FREE(mem_ctx
);
1200 length
= PyList_GET_SIZE(py_list_dn
);
1202 for (i
= 0; i
< length
; i
++) {
1203 char *part_str
= PyString_AsString(PyList_GetItem(py_list_dn
, i
));
1205 struct dsdb_ldb_dn_list_node
*node
;
1207 if (part_str
== NULL
) {
1208 TALLOC_FREE(mem_ctx
);
1209 return PyErr_NoMemory();
1212 p
= ldb_dn_new(mem_ctx
, ldb
, part_str
);
1214 PyErr_Format(PyExc_RuntimeError
, "Failed to parse DN %s", part_str
);
1215 TALLOC_FREE(mem_ctx
);
1218 node
= talloc_zero(mem_ctx
, struct dsdb_ldb_dn_list_node
);
1221 DLIST_ADD_END(part
, node
);
1224 status
= dsdb_garbage_collect_tombstones(mem_ctx
, ldb
,
1227 &num_objects_removed
,
1231 if (!NT_STATUS_IS_OK(status
)) {
1233 PyErr_Format(PyExc_RuntimeError
, "%s", error_string
);
1235 PyErr_SetNTSTATUS(status
);
1237 TALLOC_FREE(mem_ctx
);
1241 TALLOC_FREE(mem_ctx
);
1243 return Py_BuildValue("(II)", num_objects_removed
,
1248 static PyMethodDef py_dsdb_methods
[] = {
1249 { "_samdb_server_site_name", (PyCFunction
)py_samdb_server_site_name
,
1250 METH_VARARGS
, "Get the server site name as a string"},
1251 { "_dsdb_convert_schema_to_openldap",
1252 (PyCFunction
)py_dsdb_convert_schema_to_openldap
, METH_VARARGS
,
1253 "dsdb_convert_schema_to_openldap(ldb, target_str, mapping) -> str\n"
1254 "Create an OpenLDAP schema from a schema." },
1255 { "_samdb_set_domain_sid", (PyCFunction
)py_samdb_set_domain_sid
,
1257 "samdb_set_domain_sid(samdb, sid)\n"
1258 "Set SID of domain to use." },
1259 { "_samdb_get_domain_sid", (PyCFunction
)py_samdb_get_domain_sid
,
1261 "samdb_get_domain_sid(samdb)\n"
1262 "Get SID of domain in use." },
1263 { "_samdb_ntds_invocation_id", (PyCFunction
)py_samdb_ntds_invocation_id
,
1264 METH_VARARGS
, "get the NTDS invocation ID GUID as a string"},
1265 { "_samdb_set_ntds_settings_dn", (PyCFunction
)py_samdb_set_ntds_settings_dn
,
1267 "samdb_set_ntds_settings_dn(samdb, ntds_settings_dn)\n"
1268 "Set NTDS Settings DN for this LDB (allows it to be set before the DB fully exists)." },
1269 { "_dsdb_get_oid_from_attid", (PyCFunction
)py_dsdb_get_oid_from_attid
,
1270 METH_VARARGS
, NULL
},
1271 { "_dsdb_get_attid_from_lDAPDisplayName", (PyCFunction
)py_dsdb_get_attid_from_lDAPDisplayName
,
1272 METH_VARARGS
, NULL
},
1273 { "_dsdb_get_syntax_oid_from_lDAPDisplayName", (PyCFunction
)py_dsdb_get_syntax_oid_from_lDAPDisplayName
,
1274 METH_VARARGS
, NULL
},
1275 { "_dsdb_get_systemFlags_from_lDAPDisplayName", (PyCFunction
)py_dsdb_get_systemFlags_from_lDAPDisplayName
,
1276 METH_VARARGS
, NULL
},
1277 { "_dsdb_get_linkId_from_lDAPDisplayName", (PyCFunction
)py_dsdb_get_linkId_from_lDAPDisplayName
,
1278 METH_VARARGS
, NULL
},
1279 { "_dsdb_get_lDAPDisplayName_by_attid", (PyCFunction
)py_dsdb_get_lDAPDisplayName_by_attid
,
1280 METH_VARARGS
, NULL
},
1281 { "_dsdb_get_backlink_from_lDAPDisplayName", (PyCFunction
)py_dsdb_get_backlink_from_lDAPDisplayName
,
1282 METH_VARARGS
, NULL
},
1283 { "_dsdb_set_ntds_invocation_id",
1284 (PyCFunction
)py_dsdb_set_ntds_invocation_id
, METH_VARARGS
,
1286 { "_samdb_ntds_objectGUID", (PyCFunction
)py_samdb_ntds_objectGUID
,
1287 METH_VARARGS
, "get the NTDS objectGUID as a string"},
1288 { "_dsdb_set_global_schema", (PyCFunction
)py_dsdb_set_global_schema
,
1289 METH_VARARGS
, NULL
},
1290 { "_dsdb_load_partition_usn", (PyCFunction
)py_dsdb_load_partition_usn
,
1292 "get uSNHighest and uSNUrgent from the partition @REPLCHANGED"},
1293 { "_dsdb_set_am_rodc",
1294 (PyCFunction
)py_dsdb_set_am_rodc
, METH_VARARGS
,
1297 (PyCFunction
)py_dsdb_am_rodc
, METH_VARARGS
,
1300 (PyCFunction
)py_dsdb_am_pdc
, METH_VARARGS
,
1302 { "_dsdb_set_schema_from_ldif", (PyCFunction
)py_dsdb_set_schema_from_ldif
, METH_VARARGS
,
1304 { "_dsdb_set_schema_from_ldb", (PyCFunction
)py_dsdb_set_schema_from_ldb
, METH_VARARGS
,
1306 { "_dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction
)py_dsdb_write_prefixes_from_schema_to_ldb
, METH_VARARGS
,
1308 { "_dsdb_get_partitions_dn", (PyCFunction
)py_dsdb_get_partitions_dn
, METH_VARARGS
, NULL
},
1309 { "_dsdb_get_nc_root", (PyCFunction
)py_dsdb_get_nc_root
, METH_VARARGS
, NULL
},
1310 { "_dsdb_get_wellknown_dn", (PyCFunction
)py_dsdb_get_wellknown_dn
, METH_VARARGS
, NULL
},
1311 { "_dsdb_DsReplicaAttribute", (PyCFunction
)py_dsdb_DsReplicaAttribute
, METH_VARARGS
, NULL
},
1312 { "_dsdb_normalise_attributes", (PyCFunction
)py_dsdb_normalise_attributes
, METH_VARARGS
, NULL
},
1313 { "_dsdb_garbage_collect_tombstones", (PyCFunction
)py_dsdb_garbage_collect_tombstones
, METH_VARARGS
,
1314 "_dsdb_kcc_check_deleted(samdb, [dn], current_time, tombstone_lifetime)"
1315 " -> (num_objects_expunged, num_links_expunged)" },
1316 { "_dsdb_create_own_rid_set", (PyCFunction
)py_dsdb_create_own_rid_set
, METH_VARARGS
,
1317 "_dsdb_create_own_rid_set(samdb)"
1319 { "_dsdb_allocate_rid", (PyCFunction
)py_dsdb_allocate_rid
, METH_VARARGS
,
1320 "_dsdb_allocate_rid(samdb)"
1329 m
= Py_InitModule3("dsdb", py_dsdb_methods
,
1330 "Python bindings for the directory service databases.");
1334 #define ADD_DSDB_FLAG(val) PyModule_AddObject(m, #val, PyInt_FromLong(val))
1336 /* "userAccountControl" flags */
1337 ADD_DSDB_FLAG(UF_NORMAL_ACCOUNT
);
1338 ADD_DSDB_FLAG(UF_TEMP_DUPLICATE_ACCOUNT
);
1339 ADD_DSDB_FLAG(UF_SERVER_TRUST_ACCOUNT
);
1340 ADD_DSDB_FLAG(UF_WORKSTATION_TRUST_ACCOUNT
);
1341 ADD_DSDB_FLAG(UF_INTERDOMAIN_TRUST_ACCOUNT
);
1342 ADD_DSDB_FLAG(UF_PASSWD_NOTREQD
);
1343 ADD_DSDB_FLAG(UF_ACCOUNTDISABLE
);
1345 ADD_DSDB_FLAG(UF_SCRIPT
);
1346 ADD_DSDB_FLAG(UF_ACCOUNTDISABLE
);
1347 ADD_DSDB_FLAG(UF_00000004
);
1348 ADD_DSDB_FLAG(UF_HOMEDIR_REQUIRED
);
1349 ADD_DSDB_FLAG(UF_LOCKOUT
);
1350 ADD_DSDB_FLAG(UF_PASSWD_NOTREQD
);
1351 ADD_DSDB_FLAG(UF_PASSWD_CANT_CHANGE
);
1352 ADD_DSDB_FLAG(UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED
);
1353 ADD_DSDB_FLAG(UF_TEMP_DUPLICATE_ACCOUNT
);
1354 ADD_DSDB_FLAG(UF_NORMAL_ACCOUNT
);
1355 ADD_DSDB_FLAG(UF_00000400
);
1356 ADD_DSDB_FLAG(UF_INTERDOMAIN_TRUST_ACCOUNT
);
1357 ADD_DSDB_FLAG(UF_WORKSTATION_TRUST_ACCOUNT
);
1358 ADD_DSDB_FLAG(UF_SERVER_TRUST_ACCOUNT
);
1359 ADD_DSDB_FLAG(UF_00004000
);
1360 ADD_DSDB_FLAG(UF_00008000
);
1361 ADD_DSDB_FLAG(UF_DONT_EXPIRE_PASSWD
);
1362 ADD_DSDB_FLAG(UF_MNS_LOGON_ACCOUNT
);
1363 ADD_DSDB_FLAG(UF_SMARTCARD_REQUIRED
);
1364 ADD_DSDB_FLAG(UF_TRUSTED_FOR_DELEGATION
);
1365 ADD_DSDB_FLAG(UF_NOT_DELEGATED
);
1366 ADD_DSDB_FLAG(UF_USE_DES_KEY_ONLY
);
1367 ADD_DSDB_FLAG(UF_DONT_REQUIRE_PREAUTH
);
1368 ADD_DSDB_FLAG(UF_PASSWORD_EXPIRED
);
1369 ADD_DSDB_FLAG(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
);
1370 ADD_DSDB_FLAG(UF_NO_AUTH_DATA_REQUIRED
);
1371 ADD_DSDB_FLAG(UF_PARTIAL_SECRETS_ACCOUNT
);
1372 ADD_DSDB_FLAG(UF_USE_AES_KEYS
);
1374 /* groupType flags */
1375 ADD_DSDB_FLAG(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
);
1376 ADD_DSDB_FLAG(GTYPE_SECURITY_GLOBAL_GROUP
);
1377 ADD_DSDB_FLAG(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
);
1378 ADD_DSDB_FLAG(GTYPE_SECURITY_UNIVERSAL_GROUP
);
1379 ADD_DSDB_FLAG(GTYPE_DISTRIBUTION_GLOBAL_GROUP
);
1380 ADD_DSDB_FLAG(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP
);
1381 ADD_DSDB_FLAG(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP
);
1383 /* "sAMAccountType" flags */
1384 ADD_DSDB_FLAG(ATYPE_NORMAL_ACCOUNT
);
1385 ADD_DSDB_FLAG(ATYPE_WORKSTATION_TRUST
);
1386 ADD_DSDB_FLAG(ATYPE_INTERDOMAIN_TRUST
);
1387 ADD_DSDB_FLAG(ATYPE_SECURITY_GLOBAL_GROUP
);
1388 ADD_DSDB_FLAG(ATYPE_SECURITY_LOCAL_GROUP
);
1389 ADD_DSDB_FLAG(ATYPE_SECURITY_UNIVERSAL_GROUP
);
1390 ADD_DSDB_FLAG(ATYPE_DISTRIBUTION_GLOBAL_GROUP
);
1391 ADD_DSDB_FLAG(ATYPE_DISTRIBUTION_LOCAL_GROUP
);
1392 ADD_DSDB_FLAG(ATYPE_DISTRIBUTION_UNIVERSAL_GROUP
);
1394 /* "domainFunctionality", "forestFunctionality" flags in the rootDSE */
1395 ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2000
);
1396 ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2003_MIXED
);
1397 ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2003
);
1398 ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2008
);
1399 ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2008_R2
);
1400 ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2012
);
1401 ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2012_R2
);
1403 /* nc replica flags */
1404 ADD_DSDB_FLAG(INSTANCE_TYPE_IS_NC_HEAD
);
1405 ADD_DSDB_FLAG(INSTANCE_TYPE_UNINSTANT
);
1406 ADD_DSDB_FLAG(INSTANCE_TYPE_WRITE
);
1407 ADD_DSDB_FLAG(INSTANCE_TYPE_NC_ABOVE
);
1408 ADD_DSDB_FLAG(INSTANCE_TYPE_NC_COMING
);
1409 ADD_DSDB_FLAG(INSTANCE_TYPE_NC_GOING
);
1412 ADD_DSDB_FLAG(SYSTEM_FLAG_CR_NTDS_NC
);
1413 ADD_DSDB_FLAG(SYSTEM_FLAG_CR_NTDS_DOMAIN
);
1414 ADD_DSDB_FLAG(SYSTEM_FLAG_CR_NTDS_NOT_GC_REPLICATED
);
1415 ADD_DSDB_FLAG(SYSTEM_FLAG_SCHEMA_BASE_OBJECT
);
1416 ADD_DSDB_FLAG(SYSTEM_FLAG_ATTR_IS_RDN
);
1417 ADD_DSDB_FLAG(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE
);
1418 ADD_DSDB_FLAG(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE
);
1419 ADD_DSDB_FLAG(SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME
);
1420 ADD_DSDB_FLAG(SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE
);
1421 ADD_DSDB_FLAG(SYSTEM_FLAG_CONFIG_ALLOW_MOVE
);
1422 ADD_DSDB_FLAG(SYSTEM_FLAG_CONFIG_ALLOW_RENAME
);
1423 ADD_DSDB_FLAG(SYSTEM_FLAG_DISALLOW_DELETE
);
1425 /* Kerberos encryption type constants */
1426 ADD_DSDB_FLAG(ENC_ALL_TYPES
);
1427 ADD_DSDB_FLAG(ENC_CRC32
);
1428 ADD_DSDB_FLAG(ENC_RSA_MD5
);
1429 ADD_DSDB_FLAG(ENC_RC4_HMAC_MD5
);
1430 ADD_DSDB_FLAG(ENC_HMAC_SHA1_96_AES128
);
1431 ADD_DSDB_FLAG(ENC_HMAC_SHA1_96_AES256
);
1433 ADD_DSDB_FLAG(SEARCH_FLAG_ATTINDEX
);
1434 ADD_DSDB_FLAG(SEARCH_FLAG_PDNTATTINDEX
);
1435 ADD_DSDB_FLAG(SEARCH_FLAG_ANR
);
1436 ADD_DSDB_FLAG(SEARCH_FLAG_PRESERVEONDELETE
);
1437 ADD_DSDB_FLAG(SEARCH_FLAG_COPY
);
1438 ADD_DSDB_FLAG(SEARCH_FLAG_TUPLEINDEX
);
1439 ADD_DSDB_FLAG(SEARCH_FLAG_SUBTREEATTRINDEX
);
1440 ADD_DSDB_FLAG(SEARCH_FLAG_CONFIDENTIAL
);
1441 ADD_DSDB_FLAG(SEARCH_FLAG_NEVERVALUEAUDIT
);
1442 ADD_DSDB_FLAG(SEARCH_FLAG_RODC_ATTRIBUTE
);
1444 ADD_DSDB_FLAG(DS_FLAG_ATTR_NOT_REPLICATED
);
1445 ADD_DSDB_FLAG(DS_FLAG_ATTR_REQ_PARTIAL_SET_MEMBER
);
1446 ADD_DSDB_FLAG(DS_FLAG_ATTR_IS_CONSTRUCTED
);
1448 ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_AUTO_TOPOLOGY_DISABLED
);
1449 ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_TOPL_CLEANUP_DISABLED
);
1450 ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_TOPL_MIN_HOPS_DISABLED
);
1451 ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_TOPL_DETECT_STALE_DISABLED
);
1452 ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED
);
1453 ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_GROUP_CACHING_ENABLED
);
1454 ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_FORCE_KCC_WHISTLER_BEHAVIOR
);
1455 ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_RAND_BH_SELECTION_DISABLED
);
1456 ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_SCHEDULE_HASHING_ENABLED
);
1457 ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_REDUNDANT_SERVER_TOPOLOGY_ENABLED
);
1459 ADD_DSDB_FLAG(DS_NTDSDSA_OPT_IS_GC
);
1460 ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL
);
1461 ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL
);
1462 ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_NTDSCONN_XLATE
);
1463 ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_SPN_REGISTRATION
);
1465 ADD_DSDB_FLAG(NTDSCONN_KCC_GC_TOPOLOGY
);
1466 ADD_DSDB_FLAG(NTDSCONN_KCC_RING_TOPOLOGY
);
1467 ADD_DSDB_FLAG(NTDSCONN_KCC_MINIMIZE_HOPS_TOPOLOGY
);
1468 ADD_DSDB_FLAG(NTDSCONN_KCC_STALE_SERVERS_TOPOLOGY
);
1469 ADD_DSDB_FLAG(NTDSCONN_KCC_OSCILLATING_CONNECTION_TOPOLOGY
);
1470 ADD_DSDB_FLAG(NTDSCONN_KCC_INTERSITE_GC_TOPOLOGY
);
1471 ADD_DSDB_FLAG(NTDSCONN_KCC_INTERSITE_TOPOLOGY
);
1472 ADD_DSDB_FLAG(NTDSCONN_KCC_SERVER_FAILOVER_TOPOLOGY
);
1473 ADD_DSDB_FLAG(NTDSCONN_KCC_SITE_FAILOVER_TOPOLOGY
);
1474 ADD_DSDB_FLAG(NTDSCONN_KCC_REDUNDANT_SERVER_TOPOLOGY
);
1476 ADD_DSDB_FLAG(NTDSCONN_OPT_IS_GENERATED
);
1477 ADD_DSDB_FLAG(NTDSCONN_OPT_TWOWAY_SYNC
);
1478 ADD_DSDB_FLAG(NTDSCONN_OPT_OVERRIDE_NOTIFY_DEFAULT
);
1479 ADD_DSDB_FLAG(NTDSCONN_OPT_USE_NOTIFY
);
1480 ADD_DSDB_FLAG(NTDSCONN_OPT_DISABLE_INTERSITE_COMPRESSION
);
1481 ADD_DSDB_FLAG(NTDSCONN_OPT_USER_OWNED_SCHEDULE
);
1482 ADD_DSDB_FLAG(NTDSCONN_OPT_RODC_TOPOLOGY
);
1484 /* Site Link Object options */
1485 ADD_DSDB_FLAG(NTDSSITELINK_OPT_USE_NOTIFY
);
1486 ADD_DSDB_FLAG(NTDSSITELINK_OPT_TWOWAY_SYNC
);
1487 ADD_DSDB_FLAG(NTDSSITELINK_OPT_DISABLE_COMPRESSION
);
1489 /* GPO policy flags */
1490 ADD_DSDB_FLAG(GPLINK_OPT_DISABLE
);
1491 ADD_DSDB_FLAG(GPLINK_OPT_ENFORCE
);
1492 ADD_DSDB_FLAG(GPO_FLAG_USER_DISABLE
);
1493 ADD_DSDB_FLAG(GPO_FLAG_MACHINE_DISABLE
);
1494 ADD_DSDB_FLAG(GPO_INHERIT
);
1495 ADD_DSDB_FLAG(GPO_BLOCK_INHERITANCE
);
1497 #define ADD_DSDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(val))
1499 ADD_DSDB_STRING(DSDB_SYNTAX_BINARY_DN
);
1500 ADD_DSDB_STRING(DSDB_SYNTAX_STRING_DN
);
1501 ADD_DSDB_STRING(DSDB_SYNTAX_OR_NAME
);
1502 ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK
);
1503 ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA
);
1504 ADD_DSDB_STRING(DSDB_CONTROL_REPLMD_VANISH_LINKS
);
1505 ADD_DSDB_STRING(DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID
);
1506 ADD_DSDB_STRING(DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID
);
1508 ADD_DSDB_STRING(DS_GUID_COMPUTERS_CONTAINER
);
1509 ADD_DSDB_STRING(DS_GUID_DELETED_OBJECTS_CONTAINER
);
1510 ADD_DSDB_STRING(DS_GUID_DOMAIN_CONTROLLERS_CONTAINER
);
1511 ADD_DSDB_STRING(DS_GUID_FOREIGNSECURITYPRINCIPALS_CONTAINER
);
1512 ADD_DSDB_STRING(DS_GUID_INFRASTRUCTURE_CONTAINER
);
1513 ADD_DSDB_STRING(DS_GUID_LOSTANDFOUND_CONTAINER
);
1514 ADD_DSDB_STRING(DS_GUID_MICROSOFT_PROGRAM_DATA_CONTAINER
);
1515 ADD_DSDB_STRING(DS_GUID_NTDS_QUOTAS_CONTAINER
);
1516 ADD_DSDB_STRING(DS_GUID_PROGRAM_DATA_CONTAINER
);
1517 ADD_DSDB_STRING(DS_GUID_SYSTEMS_CONTAINER
);
1518 ADD_DSDB_STRING(DS_GUID_USERS_CONTAINER
);