s4:dsdb/password_hash: leave the current value of pwdLastSet as 0 an add
[sharpe/samba-autobuild/.git] / source4 / dsdb / pydsdb.c
index 62b5c8db838f18c3bc29bcc335bcb545ec6bdeb9..f663b435e59b96fb51573868a9ac2d5d49f07029 100644 (file)
 
 void initdsdb(void);
 
-/* There's no Py_ssize_t in 2.4, apparently */
-#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
-typedef int Py_ssize_t;
-typedef inquiry lenfunc;
-typedef intargfunc ssizeargfunc;
-#endif
-
 /* FIXME: These should be in a header file somewhere */
 #define PyErr_LDB_OR_RAISE(py_ldb, ldb) \
-/*     if (!PyLdb_Check(py_ldb)) { \
+       if (!py_check_dcerpc_type(py_ldb, "ldb", "Ldb")) { \
                PyErr_SetString(py_ldb_get_exception(), "Ldb connection object required"); \
                return NULL; \
-       } */\
+       } \
        ldb = pyldb_Ldb_AsLdbContext(py_ldb);
 
+#define PyErr_LDB_DN_OR_RAISE(py_ldb_dn, dn) \
+       if (!py_check_dcerpc_type(py_ldb_dn, "ldb", "Dn")) { \
+               PyErr_SetString(py_ldb_get_exception(), "ldb Dn object required"); \
+               return NULL; \
+       } \
+       dn = pyldb_Dn_AsDn(py_ldb_dn);
+
 static PyObject *py_ldb_get_exception(void)
 {
        PyObject *mod = PyImport_ImportModule("ldb");
@@ -96,7 +96,7 @@ static PyObject *py_samdb_server_site_name(PyObject *self, PyObject *args)
 }
 
 static PyObject *py_dsdb_convert_schema_to_openldap(PyObject *self,
-                                                                                                       PyObject *args)
+                                                   PyObject *args)
 {
        char *target_str, *mapping;
        PyObject *py_ldb;
@@ -252,7 +252,7 @@ static PyObject *py_dsdb_get_oid_from_attid(PyObject *self, PyObject *args)
        WERROR status;
        TALLOC_CTX *mem_ctx;
 
-       if (!PyArg_ParseTuple(args, "Oi", &py_ldb, &attid))
+       if (!PyArg_ParseTuple(args, "OI", &py_ldb, &attid))
                return NULL;
 
        PyErr_LDB_OR_RAISE(py_ldb, ldb);
@@ -320,7 +320,7 @@ static PyObject *py_dsdb_get_attid_from_lDAPDisplayName(PyObject *self, PyObject
 
        a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
        if (a == NULL) {
-               PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name);
+               PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
                return NULL;
        }
 
@@ -354,7 +354,7 @@ static PyObject *py_dsdb_get_systemFlags_from_lDAPDisplayName(PyObject *self, Py
 
        attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
        if (attribute == NULL) {
-               PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name);
+               PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
                return NULL;
        }
 
@@ -386,7 +386,7 @@ static PyObject *py_dsdb_get_linkId_from_lDAPDisplayName(PyObject *self, PyObjec
 
        attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
        if (attribute == NULL) {
-               PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name);
+               PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
                return NULL;
        }
 
@@ -418,7 +418,7 @@ static PyObject *py_dsdb_get_backlink_from_lDAPDisplayName(PyObject *self, PyObj
 
        attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
        if (attribute == NULL) {
-               PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name);
+               PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
                return NULL;
        }
 
@@ -445,7 +445,7 @@ static PyObject *py_dsdb_get_lDAPDisplayName_by_attid(PyObject *self, PyObject *
        const struct dsdb_attribute *a;
        uint32_t attid;
 
-       if (!PyArg_ParseTuple(args, "Oi", &py_ldb, &attid))
+       if (!PyArg_ParseTuple(args, "OI", &py_ldb, &attid))
                return NULL;
 
        PyErr_LDB_OR_RAISE(py_ldb, ldb);
@@ -459,7 +459,7 @@ static PyObject *py_dsdb_get_lDAPDisplayName_by_attid(PyObject *self, PyObject *
 
        a = dsdb_attribute_by_attributeID_id(schema, attid);
        if (a == NULL) {
-               PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '0x%08x'", attid);
+               PyErr_Format(PyExc_KeyError, "Failed to find attribute '0x%08x'", attid);
                return NULL;
        }
 
@@ -492,7 +492,7 @@ static PyObject *py_dsdb_get_syntax_oid_from_lDAPDisplayName(PyObject *self, PyO
 
        attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
        if (attribute == NULL) {
-               PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name);
+               PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
                return NULL;
        }
 
@@ -522,11 +522,6 @@ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args)
 
        PyErr_LDB_OR_RAISE(py_ldb, ldb);
 
-       if (!PyList_Check(el_list)) {
-               PyErr_Format(PyExc_TypeError, "ldif_elements must be a list");
-               return NULL;
-       }
-
        schema = dsdb_get_schema(ldb, NULL);
        if (!schema) {
                PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
@@ -535,7 +530,7 @@ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args)
 
        a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
        if (a == NULL) {
-               PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name);
+               PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
                return NULL;
        }
 
@@ -548,31 +543,47 @@ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args)
                return NULL;
        }
 
-       el = talloc_zero(tmp_ctx, struct ldb_message_element);
-       if (el == NULL) {
-               PyErr_NoMemory();
-               talloc_free(tmp_ctx);
-               return NULL;
-       }
-
-       el->name = ldap_display_name;
-       el->num_values = PyList_Size(el_list);
+       /* If we were not given an LdbMessageElement */
+       if (!PyList_Check(el_list)) {
+               if (!py_check_dcerpc_type(el_list, "ldb", "MessageElement")) {
+                       PyErr_SetString(py_ldb_get_exception(),
+                                       "list of strings or ldb MessageElement object required");
+                       return NULL;
+               }
+               /*
+                * NOTE:
+                * el may not be a valid talloc context, it
+                * could be part of an array
+                */
+               el = pyldb_MessageElement_AsMessageElement(el_list);
+       } else {
+               el = talloc_zero(tmp_ctx, struct ldb_message_element);
+               if (el == NULL) {
+                       PyErr_NoMemory();
+                       talloc_free(tmp_ctx);
+                       return NULL;
+               }
 
-       el->values = talloc_array(el, struct ldb_val, el->num_values);
-       if (el->values == NULL) {
-               PyErr_NoMemory();
-               talloc_free(tmp_ctx);
-               return NULL;
-       }
+               el->name = ldap_display_name;
+               el->num_values = PyList_Size(el_list);
 
-       for (i = 0; i < el->num_values; i++) {
-               PyObject *item = PyList_GetItem(el_list, i);
-               if (!PyString_Check(item)) {
-                       PyErr_Format(PyExc_TypeError, "ldif_elements should be strings");
+               el->values = talloc_array(el, struct ldb_val, el->num_values);
+               if (el->values == NULL) {
+                       PyErr_NoMemory();
+                       talloc_free(tmp_ctx);
                        return NULL;
                }
-               el->values[i].data = (uint8_t *)PyString_AsString(item);
-               el->values[i].length = PyString_Size(item);
+
+               for (i = 0; i < el->num_values; i++) {
+                       PyObject *item = PyList_GetItem(el_list, i);
+                       if (!PyString_Check(item)) {
+                               PyErr_Format(PyExc_TypeError, "ldif_elements should be strings");
+                               talloc_free(tmp_ctx);
+                               return NULL;
+                       }
+                       el->values[i].data = (uint8_t *)PyString_AsString(item);
+                       el->values[i].length = PyString_Size(item);
+               }
        }
 
        attr = talloc_zero(tmp_ctx, struct drsuapi_DsReplicaAttribute);
@@ -583,7 +594,7 @@ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args)
        }
 
        werr = a->syntax->ldb_to_drsuapi(&syntax_ctx, a, el, attr, attr);
-       PyErr_WERROR_IS_ERR_RAISE(werr);
+       PyErr_WERROR_NOT_OK_RAISE(werr);
 
        ret = py_return_ndr_struct("samba.dcerpc.drsuapi", "DsReplicaAttribute", attr, attr);
 
@@ -598,17 +609,20 @@ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args)
  */
 static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args)
 {
-       PyObject *py_ldb, *el_list, *ret;
+       PyObject *py_ldb, *el_list, *py_ret;
        struct ldb_context *ldb;
        char *ldap_display_name;
        const struct dsdb_attribute *a;
        struct dsdb_schema *schema;
        struct dsdb_syntax_ctx syntax_ctx;
-       struct ldb_message_element *el;
+       struct ldb_message_element *el, *new_el;
        struct drsuapi_DsReplicaAttribute *attr;
+       PyLdbMessageElementObject *ret;
        TALLOC_CTX *tmp_ctx;
        WERROR werr;
        Py_ssize_t i;
+       PyTypeObject *py_type = NULL;
+       PyObject *module = NULL;
 
        if (!PyArg_ParseTuple(args, "OsO", &py_ldb, &ldap_display_name, &el_list)) {
                return NULL;
@@ -616,11 +630,6 @@ static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args)
 
        PyErr_LDB_OR_RAISE(py_ldb, ldb);
 
-       if (!PyList_Check(el_list)) {
-               PyErr_Format(PyExc_TypeError, "ldif_elements must be a list");
-               return NULL;
-       }
-
        schema = dsdb_get_schema(ldb, NULL);
        if (!schema) {
                PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb");
@@ -629,7 +638,7 @@ static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args)
 
        a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
        if (a == NULL) {
-               PyErr_Format(PyExc_RuntimeError, "Failed to find attribute '%s'", ldap_display_name);
+               PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
                return NULL;
        }
 
@@ -642,31 +651,64 @@ static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args)
                return NULL;
        }
 
-       el = talloc_zero(tmp_ctx, struct ldb_message_element);
-       if (el == NULL) {
-               PyErr_NoMemory();
-               talloc_free(tmp_ctx);
-               return NULL;
-       }
+       if (!PyList_Check(el_list)) {
+               if (!py_check_dcerpc_type(el_list, "ldb", "MessageElement")) {
+                       PyErr_SetString(py_ldb_get_exception(),
+                                       "list of strings or ldb MessageElement object required");
+                       return NULL;
+               }
+               /*
+                * NOTE:
+                * el may not be a valid talloc context, it
+                * could be part of an array
+                */
+               el = pyldb_MessageElement_AsMessageElement(el_list);
+       } else {
+               el = talloc_zero(tmp_ctx, struct ldb_message_element);
+               if (el == NULL) {
+                       PyErr_NoMemory();
+                       talloc_free(tmp_ctx);
+                       return NULL;
+               }
 
-       el->name = ldap_display_name;
-       el->num_values = PyList_Size(el_list);
+               el->name = ldap_display_name;
+               el->num_values = PyList_Size(el_list);
 
-       el->values = talloc_array(el, struct ldb_val, el->num_values);
-       if (el->values == NULL) {
+               el->values = talloc_array(el, struct ldb_val, el->num_values);
+               if (el->values == NULL) {
+                       PyErr_NoMemory();
+                       talloc_free(tmp_ctx);
+                       return NULL;
+               }
+
+               for (i = 0; i < el->num_values; i++) {
+                       PyObject *item = PyList_GetItem(el_list, i);
+                       if (!PyString_Check(item)) {
+                               PyErr_Format(PyExc_TypeError, "ldif_elements should be strings");
+                               talloc_free(tmp_ctx);
+                               return NULL;
+                       }
+                       el->values[i].data = (uint8_t *)PyString_AsString(item);
+                       el->values[i].length = PyString_Size(item);
+               }
+       }
+
+       new_el = talloc_zero(tmp_ctx, struct ldb_message_element);
+       if (new_el == NULL) {
                PyErr_NoMemory();
                talloc_free(tmp_ctx);
                return NULL;
        }
 
-       for (i = 0; i < el->num_values; i++) {
-               PyObject *item = PyList_GetItem(el_list, i);
-               if (!PyString_Check(item)) {
-                       PyErr_Format(PyExc_TypeError, "ldif_elements should be strings");
+       /* Normalise "objectClass" attribute if needed */
+       if (ldb_attr_cmp(a->lDAPDisplayName, "objectClass") == 0) {
+               int iret;
+               iret = dsdb_sort_objectClass_attr(ldb, schema, el, new_el, new_el);
+               if (iret != LDB_SUCCESS) {
+                       PyErr_SetString(PyExc_RuntimeError, ldb_errstring(ldb));
+                       talloc_free(tmp_ctx);
                        return NULL;
                }
-               el->values[i].data = (uint8_t *)PyString_AsString(item);
-               el->values[i].length = PyString_Size(item);
        }
 
        /* first run ldb_to_drsuapi, then convert back again. This has
@@ -681,17 +723,34 @@ static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args)
        }
 
        werr = a->syntax->ldb_to_drsuapi(&syntax_ctx, a, el, attr, attr);
-       PyErr_WERROR_IS_ERR_RAISE(werr);
+       PyErr_WERROR_NOT_OK_RAISE(werr);
 
        /* now convert back again */
-       werr = a->syntax->drsuapi_to_ldb(&syntax_ctx, a, attr, el, el);
-       PyErr_WERROR_IS_ERR_RAISE(werr);
+       werr = a->syntax->drsuapi_to_ldb(&syntax_ctx, a, attr, new_el, new_el);
+       PyErr_WERROR_NOT_OK_RAISE(werr);
+
+       module = PyImport_ImportModule("ldb");
+       if (module == NULL) {
+               return NULL;
+       }
 
-       ret = py_return_ndr_struct("ldb", "MessageElement", el, el);
+       py_type = (PyTypeObject *)PyObject_GetAttrString(module, "MessageElement");
+       if (py_type == NULL) {
+               return NULL;
+       }
+       py_ret = py_type->tp_alloc(py_type, 0);
+       ret = (PyLdbMessageElementObject *)py_ret;
+
+       ret->mem_ctx = talloc_new(NULL);
+       if (talloc_reference(ret->mem_ctx, new_el) == NULL) {
+               PyErr_NoMemory();
+               return NULL;
+       }
+       ret->el = new_el;
 
        talloc_free(tmp_ctx);
 
-       return ret;
+       return py_ret;
 }
 
 
@@ -707,6 +766,11 @@ static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
        PyErr_LDB_OR_RAISE(py_ldb, ldb);
        GUID_from_string(PyString_AsString(py_guid), &guid);
 
+       if (GUID_all_zero(&guid)) {
+               PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id rejected due to all-zero invocation ID");
+               return NULL;
+       }
+
        ret = samdb_set_ntds_invocation_id(ldb, &guid);
        if (!ret) {
                PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id failed");
@@ -838,8 +902,8 @@ static PyObject *py_dsdb_set_schema_from_ldif(PyObject *self, PyObject *args)
 
        PyErr_LDB_OR_RAISE(py_ldb, ldb);
 
-       result = dsdb_set_schema_from_ldif(ldb, pf, df);
-       PyErr_WERROR_IS_ERR_RAISE(result);
+       result = dsdb_set_schema_from_ldif(ldb, pf, df, dn);
+       PyErr_WERROR_NOT_OK_RAISE(result);
 
        Py_RETURN_NONE;
 }
@@ -852,7 +916,9 @@ static PyObject *py_dsdb_set_schema_from_ldb(PyObject *self, PyObject *args)
        struct ldb_context *from_ldb;
        struct dsdb_schema *schema;
        int ret;
-       if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_from_ldb))
+       char write_indices_and_attributes = true;
+       if (!PyArg_ParseTuple(args, "OO|b",
+                             &py_ldb, &py_from_ldb, &write_indices_and_attributes))
                return NULL;
 
        PyErr_LDB_OR_RAISE(py_ldb, ldb);
@@ -865,7 +931,7 @@ static PyObject *py_dsdb_set_schema_from_ldb(PyObject *self, PyObject *args)
                return NULL;
        }
 
-       ret = dsdb_reference_schema(ldb, schema, true);
+       ret = dsdb_reference_schema(ldb, schema, write_indices_and_attributes);
        PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
 
        Py_RETURN_NONE;
@@ -890,7 +956,7 @@ static PyObject *py_dsdb_write_prefixes_from_schema_to_ldb(PyObject *self, PyObj
        }
 
        result = dsdb_write_prefixes_from_schema_to_ldb(NULL, ldb, schema);
-       PyErr_WERROR_IS_ERR_RAISE(result);
+       PyErr_WERROR_NOT_OK_RAISE(result);
 
        Py_RETURN_NONE;
 }
@@ -901,9 +967,6 @@ static PyObject *py_dsdb_get_partitions_dn(PyObject *self, PyObject *args)
        struct ldb_context *ldb;
        struct ldb_dn *dn;
        PyObject *py_ldb, *ret;
-       PyObject *mod;
-
-       mod = PyImport_ImportModule("ldb");
 
        if (!PyArg_ParseTuple(args, "O", &py_ldb))
                return NULL;
@@ -921,6 +984,55 @@ static PyObject *py_dsdb_get_partitions_dn(PyObject *self, PyObject *args)
 }
 
 
+static PyObject *py_dsdb_get_nc_root(PyObject *self, PyObject *args)
+{
+       struct ldb_context *ldb;
+       struct ldb_dn *dn, *nc_root;
+       PyObject *py_ldb, *py_ldb_dn, *py_nc_root;
+       int ret;
+
+       if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_ldb_dn))
+               return NULL;
+
+       PyErr_LDB_OR_RAISE(py_ldb, ldb);
+       PyErr_LDB_DN_OR_RAISE(py_ldb_dn, dn);
+
+       ret = dsdb_find_nc_root(ldb, ldb, dn, &nc_root);
+       PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
+
+       py_nc_root = pyldb_Dn_FromDn(nc_root);
+       talloc_unlink(ldb, nc_root);
+       return py_nc_root;
+}
+
+static PyObject *py_dsdb_get_wellknown_dn(PyObject *self, PyObject *args)
+{
+       struct ldb_context *ldb;
+       struct ldb_dn *nc_dn, *wk_dn;
+       char *wkguid;
+       PyObject *py_ldb, *py_nc_dn, *py_wk_dn;
+       int ret;
+
+       if (!PyArg_ParseTuple(args, "OOs", &py_ldb, &py_nc_dn, &wkguid))
+               return NULL;
+
+       PyErr_LDB_OR_RAISE(py_ldb, ldb);
+       PyErr_LDB_DN_OR_RAISE(py_nc_dn, nc_dn);
+
+       ret = dsdb_wellknown_dn(ldb, ldb, nc_dn, wkguid, &wk_dn);
+       if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+               PyErr_Format(PyExc_KeyError, "Failed to find well known DN for GUID %s", wkguid);
+               return NULL;
+       }
+
+       PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
+
+       py_wk_dn = pyldb_Dn_FromDn(wk_dn);
+       talloc_unlink(ldb, wk_dn);
+       return py_wk_dn;
+}
+
+
 /*
   call into samdb_rodc()
  */
@@ -945,6 +1057,24 @@ static PyObject *py_dsdb_am_rodc(PyObject *self, PyObject *args)
        return PyBool_FromLong(am_rodc);
 }
 
+/*
+  call into samdb_is_pdc()
+ */
+static PyObject *py_dsdb_am_pdc(PyObject *self, PyObject *args)
+{
+       PyObject *py_ldb;
+       struct ldb_context *ldb;
+       bool am_pdc;
+
+       if (!PyArg_ParseTuple(args, "O", &py_ldb))
+               return NULL;
+
+       PyErr_LDB_OR_RAISE(py_ldb, ldb);
+
+       am_pdc = samdb_is_pdc(ldb);
+       return PyBool_FromLong(am_pdc);
+}
+
 
 static PyMethodDef py_dsdb_methods[] = {
        { "_samdb_server_site_name", (PyCFunction)py_samdb_server_site_name,
@@ -997,6 +1127,9 @@ static PyMethodDef py_dsdb_methods[] = {
        { "_am_rodc",
                (PyCFunction)py_dsdb_am_rodc, METH_VARARGS,
                NULL },
+       { "_am_pdc",
+               (PyCFunction)py_dsdb_am_pdc, METH_VARARGS,
+               NULL },
        { "_dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS,
                NULL },
        { "_dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS,
@@ -1004,6 +1137,8 @@ static PyMethodDef py_dsdb_methods[] = {
        { "_dsdb_write_prefixes_from_schema_to_ldb", (PyCFunction)py_dsdb_write_prefixes_from_schema_to_ldb, METH_VARARGS,
                NULL },
        { "_dsdb_get_partitions_dn", (PyCFunction)py_dsdb_get_partitions_dn, METH_VARARGS, NULL },
+       { "_dsdb_get_nc_root", (PyCFunction)py_dsdb_get_nc_root, METH_VARARGS, NULL },
+       { "_dsdb_get_wellknown_dn", (PyCFunction)py_dsdb_get_wellknown_dn, METH_VARARGS, NULL },
        { "_dsdb_DsReplicaAttribute", (PyCFunction)py_dsdb_DsReplicaAttribute, METH_VARARGS, NULL },
        { "_dsdb_normalise_attributes", (PyCFunction)py_dsdb_normalise_attributes, METH_VARARGS, NULL },
        { NULL }
@@ -1056,6 +1191,7 @@ void initdsdb(void)
        ADD_DSDB_FLAG(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION);
        ADD_DSDB_FLAG(UF_NO_AUTH_DATA_REQUIRED);
        ADD_DSDB_FLAG(UF_PARTIAL_SECRETS_ACCOUNT);
+       ADD_DSDB_FLAG(UF_USE_AES_KEYS);
 
        /* groupType flags */
        ADD_DSDB_FLAG(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP);
@@ -1083,6 +1219,8 @@ void initdsdb(void)
        ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2003);
        ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2008);
        ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2008_R2);
+       ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2012);
+       ADD_DSDB_FLAG(DS_DOMAIN_FUNCTION_2012_R2);
 
         /* nc replica flags */
        ADD_DSDB_FLAG(INSTANCE_TYPE_IS_NC_HEAD);
@@ -1165,6 +1303,11 @@ void initdsdb(void)
         ADD_DSDB_FLAG(NTDSCONN_OPT_USER_OWNED_SCHEDULE);
         ADD_DSDB_FLAG(NTDSCONN_OPT_RODC_TOPOLOGY);
 
+        /* Site Link Object options */
+        ADD_DSDB_FLAG(NTDSSITELINK_OPT_USE_NOTIFY);
+        ADD_DSDB_FLAG(NTDSSITELINK_OPT_TWOWAY_SYNC);
+        ADD_DSDB_FLAG(NTDSSITELINK_OPT_DISABLE_COMPRESSION);
+
        /* GPO policy flags */
        ADD_DSDB_FLAG(GPLINK_OPT_DISABLE);
        ADD_DSDB_FLAG(GPLINK_OPT_ENFORCE);
@@ -1179,4 +1322,18 @@ void initdsdb(void)
        ADD_DSDB_STRING(DSDB_SYNTAX_STRING_DN);
        ADD_DSDB_STRING(DSDB_SYNTAX_OR_NAME);
        ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK);
+       ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA);
+       ADD_DSDB_STRING(DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID);
+
+       ADD_DSDB_STRING(DS_GUID_COMPUTERS_CONTAINER);
+       ADD_DSDB_STRING(DS_GUID_DELETED_OBJECTS_CONTAINER);
+       ADD_DSDB_STRING(DS_GUID_DOMAIN_CONTROLLERS_CONTAINER);
+       ADD_DSDB_STRING(DS_GUID_FOREIGNSECURITYPRINCIPALS_CONTAINER);
+       ADD_DSDB_STRING(DS_GUID_INFRASTRUCTURE_CONTAINER);
+       ADD_DSDB_STRING(DS_GUID_LOSTANDFOUND_CONTAINER);
+       ADD_DSDB_STRING(DS_GUID_MICROSOFT_PROGRAM_DATA_CONTAINER);
+       ADD_DSDB_STRING(DS_GUID_NTDS_QUOTAS_CONTAINER);
+       ADD_DSDB_STRING(DS_GUID_PROGRAM_DATA_CONTAINER);
+       ADD_DSDB_STRING(DS_GUID_SYSTEMS_CONTAINER);
+       ADD_DSDB_STRING(DS_GUID_USERS_CONTAINER);
 }