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");
}
static PyObject *py_dsdb_convert_schema_to_openldap(PyObject *self,
- PyObject *args)
+ PyObject *args)
{
char *target_str, *mapping;
PyObject *py_ldb;
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);
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;
}
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;
}
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;
}
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;
}
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);
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;
}
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;
}
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");
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;
}
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);
}
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);
*/
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;
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");
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;
}
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
}
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;
}
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");
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;
}
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);
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;
}
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;
}
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;
}
+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()
*/
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,
{ "_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,
{ "_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 }
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);
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);
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);
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);
}