LCOV - code coverage report
Current view: top level - source4/dsdb - pydsdb.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 783 1067 73.4 %
Date: 2023-11-21 12:31:41 Functions: 39 40 97.5 %

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

Generated by: LCOV version 1.14