Line data Source code
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 "lib/replace/system/python.h"
21 : #include "python/py3compat.h"
22 : #include "includes.h"
23 : #include <ldb.h>
24 : #include <pyldb.h>
25 : #include "dsdb/samdb/samdb.h"
26 : #include "libcli/security/security.h"
27 : #include "librpc/ndr/libndr.h"
28 : #include "system/kerberos.h"
29 : #include "auth/kerberos/kerberos.h"
30 : #include "librpc/rpc/pyrpc_util.h"
31 : #include "lib/policy/policy.h"
32 : #include "param/pyparam.h"
33 : #include "lib/util/dlinklist.h"
34 : #include "dsdb/kcc/garbage_collect_tombstones.h"
35 : #include "dsdb/kcc/scavenge_dns_records.h"
36 : #include "libds/common/flag_mapping.h"
37 :
38 : #undef strcasecmp
39 :
40 28 : static PyObject *py_ldb_get_exception(void)
41 : {
42 28 : PyObject *mod = PyImport_ImportModule("ldb");
43 28 : PyObject *result = NULL;
44 28 : if (mod == NULL)
45 0 : return NULL;
46 :
47 28 : result = PyObject_GetAttrString(mod, "LdbError");
48 28 : Py_CLEAR(mod);
49 28 : return result;
50 : }
51 :
52 655 : static PyObject *py_samdb_server_site_name(PyObject *self, PyObject *args)
53 : {
54 20 : PyObject *py_ldb, *result;
55 20 : struct ldb_context *ldb;
56 20 : const char *site;
57 20 : TALLOC_CTX *mem_ctx;
58 :
59 655 : if (!PyArg_ParseTuple(args, "O", &py_ldb))
60 0 : return NULL;
61 :
62 655 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
63 :
64 655 : mem_ctx = talloc_new(NULL);
65 655 : if (mem_ctx == NULL) {
66 0 : PyErr_NoMemory();
67 0 : return NULL;
68 : }
69 :
70 655 : site = samdb_server_site_name(ldb, mem_ctx);
71 655 : if (site == NULL) {
72 2 : PyErr_SetString(PyExc_RuntimeError, "Failed to find server site");
73 2 : talloc_free(mem_ctx);
74 2 : return NULL;
75 : }
76 :
77 653 : result = PyUnicode_FromString(site);
78 653 : talloc_free(mem_ctx);
79 653 : return result;
80 : }
81 :
82 0 : static PyObject *py_dsdb_convert_schema_to_openldap(PyObject *self,
83 : PyObject *args)
84 : {
85 0 : char *target_str, *mapping;
86 0 : PyObject *py_ldb;
87 0 : struct ldb_context *ldb;
88 0 : PyObject *ret;
89 0 : char *retstr;
90 :
91 0 : if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &target_str, &mapping))
92 0 : return NULL;
93 :
94 0 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
95 :
96 0 : retstr = dsdb_convert_schema_to_openldap(ldb, target_str, mapping);
97 0 : if (retstr == NULL) {
98 0 : PyErr_SetString(PyExc_RuntimeError,
99 : "dsdb_convert_schema_to_openldap failed");
100 0 : return NULL;
101 : }
102 :
103 0 : ret = PyUnicode_FromString(retstr);
104 0 : talloc_free(retstr);
105 0 : return ret;
106 : }
107 :
108 127 : static PyObject *py_samdb_set_domain_sid(PyLdbObject *self, PyObject *args)
109 : {
110 22 : PyObject *py_ldb, *py_sid;
111 22 : struct ldb_context *ldb;
112 22 : struct dom_sid *sid;
113 22 : bool ret;
114 127 : const char *sid_str = NULL;
115 :
116 127 : if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_sid))
117 0 : return NULL;
118 :
119 127 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
120 :
121 127 : sid_str = PyUnicode_AsUTF8(py_sid);
122 127 : if (sid_str == NULL) {
123 0 : PyErr_NoMemory();
124 0 : return NULL;
125 : }
126 :
127 127 : sid = dom_sid_parse_talloc(NULL, sid_str);
128 127 : if (sid == NULL) {
129 0 : PyErr_NoMemory();
130 0 : return NULL;
131 : }
132 :
133 127 : ret = samdb_set_domain_sid(ldb, sid);
134 127 : talloc_free(sid);
135 127 : if (!ret) {
136 0 : PyErr_SetString(PyExc_RuntimeError, "set_domain_sid failed");
137 0 : return NULL;
138 : }
139 127 : Py_RETURN_NONE;
140 : }
141 :
142 342 : static PyObject *py_samdb_set_ntds_settings_dn(PyLdbObject *self, PyObject *args)
143 : {
144 45 : PyObject *py_ldb, *py_ntds_settings_dn;
145 45 : struct ldb_context *ldb;
146 45 : struct ldb_dn *ntds_settings_dn;
147 45 : TALLOC_CTX *tmp_ctx;
148 45 : bool ret;
149 :
150 342 : if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_ntds_settings_dn))
151 0 : return NULL;
152 :
153 342 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
154 :
155 342 : tmp_ctx = talloc_new(NULL);
156 342 : if (tmp_ctx == NULL) {
157 0 : PyErr_NoMemory();
158 0 : return NULL;
159 : }
160 :
161 342 : if (!pyldb_Object_AsDn(tmp_ctx, py_ntds_settings_dn, ldb, &ntds_settings_dn)) {
162 : /* exception thrown by "pyldb_Object_AsDn" */
163 0 : talloc_free(tmp_ctx);
164 0 : return NULL;
165 : }
166 :
167 342 : ret = samdb_set_ntds_settings_dn(ldb, ntds_settings_dn);
168 342 : talloc_free(tmp_ctx);
169 342 : if (!ret) {
170 0 : PyErr_SetString(PyExc_RuntimeError, "set_ntds_settings_dn failed");
171 0 : return NULL;
172 : }
173 342 : Py_RETURN_NONE;
174 : }
175 :
176 19352 : static PyObject *py_samdb_get_domain_sid(PyLdbObject *self, PyObject *args)
177 : {
178 874 : PyObject *py_ldb;
179 874 : struct ldb_context *ldb;
180 874 : const struct dom_sid *sid;
181 874 : struct dom_sid_buf buf;
182 874 : PyObject *ret;
183 :
184 19352 : if (!PyArg_ParseTuple(args, "O", &py_ldb))
185 0 : return NULL;
186 :
187 19352 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
188 :
189 19352 : sid = samdb_domain_sid(ldb);
190 19352 : if (!sid) {
191 0 : PyErr_SetString(PyExc_RuntimeError, "samdb_domain_sid failed");
192 0 : return NULL;
193 : }
194 :
195 19352 : ret = PyUnicode_FromString(dom_sid_str_buf(sid, &buf));
196 19352 : return ret;
197 : }
198 :
199 1403 : static PyObject *py_samdb_ntds_invocation_id(PyObject *self, PyObject *args)
200 : {
201 0 : PyObject *py_ldb, *result;
202 0 : struct ldb_context *ldb;
203 0 : const struct GUID *guid;
204 0 : char *retstr;
205 :
206 1403 : if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
207 0 : return NULL;
208 : }
209 :
210 1403 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
211 :
212 1403 : guid = samdb_ntds_invocation_id(ldb);
213 1403 : if (guid == NULL) {
214 0 : PyErr_SetString(PyExc_RuntimeError,
215 : "Failed to find NTDS invocation ID");
216 0 : return NULL;
217 : }
218 :
219 1403 : retstr = GUID_string(NULL, guid);
220 1403 : if (retstr == NULL) {
221 0 : PyErr_NoMemory();
222 0 : return NULL;
223 : }
224 1403 : result = PyUnicode_FromString(retstr);
225 1403 : talloc_free(retstr);
226 1403 : return result;
227 : }
228 :
229 107377 : static PyObject *py_dsdb_get_oid_from_attid(PyObject *self, PyObject *args)
230 : {
231 0 : PyObject *py_ldb;
232 0 : struct ldb_context *ldb;
233 0 : uint32_t attid;
234 0 : struct dsdb_schema *schema;
235 0 : const char *oid;
236 0 : PyObject *ret;
237 0 : WERROR status;
238 0 : TALLOC_CTX *mem_ctx;
239 :
240 107377 : if (!PyArg_ParseTuple(args, "OI", &py_ldb, &attid))
241 0 : return NULL;
242 :
243 107377 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
244 :
245 107377 : mem_ctx = talloc_new(NULL);
246 107377 : if (!mem_ctx) {
247 0 : PyErr_NoMemory();
248 0 : return NULL;
249 : }
250 :
251 107377 : schema = dsdb_get_schema(ldb, mem_ctx);
252 107377 : if (!schema) {
253 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb \n");
254 0 : talloc_free(mem_ctx);
255 0 : return NULL;
256 : }
257 :
258 107377 : status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, attid,
259 : mem_ctx, &oid);
260 107377 : if (!W_ERROR_IS_OK(status)) {
261 0 : PyErr_SetWERROR(status);
262 0 : talloc_free(mem_ctx);
263 0 : return NULL;
264 : }
265 :
266 107377 : ret = PyUnicode_FromString(oid);
267 :
268 107377 : talloc_free(mem_ctx);
269 :
270 107377 : return ret;
271 : }
272 :
273 :
274 14053720 : static PyObject *py_dsdb_get_attid_from_lDAPDisplayName(PyObject *self, PyObject *args)
275 : {
276 1197233 : PyObject *py_ldb, *is_schema_nc;
277 1197233 : struct ldb_context *ldb;
278 1197233 : struct dsdb_schema *schema;
279 1197233 : const char *ldap_display_name;
280 14053720 : bool schema_nc = false;
281 1197233 : const struct dsdb_attribute *a;
282 1197233 : uint32_t attid;
283 :
284 14053720 : if (!PyArg_ParseTuple(args, "OsO", &py_ldb, &ldap_display_name, &is_schema_nc))
285 0 : return NULL;
286 :
287 14053720 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
288 :
289 14053720 : if (is_schema_nc) {
290 14053720 : if (!PyBool_Check(is_schema_nc)) {
291 0 : PyErr_SetString(PyExc_TypeError, "Expected boolean is_schema_nc");
292 0 : return NULL;
293 : }
294 14053720 : if (is_schema_nc == Py_True) {
295 6225680 : schema_nc = true;
296 : }
297 : }
298 :
299 14053720 : schema = dsdb_get_schema(ldb, NULL);
300 :
301 14053720 : if (!schema) {
302 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
303 0 : return NULL;
304 : }
305 :
306 14053720 : a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
307 14053720 : if (a == NULL) {
308 77 : PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
309 77 : return NULL;
310 : }
311 :
312 14053643 : attid = dsdb_attribute_get_attid(a, schema_nc);
313 :
314 14053643 : return PyLong_FromUnsignedLong(attid);
315 : }
316 :
317 : /*
318 : return the systemFlags as int from the attribute name
319 : */
320 9468229 : static PyObject *py_dsdb_get_systemFlags_from_lDAPDisplayName(PyObject *self, PyObject *args)
321 : {
322 1373254 : PyObject *py_ldb;
323 1373254 : struct ldb_context *ldb;
324 1373254 : struct dsdb_schema *schema;
325 1373254 : const char *ldap_display_name;
326 1373254 : const struct dsdb_attribute *attribute;
327 :
328 9468229 : if (!PyArg_ParseTuple(args, "Os", &py_ldb, &ldap_display_name))
329 0 : return NULL;
330 :
331 9468229 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
332 :
333 9468229 : schema = dsdb_get_schema(ldb, NULL);
334 :
335 9468229 : if (!schema) {
336 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
337 0 : return NULL;
338 : }
339 :
340 9468229 : attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
341 9468229 : if (attribute == NULL) {
342 0 : PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
343 0 : return NULL;
344 : }
345 :
346 9468229 : return PyLong_FromLong(attribute->systemFlags);
347 : }
348 :
349 : /*
350 : return the linkID from the attribute name
351 : */
352 26652 : static PyObject *py_dsdb_get_linkId_from_lDAPDisplayName(PyObject *self, PyObject *args)
353 : {
354 4296 : PyObject *py_ldb;
355 4296 : struct ldb_context *ldb;
356 4296 : struct dsdb_schema *schema;
357 4296 : const char *ldap_display_name;
358 4296 : const struct dsdb_attribute *attribute;
359 :
360 26652 : if (!PyArg_ParseTuple(args, "Os", &py_ldb, &ldap_display_name))
361 0 : return NULL;
362 :
363 26652 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
364 :
365 26652 : schema = dsdb_get_schema(ldb, NULL);
366 :
367 26652 : if (!schema) {
368 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
369 0 : return NULL;
370 : }
371 :
372 26652 : attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
373 26652 : if (attribute == NULL) {
374 0 : PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
375 0 : return NULL;
376 : }
377 :
378 26652 : return PyLong_FromLong(attribute->linkID);
379 : }
380 :
381 : /*
382 : return the backlink attribute name (if any) for an attribute
383 : */
384 1915 : static PyObject *py_dsdb_get_backlink_from_lDAPDisplayName(PyObject *self, PyObject *args)
385 : {
386 275 : PyObject *py_ldb;
387 275 : struct ldb_context *ldb;
388 275 : struct dsdb_schema *schema;
389 275 : const char *ldap_display_name;
390 275 : const struct dsdb_attribute *attribute, *target_attr;
391 :
392 1915 : if (!PyArg_ParseTuple(args, "Os", &py_ldb, &ldap_display_name))
393 0 : return NULL;
394 :
395 1915 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
396 :
397 1915 : schema = dsdb_get_schema(ldb, NULL);
398 :
399 1915 : if (!schema) {
400 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
401 0 : return NULL;
402 : }
403 :
404 1915 : attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
405 1915 : if (attribute == NULL) {
406 0 : PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
407 0 : return NULL;
408 : }
409 :
410 1915 : if (attribute->linkID == 0) {
411 0 : Py_RETURN_NONE;
412 : }
413 :
414 1915 : target_attr = dsdb_attribute_by_linkID(schema, attribute->linkID ^ 1);
415 1915 : if (target_attr == NULL) {
416 : /* when we add pseudo-backlinks we'll need to handle
417 : them here */
418 407 : Py_RETURN_NONE;
419 : }
420 :
421 1508 : return PyUnicode_FromString(target_attr->lDAPDisplayName);
422 : }
423 :
424 :
425 14469133 : static PyObject *py_dsdb_get_lDAPDisplayName_by_attid(PyObject *self, PyObject *args)
426 : {
427 1357389 : PyObject *py_ldb;
428 1357389 : struct ldb_context *ldb;
429 1357389 : struct dsdb_schema *schema;
430 1357389 : const struct dsdb_attribute *a;
431 1357389 : uint32_t attid;
432 :
433 14469133 : if (!PyArg_ParseTuple(args, "OI", &py_ldb, &attid))
434 0 : return NULL;
435 :
436 14469133 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
437 :
438 14469133 : schema = dsdb_get_schema(ldb, NULL);
439 :
440 14469133 : if (!schema) {
441 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
442 0 : return NULL;
443 : }
444 :
445 14469133 : a = dsdb_attribute_by_attributeID_id(schema, attid);
446 14469133 : if (a == NULL) {
447 0 : PyErr_Format(PyExc_KeyError, "Failed to find attribute '0x%08x'", attid);
448 0 : return NULL;
449 : }
450 :
451 14469133 : return PyUnicode_FromString(a->lDAPDisplayName);
452 : }
453 :
454 :
455 : /*
456 : return the attribute syntax oid as a string from the attribute name
457 : */
458 9476003 : static PyObject *py_dsdb_get_syntax_oid_from_lDAPDisplayName(PyObject *self, PyObject *args)
459 : {
460 1374199 : PyObject *py_ldb;
461 1374199 : struct ldb_context *ldb;
462 1374199 : struct dsdb_schema *schema;
463 1374199 : const char *ldap_display_name;
464 1374199 : const struct dsdb_attribute *attribute;
465 :
466 9476003 : if (!PyArg_ParseTuple(args, "Os", &py_ldb, &ldap_display_name))
467 0 : return NULL;
468 :
469 9476003 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
470 :
471 9476003 : schema = dsdb_get_schema(ldb, NULL);
472 :
473 9476003 : if (!schema) {
474 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
475 0 : return NULL;
476 : }
477 :
478 9476003 : attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
479 9476003 : if (attribute == NULL) {
480 0 : PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
481 0 : return NULL;
482 : }
483 :
484 9476003 : return PyUnicode_FromString(attribute->syntax->ldap_oid);
485 : }
486 :
487 : /*
488 : convert a python string to a DRSUAPI drsuapi_DsReplicaAttribute attribute
489 : */
490 861 : static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args)
491 : {
492 0 : PyObject *py_ldb, *el_list, *ret;
493 0 : struct ldb_context *ldb;
494 0 : char *ldap_display_name;
495 0 : const struct dsdb_attribute *a;
496 0 : struct dsdb_schema *schema;
497 0 : struct dsdb_syntax_ctx syntax_ctx;
498 0 : struct ldb_message_element *el;
499 0 : struct drsuapi_DsReplicaAttribute *attr;
500 0 : TALLOC_CTX *tmp_ctx;
501 0 : WERROR werr;
502 0 : Py_ssize_t i;
503 :
504 861 : if (!PyArg_ParseTuple(args, "OsO", &py_ldb, &ldap_display_name, &el_list)) {
505 0 : return NULL;
506 : }
507 :
508 861 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
509 :
510 861 : schema = dsdb_get_schema(ldb, NULL);
511 861 : if (!schema) {
512 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
513 0 : return NULL;
514 : }
515 :
516 861 : a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
517 861 : if (a == NULL) {
518 0 : PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
519 0 : return NULL;
520 : }
521 :
522 861 : dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema);
523 861 : syntax_ctx.is_schema_nc = false;
524 :
525 861 : tmp_ctx = talloc_new(ldb);
526 861 : if (tmp_ctx == NULL) {
527 0 : PyErr_NoMemory();
528 0 : return NULL;
529 : }
530 :
531 : /* If we were not given an LdbMessageElement */
532 861 : if (!PyList_Check(el_list)) {
533 0 : if (!py_check_dcerpc_type(el_list, "ldb", "MessageElement")) {
534 0 : PyErr_SetString(py_ldb_get_exception(),
535 : "list of strings or ldb MessageElement object required");
536 0 : return NULL;
537 : }
538 : /*
539 : * NOTE:
540 : * el may not be a valid talloc context, it
541 : * could be part of an array
542 : */
543 0 : el = pyldb_MessageElement_AsMessageElement(el_list);
544 : } else {
545 861 : el = talloc_zero(tmp_ctx, struct ldb_message_element);
546 861 : if (el == NULL) {
547 0 : PyErr_NoMemory();
548 0 : talloc_free(tmp_ctx);
549 0 : return NULL;
550 : }
551 :
552 861 : el->name = ldap_display_name;
553 861 : el->num_values = PyList_Size(el_list);
554 :
555 861 : el->values = talloc_array(el, struct ldb_val, el->num_values);
556 861 : if (el->values == NULL) {
557 0 : PyErr_NoMemory();
558 0 : talloc_free(tmp_ctx);
559 0 : return NULL;
560 : }
561 :
562 2118 : for (i = 0; i < el->num_values; i++) {
563 1257 : PyObject *item = PyList_GetItem(el_list, i);
564 1257 : if (!(PyBytes_Check(item))) {
565 0 : PyErr_Format(PyExc_TypeError,
566 : "ldif_element type should be bytes"
567 : );
568 0 : talloc_free(tmp_ctx);
569 0 : return NULL;
570 : }
571 2514 : el->values[i].data =
572 1257 : (uint8_t *)PyBytes_AsString(item);
573 1257 : el->values[i].length = PyBytes_Size(item);
574 : }
575 : }
576 :
577 861 : attr = talloc_zero(tmp_ctx, struct drsuapi_DsReplicaAttribute);
578 861 : if (attr == NULL) {
579 0 : PyErr_NoMemory();
580 0 : talloc_free(tmp_ctx);
581 0 : return NULL;
582 : }
583 :
584 861 : werr = a->syntax->ldb_to_drsuapi(&syntax_ctx, a, el, attr, attr);
585 861 : PyErr_WERROR_NOT_OK_RAISE(werr);
586 :
587 861 : ret = py_return_ndr_struct("samba.dcerpc.drsuapi", "DsReplicaAttribute", attr, attr);
588 :
589 861 : talloc_free(tmp_ctx);
590 :
591 861 : return ret;
592 : }
593 :
594 :
595 : /*
596 : normalise a ldb attribute list
597 : */
598 10887190 : static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args)
599 : {
600 1657928 : PyObject *py_ldb, *el_list, *py_ret;
601 1657928 : struct ldb_context *ldb;
602 1657928 : char *ldap_display_name;
603 1657928 : const struct dsdb_attribute *a;
604 1657928 : struct dsdb_schema *schema;
605 1657928 : struct dsdb_syntax_ctx syntax_ctx;
606 1657928 : struct ldb_message_element *el, *new_el;
607 1657928 : struct drsuapi_DsReplicaAttribute *attr;
608 1657928 : PyLdbMessageElementObject *ret;
609 1657928 : TALLOC_CTX *tmp_ctx;
610 1657928 : WERROR werr;
611 1657928 : Py_ssize_t i;
612 10887190 : PyTypeObject *py_type = NULL;
613 10887190 : PyObject *module = NULL;
614 :
615 10887190 : if (!PyArg_ParseTuple(args, "OsO", &py_ldb, &ldap_display_name, &el_list)) {
616 0 : return NULL;
617 : }
618 :
619 10887190 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
620 :
621 10887190 : schema = dsdb_get_schema(ldb, NULL);
622 10887190 : if (!schema) {
623 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
624 0 : return NULL;
625 : }
626 :
627 10887190 : a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
628 10887190 : if (a == NULL) {
629 0 : PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
630 0 : return NULL;
631 : }
632 :
633 10887190 : dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema);
634 10887190 : syntax_ctx.is_schema_nc = false;
635 :
636 10887190 : tmp_ctx = talloc_new(ldb);
637 10887190 : if (tmp_ctx == NULL) {
638 0 : PyErr_NoMemory();
639 0 : return NULL;
640 : }
641 :
642 10887190 : if (!PyList_Check(el_list)) {
643 508353 : if (!py_check_dcerpc_type(el_list, "ldb", "MessageElement")) {
644 0 : PyErr_SetString(py_ldb_get_exception(),
645 : "list of strings or ldb MessageElement object required");
646 0 : return NULL;
647 : }
648 : /*
649 : * NOTE:
650 : * el may not be a valid talloc context, it
651 : * could be part of an array
652 : */
653 508353 : el = pyldb_MessageElement_AsMessageElement(el_list);
654 : } else {
655 10378837 : el = talloc_zero(tmp_ctx, struct ldb_message_element);
656 10378837 : if (el == NULL) {
657 0 : PyErr_NoMemory();
658 0 : talloc_free(tmp_ctx);
659 0 : return NULL;
660 : }
661 :
662 10378837 : el->name = ldap_display_name;
663 10378837 : el->num_values = PyList_Size(el_list);
664 :
665 10378837 : el->values = talloc_array(el, struct ldb_val, el->num_values);
666 10378837 : if (el->values == NULL) {
667 0 : PyErr_NoMemory();
668 0 : talloc_free(tmp_ctx);
669 0 : return NULL;
670 : }
671 :
672 20757674 : for (i = 0; i < el->num_values; i++) {
673 10378837 : PyObject *item = PyList_GetItem(el_list, i);
674 10378837 : if (!PyBytes_Check(item)) {
675 0 : PyErr_Format(PyExc_TypeError,
676 : "ldif_element type should be bytes"
677 : );
678 0 : talloc_free(tmp_ctx);
679 0 : return NULL;
680 : }
681 10378837 : el->values[i].data = (uint8_t *)PyBytes_AsString(item);
682 10378837 : el->values[i].length = PyBytes_Size(item);
683 : }
684 : }
685 :
686 10887190 : new_el = talloc_zero(tmp_ctx, struct ldb_message_element);
687 10887190 : if (new_el == NULL) {
688 0 : PyErr_NoMemory();
689 0 : talloc_free(tmp_ctx);
690 0 : return NULL;
691 : }
692 :
693 : /* Normalise "objectClass" attribute if needed */
694 10887190 : if (ldb_attr_cmp(a->lDAPDisplayName, "objectClass") == 0) {
695 79043 : int iret;
696 508353 : iret = dsdb_sort_objectClass_attr(ldb, schema, el, new_el, new_el);
697 508353 : if (iret != LDB_SUCCESS) {
698 0 : PyErr_SetString(PyExc_RuntimeError, ldb_errstring(ldb));
699 0 : talloc_free(tmp_ctx);
700 0 : return NULL;
701 : }
702 : }
703 :
704 : /* first run ldb_to_drsuapi, then convert back again. This has
705 : * the effect of normalising the attributes
706 : */
707 :
708 10887190 : attr = talloc_zero(tmp_ctx, struct drsuapi_DsReplicaAttribute);
709 10887190 : if (attr == NULL) {
710 0 : PyErr_NoMemory();
711 0 : talloc_free(tmp_ctx);
712 0 : return NULL;
713 : }
714 :
715 10887190 : werr = a->syntax->ldb_to_drsuapi(&syntax_ctx, a, el, attr, attr);
716 10887190 : PyErr_WERROR_NOT_OK_RAISE(werr);
717 :
718 : /* now convert back again */
719 10887190 : werr = a->syntax->drsuapi_to_ldb(&syntax_ctx, a, attr, new_el, new_el);
720 10887190 : PyErr_WERROR_NOT_OK_RAISE(werr);
721 :
722 10887190 : module = PyImport_ImportModule("ldb");
723 10887190 : if (module == NULL) {
724 0 : return NULL;
725 : }
726 :
727 10887190 : py_type = (PyTypeObject *)PyObject_GetAttrString(module, "MessageElement");
728 10887190 : if (py_type == NULL) {
729 0 : Py_DECREF(module);
730 0 : return NULL;
731 : }
732 :
733 10887190 : Py_CLEAR(module);
734 :
735 10887190 : py_ret = py_type->tp_alloc(py_type, 0);
736 10887190 : Py_CLEAR(py_type);
737 10887190 : if (py_ret == NULL) {
738 0 : PyErr_NoMemory();
739 0 : return NULL;
740 : }
741 10887190 : ret = (PyLdbMessageElementObject *)py_ret;
742 :
743 10887190 : ret->mem_ctx = talloc_new(NULL);
744 10887190 : if (talloc_reference(ret->mem_ctx, new_el) == NULL) {
745 0 : Py_CLEAR(py_ret);
746 0 : PyErr_NoMemory();
747 0 : return NULL;
748 : }
749 10887190 : ret->el = new_el;
750 :
751 10887190 : talloc_free(tmp_ctx);
752 :
753 10887190 : return py_ret;
754 : }
755 :
756 :
757 266 : static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
758 : {
759 44 : PyObject *py_ldb, *py_guid;
760 44 : bool ret;
761 44 : struct GUID guid;
762 44 : struct ldb_context *ldb;
763 266 : if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_guid))
764 0 : return NULL;
765 :
766 266 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
767 266 : GUID_from_string(PyUnicode_AsUTF8(py_guid), &guid);
768 :
769 266 : if (GUID_all_zero(&guid)) {
770 0 : PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id rejected due to all-zero invocation ID");
771 0 : return NULL;
772 : }
773 :
774 266 : ret = samdb_set_ntds_invocation_id(ldb, &guid);
775 266 : if (!ret) {
776 0 : PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id failed");
777 0 : return NULL;
778 : }
779 266 : Py_RETURN_NONE;
780 : }
781 :
782 4669 : static PyObject *py_samdb_ntds_objectGUID(PyObject *self, PyObject *args)
783 : {
784 27 : PyObject *py_ldb, *result;
785 27 : struct ldb_context *ldb;
786 27 : const struct GUID *guid;
787 27 : char *retstr;
788 :
789 4669 : if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
790 0 : return NULL;
791 : }
792 :
793 4669 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
794 :
795 4669 : guid = samdb_ntds_objectGUID(ldb);
796 4669 : if (guid == NULL) {
797 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to find NTDS GUID");
798 0 : return NULL;
799 : }
800 :
801 4669 : retstr = GUID_string(NULL, guid);
802 4669 : if (retstr == NULL) {
803 0 : PyErr_NoMemory();
804 0 : return NULL;
805 : }
806 4669 : result = PyUnicode_FromString(retstr);
807 4669 : talloc_free(retstr);
808 4669 : return result;
809 : }
810 :
811 31889 : static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args)
812 : {
813 169 : PyObject *py_ldb;
814 169 : struct ldb_context *ldb;
815 169 : int ret;
816 31889 : if (!PyArg_ParseTuple(args, "O", &py_ldb))
817 0 : return NULL;
818 :
819 31889 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
820 :
821 31889 : ret = dsdb_set_global_schema(ldb);
822 31889 : PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
823 :
824 31889 : Py_RETURN_NONE;
825 : }
826 :
827 25 : static PyObject *py_dsdb_load_partition_usn(PyObject *self, PyObject *args)
828 : {
829 0 : PyObject *py_dn, *py_ldb, *result;
830 0 : struct ldb_dn *dn;
831 0 : uint64_t highest_uSN, urgent_uSN;
832 0 : struct ldb_context *ldb;
833 0 : TALLOC_CTX *mem_ctx;
834 0 : int ret;
835 :
836 25 : if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_dn)) {
837 0 : return NULL;
838 : }
839 :
840 25 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
841 :
842 25 : mem_ctx = talloc_new(NULL);
843 25 : if (mem_ctx == NULL) {
844 0 : PyErr_NoMemory();
845 0 : return NULL;
846 : }
847 :
848 25 : if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb, &dn)) {
849 0 : talloc_free(mem_ctx);
850 0 : return NULL;
851 : }
852 :
853 25 : ret = dsdb_load_partition_usn(ldb, dn, &highest_uSN, &urgent_uSN);
854 25 : if (ret != LDB_SUCCESS) {
855 0 : PyErr_Format(PyExc_RuntimeError,
856 : "Failed to load partition [%s] uSN - %s",
857 : ldb_dn_get_linearized(dn),
858 : ldb_errstring(ldb));
859 0 : talloc_free(mem_ctx);
860 0 : return NULL;
861 : }
862 :
863 25 : talloc_free(mem_ctx);
864 :
865 25 : result = Py_BuildValue(
866 : "{s:l, s:l}",
867 : "uSNHighest", (uint64_t)highest_uSN,
868 : "uSNUrgent", (uint64_t)urgent_uSN);
869 :
870 25 : return result;
871 : }
872 :
873 692 : static PyObject *py_dsdb_set_am_rodc(PyObject *self, PyObject *args)
874 : {
875 47 : PyObject *py_ldb;
876 47 : bool ret;
877 47 : struct ldb_context *ldb;
878 47 : int py_val;
879 :
880 692 : if (!PyArg_ParseTuple(args, "Oi", &py_ldb, &py_val))
881 0 : return NULL;
882 :
883 692 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
884 692 : ret = samdb_set_am_rodc(ldb, (bool)py_val);
885 692 : if (!ret) {
886 0 : PyErr_SetString(PyExc_RuntimeError, "set_am_rodc failed");
887 0 : return NULL;
888 : }
889 692 : Py_RETURN_NONE;
890 : }
891 :
892 390 : static PyObject *py_dsdb_set_schema_from_ldif(PyObject *self, PyObject *args)
893 : {
894 24 : WERROR result;
895 24 : char *pf, *df, *dn;
896 24 : PyObject *py_ldb;
897 24 : struct ldb_context *ldb;
898 :
899 390 : if (!PyArg_ParseTuple(args, "Osss", &py_ldb, &pf, &df, &dn))
900 0 : return NULL;
901 :
902 390 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
903 :
904 390 : result = dsdb_set_schema_from_ldif(ldb, pf, df, dn);
905 390 : PyErr_WERROR_NOT_OK_RAISE(result);
906 :
907 390 : Py_RETURN_NONE;
908 : }
909 :
910 512 : static PyObject *py_dsdb_set_schema_from_ldb(PyObject *self, PyObject *args)
911 : {
912 46 : PyObject *py_ldb;
913 46 : struct ldb_context *ldb;
914 46 : PyObject *py_from_ldb;
915 46 : struct ldb_context *from_ldb;
916 46 : struct dsdb_schema *schema;
917 46 : int ret;
918 512 : char write_indices_and_attributes = SCHEMA_WRITE;
919 512 : if (!PyArg_ParseTuple(args, "OO|b",
920 : &py_ldb, &py_from_ldb, &write_indices_and_attributes))
921 0 : return NULL;
922 :
923 512 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
924 :
925 512 : PyErr_LDB_OR_RAISE(py_from_ldb, from_ldb);
926 :
927 512 : schema = dsdb_get_schema(from_ldb, NULL);
928 512 : if (!schema) {
929 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on 'from' ldb!\n");
930 0 : return NULL;
931 : }
932 :
933 512 : ret = dsdb_reference_schema(ldb, schema, write_indices_and_attributes);
934 512 : PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
935 :
936 512 : Py_RETURN_NONE;
937 : }
938 :
939 127 : static PyObject *py_dsdb_write_prefixes_from_schema_to_ldb(PyObject *self, PyObject *args)
940 : {
941 22 : PyObject *py_ldb;
942 22 : struct ldb_context *ldb;
943 22 : WERROR result;
944 22 : struct dsdb_schema *schema;
945 :
946 127 : if (!PyArg_ParseTuple(args, "O", &py_ldb))
947 0 : return NULL;
948 :
949 127 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
950 :
951 127 : schema = dsdb_get_schema(ldb, NULL);
952 127 : if (!schema) {
953 0 : PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on ldb!\n");
954 0 : return NULL;
955 : }
956 :
957 127 : result = dsdb_write_prefixes_from_schema_to_ldb(NULL, ldb, schema);
958 127 : PyErr_WERROR_NOT_OK_RAISE(result);
959 :
960 127 : Py_RETURN_NONE;
961 : }
962 :
963 :
964 5818 : static PyObject *py_dsdb_get_partitions_dn(PyObject *self, PyObject *args)
965 : {
966 117 : struct ldb_context *ldb;
967 117 : struct ldb_dn *dn;
968 117 : PyObject *py_ldb, *ret;
969 :
970 5818 : if (!PyArg_ParseTuple(args, "O", &py_ldb))
971 0 : return NULL;
972 :
973 5818 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
974 :
975 5818 : dn = samdb_partitions_dn(ldb, NULL);
976 5818 : if (dn == NULL) {
977 0 : PyErr_NoMemory();
978 0 : return NULL;
979 : }
980 5818 : ret = pyldb_Dn_FromDn(dn, (PyLdbObject *)py_ldb);
981 5818 : talloc_free(dn);
982 5818 : return ret;
983 : }
984 :
985 :
986 1764334 : static PyObject *py_dsdb_get_nc_root(PyObject *self, PyObject *args)
987 : {
988 194564 : struct ldb_context *ldb;
989 194564 : struct ldb_dn *dn, *nc_root;
990 194564 : PyObject *py_ldb, *py_ldb_dn, *py_nc_root;
991 194564 : int ret;
992 :
993 1764334 : if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_ldb_dn))
994 0 : return NULL;
995 :
996 1764334 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
997 1764334 : PyErr_LDB_DN_OR_RAISE(py_ldb_dn, dn);
998 :
999 1764334 : ret = dsdb_find_nc_root(ldb, ldb, dn, &nc_root);
1000 1764334 : PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
1001 :
1002 1764322 : py_nc_root = pyldb_Dn_FromDn(nc_root, (PyLdbObject *)py_ldb);
1003 1764322 : talloc_unlink(ldb, nc_root);
1004 1764322 : return py_nc_root;
1005 : }
1006 :
1007 570333 : static PyObject *py_dsdb_get_wellknown_dn(PyObject *self, PyObject *args)
1008 : {
1009 77055 : struct ldb_context *ldb;
1010 77055 : struct ldb_dn *nc_dn, *wk_dn;
1011 77055 : char *wkguid;
1012 77055 : PyObject *py_ldb, *py_nc_dn, *py_wk_dn;
1013 77055 : int ret;
1014 :
1015 570333 : if (!PyArg_ParseTuple(args, "OOs", &py_ldb, &py_nc_dn, &wkguid))
1016 0 : return NULL;
1017 :
1018 570333 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
1019 570333 : PyErr_LDB_DN_OR_RAISE(py_nc_dn, nc_dn);
1020 :
1021 570333 : ret = dsdb_wellknown_dn(ldb, ldb, nc_dn, wkguid, &wk_dn);
1022 570333 : if (ret == LDB_ERR_NO_SUCH_OBJECT) {
1023 553073 : PyErr_Format(PyExc_KeyError, "Failed to find well known DN for GUID %s", wkguid);
1024 553073 : return NULL;
1025 : }
1026 :
1027 17260 : PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
1028 :
1029 17251 : py_wk_dn = pyldb_Dn_FromDn(wk_dn, (PyLdbObject *)py_ldb);
1030 17251 : talloc_unlink(ldb, wk_dn);
1031 17251 : return py_wk_dn;
1032 : }
1033 :
1034 :
1035 : /*
1036 : call into samdb_rodc()
1037 : */
1038 346 : static PyObject *py_dsdb_am_rodc(PyObject *self, PyObject *args)
1039 : {
1040 20 : PyObject *py_ldb;
1041 20 : struct ldb_context *ldb;
1042 20 : int ret;
1043 20 : bool am_rodc;
1044 :
1045 346 : if (!PyArg_ParseTuple(args, "O", &py_ldb))
1046 0 : return NULL;
1047 :
1048 346 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
1049 :
1050 346 : ret = samdb_rodc(ldb, &am_rodc);
1051 346 : if (ret != LDB_SUCCESS) {
1052 0 : PyErr_SetString(PyExc_RuntimeError, ldb_errstring(ldb));
1053 0 : return NULL;
1054 : }
1055 :
1056 346 : return PyBool_FromLong(am_rodc);
1057 : }
1058 :
1059 : /*
1060 : call into samdb_is_pdc()
1061 : */
1062 200 : static PyObject *py_dsdb_am_pdc(PyObject *self, PyObject *args)
1063 : {
1064 4 : PyObject *py_ldb;
1065 4 : struct ldb_context *ldb;
1066 4 : bool am_pdc;
1067 :
1068 200 : if (!PyArg_ParseTuple(args, "O", &py_ldb))
1069 0 : return NULL;
1070 :
1071 200 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
1072 :
1073 200 : am_pdc = samdb_is_pdc(ldb);
1074 200 : return PyBool_FromLong(am_pdc);
1075 : }
1076 :
1077 : /*
1078 : call DSDB_EXTENDED_CREATE_OWN_RID_SET to get a new RID set for this server
1079 : */
1080 39 : static PyObject *py_dsdb_create_own_rid_set(PyObject *self, PyObject *args)
1081 : {
1082 0 : PyObject *py_ldb;
1083 0 : struct ldb_context *ldb;
1084 0 : int ret;
1085 0 : struct ldb_result *ext_res;
1086 :
1087 39 : if (!PyArg_ParseTuple(args, "O", &py_ldb))
1088 0 : return NULL;
1089 :
1090 39 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
1091 :
1092 : /*
1093 : * Run DSDB_EXTENDED_CREATE_OWN_RID_SET to get a RID set
1094 : */
1095 :
1096 39 : ret = ldb_extended(ldb, DSDB_EXTENDED_CREATE_OWN_RID_SET, NULL, &ext_res);
1097 :
1098 39 : PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
1099 :
1100 38 : TALLOC_FREE(ext_res);
1101 :
1102 38 : Py_RETURN_NONE;
1103 : }
1104 :
1105 : /*
1106 : call DSDB_EXTENDED_ALLOCATE_RID to get a new RID set for this server
1107 : */
1108 995 : static PyObject *py_dsdb_allocate_rid(PyObject *self, PyObject *args)
1109 : {
1110 0 : PyObject *py_ldb;
1111 0 : struct ldb_context *ldb;
1112 0 : int ret;
1113 0 : uint32_t rid;
1114 995 : struct ldb_result *ext_res = NULL;
1115 995 : struct dsdb_extended_allocate_rid *rid_return = NULL;
1116 995 : if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
1117 0 : return NULL;
1118 : }
1119 :
1120 995 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
1121 :
1122 995 : rid_return = talloc_zero(ldb, struct dsdb_extended_allocate_rid);
1123 995 : if (rid_return == NULL) {
1124 0 : return PyErr_NoMemory();
1125 : }
1126 :
1127 : /*
1128 : * Run DSDB_EXTENDED_ALLOCATE_RID to get a new RID
1129 : */
1130 :
1131 995 : ret = ldb_extended(ldb, DSDB_EXTENDED_ALLOCATE_RID, rid_return, &ext_res);
1132 995 : if (ret != LDB_SUCCESS) {
1133 2 : TALLOC_FREE(rid_return);
1134 2 : TALLOC_FREE(ext_res);
1135 2 : PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
1136 : }
1137 :
1138 993 : rid = rid_return->rid;
1139 993 : TALLOC_FREE(rid_return);
1140 993 : TALLOC_FREE(ext_res);
1141 :
1142 993 : return PyLong_FromLong(rid);
1143 : }
1144 :
1145 : #ifdef AD_DC_BUILD_IS_ENABLED
1146 : /*
1147 : * These functions will not work correctly on non-AD_DC builds.
1148 : *
1149 : * The only real principal in deciding whether to put something within
1150 : * these guards is whether it will compile and work when
1151 : * bld.AD_DC_BUILD_IS_ENABLED() says no.
1152 : *
1153 : * Most of DSDB is built and samba-tool will work fine with remote
1154 : * servers (using -H ldap://), but some DNS and periodic service
1155 : * functions are not built.
1156 : */
1157 :
1158 8 : static PyObject *py_dns_delete_tombstones(PyObject *self, PyObject *args)
1159 : {
1160 0 : PyObject *py_ldb;
1161 0 : NTSTATUS status;
1162 8 : struct ldb_context *ldb = NULL;
1163 8 : TALLOC_CTX *mem_ctx = NULL;
1164 8 : char *error_string = NULL;
1165 :
1166 8 : if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
1167 0 : return NULL;
1168 : }
1169 8 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
1170 :
1171 8 : mem_ctx = talloc_new(ldb);
1172 8 : if (mem_ctx == NULL) {
1173 0 : return PyErr_NoMemory();
1174 : }
1175 :
1176 8 : status = dns_delete_tombstones(mem_ctx, ldb, &error_string);
1177 :
1178 8 : if (!NT_STATUS_IS_OK(status)) {
1179 0 : if (error_string) {
1180 0 : PyErr_Format(PyExc_RuntimeError, "%s", error_string);
1181 : } else {
1182 0 : PyErr_SetNTSTATUS(status);
1183 : }
1184 0 : TALLOC_FREE(mem_ctx);
1185 0 : return NULL;
1186 : }
1187 :
1188 8 : TALLOC_FREE(mem_ctx);
1189 8 : Py_RETURN_NONE;
1190 : }
1191 :
1192 6 : static PyObject *py_scavenge_dns_records(PyObject *self, PyObject *args)
1193 : {
1194 0 : PyObject *py_ldb;
1195 0 : NTSTATUS status;
1196 6 : struct ldb_context *ldb = NULL;
1197 6 : TALLOC_CTX *mem_ctx = NULL;
1198 6 : char *error_string = NULL;
1199 :
1200 6 : if (!PyArg_ParseTuple(args, "O", &py_ldb)) {
1201 0 : return NULL;
1202 : }
1203 6 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
1204 :
1205 6 : mem_ctx = talloc_new(ldb);
1206 6 : if (mem_ctx == NULL) {
1207 0 : return PyErr_NoMemory();
1208 : }
1209 :
1210 6 : status = dns_tombstone_records(mem_ctx, ldb, &error_string);
1211 :
1212 6 : if (!NT_STATUS_IS_OK(status)) {
1213 0 : if (error_string) {
1214 0 : PyErr_Format(PyExc_RuntimeError, "%s", error_string);
1215 : } else {
1216 0 : PyErr_SetNTSTATUS(status);
1217 : }
1218 0 : TALLOC_FREE(mem_ctx);
1219 0 : return NULL;
1220 : }
1221 :
1222 6 : TALLOC_FREE(mem_ctx);
1223 6 : Py_RETURN_NONE;
1224 : }
1225 :
1226 4 : static PyObject *py_dsdb_garbage_collect_tombstones(PyObject *self, PyObject *args)
1227 : {
1228 1 : PyObject *py_ldb, *py_list_dn;
1229 4 : struct ldb_context *ldb = NULL;
1230 1 : Py_ssize_t i;
1231 1 : Py_ssize_t length;
1232 4 : long long _current_time, _tombstone_lifetime = LLONG_MAX;
1233 1 : uint32_t tombstone_lifetime32;
1234 4 : struct dsdb_ldb_dn_list_node *part = NULL;
1235 1 : time_t current_time, tombstone_lifetime;
1236 4 : TALLOC_CTX *mem_ctx = NULL;
1237 1 : NTSTATUS status;
1238 4 : unsigned int num_objects_removed = 0;
1239 4 : unsigned int num_links_removed = 0;
1240 4 : char *error_string = NULL;
1241 :
1242 4 : if (!PyArg_ParseTuple(args, "OOL|L", &py_ldb,
1243 : &py_list_dn, &_current_time, &_tombstone_lifetime)) {
1244 0 : return NULL;
1245 : }
1246 :
1247 :
1248 4 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
1249 :
1250 4 : mem_ctx = talloc_new(ldb);
1251 4 : if (mem_ctx == NULL) {
1252 0 : return PyErr_NoMemory();
1253 : }
1254 :
1255 4 : current_time = _current_time;
1256 :
1257 4 : if (_tombstone_lifetime == LLONG_MAX) {
1258 0 : int ret = dsdb_tombstone_lifetime(ldb, &tombstone_lifetime32);
1259 0 : if (ret != LDB_SUCCESS) {
1260 0 : PyErr_Format(PyExc_RuntimeError,
1261 : "Failed to get tombstone lifetime: %s",
1262 : ldb_errstring(ldb));
1263 0 : TALLOC_FREE(mem_ctx);
1264 0 : return NULL;
1265 : }
1266 0 : tombstone_lifetime = tombstone_lifetime32;
1267 : } else {
1268 3 : tombstone_lifetime = _tombstone_lifetime;
1269 : }
1270 :
1271 4 : if (!PyList_Check(py_list_dn)) {
1272 0 : PyErr_SetString(PyExc_TypeError, "A list of DNs were expected");
1273 0 : TALLOC_FREE(mem_ctx);
1274 0 : return NULL;
1275 : }
1276 :
1277 4 : length = PyList_GET_SIZE(py_list_dn);
1278 :
1279 20 : for (i = 0; i < length; i++) {
1280 16 : const char *part_str = PyUnicode_AsUTF8(PyList_GetItem(py_list_dn, i));
1281 5 : struct ldb_dn *p;
1282 5 : struct dsdb_ldb_dn_list_node *node;
1283 :
1284 16 : if (part_str == NULL) {
1285 0 : TALLOC_FREE(mem_ctx);
1286 0 : return PyErr_NoMemory();
1287 : }
1288 :
1289 16 : p = ldb_dn_new(mem_ctx, ldb, part_str);
1290 16 : if (p == NULL) {
1291 0 : PyErr_Format(PyExc_RuntimeError, "Failed to parse DN %s", part_str);
1292 0 : TALLOC_FREE(mem_ctx);
1293 0 : return NULL;
1294 : }
1295 16 : node = talloc_zero(mem_ctx, struct dsdb_ldb_dn_list_node);
1296 16 : node->dn = p;
1297 :
1298 16 : DLIST_ADD_END(part, node);
1299 : }
1300 :
1301 4 : status = dsdb_garbage_collect_tombstones(mem_ctx, ldb,
1302 : part, current_time,
1303 : tombstone_lifetime,
1304 : &num_objects_removed,
1305 : &num_links_removed,
1306 : &error_string);
1307 :
1308 4 : if (!NT_STATUS_IS_OK(status)) {
1309 0 : if (error_string) {
1310 0 : PyErr_Format(PyExc_RuntimeError, "%s", error_string);
1311 : } else {
1312 0 : PyErr_SetNTSTATUS(status);
1313 : }
1314 0 : TALLOC_FREE(mem_ctx);
1315 0 : return NULL;
1316 : }
1317 :
1318 4 : TALLOC_FREE(mem_ctx);
1319 :
1320 4 : return Py_BuildValue("(II)", num_objects_removed,
1321 : num_links_removed);
1322 : }
1323 :
1324 : #else
1325 :
1326 0 : static PyObject *py_dsdb_not_implemented(PyObject *self, PyObject *args)
1327 : {
1328 0 : PyErr_SetString(PyExc_NotImplementedError,
1329 : "Library built without AD DC support");
1330 0 : return NULL;
1331 : }
1332 :
1333 : #endif /* AD_DC_BUILD_IS_ENABLED */
1334 :
1335 :
1336 100 : static PyObject *py_dsdb_create_gkdi_root_key(PyObject *self, PyObject *args, PyObject *kwargs)
1337 : {
1338 22 : int ret;
1339 100 : PyObject *py_ldb = NULL;
1340 100 : PyObject *py_dn = NULL;
1341 22 : struct ldb_context *samdb;
1342 : /* long long time for Python conversions, NTTIME for Samba libs */
1343 100 : unsigned long long ll_current_time = 0;
1344 100 : unsigned long long ll_use_start_time = 0;
1345 22 : NTTIME current_time, use_start_time;
1346 100 : struct GUID root_key_id = {0};
1347 100 : const struct ldb_message * root_key_msg = NULL;
1348 :
1349 100 : TALLOC_CTX *tmp_ctx = NULL;
1350 100 : const char * const kwnames[] = {
1351 : "ldb",
1352 : "current_time",
1353 : "use_start_time",
1354 : NULL
1355 : };
1356 :
1357 100 : if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|KK",
1358 : discard_const_p(char *, kwnames),
1359 : &py_ldb,
1360 : &ll_current_time,
1361 : &ll_use_start_time)) {
1362 0 : return NULL;
1363 : }
1364 :
1365 100 : PyErr_LDB_OR_RAISE(py_ldb, samdb);
1366 :
1367 100 : current_time = ll_current_time;
1368 100 : use_start_time = ll_use_start_time;
1369 : /*
1370 : * If current_time or use_start_time are not provided, we use
1371 : * now. FIXME? should use_start_time be +10 hours or something?
1372 : */
1373 100 : if (current_time == 0 || use_start_time == 0) {
1374 12 : struct timeval now = timeval_current();
1375 12 : NTTIME nt_now = timeval_to_nttime(&now);
1376 12 : if (current_time == 0) {
1377 12 : current_time = nt_now;
1378 : }
1379 12 : if (use_start_time == 0) {
1380 9 : use_start_time = nt_now;
1381 : }
1382 : }
1383 :
1384 100 : tmp_ctx = talloc_new(samdb);
1385 100 : if (tmp_ctx == NULL) {
1386 0 : return PyErr_NoMemory();
1387 : }
1388 100 : ret = gkdi_new_root_key(tmp_ctx,
1389 : samdb,
1390 : current_time,
1391 : use_start_time,
1392 : &root_key_id,
1393 : &root_key_msg);
1394 :
1395 100 : PyErr_LDB_ERROR_IS_ERR_RAISE_FREE(py_ldb_get_exception(), ret,
1396 : samdb, tmp_ctx);
1397 :
1398 :
1399 97 : py_dn = pyldb_Dn_FromDn(root_key_msg->dn,
1400 : (PyLdbObject *)py_ldb);
1401 97 : if (py_dn == NULL) {
1402 0 : PyErr_LDB_ERROR_IS_ERR_RAISE_FREE(py_ldb_get_exception(),
1403 : LDB_ERR_OPERATIONS_ERROR,
1404 : samdb, tmp_ctx);
1405 : }
1406 :
1407 : /*
1408 : * py_dn keeps a talloc_reference to it's own dn, and the
1409 : * root_key is in the database.
1410 : */
1411 97 : TALLOC_FREE(tmp_ctx);
1412 97 : return py_dn;
1413 : }
1414 :
1415 :
1416 596 : static PyObject *py_dsdb_load_udv_v2(PyObject *self, PyObject *args)
1417 : {
1418 0 : uint32_t count;
1419 0 : int ret, i;
1420 0 : bool ok;
1421 596 : PyObject *py_ldb = NULL, *py_dn = NULL, *pylist = NULL;
1422 596 : struct ldb_context *samdb = NULL;
1423 596 : struct ldb_dn *dn = NULL;
1424 596 : struct drsuapi_DsReplicaCursor2 *cursors = NULL;
1425 596 : TALLOC_CTX *tmp_ctx = NULL;
1426 :
1427 596 : if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_dn)) {
1428 0 : return NULL;
1429 : }
1430 :
1431 596 : PyErr_LDB_OR_RAISE(py_ldb, samdb);
1432 :
1433 596 : tmp_ctx = talloc_new(samdb);
1434 596 : if (tmp_ctx == NULL) {
1435 0 : return PyErr_NoMemory();
1436 : }
1437 :
1438 596 : ok = pyldb_Object_AsDn(tmp_ctx, py_dn, samdb, &dn);
1439 596 : if (!ok) {
1440 0 : TALLOC_FREE(tmp_ctx);
1441 0 : return NULL;
1442 : }
1443 :
1444 596 : ret = dsdb_load_udv_v2(samdb, dn, tmp_ctx, &cursors, &count);
1445 596 : if (ret != LDB_SUCCESS) {
1446 0 : TALLOC_FREE(tmp_ctx);
1447 0 : PyErr_SetString(PyExc_RuntimeError,
1448 : "Failed to load udv from ldb");
1449 0 : return NULL;
1450 : }
1451 :
1452 596 : pylist = PyList_New(count);
1453 596 : if (pylist == NULL) {
1454 0 : TALLOC_FREE(tmp_ctx);
1455 0 : return PyErr_NoMemory();
1456 : }
1457 :
1458 1590 : for (i = 0; i < count; i++) {
1459 0 : PyObject *py_cursor;
1460 0 : struct drsuapi_DsReplicaCursor2 *cursor;
1461 994 : cursor = talloc(tmp_ctx, struct drsuapi_DsReplicaCursor2);
1462 994 : if (cursor == NULL) {
1463 0 : TALLOC_FREE(tmp_ctx);
1464 0 : return PyErr_NoMemory();
1465 : }
1466 994 : *cursor = cursors[i];
1467 :
1468 994 : py_cursor = py_return_ndr_struct("samba.dcerpc.drsuapi",
1469 : "DsReplicaCursor2",
1470 : cursor, cursor);
1471 994 : if (py_cursor == NULL) {
1472 0 : TALLOC_FREE(tmp_ctx);
1473 0 : return PyErr_NoMemory();
1474 : }
1475 :
1476 994 : PyList_SetItem(pylist, i, py_cursor);
1477 : }
1478 :
1479 596 : TALLOC_FREE(tmp_ctx);
1480 596 : return pylist;
1481 : }
1482 :
1483 648 : static PyObject *py_dsdb_user_account_control_flag_bit_to_string(PyObject *self, PyObject *args)
1484 : {
1485 31 : const char *str;
1486 31 : long long uf;
1487 648 : if (!PyArg_ParseTuple(args, "L", &uf)) {
1488 0 : return NULL;
1489 : }
1490 :
1491 647 : if (uf > UINT32_MAX) {
1492 1 : return PyErr_Format(PyExc_OverflowError, "No UF_ flags are over UINT32_MAX");
1493 : }
1494 646 : if (uf < 0) {
1495 0 : return PyErr_Format(PyExc_KeyError, "No UF_ flags are less then zero");
1496 : }
1497 :
1498 646 : str = dsdb_user_account_control_flag_bit_to_string(uf);
1499 646 : if (str == NULL) {
1500 5 : return PyErr_Format(PyExc_KeyError,
1501 : "No such UF_ flag 0x%08x",
1502 : (unsigned int)uf);
1503 : }
1504 641 : return PyUnicode_FromString(str);
1505 : }
1506 :
1507 5 : static PyObject *py_dsdb_check_and_update_fl(PyObject *self, PyObject *args)
1508 : {
1509 5 : TALLOC_CTX *frame = NULL;
1510 :
1511 5 : PyObject *py_ldb = NULL, *py_lp = NULL;
1512 5 : struct ldb_context *ldb = NULL;
1513 5 : struct loadparm_context *lp_ctx = NULL;
1514 :
1515 1 : int ret;
1516 :
1517 5 : if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_lp)) {
1518 0 : return NULL;
1519 : }
1520 :
1521 5 : PyErr_LDB_OR_RAISE(py_ldb, ldb);
1522 :
1523 5 : frame = talloc_stackframe();
1524 :
1525 5 : lp_ctx = lpcfg_from_py_object(frame, py_lp);
1526 5 : if (lp_ctx == NULL) {
1527 0 : TALLOC_FREE(frame);
1528 0 : return NULL;
1529 : }
1530 :
1531 5 : ret = dsdb_check_and_update_fl(ldb, lp_ctx);
1532 5 : TALLOC_FREE(frame);
1533 :
1534 5 : PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
1535 :
1536 4 : Py_RETURN_NONE;
1537 : }
1538 :
1539 127 : static PyObject *py_dsdb_dc_operatingSystemVersion(PyObject *self, PyObject *args)
1540 : {
1541 127 : const char *str = NULL;
1542 127 : int dc_level = 0;
1543 :
1544 127 : if (!PyArg_ParseTuple(args, "i", &dc_level)) {
1545 0 : return NULL;
1546 : }
1547 :
1548 127 : str = dsdb_dc_operatingSystemVersion(dc_level);
1549 127 : if (str == NULL) {
1550 0 : return PyErr_Format(PyExc_KeyError,
1551 : "dsdb_dc_operatingSystemVersion(%d) failed",
1552 : dc_level);
1553 : }
1554 :
1555 127 : return PyUnicode_FromString(str);
1556 : }
1557 :
1558 : static PyMethodDef py_dsdb_methods[] = {
1559 : { "_samdb_server_site_name", (PyCFunction)py_samdb_server_site_name,
1560 : METH_VARARGS, "Get the server site name as a string"},
1561 : { "_dsdb_convert_schema_to_openldap",
1562 : (PyCFunction)py_dsdb_convert_schema_to_openldap, METH_VARARGS,
1563 : "dsdb_convert_schema_to_openldap(ldb, target_str, mapping) -> str\n"
1564 : "Create an OpenLDAP schema from a schema." },
1565 : { "_samdb_set_domain_sid", (PyCFunction)py_samdb_set_domain_sid,
1566 : METH_VARARGS,
1567 : "samdb_set_domain_sid(samdb, sid)\n"
1568 : "Set SID of domain to use." },
1569 : { "_samdb_get_domain_sid", (PyCFunction)py_samdb_get_domain_sid,
1570 : METH_VARARGS,
1571 : "samdb_get_domain_sid(samdb)\n"
1572 : "Get SID of domain in use." },
1573 : { "_samdb_ntds_invocation_id", (PyCFunction)py_samdb_ntds_invocation_id,
1574 : METH_VARARGS, "get the NTDS invocation ID GUID as a string"},
1575 : { "_samdb_set_ntds_settings_dn", (PyCFunction)py_samdb_set_ntds_settings_dn,
1576 : METH_VARARGS,
1577 : "samdb_set_ntds_settings_dn(samdb, ntds_settings_dn)\n"
1578 : "Set NTDS Settings DN for this LDB (allows it to be set before the DB fully exists)." },
1579 : { "_dsdb_get_oid_from_attid", (PyCFunction)py_dsdb_get_oid_from_attid,
1580 : METH_VARARGS, NULL },
1581 : { "_dsdb_get_attid_from_lDAPDisplayName", (PyCFunction)py_dsdb_get_attid_from_lDAPDisplayName,
1582 : METH_VARARGS, NULL },
1583 : { "_dsdb_get_syntax_oid_from_lDAPDisplayName", (PyCFunction)py_dsdb_get_syntax_oid_from_lDAPDisplayName,
1584 : METH_VARARGS, NULL },
1585 : { "_dsdb_get_systemFlags_from_lDAPDisplayName", (PyCFunction)py_dsdb_get_systemFlags_from_lDAPDisplayName,
1586 : METH_VARARGS, NULL },
1587 : { "_dsdb_get_linkId_from_lDAPDisplayName", (PyCFunction)py_dsdb_get_linkId_from_lDAPDisplayName,
1588 : METH_VARARGS, NULL },
1589 : { "_dsdb_get_lDAPDisplayName_by_attid", (PyCFunction)py_dsdb_get_lDAPDisplayName_by_attid,
1590 : METH_VARARGS, NULL },
1591 : { "_dsdb_get_backlink_from_lDAPDisplayName", (PyCFunction)py_dsdb_get_backlink_from_lDAPDisplayName,
1592 : METH_VARARGS, NULL },
1593 : { "_dsdb_set_ntds_invocation_id",
1594 : (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
1595 : NULL },
1596 : { "_samdb_ntds_objectGUID", (PyCFunction)py_samdb_ntds_objectGUID,
1597 : METH_VARARGS, "get the NTDS objectGUID as a string"},
1598 : { "_dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema,
1599 : METH_VARARGS, NULL },
1600 : { "_dsdb_load_partition_usn", (PyCFunction)py_dsdb_load_partition_usn,
1601 : METH_VARARGS,
1602 : "get uSNHighest and uSNUrgent from the partition @REPLCHANGED"},
1603 : { "_dsdb_set_am_rodc",
1604 : (PyCFunction)py_dsdb_set_am_rodc, METH_VARARGS,
1605 : NULL },
1606 : { "_am_rodc",
1607 : (PyCFunction)py_dsdb_am_rodc, METH_VARARGS,
1608 : NULL },
1609 : { "_am_pdc",
1610 : (PyCFunction)py_dsdb_am_pdc, METH_VARARGS,
1611 : NULL },
1612 : { "_dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS,
1613 : NULL },
1614 : { "_dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS,
1615 : NULL },
1616 : { "_dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction)py_dsdb_write_prefixes_from_schema_to_ldb, METH_VARARGS,
1617 : NULL },
1618 : { "_dsdb_get_partitions_dn", (PyCFunction)py_dsdb_get_partitions_dn, METH_VARARGS, NULL },
1619 : { "_dsdb_get_nc_root", (PyCFunction)py_dsdb_get_nc_root, METH_VARARGS, NULL },
1620 : { "_dsdb_get_wellknown_dn", (PyCFunction)py_dsdb_get_wellknown_dn, METH_VARARGS, NULL },
1621 : { "_dsdb_DsReplicaAttribute", (PyCFunction)py_dsdb_DsReplicaAttribute, METH_VARARGS, NULL },
1622 : { "_dsdb_normalise_attributes", (PyCFunction)py_dsdb_normalise_attributes, METH_VARARGS, NULL },
1623 : #ifdef AD_DC_BUILD_IS_ENABLED
1624 : { "_dsdb_garbage_collect_tombstones", (PyCFunction)py_dsdb_garbage_collect_tombstones, METH_VARARGS,
1625 : "_dsdb_kcc_check_deleted(samdb, [dn], current_time, tombstone_lifetime)"
1626 : " -> (num_objects_expunged, num_links_expunged)" },
1627 : { "_scavenge_dns_records", (PyCFunction)py_scavenge_dns_records,
1628 : METH_VARARGS, NULL},
1629 : { "_dns_delete_tombstones", (PyCFunction)py_dns_delete_tombstones,
1630 : METH_VARARGS, NULL},
1631 : #else
1632 : { "_dsdb_garbage_collect_tombstones", (PyCFunction)py_dsdb_not_implemented,
1633 : METH_VARARGS, NULL},
1634 : { "_scavenge_dns_records", (PyCFunction)py_dsdb_not_implemented,
1635 : METH_VARARGS, NULL},
1636 : { "_dns_delete_tombstones", (PyCFunction)py_dsdb_not_implemented,
1637 : METH_VARARGS, NULL},
1638 : #endif
1639 : { "_dsdb_create_gkdi_root_key",
1640 : (PyCFunction)py_dsdb_create_gkdi_root_key,
1641 : METH_VARARGS | METH_KEYWORDS,
1642 : PyDoc_STR("_dsdb_create_gkdi_root_key(samdb)"
1643 : " -> Dn of the new root key") },
1644 : { "_dsdb_create_own_rid_set", (PyCFunction)py_dsdb_create_own_rid_set, METH_VARARGS,
1645 : "_dsdb_create_own_rid_set(samdb)"
1646 : " -> None" },
1647 : { "_dsdb_allocate_rid", (PyCFunction)py_dsdb_allocate_rid, METH_VARARGS,
1648 : "_dsdb_allocate_rid(samdb)"
1649 : " -> RID" },
1650 : { "_dsdb_load_udv_v2", (PyCFunction)py_dsdb_load_udv_v2, METH_VARARGS, NULL },
1651 : { "user_account_control_flag_bit_to_string",
1652 : (PyCFunction)py_dsdb_user_account_control_flag_bit_to_string,
1653 : METH_VARARGS,
1654 : "user_account_control_flag_bit_to_string(bit)"
1655 : " -> string name" },
1656 : { "check_and_update_fl",
1657 : (PyCFunction)py_dsdb_check_and_update_fl,
1658 : METH_VARARGS,
1659 : "check_and_update_fl(ldb, lp) -> None\n"
1660 : "Hook to run in testing the code run on samba server startup "
1661 : "to validate and update DC functional levels"},
1662 : { "dc_operatingSystemVersion",
1663 : (PyCFunction)py_dsdb_dc_operatingSystemVersion,
1664 : METH_VARARGS,
1665 : "dsdb_dc_operatingSystemVersion(dc_level)"
1666 : " -> string name" },
1667 : {0}
1668 : };
1669 :
1670 : static struct PyModuleDef moduledef = {
1671 : PyModuleDef_HEAD_INIT,
1672 : .m_name = "dsdb",
1673 : .m_doc = "Python bindings for the directory service databases.",
1674 : .m_size = -1,
1675 : .m_methods = py_dsdb_methods,
1676 : };
1677 :
1678 7630 : MODULE_INIT_FUNC(dsdb)
1679 : {
1680 192 : PyObject *m;
1681 :
1682 7630 : m = PyModule_Create(&moduledef);
1683 :
1684 7630 : if (m == NULL)
1685 0 : return NULL;
1686 :
1687 : #define ADD_DSDB_FLAG(val) PyModule_AddObject(m, #val, PyLong_FromLong(val))
1688 :
1689 : /* "userAccountControl" flags */
1690 7630 : ADD_DSDB_FLAG(UF_NORMAL_ACCOUNT);
1691 7630 : ADD_DSDB_FLAG(UF_TEMP_DUPLICATE_ACCOUNT);
1692 7630 : ADD_DSDB_FLAG(UF_SERVER_TRUST_ACCOUNT);
1693 7630 : ADD_DSDB_FLAG(UF_WORKSTATION_TRUST_ACCOUNT);
1694 7630 : ADD_DSDB_FLAG(UF_INTERDOMAIN_TRUST_ACCOUNT);
1695 7630 : ADD_DSDB_FLAG(UF_PASSWD_NOTREQD);
1696 7630 : ADD_DSDB_FLAG(UF_ACCOUNTDISABLE);
1697 :
1698 7630 : ADD_DSDB_FLAG(UF_SCRIPT);
1699 7630 : ADD_DSDB_FLAG(UF_ACCOUNTDISABLE);
1700 7630 : ADD_DSDB_FLAG(UF_00000004);
1701 7630 : ADD_DSDB_FLAG(UF_HOMEDIR_REQUIRED);
1702 7630 : ADD_DSDB_FLAG(UF_LOCKOUT);
1703 7630 : ADD_DSDB_FLAG(UF_PASSWD_NOTREQD);
1704 7630 : ADD_DSDB_FLAG(UF_PASSWD_CANT_CHANGE);
1705 7630 : ADD_DSDB_FLAG(UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED);
1706 7630 : ADD_DSDB_FLAG(UF_TEMP_DUPLICATE_ACCOUNT);
1707 7630 : ADD_DSDB_FLAG(UF_NORMAL_ACCOUNT);
1708 7630 : ADD_DSDB_FLAG(UF_00000400);
1709 7630 : ADD_DSDB_FLAG(UF_INTERDOMAIN_TRUST_ACCOUNT);
1710 7630 : ADD_DSDB_FLAG(UF_WORKSTATION_TRUST_ACCOUNT);
1711 7630 : ADD_DSDB_FLAG(UF_SERVER_TRUST_ACCOUNT);
1712 7630 : ADD_DSDB_FLAG(UF_00004000);
1713 7630 : ADD_DSDB_FLAG(UF_00008000);
1714 7630 : ADD_DSDB_FLAG(UF_DONT_EXPIRE_PASSWD);
1715 7630 : ADD_DSDB_FLAG(UF_MNS_LOGON_ACCOUNT);
1716 7630 : ADD_DSDB_FLAG(UF_SMARTCARD_REQUIRED);
1717 7630 : ADD_DSDB_FLAG(UF_TRUSTED_FOR_DELEGATION);
1718 7630 : ADD_DSDB_FLAG(UF_NOT_DELEGATED);
1719 7630 : ADD_DSDB_FLAG(UF_USE_DES_KEY_ONLY);
1720 7630 : ADD_DSDB_FLAG(UF_DONT_REQUIRE_PREAUTH);
1721 7630 : ADD_DSDB_FLAG(UF_PASSWORD_EXPIRED);
1722 7630 : ADD_DSDB_FLAG(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION);
1723 7630 : ADD_DSDB_FLAG(UF_NO_AUTH_DATA_REQUIRED);
1724 7630 : ADD_DSDB_FLAG(UF_PARTIAL_SECRETS_ACCOUNT);
1725 7630 : ADD_DSDB_FLAG(UF_USE_AES_KEYS);
1726 :
1727 : /* groupType flags */
1728 7630 : ADD_DSDB_FLAG(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP);
1729 7630 : ADD_DSDB_FLAG(GTYPE_SECURITY_GLOBAL_GROUP);
1730 7630 : ADD_DSDB_FLAG(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1731 7630 : ADD_DSDB_FLAG(GTYPE_SECURITY_UNIVERSAL_GROUP);
1732 7630 : ADD_DSDB_FLAG(GTYPE_DISTRIBUTION_GLOBAL_GROUP);
1733 7630 : ADD_DSDB_FLAG(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP);
1734 7630 : ADD_DSDB_FLAG(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP);
1735 :
1736 : /* "sAMAccountType" flags */
1737 7630 : ADD_DSDB_FLAG(ATYPE_NORMAL_ACCOUNT);
1738 7630 : ADD_DSDB_FLAG(ATYPE_WORKSTATION_TRUST);
1739 7630 : ADD_DSDB_FLAG(ATYPE_INTERDOMAIN_TRUST);
1740 7630 : ADD_DSDB_FLAG(ATYPE_SECURITY_GLOBAL_GROUP);
1741 7630 : ADD_DSDB_FLAG(ATYPE_SECURITY_LOCAL_GROUP);
1742 7630 : ADD_DSDB_FLAG(ATYPE_SECURITY_UNIVERSAL_GROUP);
1743 7630 : ADD_DSDB_FLAG(ATYPE_DISTRIBUTION_GLOBAL_GROUP);
1744 7630 : ADD_DSDB_FLAG(ATYPE_DISTRIBUTION_LOCAL_GROUP);
1745 7630 : ADD_DSDB_FLAG(ATYPE_DISTRIBUTION_UNIVERSAL_GROUP);
1746 :
1747 : /* "domainFunctionality", "forestFunctionality" flags in the rootDSE */
1748 7630 : ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2000);
1749 7630 : ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2003_MIXED);
1750 7630 : ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2003);
1751 7630 : ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2008);
1752 7630 : ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2008_R2);
1753 7630 : ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2012);
1754 7630 : ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2012_R2);
1755 7630 : ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2016);
1756 :
1757 : /* nc replica flags */
1758 7630 : ADD_DSDB_FLAG(INSTANCE_TYPE_IS_NC_HEAD);
1759 7630 : ADD_DSDB_FLAG(INSTANCE_TYPE_UNINSTANT);
1760 7630 : ADD_DSDB_FLAG(INSTANCE_TYPE_WRITE);
1761 7630 : ADD_DSDB_FLAG(INSTANCE_TYPE_NC_ABOVE);
1762 7630 : ADD_DSDB_FLAG(INSTANCE_TYPE_NC_COMING);
1763 7630 : ADD_DSDB_FLAG(INSTANCE_TYPE_NC_GOING);
1764 :
1765 : /* "systemFlags" */
1766 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_CR_NTDS_NC);
1767 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_CR_NTDS_DOMAIN);
1768 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_CR_NTDS_NOT_GC_REPLICATED);
1769 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_SCHEMA_BASE_OBJECT);
1770 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_ATTR_IS_RDN);
1771 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE);
1772 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE);
1773 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME);
1774 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE);
1775 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_CONFIG_ALLOW_MOVE);
1776 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_CONFIG_ALLOW_RENAME);
1777 7630 : ADD_DSDB_FLAG(SYSTEM_FLAG_DISALLOW_DELETE);
1778 :
1779 : /* Kerberos encryption type constants */
1780 7630 : ADD_DSDB_FLAG(ENC_ALL_TYPES);
1781 7630 : ADD_DSDB_FLAG(ENC_CRC32);
1782 7630 : ADD_DSDB_FLAG(ENC_RSA_MD5);
1783 7630 : ADD_DSDB_FLAG(ENC_RC4_HMAC_MD5);
1784 7630 : ADD_DSDB_FLAG(ENC_HMAC_SHA1_96_AES128);
1785 7630 : ADD_DSDB_FLAG(ENC_HMAC_SHA1_96_AES256);
1786 7630 : ADD_DSDB_FLAG(ENC_HMAC_SHA1_96_AES256_SK);
1787 :
1788 7630 : ADD_DSDB_FLAG(SEARCH_FLAG_ATTINDEX);
1789 7630 : ADD_DSDB_FLAG(SEARCH_FLAG_PDNTATTINDEX);
1790 7630 : ADD_DSDB_FLAG(SEARCH_FLAG_ANR);
1791 7630 : ADD_DSDB_FLAG(SEARCH_FLAG_PRESERVEONDELETE);
1792 7630 : ADD_DSDB_FLAG(SEARCH_FLAG_COPY);
1793 7630 : ADD_DSDB_FLAG(SEARCH_FLAG_TUPLEINDEX);
1794 7630 : ADD_DSDB_FLAG(SEARCH_FLAG_SUBTREEATTRINDEX);
1795 7630 : ADD_DSDB_FLAG(SEARCH_FLAG_CONFIDENTIAL);
1796 7630 : ADD_DSDB_FLAG(SEARCH_FLAG_NEVERVALUEAUDIT);
1797 7630 : ADD_DSDB_FLAG(SEARCH_FLAG_RODC_ATTRIBUTE);
1798 :
1799 7630 : ADD_DSDB_FLAG(DS_FLAG_ATTR_NOT_REPLICATED);
1800 7630 : ADD_DSDB_FLAG(DS_FLAG_ATTR_REQ_PARTIAL_SET_MEMBER);
1801 7630 : ADD_DSDB_FLAG(DS_FLAG_ATTR_IS_CONSTRUCTED);
1802 :
1803 7630 : ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_AUTO_TOPOLOGY_DISABLED);
1804 7630 : ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_TOPL_CLEANUP_DISABLED);
1805 7630 : ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_TOPL_MIN_HOPS_DISABLED);
1806 7630 : ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_TOPL_DETECT_STALE_DISABLED);
1807 7630 : ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED);
1808 7630 : ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_GROUP_CACHING_ENABLED);
1809 7630 : ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_FORCE_KCC_WHISTLER_BEHAVIOR);
1810 7630 : ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_RAND_BH_SELECTION_DISABLED);
1811 7630 : ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_SCHEDULE_HASHING_ENABLED);
1812 7630 : ADD_DSDB_FLAG(DS_NTDSSETTINGS_OPT_IS_REDUNDANT_SERVER_TOPOLOGY_ENABLED);
1813 :
1814 7630 : ADD_DSDB_FLAG(DS_NTDSDSA_OPT_IS_GC);
1815 7630 : ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL);
1816 7630 : ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL);
1817 7630 : ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_NTDSCONN_XLATE);
1818 7630 : ADD_DSDB_FLAG(DS_NTDSDSA_OPT_DISABLE_SPN_REGISTRATION);
1819 :
1820 : /* dsHeuristics character indexes (see MS-ADTS 7.1.1.2.4.1.2) */
1821 7630 : ADD_DSDB_FLAG(DS_HR_SUPFIRSTLASTANR);
1822 7630 : ADD_DSDB_FLAG(DS_HR_SUPLASTFIRSTANR);
1823 7630 : ADD_DSDB_FLAG(DS_HR_DOLISTOBJECT);
1824 7630 : ADD_DSDB_FLAG(DS_HR_DONICKRES);
1825 7630 : ADD_DSDB_FLAG(DS_HR_LDAP_USEPERMMOD);
1826 7630 : ADD_DSDB_FLAG(DS_HR_HIDEDSID);
1827 7630 : ADD_DSDB_FLAG(DS_HR_BLOCK_ANONYMOUS_OPS);
1828 7630 : ADD_DSDB_FLAG(DS_HR_ALLOW_ANON_NSPI);
1829 7630 : ADD_DSDB_FLAG(DS_HR_USER_PASSWORD_SUPPORT);
1830 7630 : ADD_DSDB_FLAG(DS_HR_TENTH_CHAR);
1831 7630 : ADD_DSDB_FLAG(DS_HR_SPECIFY_GUID_ON_ADD);
1832 7630 : ADD_DSDB_FLAG(DS_HR_NO_STANDARD_SD);
1833 7630 : ADD_DSDB_FLAG(DS_HR_ALLOW_NONSECURE_PWD_OPS);
1834 7630 : ADD_DSDB_FLAG(DS_HR_NO_PROPAGATE_ON_NOCHANGE);
1835 7630 : ADD_DSDB_FLAG(DS_HR_COMPUTE_ANR_STATS);
1836 7630 : ADD_DSDB_FLAG(DS_HR_ADMINSDEXMASK);
1837 7630 : ADD_DSDB_FLAG(DS_HR_KVNOEMUW2K);
1838 :
1839 7630 : ADD_DSDB_FLAG(DS_HR_TWENTIETH_CHAR);
1840 7630 : ADD_DSDB_FLAG(DS_HR_ATTR_AUTHZ_ON_LDAP_ADD);
1841 7630 : ADD_DSDB_FLAG(DS_HR_BLOCK_OWNER_IMPLICIT_RIGHTS);
1842 7630 : ADD_DSDB_FLAG(DS_HR_THIRTIETH_CHAR);
1843 7630 : ADD_DSDB_FLAG(DS_HR_FOURTIETH_CHAR);
1844 7630 : ADD_DSDB_FLAG(DS_HR_FIFTIETH_CHAR);
1845 7630 : ADD_DSDB_FLAG(DS_HR_SIXTIETH_CHAR);
1846 7630 : ADD_DSDB_FLAG(DS_HR_SEVENTIETH_CHAR);
1847 7630 : ADD_DSDB_FLAG(DS_HR_EIGHTIETH_CHAR);
1848 7630 : ADD_DSDB_FLAG(DS_HR_NINETIETH_CHAR);
1849 :
1850 7630 : ADD_DSDB_FLAG(NTDSCONN_KCC_GC_TOPOLOGY);
1851 7630 : ADD_DSDB_FLAG(NTDSCONN_KCC_RING_TOPOLOGY);
1852 7630 : ADD_DSDB_FLAG(NTDSCONN_KCC_MINIMIZE_HOPS_TOPOLOGY);
1853 7630 : ADD_DSDB_FLAG(NTDSCONN_KCC_STALE_SERVERS_TOPOLOGY);
1854 7630 : ADD_DSDB_FLAG(NTDSCONN_KCC_OSCILLATING_CONNECTION_TOPOLOGY);
1855 7630 : ADD_DSDB_FLAG(NTDSCONN_KCC_INTERSITE_GC_TOPOLOGY);
1856 7630 : ADD_DSDB_FLAG(NTDSCONN_KCC_INTERSITE_TOPOLOGY);
1857 7630 : ADD_DSDB_FLAG(NTDSCONN_KCC_SERVER_FAILOVER_TOPOLOGY);
1858 7630 : ADD_DSDB_FLAG(NTDSCONN_KCC_SITE_FAILOVER_TOPOLOGY);
1859 7630 : ADD_DSDB_FLAG(NTDSCONN_KCC_REDUNDANT_SERVER_TOPOLOGY);
1860 :
1861 7630 : ADD_DSDB_FLAG(NTDSCONN_OPT_IS_GENERATED);
1862 7630 : ADD_DSDB_FLAG(NTDSCONN_OPT_TWOWAY_SYNC);
1863 7630 : ADD_DSDB_FLAG(NTDSCONN_OPT_OVERRIDE_NOTIFY_DEFAULT);
1864 7630 : ADD_DSDB_FLAG(NTDSCONN_OPT_USE_NOTIFY);
1865 7630 : ADD_DSDB_FLAG(NTDSCONN_OPT_DISABLE_INTERSITE_COMPRESSION);
1866 7630 : ADD_DSDB_FLAG(NTDSCONN_OPT_USER_OWNED_SCHEDULE);
1867 7630 : ADD_DSDB_FLAG(NTDSCONN_OPT_RODC_TOPOLOGY);
1868 :
1869 : /* Site Link Object options */
1870 7630 : ADD_DSDB_FLAG(NTDSSITELINK_OPT_USE_NOTIFY);
1871 7630 : ADD_DSDB_FLAG(NTDSSITELINK_OPT_TWOWAY_SYNC);
1872 7630 : ADD_DSDB_FLAG(NTDSSITELINK_OPT_DISABLE_COMPRESSION);
1873 :
1874 : /* GPO policy flags */
1875 7630 : ADD_DSDB_FLAG(GPLINK_OPT_DISABLE);
1876 7630 : ADD_DSDB_FLAG(GPLINK_OPT_ENFORCE);
1877 7630 : ADD_DSDB_FLAG(GPO_FLAG_USER_DISABLE);
1878 7630 : ADD_DSDB_FLAG(GPO_FLAG_MACHINE_DISABLE);
1879 7630 : ADD_DSDB_FLAG(GPO_INHERIT);
1880 7630 : ADD_DSDB_FLAG(GPO_BLOCK_INHERITANCE);
1881 :
1882 : #define ADD_DSDB_STRING(val) PyModule_AddObject(m, #val, PyUnicode_FromString(val))
1883 :
1884 7630 : ADD_DSDB_STRING(DSDB_SYNTAX_BINARY_DN);
1885 7630 : ADD_DSDB_STRING(DSDB_SYNTAX_STRING_DN);
1886 7630 : ADD_DSDB_STRING(DSDB_SYNTAX_OR_NAME);
1887 7630 : ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK);
1888 7630 : ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA);
1889 7630 : ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_FIX_DUPLICATE_LINKS);
1890 7630 : ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_FIX_LINK_DN_NAME);
1891 7630 : ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_FIX_LINK_DN_SID);
1892 7630 : ADD_DSDB_STRING(DSDB_CONTROL_REPLMD_VANISH_LINKS);
1893 7630 : ADD_DSDB_STRING(DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID);
1894 7630 : ADD_DSDB_STRING(DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID);
1895 7630 : ADD_DSDB_STRING(DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID);
1896 7630 : ADD_DSDB_STRING(DSDB_CONTROL_INVALID_NOT_IMPLEMENTED);
1897 :
1898 7630 : ADD_DSDB_STRING(DS_GUID_COMPUTERS_CONTAINER);
1899 7630 : ADD_DSDB_STRING(DS_GUID_DELETED_OBJECTS_CONTAINER);
1900 7630 : ADD_DSDB_STRING(DS_GUID_DOMAIN_CONTROLLERS_CONTAINER);
1901 7630 : ADD_DSDB_STRING(DS_GUID_FOREIGNSECURITYPRINCIPALS_CONTAINER);
1902 7630 : ADD_DSDB_STRING(DS_GUID_INFRASTRUCTURE_CONTAINER);
1903 7630 : ADD_DSDB_STRING(DS_GUID_LOSTANDFOUND_CONTAINER);
1904 7630 : ADD_DSDB_STRING(DS_GUID_MICROSOFT_PROGRAM_DATA_CONTAINER);
1905 7630 : ADD_DSDB_STRING(DS_GUID_NTDS_QUOTAS_CONTAINER);
1906 7630 : ADD_DSDB_STRING(DS_GUID_PROGRAM_DATA_CONTAINER);
1907 7630 : ADD_DSDB_STRING(DS_GUID_SYSTEMS_CONTAINER);
1908 7630 : ADD_DSDB_STRING(DS_GUID_USERS_CONTAINER);
1909 7630 : ADD_DSDB_STRING(DS_GUID_MANAGED_SERVICE_ACCOUNTS_CONTAINER);
1910 :
1911 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_ATTR_DEPARTMENT);
1912 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_ATTR_DNS_HOST_NAME);
1913 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_ATTR_INSTANCE_TYPE);
1914 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_ATTR_MS_SFU_30);
1915 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_ATTR_NT_SECURITY_DESCRIPTOR);
1916 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_ATTR_PRIMARY_GROUP_ID);
1917 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_ATTR_SERVICE_PRINCIPAL_NAME);
1918 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_ATTR_USER_ACCOUNT_CONTROL);
1919 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_ATTR_USER_PASSWORD);
1920 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_CLASS_COMPUTER);
1921 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_CLASS_MANAGED_SERVICE_ACCOUNT);
1922 7630 : ADD_DSDB_STRING(DS_GUID_SCHEMA_CLASS_USER);
1923 :
1924 7630 : ADD_DSDB_STRING(DSDB_FULL_JOIN_REPLICATION_COMPLETED_OPAQUE_NAME);
1925 :
1926 7630 : return m;
1927 : }
|