static bool torture_test_syntax(struct torture_context *torture, struct torture_dsdb_syntax *priv, const char *oid, const char *attr_string, const char *ldb_str, const char *drs_str) { TALLOC_CTX *tmp_ctx = talloc_new(torture); DATA_BLOB drs_binary = hexstr_to_data_blob(tmp_ctx, drs_str); DATA_BLOB ldb_blob = data_blob_string_const(ldb_str); struct drsuapi_DsReplicaAttribute drs, drs2; struct drsuapi_DsAttributeValue val; const struct dsdb_syntax *syntax; const struct dsdb_attribute *attr; struct ldb_message_element el; struct ldb_context *ldb = priv->ldb; struct dsdb_schema *schema = priv->schema; struct dsdb_syntax_ctx syntax_ctx; /* use default syntax conversion context */ dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema); drs.value_ctr.num_values = 1; drs.value_ctr.values = &val; val.blob = &drs_binary; torture_assert(torture, syntax = find_syntax_map_by_standard_oid(oid), "Failed to find syntax handler"); torture_assert(torture, attr = dsdb_attribute_by_lDAPDisplayName(schema, attr_string), "Failed to find attribute handler"); torture_assert_str_equal(torture, attr->syntax->name, syntax->name, "Syntax from schema not as expected"); torture_assert_werr_ok(torture, syntax->drsuapi_to_ldb(&syntax_ctx, attr, &drs, tmp_ctx, &el), "Failed to convert from DRS to ldb format"); torture_assert_data_blob_equal(torture, el.values[0], ldb_blob, "Incorrect conversion from DRS to ldb format"); torture_assert_werr_ok(torture, syntax->ldb_to_drsuapi(&syntax_ctx, attr, &el, tmp_ctx, &drs2), "Failed to convert from ldb to DRS format"); torture_assert(torture, drs2.value_ctr.values[0].blob, "No blob returned from conversion"); torture_assert_data_blob_equal(torture, *drs2.value_ctr.values[0].blob, drs_binary, "Incorrect conversion from ldb to DRS format"); return true; }
/* normalise a ldb attribute list */ static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args) { PyObject *py_ldb, *el_list, *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 drsuapi_DsReplicaAttribute *attr; TALLOC_CTX *tmp_ctx; WERROR werr; Py_ssize_t i; 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"); return NULL; } a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name); if (a == NULL) { PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name); return NULL; } dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema); syntax_ctx.is_schema_nc = false; tmp_ctx = talloc_new(ldb); if (tmp_ctx == NULL) { PyErr_NoMemory(); 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); 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); } /* Normalise "objectClass" attribute if needed */ if (ldb_attr_cmp(a->lDAPDisplayName, "objectClass") == 0) { int iret; iret = dsdb_sort_objectClass_attr(ldb, schema, el, tmp_ctx, el); if (iret != LDB_SUCCESS) { PyErr_SetString(PyExc_RuntimeError, ldb_errstring(ldb)); talloc_free(tmp_ctx); return NULL; } } /* first run ldb_to_drsuapi, then convert back again. This has * the effect of normalising the attributes */ attr = talloc_zero(tmp_ctx, struct drsuapi_DsReplicaAttribute); if (attr == NULL) { PyErr_NoMemory(); talloc_free(tmp_ctx); return NULL; } werr = a->syntax->ldb_to_drsuapi(&syntax_ctx, a, el, attr, attr); PyErr_WERROR_NOT_OK_RAISE(werr); /* now convert back again */ werr = a->syntax->drsuapi_to_ldb(&syntax_ctx, a, attr, el, el); PyErr_WERROR_NOT_OK_RAISE(werr); ret = py_return_ndr_struct("ldb", "MessageElement", el, el); talloc_free(tmp_ctx); return ret; }
/* convert a python string to a DRSUAPI drsuapi_DsReplicaAttribute attribute */ static PyObject *py_dsdb_DsReplicaAttribute(PyObject *self, PyObject *args) { PyObject *py_ldb, *el_list, *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 drsuapi_DsReplicaAttribute *attr; TALLOC_CTX *tmp_ctx; WERROR werr; Py_ssize_t i; 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"); return NULL; } a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name); if (a == NULL) { PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name); return NULL; } dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema); syntax_ctx.is_schema_nc = false; tmp_ctx = talloc_new(ldb); if (tmp_ctx == NULL) { PyErr_NoMemory(); 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); 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); } attr = talloc_zero(tmp_ctx, struct drsuapi_DsReplicaAttribute); if (attr == NULL) { PyErr_NoMemory(); talloc_free(tmp_ctx); return NULL; } werr = a->syntax->ldb_to_drsuapi(&syntax_ctx, a, el, attr, attr); PyErr_WERROR_NOT_OK_RAISE(werr); ret = py_return_ndr_struct("samba.dcerpc.drsuapi", "DsReplicaAttribute", attr, attr); talloc_free(tmp_ctx); return ret; }
/* normalise a ldb attribute list */ static PyObject *py_dsdb_normalise_attributes(PyObject *self, PyObject *args) { 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, *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); schema = dsdb_get_schema(ldb, NULL); if (!schema) { PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb"); return NULL; } a = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name); if (a == NULL) { PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name); return NULL; } dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema); syntax_ctx.is_schema_nc = false; tmp_ctx = talloc_new(ldb); if (tmp_ctx == NULL) { PyErr_NoMemory(); 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->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; } /* 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; } } /* first run ldb_to_drsuapi, then convert back again. This has * the effect of normalising the attributes */ attr = talloc_zero(tmp_ctx, struct drsuapi_DsReplicaAttribute); if (attr == NULL) { PyErr_NoMemory(); talloc_free(tmp_ctx); return NULL; } werr = a->syntax->ldb_to_drsuapi(&syntax_ctx, a, el, attr, attr); PyErr_WERROR_NOT_OK_RAISE(werr); /* now convert back again */ 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; } 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 py_ret; }