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