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