s4:dsdb/repl/drepl* - move "lib/messaging/irpc.h" include into "drepl_service.h"
[nivanova/samba-autobuild/.git] / source4 / dsdb / pydsdb.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2010
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 "libcli/util/pyerrors.h"
23 #include "dsdb/samdb/samdb.h"
24 #include "lib/ldb/pyldb.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
31 /* There's no Py_ssize_t in 2.4, apparently */
32 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
33 typedef int Py_ssize_t;
34 typedef inquiry lenfunc;
35 typedef intargfunc ssizeargfunc;
36 #endif
37
38 #ifndef Py_RETURN_NONE
39 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
40 #endif
41
42 /* FIXME: These should be in a header file somewhere, once we finish moving
43  * away from SWIG .. */
44 #define PyErr_LDB_OR_RAISE(py_ldb, ldb) \
45 /*      if (!PyLdb_Check(py_ldb)) { \
46                 PyErr_SetString(py_ldb_get_exception(), "Ldb connection object required"); \
47                 return NULL; \
48         } */\
49         ldb = PyLdb_AsLdbContext(py_ldb);
50
51 static PyObject *py_ldb_get_exception(void)
52 {
53         PyObject *mod = PyImport_ImportModule("ldb");
54         if (mod == NULL)
55                 return NULL;
56
57         return PyObject_GetAttrString(mod, "LdbError");
58 }
59
60 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
61 {
62         if (ret == LDB_ERR_PYTHON_EXCEPTION)
63                 return; /* Python exception should already be set, just keep that */
64
65         PyErr_SetObject(error, 
66                         Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
67                         ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
68 }
69
70 static PyObject *py_samdb_server_site_name(PyObject *self, PyObject *args)
71 {
72         PyObject *py_ldb, *result;
73         struct ldb_context *ldb;
74         const char *site;
75         TALLOC_CTX *mem_ctx;
76
77         if (!PyArg_ParseTuple(args, "O", &py_ldb))
78                 return NULL;
79
80         PyErr_LDB_OR_RAISE(py_ldb, ldb);
81
82         mem_ctx = talloc_new(NULL);
83
84         site = samdb_server_site_name(ldb, mem_ctx);
85         if (site == NULL) {
86                 PyErr_SetString(PyExc_RuntimeError, "Failed to find server site");
87                 talloc_free(mem_ctx);
88                 return NULL;
89         }
90
91         result = PyString_FromString(site);
92         talloc_free(mem_ctx);
93         return result;
94 }
95
96 static PyObject *py_dsdb_convert_schema_to_openldap(PyObject *self,
97                                                                                                         PyObject *args)
98 {
99         char *target_str, *mapping;
100         PyObject *py_ldb;
101         struct ldb_context *ldb;
102         PyObject *ret;
103         char *retstr;
104
105         if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &target_str, &mapping))
106                 return NULL;
107
108         PyErr_LDB_OR_RAISE(py_ldb, ldb);
109
110         retstr = dsdb_convert_schema_to_openldap(ldb, target_str, mapping);
111         if (retstr == NULL) {
112                 PyErr_SetString(PyExc_RuntimeError,
113                                                 "dsdb_convert_schema_to_openldap failed");
114                 return NULL;
115         } 
116
117         ret = PyString_FromString(retstr);
118         talloc_free(retstr);
119         return ret;
120 }
121
122 static PyObject *py_samdb_set_domain_sid(PyLdbObject *self, PyObject *args)
123
124         PyObject *py_ldb, *py_sid;
125         struct ldb_context *ldb;
126         struct dom_sid *sid;
127         bool ret;
128
129         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_sid))
130                 return NULL;
131         
132         PyErr_LDB_OR_RAISE(py_ldb, ldb);
133
134         sid = dom_sid_parse_talloc(NULL, PyString_AsString(py_sid));
135
136         ret = samdb_set_domain_sid(ldb, sid);
137         talloc_free(sid);
138         if (!ret) {
139                 PyErr_SetString(PyExc_RuntimeError, "set_domain_sid failed");
140                 return NULL;
141         } 
142         Py_RETURN_NONE;
143 }
144
145 static PyObject *py_samdb_set_ntds_settings_dn(PyLdbObject *self, PyObject *args)
146
147         PyObject *py_ldb, *py_ntds_settings_dn;
148         struct ldb_context *ldb;
149         struct ldb_dn *ntds_settings_dn;
150         TALLOC_CTX *tmp_ctx;
151         bool ret;
152
153         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_ntds_settings_dn))
154                 return NULL;
155         
156         PyErr_LDB_OR_RAISE(py_ldb, ldb);
157
158         tmp_ctx = talloc_new(NULL);
159         if (tmp_ctx == NULL) {
160                 PyErr_NoMemory();
161                 return NULL;
162         }
163
164         if (!PyObject_AsDn(tmp_ctx, py_ntds_settings_dn, ldb, &ntds_settings_dn)) {
165                 return NULL;
166         }
167
168         ret = samdb_set_ntds_settings_dn(ldb, ntds_settings_dn);
169         talloc_free(tmp_ctx);
170         if (!ret) {
171                 PyErr_SetString(PyExc_RuntimeError, "set_ntds_settings_dn failed");
172                 return NULL;
173         } 
174         Py_RETURN_NONE;
175 }
176
177 static PyObject *py_samdb_get_domain_sid(PyLdbObject *self, PyObject *args)
178
179         PyObject *py_ldb;
180         struct ldb_context *ldb;
181         const struct dom_sid *sid;
182         PyObject *ret;
183         char *retstr;
184
185         if (!PyArg_ParseTuple(args, "O", &py_ldb))
186                 return NULL;
187         
188         PyErr_LDB_OR_RAISE(py_ldb, ldb);
189
190         sid = samdb_domain_sid(ldb);
191         if (!sid) {
192                 PyErr_SetString(PyExc_RuntimeError, "samdb_domain_sid failed");
193                 return NULL;
194         } 
195         retstr = dom_sid_string(NULL, sid);
196         ret = PyString_FromString(retstr);
197         talloc_free(retstr);
198         return ret;
199 }
200
201 static PyObject *py_samdb_ntds_invocation_id(PyObject *self, PyObject *args)
202 {
203         PyObject *py_ldb, *result;
204         struct ldb_context *ldb;
205         TALLOC_CTX *mem_ctx;
206         const struct GUID *guid;
207
208         mem_ctx = talloc_new(NULL);
209         if (mem_ctx == NULL) {
210                 PyErr_NoMemory();
211                 return NULL;
212         }
213
214         if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
215                 talloc_free(mem_ctx);
216                 return NULL;
217         }
218
219         PyErr_LDB_OR_RAISE(py_ldb, ldb);
220
221         guid = samdb_ntds_invocation_id(ldb);
222         if (guid == NULL) {
223                 PyErr_SetString(PyExc_RuntimeError,
224                                                 "Failed to find NTDS invocation ID");
225                 talloc_free(mem_ctx);
226                 return NULL;
227         }
228
229         result = PyString_FromString(GUID_string(mem_ctx, guid));
230         talloc_free(mem_ctx);
231         return result;
232 }
233
234 static PyObject *py_dsdb_get_oid_from_attid(PyObject *self, PyObject *args)
235 {
236         PyObject *py_ldb;
237         struct ldb_context *ldb;
238         uint32_t attid;
239         struct dsdb_schema *schema;
240         const char *oid;
241         PyObject *ret;
242         TALLOC_CTX *mem_ctx;
243         WERROR status;
244
245         if (!PyArg_ParseTuple(args, "Oi", &py_ldb, &attid))
246                 return NULL;
247
248         PyErr_LDB_OR_RAISE(py_ldb, ldb);
249
250         mem_ctx = talloc_new(NULL);
251         if (mem_ctx == NULL) {
252            PyErr_NoMemory();
253            return NULL;
254         }
255
256         schema = dsdb_get_schema(ldb, NULL);
257
258         if (!schema) {
259                 PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb \n");
260                 talloc_free(mem_ctx);
261                 return NULL;
262         }
263         
264         status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, attid,
265                                                 mem_ctx, &oid);
266         PyErr_WERROR_IS_ERR_RAISE(status);
267
268         ret = PyString_FromString(oid);
269
270         talloc_free(mem_ctx);
271
272         return ret;
273 }
274
275
276 static PyObject *py_dsdb_get_attid_from_lDAPDisplayName(PyObject *self, PyObject *args)
277 {
278         PyObject *py_ldb, *is_schema_nc;
279         struct ldb_context *ldb;
280         struct dsdb_schema *schema;
281         const char *ldap_display_name;
282         bool schema_nc = false;
283         const struct dsdb_attribute *a;
284         uint32_t attid;
285
286         if (!PyArg_ParseTuple(args, "OsO", &py_ldb, &ldap_display_name, &is_schema_nc))
287                 return NULL;
288
289         PyErr_LDB_OR_RAISE(py_ldb, ldb);
290
291         if (is_schema_nc) {
292                 if (!PyBool_Check(is_schema_nc)) {
293                         PyErr_SetString(PyExc_TypeError, "Expected boolean is_schema_nc");
294                         return NULL;
295                 }
296                 if (is_schema_nc == Py_True) {
297                         schema_nc = true;
298                 }
299         }
300
301         schema = dsdb_get_schema(ldb, NULL);
302
303         if (!schema) {
304                 PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
305                 return NULL;
306         }
307
308         a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
309         if (a == NULL) {
310                 PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name);
311                 return NULL;
312         }
313
314         attid = dsdb_attribute_get_attid(a, schema_nc);
315
316         return PyLong_FromUnsignedLong(attid);
317 }
318
319 /*
320   convert a python string to a DRSUAPI drsuapi_DsReplicaAttribute attribute
321  */
322 static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args)
323 {
324         PyObject *py_ldb, *el_list, *ret;
325         struct ldb_context *ldb;
326         char *ldap_display_name;
327         const struct dsdb_attribute *a;
328         struct dsdb_schema *schema;
329         struct dsdb_syntax_ctx syntax_ctx;
330         struct ldb_message_element *el;
331         struct drsuapi_DsReplicaAttribute *attr;
332         TALLOC_CTX *tmp_ctx;
333         WERROR werr;
334         Py_ssize_t i;
335
336         if (!PyArg_ParseTuple(args, "OsO", &py_ldb, &ldap_display_name, &el_list)) {
337                 return NULL;
338         }
339
340         PyErr_LDB_OR_RAISE(py_ldb, ldb);
341
342         if (!PyList_Check(el_list)) {
343                 PyErr_Format(PyExc_TypeError, "ldif_elements must be a list");
344                 return NULL;
345         }
346
347         schema = dsdb_get_schema(ldb, NULL);
348         if (!schema) {
349                 PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
350                 return NULL;
351         }
352
353         a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
354         if (a == NULL) {
355                 PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name);
356                 return NULL;
357         }
358
359         dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema);
360         syntax_ctx.is_schema_nc = false;
361
362         tmp_ctx = talloc_new(ldb);
363
364         el = talloc_zero(tmp_ctx, struct ldb_message_element);
365         el->name = ldap_display_name;
366         el->num_values = PyList_Size(el_list);
367         el->values = talloc_array(el, struct ldb_val, el->num_values);
368         for (i = 0; i < el->num_values; i++) {
369                 PyObject *item = PyList_GetItem(el_list, i);
370                 if (!PyString_Check(item)) {
371                         PyErr_Format(PyExc_TypeError, "ldif_elements should be strings");
372                         return NULL;
373                 }
374                 el->values[i].data = (uint8_t *)PyString_AsString(item);
375                 el->values[i].length = PyString_Size(item);
376         }
377
378         attr = talloc_zero(tmp_ctx, struct drsuapi_DsReplicaAttribute);
379
380         werr = a->syntax->ldb_to_drsuapi(&syntax_ctx, a, el, attr, attr);
381         PyErr_WERROR_IS_ERR_RAISE(werr);
382
383         ret = py_return_ndr_struct("samba.dcerpc.drsuapi", "DsReplicaAttribute", attr, attr);
384
385         talloc_unlink(ldb, tmp_ctx);
386
387         return ret;
388 }
389
390 static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
391 {
392         PyObject *py_ldb, *py_guid;
393         bool ret;
394         struct GUID guid;
395         struct ldb_context *ldb;
396         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_guid))
397                 return NULL;
398
399         PyErr_LDB_OR_RAISE(py_ldb, ldb);
400         GUID_from_string(PyString_AsString(py_guid), &guid);
401
402         ret = samdb_set_ntds_invocation_id(ldb, &guid);
403         if (!ret) {
404                 PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id failed");
405                 return NULL;
406         }
407         Py_RETURN_NONE;
408 }
409
410 static PyObject *py_samdb_ntds_objectGUID(PyObject *self, PyObject *args)
411 {
412         PyObject *py_ldb, *result;
413         struct ldb_context *ldb;
414         TALLOC_CTX *mem_ctx;
415         const struct GUID *guid;
416
417         if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
418                 return NULL;
419         }
420
421         PyErr_LDB_OR_RAISE(py_ldb, ldb);
422
423         mem_ctx = talloc_new(NULL);
424         if (mem_ctx == NULL) {
425                 PyErr_NoMemory();
426                 return NULL;
427         }
428
429         guid = samdb_ntds_objectGUID(ldb);
430         if (guid == NULL) {
431                 PyErr_SetString(PyExc_RuntimeError, "Failed to find NTDS GUID");
432                 talloc_free(mem_ctx);
433                 return NULL;
434         }
435
436         result = PyString_FromString(GUID_string(mem_ctx, guid));
437         talloc_free(mem_ctx);
438         return result;
439 }
440
441 static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args)
442 {
443         PyObject *py_ldb;
444         struct ldb_context *ldb;
445         int ret;
446         if (!PyArg_ParseTuple(args, "O", &py_ldb))
447                 return NULL;
448
449         PyErr_LDB_OR_RAISE(py_ldb, ldb);
450
451         ret = dsdb_set_global_schema(ldb);
452         PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
453
454         Py_RETURN_NONE;
455 }
456
457 static PyObject *py_dsdb_load_partition_usn(PyObject *self, PyObject *args)
458 {
459         PyObject *py_dn, *py_ldb, *result;
460         struct ldb_dn *dn;
461         uint64_t highest_uSN, urgent_uSN;
462         struct ldb_context *ldb;
463         TALLOC_CTX *mem_ctx;
464         int ret;
465
466         mem_ctx = talloc_new(NULL);
467         if (mem_ctx == NULL) {
468            PyErr_NoMemory();
469            return NULL;
470         }
471
472         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_dn)) {
473            talloc_free(mem_ctx);
474            return NULL;
475         }
476
477         PyErr_LDB_OR_RAISE(py_ldb, ldb);
478
479         if (!PyObject_AsDn(mem_ctx, py_dn, ldb, &dn)) {
480            talloc_free(mem_ctx);
481            return NULL;
482         }
483
484         ret = dsdb_load_partition_usn(ldb, dn, &highest_uSN, &urgent_uSN);
485         if (ret != LDB_SUCCESS) {
486            PyErr_Format(PyExc_RuntimeError,
487                         "Failed to load partition [%s] uSN - %s",
488                         ldb_dn_get_linearized(dn),
489                         ldb_errstring(ldb));
490            talloc_free(mem_ctx);
491            return NULL;
492         }
493
494         talloc_free(mem_ctx);
495
496         result = PyDict_New();
497
498         PyDict_SetItemString(result, "uSNHighest", PyInt_FromLong((uint64_t)highest_uSN));
499         PyDict_SetItemString(result, "uSNUrgent", PyInt_FromLong((uint64_t)urgent_uSN));
500
501
502         return result;
503 }
504
505 static PyObject *py_dsdb_set_am_rodc(PyObject *self, PyObject *args)
506 {
507         PyObject *py_ldb;
508         bool ret;
509         struct ldb_context *ldb;
510         int py_val;
511
512         if (!PyArg_ParseTuple(args, "Oi", &py_ldb, &py_val))
513                 return NULL;
514
515         PyErr_LDB_OR_RAISE(py_ldb, ldb);
516         ret = samdb_set_am_rodc(ldb, (bool)py_val);
517         if (!ret) {
518                 PyErr_SetString(PyExc_RuntimeError, "set_am_rodc failed");
519                 return NULL;
520         }
521         Py_RETURN_NONE;
522 }
523
524 static PyObject *py_dsdb_set_schema_from_ldif(PyObject *self, PyObject *args)
525 {
526         WERROR result;
527         char *pf, *df;
528         PyObject *py_ldb;
529         struct ldb_context *ldb;
530
531         if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &pf, &df))
532                 return NULL;
533
534         PyErr_LDB_OR_RAISE(py_ldb, ldb);
535
536         result = dsdb_set_schema_from_ldif(ldb, pf, df);
537         PyErr_WERROR_IS_ERR_RAISE(result);
538
539         Py_RETURN_NONE;
540 }
541
542 static PyObject *py_dsdb_set_schema_from_ldb(PyObject *self, PyObject *args)
543 {
544         PyObject *py_ldb;
545         struct ldb_context *ldb;
546         PyObject *py_from_ldb;
547         struct ldb_context *from_ldb;
548         struct dsdb_schema *schema;
549         int ret;
550         if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_from_ldb))
551                 return NULL;
552
553         PyErr_LDB_OR_RAISE(py_ldb, ldb);
554
555         PyErr_LDB_OR_RAISE(py_from_ldb, from_ldb);
556
557         schema = dsdb_get_schema(from_ldb, NULL);
558         if (!schema) {
559                 PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on 'from' ldb!\n");
560                 return NULL;
561         }
562
563         ret = dsdb_reference_schema(ldb, schema, true);
564         PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
565
566         Py_RETURN_NONE;
567 }
568
569 static PyObject *py_dsdb_write_prefixes_from_schema_to_ldb(PyObject *self, PyObject *args)
570 {
571         PyObject *py_ldb;
572         struct ldb_context *ldb;
573         WERROR result;
574         struct dsdb_schema *schema;
575
576         if (!PyArg_ParseTuple(args, "O", &py_ldb))
577                 return NULL;
578
579         PyErr_LDB_OR_RAISE(py_ldb, ldb);
580
581         schema = dsdb_get_schema(ldb, NULL);
582         if (!schema) {
583                 PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on ldb!\n");
584                 return NULL;
585         }
586
587         result = dsdb_write_prefixes_from_schema_to_ldb(NULL, ldb, schema);
588         PyErr_WERROR_IS_ERR_RAISE(result);
589
590         Py_RETURN_NONE;
591 }
592
593
594 static PyObject *py_dsdb_get_partitions_dn(PyObject *self, PyObject *args)
595 {
596         struct ldb_context *ldb;
597         struct ldb_dn *dn;
598         PyObject *py_ldb, *ret;
599         TALLOC_CTX *tmp_ctx;
600         PyObject *mod;
601
602         mod = PyImport_ImportModule("ldb");
603
604         if (!PyArg_ParseTuple(args, "O", &py_ldb))
605                 return NULL;
606
607         PyErr_LDB_OR_RAISE(py_ldb, ldb);
608
609         tmp_ctx = talloc_new(NULL);
610
611         dn = samdb_partitions_dn(ldb, tmp_ctx);
612
613         if (dn == NULL) {
614                 talloc_free(tmp_ctx);
615                 Py_RETURN_NONE;
616         }
617         ret = PyLdbDn_FromDn(dn);
618         talloc_free(tmp_ctx);
619         return ret;
620 }
621
622
623 /*
624   call into samdb_rodc()
625  */
626 static PyObject *py_dsdb_am_rodc(PyObject *self, PyObject *args)
627 {
628         PyObject *py_ldb;
629         struct ldb_context *ldb;
630         int ret;
631         bool am_rodc;
632
633         if (!PyArg_ParseTuple(args, "O", &py_ldb))
634                 return NULL;
635
636         PyErr_LDB_OR_RAISE(py_ldb, ldb);
637
638         ret = samdb_rodc(ldb, &am_rodc);
639         if (ret != LDB_SUCCESS) {
640                 PyErr_SetString(PyExc_RuntimeError, ldb_errstring(ldb));
641                 return NULL;
642         }
643
644         return PyBool_FromLong(am_rodc);
645 }
646
647
648 static PyMethodDef py_dsdb_methods[] = {
649         { "_samdb_server_site_name", (PyCFunction)py_samdb_server_site_name,
650                 METH_VARARGS, "Get the server site name as a string"},
651         { "_dsdb_convert_schema_to_openldap",
652                 (PyCFunction)py_dsdb_convert_schema_to_openldap, METH_VARARGS, 
653                 "dsdb_convert_schema_to_openldap(ldb, target_str, mapping) -> str\n"
654                 "Create an OpenLDAP schema from a schema." },
655         { "_samdb_set_domain_sid", (PyCFunction)py_samdb_set_domain_sid,
656                 METH_VARARGS,
657                 "samdb_set_domain_sid(samdb, sid)\n"
658                 "Set SID of domain to use." },
659         { "_samdb_get_domain_sid", (PyCFunction)py_samdb_get_domain_sid,
660                 METH_VARARGS,
661                 "samdb_get_domain_sid(samdb)\n"
662                 "Get SID of domain in use." },
663         { "_samdb_ntds_invocation_id", (PyCFunction)py_samdb_ntds_invocation_id,
664                 METH_VARARGS, "get the NTDS invocation ID GUID as a string"},
665         { "_samdb_set_ntds_settings_dn", (PyCFunction)py_samdb_set_ntds_settings_dn,
666                 METH_VARARGS,
667                 "samdb_set_ntds_settings_dn(samdb, ntds_settings_dn)\n"
668                 "Set NTDS Settings DN for this LDB (allows it to be set before the DB fully exists)." },
669         { "_dsdb_get_oid_from_attid", (PyCFunction)py_dsdb_get_oid_from_attid,
670                 METH_VARARGS, NULL },
671         { "_dsdb_get_attid_from_lDAPDisplayName", (PyCFunction)py_dsdb_get_attid_from_lDAPDisplayName,
672                 METH_VARARGS, NULL },
673         { "_dsdb_set_ntds_invocation_id",
674                 (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
675                 NULL },
676         { "_samdb_ntds_objectGUID", (PyCFunction)py_samdb_ntds_objectGUID,
677                 METH_VARARGS, "get the NTDS objectGUID as a string"},
678         { "_dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema,
679                 METH_VARARGS, NULL },
680         { "_dsdb_load_partition_usn", (PyCFunction)py_dsdb_load_partition_usn,
681                 METH_VARARGS,
682                 "get uSNHighest and uSNUrgent from the partition @REPLCHANGED"},
683         { "_dsdb_set_am_rodc",
684                 (PyCFunction)py_dsdb_set_am_rodc, METH_VARARGS,
685                 NULL },
686         { "_am_rodc",
687                 (PyCFunction)py_dsdb_am_rodc, METH_VARARGS,
688                 NULL },
689         { "_dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS,
690                 NULL },
691         { "_dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS,
692                 NULL },
693         { "_dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction)py_dsdb_write_prefixes_from_schema_to_ldb, METH_VARARGS,
694                 NULL },
695         { "_dsdb_get_partitions_dn", (PyCFunction)py_dsdb_get_partitions_dn, METH_VARARGS, NULL },
696         { "_dsdb_DsReplicaAttribute", (PyCFunction)py_dsdb_DsReplicaAttribute, METH_VARARGS, NULL },
697         { NULL }
698 };
699
700 void initdsdb(void)
701 {
702         PyObject *m;
703
704         m = Py_InitModule3("dsdb", py_dsdb_methods, 
705                            "Python bindings for the directory service databases.");
706         if (m == NULL)
707                 return;
708
709 #define ADD_DSDB_FLAG(val)  PyModule_AddObject(m, #val, PyInt_FromLong(val))
710
711         /* "userAccountControl" flags */
712         ADD_DSDB_FLAG(UF_NORMAL_ACCOUNT);
713         ADD_DSDB_FLAG(UF_TEMP_DUPLICATE_ACCOUNT);
714         ADD_DSDB_FLAG(UF_SERVER_TRUST_ACCOUNT);
715         ADD_DSDB_FLAG(UF_WORKSTATION_TRUST_ACCOUNT);
716         ADD_DSDB_FLAG(UF_INTERDOMAIN_TRUST_ACCOUNT);
717         ADD_DSDB_FLAG(UF_PASSWD_NOTREQD);
718         ADD_DSDB_FLAG(UF_ACCOUNTDISABLE);
719
720         ADD_DSDB_FLAG(UF_SCRIPT);
721         ADD_DSDB_FLAG(UF_ACCOUNTDISABLE);
722         ADD_DSDB_FLAG(UF_00000004);
723         ADD_DSDB_FLAG(UF_HOMEDIR_REQUIRED);
724         ADD_DSDB_FLAG(UF_LOCKOUT);
725         ADD_DSDB_FLAG(UF_PASSWD_NOTREQD);
726         ADD_DSDB_FLAG(UF_PASSWD_CANT_CHANGE);
727         ADD_DSDB_FLAG(UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED);
728         ADD_DSDB_FLAG(UF_TEMP_DUPLICATE_ACCOUNT);
729         ADD_DSDB_FLAG(UF_NORMAL_ACCOUNT);
730         ADD_DSDB_FLAG(UF_00000400);
731         ADD_DSDB_FLAG(UF_INTERDOMAIN_TRUST_ACCOUNT);
732         ADD_DSDB_FLAG(UF_WORKSTATION_TRUST_ACCOUNT);
733         ADD_DSDB_FLAG(UF_SERVER_TRUST_ACCOUNT);
734         ADD_DSDB_FLAG(UF_00004000);
735         ADD_DSDB_FLAG(UF_00008000);
736         ADD_DSDB_FLAG(UF_DONT_EXPIRE_PASSWD);
737         ADD_DSDB_FLAG(UF_MNS_LOGON_ACCOUNT);
738         ADD_DSDB_FLAG(UF_SMARTCARD_REQUIRED);
739         ADD_DSDB_FLAG(UF_TRUSTED_FOR_DELEGATION);
740         ADD_DSDB_FLAG(UF_NOT_DELEGATED);
741         ADD_DSDB_FLAG(UF_USE_DES_KEY_ONLY);
742         ADD_DSDB_FLAG(UF_DONT_REQUIRE_PREAUTH);
743         ADD_DSDB_FLAG(UF_PASSWORD_EXPIRED);
744         ADD_DSDB_FLAG(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION);
745         ADD_DSDB_FLAG(UF_NO_AUTH_DATA_REQUIRED);
746         ADD_DSDB_FLAG(UF_PARTIAL_SECRETS_ACCOUNT);
747
748         /* groupType flags */
749         ADD_DSDB_FLAG(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP);
750         ADD_DSDB_FLAG(GTYPE_SECURITY_GLOBAL_GROUP);
751         ADD_DSDB_FLAG(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
752         ADD_DSDB_FLAG(GTYPE_SECURITY_UNIVERSAL_GROUP);
753         ADD_DSDB_FLAG(GTYPE_DISTRIBUTION_GLOBAL_GROUP);
754         ADD_DSDB_FLAG(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP);
755         ADD_DSDB_FLAG(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP);
756
757         /* "sAMAccountType" flags */
758         ADD_DSDB_FLAG(ATYPE_NORMAL_ACCOUNT);
759         ADD_DSDB_FLAG(ATYPE_WORKSTATION_TRUST);
760         ADD_DSDB_FLAG(ATYPE_INTERDOMAIN_TRUST);
761         ADD_DSDB_FLAG(ATYPE_SECURITY_GLOBAL_GROUP);
762         ADD_DSDB_FLAG(ATYPE_SECURITY_LOCAL_GROUP);
763         ADD_DSDB_FLAG(ATYPE_SECURITY_UNIVERSAL_GROUP);
764         ADD_DSDB_FLAG(ATYPE_DISTRIBUTION_GLOBAL_GROUP);
765         ADD_DSDB_FLAG(ATYPE_DISTRIBUTION_LOCAL_GROUP);
766         ADD_DSDB_FLAG(ATYPE_DISTRIBUTION_UNIVERSAL_GROUP);
767
768         /* "domainFunctionality", "forestFunctionality" flags in the rootDSE */
769         ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2000);
770         ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2003_MIXED);
771         ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2003);
772         ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2008);
773         ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2008_R2);
774
775         /* "systemFlags" */
776         ADD_DSDB_FLAG(SYSTEM_FLAG_CR_NTDS_NC);
777         ADD_DSDB_FLAG(SYSTEM_FLAG_CR_NTDS_DOMAIN);
778         ADD_DSDB_FLAG(SYSTEM_FLAG_CR_NTDS_NOT_GC_REPLICATED);
779         ADD_DSDB_FLAG(SYSTEM_FLAG_SCHEMA_BASE_OBJECT);
780         ADD_DSDB_FLAG(SYSTEM_FLAG_ATTR_IS_RDN);
781         ADD_DSDB_FLAG(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE);
782         ADD_DSDB_FLAG(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE);
783         ADD_DSDB_FLAG(SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME);
784         ADD_DSDB_FLAG(SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE);
785         ADD_DSDB_FLAG(SYSTEM_FLAG_CONFIG_ALLOW_MOVE);
786         ADD_DSDB_FLAG(SYSTEM_FLAG_CONFIG_ALLOW_RENAME);
787         ADD_DSDB_FLAG(SYSTEM_FLAG_DISALLOW_DELETE);
788
789         /* Kerberos encryption type constants */
790         ADD_DSDB_FLAG(ENC_ALL_TYPES);
791         ADD_DSDB_FLAG(ENC_CRC32);
792         ADD_DSDB_FLAG(ENC_RSA_MD5);
793         ADD_DSDB_FLAG(ENC_RC4_HMAC_MD5);
794         ADD_DSDB_FLAG(ENC_HMAC_SHA1_96_AES128);
795         ADD_DSDB_FLAG(ENC_HMAC_SHA1_96_AES256);
796
797         ADD_DSDB_FLAG(SEARCH_FLAG_ATTINDEX);
798         ADD_DSDB_FLAG(SEARCH_FLAG_PDNTATTINDEX);
799         ADD_DSDB_FLAG(SEARCH_FLAG_ANR);
800         ADD_DSDB_FLAG(SEARCH_FLAG_PRESERVEONDELETE);
801         ADD_DSDB_FLAG(SEARCH_FLAG_COPY);
802         ADD_DSDB_FLAG(SEARCH_FLAG_TUPLEINDEX);
803         ADD_DSDB_FLAG(SEARCH_FLAG_SUBTREEATTRINDEX);
804         ADD_DSDB_FLAG(SEARCH_FLAG_CONFIDENTIAL);
805         ADD_DSDB_FLAG(SEARCH_FLAG_NEVERVALUEAUDIT);
806         ADD_DSDB_FLAG(SEARCH_FLAG_RODC_ATTRIBUTE);
807
808         ADD_DSDB_FLAG(DS_FLAG_ATTR_NOT_REPLICATED);
809         ADD_DSDB_FLAG(DS_FLAG_ATTR_REQ_PARTIAL_SET_MEMBER);
810         ADD_DSDB_FLAG(DS_FLAG_ATTR_IS_CONSTRUCTED);
811
812         ADD_DSDB_FLAG(DS_NTDSDSA_OPT_IS_GC);
813         ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL);
814         ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL);
815         ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_NTDSCONN_XLATE);
816         ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_SPN_REGISTRATION);
817
818         ADD_DSDB_FLAG(NTDSCONN_KCC_GC_TOPOLOGY);
819         ADD_DSDB_FLAG(NTDSCONN_KCC_RING_TOPOLOGY);
820         ADD_DSDB_FLAG(NTDSCONN_KCC_MINIMIZE_HOPS_TOPOLOGY);
821         ADD_DSDB_FLAG(NTDSCONN_KCC_STALE_SERVERS_TOPOLOGY);
822         ADD_DSDB_FLAG(NTDSCONN_KCC_OSCILLATING_CONNECTION_TOPOLOGY);
823         ADD_DSDB_FLAG(NTDSCONN_KCC_INTERSITE_GC_TOPOLOGY);
824         ADD_DSDB_FLAG(NTDSCONN_KCC_INTERSITE_TOPOLOGY);
825         ADD_DSDB_FLAG(NTDSCONN_KCC_SERVER_FAILOVER_TOPOLOGY);
826         ADD_DSDB_FLAG(NTDSCONN_KCC_SITE_FAILOVER_TOPOLOGY);
827         ADD_DSDB_FLAG(NTDSCONN_KCC_REDUNDANT_SERVER_TOPOLOGY);
828 }