Esempio n. 1
0
/*
  return the attribute syntax oid as a string from the attribute name
 */
static PyObject *py_dsdb_get_syntax_oid_from_lDAPDisplayName(PyObject *self, PyObject *args)
{
	PyObject *py_ldb;
	struct ldb_context *ldb;
	struct dsdb_schema *schema;
	const char *ldap_display_name;
	const struct dsdb_attribute *attribute;

	if (!PyArg_ParseTuple(args, "Os", &py_ldb, &ldap_display_name))
		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;
	}

	attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
	if (attribute == NULL) {
		PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
		return NULL;
	}

	return PyString_FromString(attribute->syntax->ldap_oid);
}
Esempio n. 2
0
static int validate_update_modify(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_context *ldb;
	struct dsdb_schema *schema;
	int ret;

	ldb = ldb_module_get_ctx(module);
	schema = dsdb_get_schema(ldb);

	if (!schema) {
		return ldb_next_request(module, req);
	}

	/* do not manipulate our control entries */
	if (ldb_dn_is_special(req->op.mod.message->dn)) {
		return ldb_next_request(module, req);
	}

	ret = validate_update_message(ldb, schema,
				      req->op.mod.message);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	return ldb_next_request(module, req);
}
Esempio n. 3
0
static PyObject *py_dsdb_set_schema_from_ldb(PyObject *self, PyObject *args)
{
	PyObject *py_ldb;
	struct ldb_context *ldb;
	PyObject *py_from_ldb;
	struct ldb_context *from_ldb;
	struct dsdb_schema *schema;
	int ret;
	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);

	PyErr_LDB_OR_RAISE(py_from_ldb, from_ldb);

	schema = dsdb_get_schema(from_ldb, NULL);
	if (!schema) {
		PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on 'from' ldb!\n");
		return NULL;
	}

	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;
}
Esempio n. 4
0
static PyObject *py_dsdb_get_lDAPDisplayName_by_attid(PyObject *self, PyObject *args)
{
	PyObject *py_ldb;
	struct ldb_context *ldb;
	struct dsdb_schema *schema;
	const struct dsdb_attribute *a;
	uint32_t attid;

	if (!PyArg_ParseTuple(args, "Oi", &py_ldb, &attid))
		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_attributeID_id(schema, attid);
	if (a == NULL) {
		PyErr_Format(PyExc_KeyError, "Failed to find attribute '0x%08x'", attid);
		return NULL;
	}

	return PyString_FromString(a->lDAPDisplayName);
}
Esempio n. 5
0
static int construct_modifyTimeStamp(struct ldb_module *module,
					struct ldb_message *msg, enum ldb_scope scope,
					struct ldb_request *parent)
{
	struct operational_data *data = talloc_get_type(ldb_module_get_private(module), struct operational_data);
	struct ldb_context *ldb = ldb_module_get_ctx(module);

	/* We may be being called before the init function has finished */
	if (!data) {
		return LDB_SUCCESS;
	}

	/* Try and set this value up, if possible.  Don't worry if it
	 * fails, we may not have the DB set up yet.
	 */
	if (!data->aggregate_dn) {
		data->aggregate_dn = samdb_aggregate_schema_dn(ldb, data);
	}

	if (data->aggregate_dn && ldb_dn_compare(data->aggregate_dn, msg->dn) == 0) {
		/*
		 * If we have the DN for the object with common name = Aggregate and
		 * the request is for this DN then let's do the following:
		 * 1) search the object which changedUSN correspond to the one of the loaded
		 * schema.
		 * 2) Get the whenChanged attribute
		 * 3) Generate the modifyTimestamp out of the whenChanged attribute
		 */
		const struct dsdb_schema *schema = dsdb_get_schema(ldb, NULL);
		char *value = ldb_timestring(msg, schema->ts_last_change);

		return ldb_msg_add_string(msg, "modifyTimeStamp", value);
	}
	return ldb_msg_copy_attr(msg, "whenChanged", "modifyTimeStamp");
}
Esempio n. 6
0
static int acl_childClasses(struct ldb_module *module,
			    struct ldb_message *sd_msg,
			    struct ldb_message *msg,
			    const char *attrName)
{
	struct ldb_message_element *oc_el;
	struct ldb_message_element *allowedClasses;
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	const struct dsdb_schema *schema = dsdb_get_schema(ldb);
	const struct dsdb_class *sclass;
	int i, j, ret;

	/* If we don't have a schema yet, we can't do anything... */
	if (schema == NULL) {
		return LDB_SUCCESS;
	}

	/* Must remove any existing attribute, or else confusion reins */
	ldb_msg_remove_attr(msg, attrName);
	ret = ldb_msg_add_empty(msg, attrName, 0, &allowedClasses);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	oc_el = ldb_msg_find_element(sd_msg, "objectClass");

	for (i=0; oc_el && i < oc_el->num_values; i++) {
		sclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &oc_el->values[i]);
		if (!sclass) {
			/* We don't know this class?  what is going on? */
			continue;
		}

		for (j=0; sclass->possibleInferiors && sclass->possibleInferiors[j]; j++) {
			ldb_msg_add_string(msg, attrName, sclass->possibleInferiors[j]);
		}
	}
	if (allowedClasses->num_values > 1) {
		qsort(allowedClasses->values,
		      allowedClasses->num_values,
		      sizeof(*allowedClasses->values),
		      (comparison_fn_t)data_blob_cmp);

		for (i=1 ; i < allowedClasses->num_values; i++) {
			struct ldb_val *val1 = &allowedClasses->values[i-1];
			struct ldb_val *val2 = &allowedClasses->values[i];
			if (data_blob_cmp(val1, val2) == 0) {
				memmove(val1, val2, (allowedClasses->num_values - i) * sizeof(struct ldb_val));
				allowedClasses->num_values--;
				i--;
			}
		}
	}

	return LDB_SUCCESS;
}
Esempio n. 7
0
static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_ctx,
					    const struct ldb_val *in, struct ldb_val *out)
{
	struct ldb_dn *dn1 = NULL;
	const struct dsdb_schema *schema = dsdb_get_schema(ldb, NULL);
	const struct dsdb_class *sclass;
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	if (!tmp_ctx) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	if (!schema) {
		talloc_free(tmp_ctx);
		*out = data_blob_talloc(mem_ctx, in->data, in->length);
		if (in->data && !out->data) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
		return LDB_SUCCESS;
	}
	dn1 = ldb_dn_from_ldb_val(tmp_ctx, ldb, in);
	if ( ! ldb_dn_validate(dn1)) {
		const char *lDAPDisplayName = talloc_strndup(tmp_ctx, (char *)in->data, in->length);
		sclass = dsdb_class_by_lDAPDisplayName(schema, lDAPDisplayName);
		if (sclass) {
			struct ldb_dn *dn = ldb_dn_new(tmp_ctx, ldb,
						       sclass->defaultObjectCategory);
			if (dn == NULL) {
				talloc_free(tmp_ctx);
				return LDB_ERR_OPERATIONS_ERROR;
			}

			*out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn));
			talloc_free(tmp_ctx);

			if (!out->data) {
				return LDB_ERR_OPERATIONS_ERROR;
			}
			return LDB_SUCCESS;
		} else {
			*out = data_blob_talloc(mem_ctx, in->data, in->length);
			talloc_free(tmp_ctx);

			if (in->data && !out->data) {
				return LDB_ERR_OPERATIONS_ERROR;
			}
			return LDB_SUCCESS;
		}
	}
	*out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn1));
	talloc_free(tmp_ctx);

	if (!out->data) {
		return LDB_ERR_OPERATIONS_ERROR;
	}
	return LDB_SUCCESS;
}
Esempio n. 8
0
static const struct GUID *get_oc_guid_from_message(struct ldb_module *module,
						   struct ldb_message *msg)
{
	struct ldb_message_element *oc_el;
	struct ldb_context *ldb = ldb_module_get_ctx(module);

	oc_el = ldb_msg_find_element(msg, "objectClass");
	if (!oc_el) {
		return NULL;
	}

	return class_schemaid_guid_by_lDAPDisplayName(dsdb_get_schema(ldb),
						      (char *)oc_el->values[oc_el->num_values-1].data);
}
Esempio n. 9
0
static int acl_check_access_on_class(struct ldb_module *module,
				     TALLOC_CTX *mem_ctx,
				     struct security_descriptor *sd,
				     struct dom_sid *rp_sid,
				     uint32_t access,
				     const char *class_name)
{
	int ret;
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	NTSTATUS status;
	uint32_t access_granted;
	struct object_tree *root = NULL;
	struct object_tree *new_node = NULL;
	struct GUID *guid;
	const struct dsdb_schema *schema = dsdb_get_schema(ldb);
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	struct security_token *token = acl_user_token(module);
	if (class_name) {
		guid = class_schemaid_guid_by_lDAPDisplayName(schema, class_name);
		if (!guid) {
			DEBUG(10, ("acl_search: cannot find class %s\n",
				   class_name));
			goto fail;
		}
		if (!insert_in_object_tree(tmp_ctx,
					   guid, access,
					   &root, &new_node)) {
			DEBUG(10, ("acl_search: cannot add to object tree guid\n"));
			goto fail;
		}
	}
	status = sec_access_check_ds(sd, token,
				     access,
				     &access_granted,
				     root,
				     rp_sid);
	if (!NT_STATUS_IS_OK(status)) {
		ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
	}
	else {
		ret = LDB_SUCCESS;
	}
	return ret;
fail:
	return LDB_ERR_OPERATIONS_ERROR;
}
Esempio n. 10
0
static int acl_add(struct ldb_module *module, struct ldb_request *req)
{
	int ret;
	struct ldb_dn *parent = ldb_dn_get_parent(req, req->op.add.message->dn);
	struct ldb_context *ldb;
	struct ldb_message_element *oc_el;
	const struct GUID *guid;
	struct object_tree *root = NULL;
	struct object_tree *new_node = NULL;

	if (what_is_user(module) == SECURITY_SYSTEM) {
		return ldb_next_request(module, req);
	}

	if (ldb_dn_is_special(req->op.add.message->dn)) {
		return ldb_next_request(module, req);
	}
	ldb = ldb_module_get_ctx(module);
	/* Creating an NC. There is probably something we should do here,
	 * but we will establish that later */
	if ((ldb_dn_compare(req->op.add.message->dn, (ldb_get_schema_basedn(ldb))) == 0) ||
	    (ldb_dn_compare(req->op.add.message->dn, (ldb_get_config_basedn(ldb))) == 0) ||
	    (ldb_dn_compare(req->op.add.message->dn, (ldb_get_root_basedn(ldb))) == 0)) {
		return ldb_next_request(module, req);
	}

	oc_el = ldb_msg_find_element(req->op.add.message, "objectClass");
	if (!oc_el || oc_el->num_values == 0) {
		DEBUG(10,("acl:operation error %s\n", ldb_dn_get_linearized(req->op.add.message->dn)));
		return ldb_module_done(req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
	}

	guid = class_schemaid_guid_by_lDAPDisplayName(dsdb_get_schema(ldb),
						      (char *)oc_el->values[oc_el->num_values-1].data);

	if (!insert_in_object_tree(req, guid, SEC_ADS_CREATE_CHILD, &root, &new_node)) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ret = check_access_on_dn(module, req, parent, SEC_ADS_CREATE_CHILD, root);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	return ldb_next_request(module, req);
}
Esempio n. 11
0
void dsdb_make_schema_global(struct ldb_context *ldb)
{
	struct dsdb_schema *schema = dsdb_get_schema(ldb);
	if (!schema) {
		return;
	}

	if (global_schema) {
		talloc_unlink(talloc_autofree_context(), global_schema);
	}

	/* we want the schema to be around permanently */
	talloc_reparent(talloc_parent(schema), talloc_autofree_context(), schema);

	global_schema = schema;

	dsdb_set_global_schema(ldb);
}
Esempio n. 12
0
static PyObject *py_dsdb_get_oid_from_attid(PyObject *self, PyObject *args)
{
	PyObject *py_ldb;
	struct ldb_context *ldb;
	uint32_t attid;
	struct dsdb_schema *schema;
	const char *oid;
	PyObject *ret;
	WERROR status;
	TALLOC_CTX *mem_ctx;

	if (!PyArg_ParseTuple(args, "Oi", &py_ldb, &attid))
		return NULL;

	PyErr_LDB_OR_RAISE(py_ldb, ldb);

	mem_ctx = talloc_new(NULL);
	if (!mem_ctx) {
		PyErr_NoMemory();
		return NULL;
	}

	schema = dsdb_get_schema(ldb, mem_ctx);
	if (!schema) {
		PyErr_SetString(PyExc_RuntimeError, "Failed to find a schema from ldb \n");
		talloc_free(mem_ctx);
		return NULL;
	}
	
	status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, attid,
	                                        mem_ctx, &oid);
	if (!W_ERROR_IS_OK(status)) {
		PyErr_SetWERROR(status);
		talloc_free(mem_ctx);
		return NULL;
	}

	ret = PyString_FromString(oid);

	talloc_free(mem_ctx);

	return ret;
}
Esempio n. 13
0
static PyObject *py_dsdb_get_attid_from_lDAPDisplayName(PyObject *self, PyObject *args)
{
	PyObject *py_ldb, *is_schema_nc;
	struct ldb_context *ldb;
	struct dsdb_schema *schema;
	const char *ldap_display_name;
	bool schema_nc = false;
	const struct dsdb_attribute *a;
	uint32_t attid;

	if (!PyArg_ParseTuple(args, "OsO", &py_ldb, &ldap_display_name, &is_schema_nc))
		return NULL;

	PyErr_LDB_OR_RAISE(py_ldb, ldb);

	if (is_schema_nc) {
		if (!PyBool_Check(is_schema_nc)) {
			PyErr_SetString(PyExc_TypeError, "Expected boolean is_schema_nc");
			return NULL;
		}
		if (is_schema_nc == Py_True) {
			schema_nc = true;
		}
	}

	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;
	}

	attid = dsdb_attribute_get_attid(a, schema_nc);

	return PyLong_FromUnsignedLong(attid);
}
Esempio n. 14
0
/*
 * DSDB-SYNTAX fixture setup/teardown handlers implementation
 */
static bool torture_dsdb_syntax_tcase_setup(struct torture_context *tctx, void **data)
{
	struct torture_dsdb_syntax *priv;

	priv = talloc_zero(tctx, struct torture_dsdb_syntax);
	torture_assert(tctx, priv, "No memory");

	priv->ldb = provision_get_schema(priv, tctx->lp_ctx, NULL, NULL);
	torture_assert(tctx, priv->ldb, "Failed to load schema from disk");

	priv->schema = dsdb_get_schema(priv->ldb, NULL);
	torture_assert(tctx, priv->schema, "Failed to fetch schema");

	/* add 'authOrig' attribute with OR-Name syntax to schema */
	if (!torture_syntax_add_OR_Name(tctx, priv->ldb, priv->schema)) {
		return false;
	}

	*data = priv;
	return true;
}
Esempio n. 15
0
/*
  return the backlink attribute name (if any) for an attribute
 */
static PyObject *py_dsdb_get_backlink_from_lDAPDisplayName(PyObject *self, PyObject *args)
{
	PyObject *py_ldb;
	struct ldb_context *ldb;
	struct dsdb_schema *schema;
	const char *ldap_display_name;
	const struct dsdb_attribute *attribute, *target_attr;

	if (!PyArg_ParseTuple(args, "Os", &py_ldb, &ldap_display_name))
		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;
	}

	attribute = dsdb_attribute_by_lDAPDisplayName(schema, ldap_display_name);
	if (attribute == NULL) {
		PyErr_Format(PyExc_KeyError, "Failed to find attribute '%s'", ldap_display_name);
		return NULL;
	}

	if (attribute->linkID == 0) {
		Py_RETURN_NONE;
	}

	target_attr = dsdb_attribute_by_linkID(schema, attribute->linkID ^ 1);
	if (target_attr == NULL) {
		/* when we add pseudo-backlinks we'll need to handle
		   them here */
		Py_RETURN_NONE;
	}

	return PyString_FromString(target_attr->lDAPDisplayName);
}
Esempio n. 16
0
static PyObject *py_dsdb_write_prefixes_from_schema_to_ldb(PyObject *self, PyObject *args)
{
	PyObject *py_ldb;
	struct ldb_context *ldb;
	WERROR result;
	struct dsdb_schema *schema;

	if (!PyArg_ParseTuple(args, "O", &py_ldb))
		return NULL;

	PyErr_LDB_OR_RAISE(py_ldb, ldb);

	schema = dsdb_get_schema(ldb, NULL);
	if (!schema) {
		PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on ldb!\n");
		return NULL;
	}

	result = dsdb_write_prefixes_from_schema_to_ldb(NULL, ldb, schema);
	PyErr_WERROR_NOT_OK_RAISE(result);

	Py_RETURN_NONE;
}
Esempio n. 17
0
bool torture_net_become_dc(struct torture_context *torture)
{
	bool ret = true;
	NTSTATUS status;
	struct libnet_BecomeDC b;
	struct libnet_UnbecomeDC u;
	struct libnet_vampire_cb_state *s;
	struct ldb_message *msg;
	int ldb_ret;
	uint32_t i;
	char *private_dir;
	const char *address;
	struct nbt_name name;
	const char *netbios_name;
	struct cli_credentials *machine_account;
	struct test_join *tj;
	struct loadparm_context *lp_ctx;
	struct ldb_context *ldb;
	struct libnet_context *ctx;
	struct dsdb_schema *schema;

	char *location = NULL;
	torture_assert_ntstatus_ok(torture, torture_temp_dir(torture, "libnet_BecomeDC", &location), 
				   "torture_temp_dir should return NT_STATUS_OK" );

	netbios_name = lpcfg_parm_string(torture->lp_ctx, NULL, "become dc", "smbtorture dc");
	if (!netbios_name || !netbios_name[0]) {
		netbios_name = "smbtorturedc";
	}

	make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL));

	/* do an initial name resolution to find its IP */
	status = resolve_name_ex(lpcfg_resolve_context(torture->lp_ctx),
				 0, 0,
				 &name, torture, &address, torture->ev);
	torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
				   "Failed to resolve %s - %s\n",
				   name.name, nt_errstr(status)));


	/* Join domain as a member server. */
	tj = torture_join_domain(torture, netbios_name,
				 ACB_WSTRUST,
				 &machine_account);
	torture_assert(torture, tj, talloc_asprintf(torture,
						    "%s failed to join domain as workstation\n",
						    netbios_name));

	s = libnet_vampire_cb_state_init(torture, torture->lp_ctx, torture->ev,
			       netbios_name,
			       torture_join_dom_netbios_name(tj),
			       torture_join_dom_dns_name(tj),
			       location);
	torture_assert(torture, s, "libnet_vampire_cb_state_init");

	ctx = libnet_context_init(torture->ev, torture->lp_ctx);
	ctx->cred = cmdline_credentials;

	ZERO_STRUCT(b);
	b.in.domain_dns_name		= torture_join_dom_dns_name(tj);
	b.in.domain_netbios_name	= torture_join_dom_netbios_name(tj);
	b.in.domain_sid			= torture_join_sid(tj);
	b.in.source_dsa_address		= address;
	b.in.dest_dsa_netbios_name	= netbios_name;

	b.in.callbacks.private_data	= s;
	b.in.callbacks.check_options	= libnet_vampire_cb_check_options;
	b.in.callbacks.prepare_db       = libnet_vampire_cb_prepare_db;
	b.in.callbacks.schema_chunk	= libnet_vampire_cb_schema_chunk;
	b.in.callbacks.config_chunk	= libnet_vampire_cb_store_chunk;
	b.in.callbacks.domain_chunk	= libnet_vampire_cb_store_chunk;

	status = libnet_BecomeDC(ctx, s, &b);
	torture_assert_ntstatus_ok_goto(torture, status, ret, cleanup, talloc_asprintf(torture,
				   "libnet_BecomeDC() failed - %s %s\n",
				   nt_errstr(status), b.out.error_string));
	ldb = libnet_vampire_cb_ldb(s);

	msg = ldb_msg_new(s);
	torture_assert_int_equal_goto(torture, (msg?1:0), 1, ret, cleanup,
				      "ldb_msg_new() failed\n");
	msg->dn = ldb_dn_new(msg, ldb, "@ROOTDSE");
	torture_assert_int_equal_goto(torture, (msg->dn?1:0), 1, ret, cleanup,
				      "ldb_msg_new(@ROOTDSE) failed\n");

	ldb_ret = ldb_msg_add_string(msg, "isSynchronized", "TRUE");
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_msg_add_string(msg, isSynchronized, TRUE) failed\n");

	for (i=0; i < msg->num_elements; i++) {
		msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
	}

	torture_comment(torture, "mark ROOTDSE with isSynchronized=TRUE\n");
	ldb_ret = ldb_modify(libnet_vampire_cb_ldb(s), msg);
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_modify() failed\n");
	
	/* commit the transaction now we know the secrets were written
	 * out properly
	*/
	ldb_ret = ldb_transaction_commit(ldb);
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_transaction_commit() failed\n");

	/* reopen the ldb */
	talloc_unlink(s, ldb);

	lp_ctx = libnet_vampire_cb_lp_ctx(s);
	private_dir = talloc_asprintf(s, "%s/%s", location, "private");
	lpcfg_set_cmdline(lp_ctx, "private dir", private_dir);
	torture_comment(torture, "Reopen the SAM LDB with system credentials and all replicated data: %s\n", private_dir);
	ldb = samdb_connect(s, torture->ev, lp_ctx, system_session(lp_ctx), 0);
	torture_assert_goto(torture, ldb != NULL, ret, cleanup,
				      talloc_asprintf(torture,
				      "Failed to open '%s/sam.ldb'\n", private_dir));

	torture_assert_goto(torture, dsdb_uses_global_schema(ldb), ret, cleanup,
						"Uses global schema");

	schema = dsdb_get_schema(ldb, s);
	torture_assert_goto(torture, schema != NULL, ret, cleanup,
				      "Failed to get loaded dsdb_schema\n");

	/* Make sure we get this from the command line */
	if (lpcfg_parm_bool(torture->lp_ctx, NULL, "become dc", "do not unjoin", false)) {
		talloc_free(s);
		return ret;
	}

cleanup:
	ZERO_STRUCT(u);
	u.in.domain_dns_name		= torture_join_dom_dns_name(tj);
	u.in.domain_netbios_name	= torture_join_dom_netbios_name(tj);
	u.in.source_dsa_address		= address;
	u.in.dest_dsa_netbios_name	= netbios_name;

	status = libnet_UnbecomeDC(ctx, s, &u);
	torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
				   "libnet_UnbecomeDC() failed - %s %s\n",
				   nt_errstr(status), u.out.error_string));

	/* Leave domain. */
	torture_leave_domain(torture, tj);

	talloc_free(s);
	return ret;
}
Esempio n. 18
0
static int acl_childClassesEffective(struct ldb_module *module,
				     struct ldb_message *sd_msg,
				     struct ldb_message *msg,
				     struct acl_context *ac)
{
	struct ldb_message_element *oc_el;
	struct ldb_message_element *allowedClasses = NULL;
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	const struct dsdb_schema *schema = dsdb_get_schema(ldb);
	const struct dsdb_class *sclass;
	struct security_descriptor *sd;
	struct dom_sid *sid = NULL;
	int i, j, ret;

	if (ac->user_type == SECURITY_SYSTEM) {
		return acl_childClasses(module, sd_msg, msg, "allowedChildClassesEffective");
	}

	/* If we don't have a schema yet, we can't do anything... */
	if (schema == NULL) {
		return LDB_SUCCESS;
	}

	/* Must remove any existing attribute, or else confusion reins */
	ldb_msg_remove_attr(msg, "allowedChildClassesEffective");

	oc_el = ldb_msg_find_element(sd_msg, "objectClass");
	ret = get_sd_from_ldb_message(msg, sd_msg, &sd);
	if (ret != LDB_SUCCESS) {
		return ret;
	}
	ret = get_dom_sid_from_ldb_message(msg, sd_msg, &sid);

	if (ret != LDB_SUCCESS) {
		return ret;
	}
	for (i=0; oc_el && i < oc_el->num_values; i++) {
		sclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &oc_el->values[i]);
		if (!sclass) {
			/* We don't know this class?  what is going on? */
			continue;
		}

		for (j=0; sclass->possibleInferiors && sclass->possibleInferiors[j]; j++) {
			ret = acl_check_access_on_class(module,
							msg,
							sd,
							sid,
							SEC_ADS_CREATE_CHILD,
							sclass->possibleInferiors[j]);
			if (ret == LDB_SUCCESS) {
				ldb_msg_add_string(msg, "allowedChildClassesEffective",
						   sclass->possibleInferiors[j]);
			}
		}
	}
	allowedClasses = ldb_msg_find_element(msg, "allowedChildClassesEffective");
	if (!allowedClasses) {
		return LDB_SUCCESS;
	}

	if (allowedClasses->num_values > 1) {
		qsort(allowedClasses->values,
		      allowedClasses->num_values,
		      sizeof(*allowedClasses->values),
		      (comparison_fn_t)data_blob_cmp);
		for (i=1 ; i < allowedClasses->num_values; i++) {
			struct ldb_val *val1 = &allowedClasses->values[i-1];
			struct ldb_val *val2 = &allowedClasses->values[i];
			if (data_blob_cmp(val1, val2) == 0) {
				memmove(val1, val2, (allowedClasses->num_values - i) * sizeof( struct ldb_val));
				allowedClasses->num_values--;
				i--;
			}
		}
	}
	return LDB_SUCCESS;
}
Esempio n. 19
0
WERROR dsdb_origin_objects_commit(struct ldb_context *ldb,
				  TALLOC_CTX *mem_ctx,
				  const struct drsuapi_DsReplicaObjectListItem *first_object,
				  uint32_t *_num,
				  uint32_t dsdb_repl_flags,
				  struct drsuapi_DsReplicaObjectIdentifier2 **_ids)
{
	WERROR status;
	const struct dsdb_schema *schema;
	const struct drsuapi_DsReplicaObjectListItem *cur;
	struct ldb_message **objects;
	struct drsuapi_DsReplicaObjectIdentifier2 *ids;
	uint32_t i;
	uint32_t num_objects = 0;
	const char * const attrs[] = {
		"objectGUID",
		"objectSid",
		NULL
	};
	struct ldb_result *res;
	int ret;

	for (cur = first_object; cur; cur = cur->next_object) {
		num_objects++;
	}

	if (num_objects == 0) {
		return WERR_OK;
	}

	ret = ldb_transaction_start(ldb);
	if (ret != LDB_SUCCESS) {
		return WERR_DS_INTERNAL_FAILURE;
	}

	objects	= talloc_array(mem_ctx, struct ldb_message *,
			       num_objects);
	if (objects == NULL) {
		status = WERR_NOMEM;
		goto cancel;
	}

	schema = dsdb_get_schema(ldb, objects);
	if (!schema) {
		return WERR_DS_SCHEMA_NOT_LOADED;
	}

	for (i=0, cur = first_object; cur; cur = cur->next_object, i++) {
		status = dsdb_origin_object_convert(ldb, schema, cur,
						    objects, &objects[i]);
		if (!W_ERROR_IS_OK(status)) {
			goto cancel;
		}
	}

	ids = talloc_array(mem_ctx,
			   struct drsuapi_DsReplicaObjectIdentifier2,
			   num_objects);
	if (ids == NULL) {
		status = WERR_NOMEM;
		goto cancel;
	}

	if (dsdb_repl_flags & DSDB_REPL_FLAG_ADD_NCNAME) {
		/* check for possible NC creation */
		for (i=0; i < num_objects; i++) {
			struct ldb_message *msg = objects[i];
			struct ldb_message_element *el;
			struct ldb_dn *nc_dn;

			if (ldb_msg_check_string_attribute(msg, "objectClass", "crossRef") == 0) {
				continue;
			}
			el = ldb_msg_find_element(msg, "nCName");
			if (el == NULL || el->num_values != 1) {
				continue;
			}
			nc_dn = ldb_dn_from_ldb_val(objects, ldb, &el->values[0]);
			if (!ldb_dn_validate(nc_dn)) {
				continue;
			}
			ret = dsdb_create_partial_replica_NC(ldb, nc_dn);
			if (ret != LDB_SUCCESS) {
				status = WERR_DS_INTERNAL_FAILURE;
				goto cancel;
			}
		}
	}

	for (i=0; i < num_objects; i++) {
		struct dom_sid *sid = NULL;
		struct ldb_request *add_req;

		DEBUG(6,(__location__ ": adding %s\n", 
			 ldb_dn_get_linearized(objects[i]->dn)));

		ret = ldb_build_add_req(&add_req,
					ldb,
					objects,
					objects[i],
					NULL,
					NULL,
					ldb_op_default_callback,
					NULL);
		if (ret != LDB_SUCCESS) {
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}

		ret = ldb_request_add_control(add_req, LDB_CONTROL_RELAX_OID, true, NULL);
		if (ret != LDB_SUCCESS) {
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}
		
		ret = ldb_request(ldb, add_req);
		if (ret == LDB_SUCCESS) {
			ret = ldb_wait(add_req->handle, LDB_WAIT_ALL);
		}
		if (ret != LDB_SUCCESS) {
			DEBUG(0,(__location__ ": Failed add of %s - %s\n",
				 ldb_dn_get_linearized(objects[i]->dn), ldb_errstring(ldb)));
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}

		talloc_free(add_req);

		ret = ldb_search(ldb, objects, &res, objects[i]->dn,
				 LDB_SCOPE_BASE, attrs,
				 "(objectClass=*)");
		if (ret != LDB_SUCCESS) {
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}
		ids[i].guid = samdb_result_guid(res->msgs[0], "objectGUID");
		sid = samdb_result_dom_sid(objects, res->msgs[0], "objectSid");
		if (sid) {
			ids[i].sid = *sid;
		} else {
			ZERO_STRUCT(ids[i].sid);
		}
	}

	ret = ldb_transaction_commit(ldb);
	if (ret != LDB_SUCCESS) {
		return WERR_DS_INTERNAL_FAILURE;
	}

	talloc_free(objects);

	*_num = num_objects;
	*_ids = ids;
	return WERR_OK;

cancel:
	talloc_free(objects);
	ldb_transaction_cancel(ldb);
	return status;
}
Esempio n. 20
0
static int acl_allowedAttributes(struct ldb_module *module,
				 struct ldb_message *sd_msg,
				 struct ldb_message *msg,
				 struct acl_context *ac)
{
	struct ldb_message_element *oc_el;
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	const struct dsdb_schema *schema = dsdb_get_schema(ldb);
	TALLOC_CTX *mem_ctx;
	const char **attr_list;
	int i, ret;

	/* If we don't have a schema yet, we can't do anything... */
	if (schema == NULL) {
		return LDB_SUCCESS;
	}

	/* Must remove any existing attribute */
	if (ac->allowedAttributes) {
		ldb_msg_remove_attr(msg, "allowedAttributes");
	}

	mem_ctx = talloc_new(msg);
	if (!mem_ctx) {
		ldb_oom(ldb);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	oc_el = ldb_msg_find_element(sd_msg, "objectClass");
	attr_list = dsdb_full_attribute_list(mem_ctx, schema, oc_el, DSDB_SCHEMA_ALL);
	if (!attr_list) {
		ldb_asprintf_errstring(ldb, "acl: Failed to get list of attributes");
		talloc_free(mem_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}
	if (ac->allowedAttributes) {
		for (i=0; attr_list && attr_list[i]; i++) {
			ldb_msg_add_string(msg, "allowedAttributes", attr_list[i]);
		}
	}
	if (ac->allowedAttributesEffective) {
		struct security_descriptor *sd;
		struct dom_sid *sid = NULL;
		ldb_msg_remove_attr(msg, "allowedAttributesEffective");
		if (ac->user_type == SECURITY_SYSTEM) {
			for (i=0; attr_list && attr_list[i]; i++) {
				ldb_msg_add_string(msg, "allowedAttributesEffective", attr_list[i]);
			}
			return LDB_SUCCESS;
		}

		ret = get_sd_from_ldb_message(mem_ctx, sd_msg, &sd);

		if (ret != LDB_SUCCESS) {
			return ret;
		}
		ret = get_dom_sid_from_ldb_message(mem_ctx, sd_msg, &sid);

		if (ret != LDB_SUCCESS) {
			return ret;
		}
		for (i=0; attr_list && attr_list[i]; i++) {
			struct dsdb_attribute *attr = dsdb_attribute_by_lDAPDisplayName(schema,
											attr_list[i]);
			if (!attr) {
				return LDB_ERR_OPERATIONS_ERROR;
			}
			/* remove constructed attributes */
			if (attr->systemFlags & DS_FLAG_ATTR_IS_CONSTRUCTED
			    || attr->systemOnly
			    || (attr->linkID != 0 && attr->linkID % 2 != 0 )) {
				continue;
			}
			ret = acl_check_access_on_attribute(module,
							    msg,
							    sd,
							    sid,
							    SEC_ADS_WRITE_PROP,
							    attr);
			if (ret == LDB_SUCCESS) {
				ldb_msg_add_string(msg, "allowedAttributesEffective", attr_list[i]);
			}
		}
	}
	return LDB_SUCCESS;
}
Esempio n. 21
0
/**
 * Commits a list of replicated objects.
 *
 * @param working_schema dsdb_schema to be used for resolving
 * 			 Classes/Attributes during Schema replication. If not NULL,
 * 			 it will be set on ldb and used while committing replicated objects
 */
WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
				      struct dsdb_schema *working_schema,
				      struct dsdb_extended_replicated_objects *objects,
				      uint64_t *notify_uSN)
{
	WERROR werr;
	struct ldb_result *ext_res;
	struct dsdb_schema *cur_schema = NULL;
	struct dsdb_schema *new_schema = NULL;
	int ret;
	uint64_t seq_num1, seq_num2;
	bool used_global_schema = false;

	TALLOC_CTX *tmp_ctx = talloc_new(objects);
	if (!tmp_ctx) {
		DEBUG(0,("Failed to start talloc\n"));
		return WERR_NOMEM;
	}

	/* TODO: handle linked attributes */

	/* wrap the extended operation in a transaction 
	   See [MS-DRSR] 3.3.2 Transactions
	 */
	ret = ldb_transaction_start(ldb);
	if (ret != LDB_SUCCESS) {
		DEBUG(0,(__location__ " Failed to start transaction\n"));
		return WERR_FOOBAR;
	}

	ret = dsdb_load_partition_usn(ldb, objects->partition_dn, &seq_num1, NULL);
	if (ret != LDB_SUCCESS) {
		DEBUG(0,(__location__ " Failed to load partition uSN\n"));
		ldb_transaction_cancel(ldb);
		TALLOC_FREE(tmp_ctx);
		return WERR_FOOBAR;		
	}

	/*
	 * Set working_schema for ldb in case we are replicating from Schema NC.
	 * Schema won't be reloaded during Replicated Objects commit, as it is
	 * done in a transaction. So we need some way to search for newly
	 * added Classes and Attributes
	 */
	if (working_schema) {
		/* store current schema so we can fall back in case of failure */
		cur_schema = dsdb_get_schema(ldb, tmp_ctx);
		used_global_schema = dsdb_uses_global_schema(ldb);

		ret = dsdb_reference_schema(ldb, working_schema, false);
		if (ret != LDB_SUCCESS) {
			DEBUG(0,(__location__ "Failed to reference working schema - %s\n",
				 ldb_strerror(ret)));
			/* TODO: Map LDB Error to NTSTATUS? */
			ldb_transaction_cancel(ldb);
			TALLOC_FREE(tmp_ctx);
			return WERR_INTERNAL_ERROR;
		}
	}

	ret = ldb_extended(ldb, DSDB_EXTENDED_REPLICATED_OBJECTS_OID, objects, &ext_res);
	if (ret != LDB_SUCCESS) {
		/* restore previous schema */
		if (used_global_schema) { 
			dsdb_set_global_schema(ldb);
		} else if (cur_schema) {
			dsdb_reference_schema(ldb, cur_schema, false);
		}

		DEBUG(0,("Failed to apply records: %s: %s\n",
			 ldb_errstring(ldb), ldb_strerror(ret)));
		ldb_transaction_cancel(ldb);
		TALLOC_FREE(tmp_ctx);
		return WERR_FOOBAR;
	}
	talloc_free(ext_res);

	/* Save our updated prefixMap */
	if (working_schema) {
		werr = dsdb_write_prefixes_from_schema_to_ldb(working_schema,
							      ldb,
							      working_schema);
		if (!W_ERROR_IS_OK(werr)) {
			/* restore previous schema */
			if (used_global_schema) { 
				dsdb_set_global_schema(ldb);
			} else if (cur_schema ) {
				dsdb_reference_schema(ldb, cur_schema, false);
			}
			DEBUG(0,("Failed to save updated prefixMap: %s\n",
				 win_errstr(werr)));
			TALLOC_FREE(tmp_ctx);
			return werr;
		}
	}

	ret = ldb_transaction_prepare_commit(ldb);
	if (ret != LDB_SUCCESS) {
		/* restore previous schema */
		if (used_global_schema) { 
			dsdb_set_global_schema(ldb);
		} else if (cur_schema ) {
			dsdb_reference_schema(ldb, cur_schema, false);
		}
		DEBUG(0,(__location__ " Failed to prepare commit of transaction: %s\n",
			 ldb_errstring(ldb)));
		TALLOC_FREE(tmp_ctx);
		return WERR_FOOBAR;
	}

	ret = dsdb_load_partition_usn(ldb, objects->partition_dn, &seq_num2, NULL);
	if (ret != LDB_SUCCESS) {
		/* restore previous schema */
		if (used_global_schema) { 
			dsdb_set_global_schema(ldb);
		} else if (cur_schema ) {
			dsdb_reference_schema(ldb, cur_schema, false);
		}
		DEBUG(0,(__location__ " Failed to load partition uSN\n"));
		ldb_transaction_cancel(ldb);
		TALLOC_FREE(tmp_ctx);
		return WERR_FOOBAR;		
	}

	ret = ldb_transaction_commit(ldb);
	if (ret != LDB_SUCCESS) {
		/* restore previous schema */
		if (used_global_schema) { 
			dsdb_set_global_schema(ldb);
		} else if (cur_schema ) {
			dsdb_reference_schema(ldb, cur_schema, false);
		}
		DEBUG(0,(__location__ " Failed to commit transaction\n"));
		TALLOC_FREE(tmp_ctx);
		return WERR_FOOBAR;
	}

	/* if this replication partner didn't need to be notified
	   before this transaction then it still doesn't need to be
	   notified, as the changes came from this server */
	if (seq_num2 > seq_num1 && seq_num1 <= *notify_uSN) {
		*notify_uSN = seq_num2;
	}

	/*
	 * Reset the Schema used by ldb. This will lead to
	 * a schema cache being refreshed from database.
	 */
	if (working_schema) {
		struct ldb_message *msg;
		struct ldb_request *req;

		/* Force a reload */
		working_schema->last_refresh = 0;
		new_schema = dsdb_get_schema(ldb, tmp_ctx);
		/* TODO: 
		 * If dsdb_get_schema() fails, we just fall back
		 * to what we had.  However, the database is probably
		 * unable to operate for other users from this
		 * point... */
		if (new_schema && used_global_schema) {
			dsdb_make_schema_global(ldb, new_schema);
		} else if (used_global_schema) { 
			DEBUG(0,("Failed to re-load schema after commit of transaction\n"));
			dsdb_set_global_schema(ldb);
			TALLOC_FREE(tmp_ctx);
			return WERR_INTERNAL_ERROR;
		} else {
			DEBUG(0,("Failed to re-load schema after commit of transaction\n"));
			dsdb_reference_schema(ldb, cur_schema, false);
			TALLOC_FREE(tmp_ctx);
			return WERR_INTERNAL_ERROR;
		}
		msg = ldb_msg_new(tmp_ctx);
		if (msg == NULL) {
			TALLOC_FREE(tmp_ctx);
			return WERR_NOMEM;
		}
		msg->dn = ldb_dn_new(msg, ldb, "");
		if (msg->dn == NULL) {
			TALLOC_FREE(tmp_ctx);
			return WERR_NOMEM;
		}

		ret = ldb_msg_add_string(msg, "schemaUpdateNow", "1");
		if (ret != LDB_SUCCESS) {
			TALLOC_FREE(tmp_ctx);
			return WERR_INTERNAL_ERROR;
		}

		ret = ldb_build_mod_req(&req, ldb, objects,
				msg,
				NULL,
				NULL,
				ldb_op_default_callback,
				NULL);

		if (ret != LDB_SUCCESS) {
			TALLOC_FREE(tmp_ctx);
			return WERR_DS_DRA_INTERNAL_ERROR;
		}

		ret = ldb_transaction_start(ldb);
		if (ret != LDB_SUCCESS) {
			TALLOC_FREE(tmp_ctx);
			DEBUG(0, ("Autotransaction start failed\n"));
			return WERR_DS_DRA_INTERNAL_ERROR;
		}

		ret = ldb_request(ldb, req);
		if (ret == LDB_SUCCESS) {
			ret = ldb_wait(req->handle, LDB_WAIT_ALL);
		}

		if (ret == LDB_SUCCESS) {
			ret = ldb_transaction_commit(ldb);
		} else {
			DEBUG(0, ("Schema update now failed: %s\n",
				  ldb_errstring(ldb)));
			ldb_transaction_cancel(ldb);
		}

		if (ret != LDB_SUCCESS) {
			DEBUG(0, ("Commit failed: %s\n", ldb_errstring(ldb)));
			TALLOC_FREE(tmp_ctx);
			return WERR_DS_INTERNAL_FAILURE;
		}
	}

	DEBUG(2,("Replicated %u objects (%u linked attributes) for %s\n",
		 objects->num_objects, objects->linked_attributes_count,
		 ldb_dn_get_linearized(objects->partition_dn)));
		 
	TALLOC_FREE(tmp_ctx);
	return WERR_OK;
}
Esempio n. 22
0
File: pydsdb.c Progetto: GSam/samba
/*
  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;
}
Esempio n. 23
0
/**
 * Loads dsdb_schema from ldb connection using remote prefixMap.
 * Schema will be loaded only if:
 *  - ldb has no attached schema
 *  - reload_schema is true
 *
 * This function is to be used in tests that use GetNCChanges() function
 */
bool drs_util_dsdb_schema_load_ldb(struct torture_context *tctx,
				   struct ldb_context *ldb,
				   const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr,
				   bool reload_schema)
{
	int i, ret;
	WERROR werr;
	const char *err_msg;
	struct ldb_result *a_res;
	struct ldb_result *c_res;
	struct ldb_dn *schema_dn;
	struct dsdb_schema *ldap_schema;

	ldap_schema = dsdb_get_schema(ldb, NULL);
	if (ldap_schema && !reload_schema) {
		return true;
	}

	schema_dn = ldb_get_schema_basedn(ldb);
	torture_assert(tctx, schema_dn != NULL,
		       talloc_asprintf(tctx, "ldb_get_schema_basedn() failed: %s", ldb_errstring(ldb)));

	ldap_schema = dsdb_new_schema(ldb);
	torture_assert(tctx, ldap_schema != NULL, "dsdb_new_schema() failed!");

	werr = dsdb_load_prefixmap_from_drsuapi(ldap_schema, mapping_ctr);
	torture_assert_werr_ok(tctx, werr,
			       "Failed to construct prefixMap from drsuapi data");

	/*
	 * load the attribute definitions
	 */
	ret = ldb_search(ldb, ldap_schema, &a_res,
			 schema_dn, LDB_SCOPE_ONELEVEL, NULL,
			 "(objectClass=attributeSchema)");
	if (ret != LDB_SUCCESS) {
		err_msg = talloc_asprintf(tctx,
					  "failed to search attributeSchema objects: %s",
					  ldb_errstring(ldb));
		torture_fail(tctx, err_msg);
	}

	/*
	 * load the objectClass definitions
	 */
	ret = ldb_search(ldb, ldap_schema, &c_res,
			 schema_dn, LDB_SCOPE_ONELEVEL, NULL,
			 "(objectClass=classSchema)");
	if (ret != LDB_SUCCESS) {
		err_msg = talloc_asprintf(tctx,
					  "failed to search classSchema objects: %s",
					  ldb_errstring(ldb));
		torture_fail(tctx, err_msg);
	}

	/* Build schema */
	for (i=0; i < a_res->count; i++) {
		werr = dsdb_attribute_from_ldb(ldb, ldap_schema, a_res->msgs[i]);
		torture_assert_werr_ok(tctx, werr,
				       talloc_asprintf(tctx,
						       "dsdb_attribute_from_ldb() failed for: %s",
						       ldb_dn_get_linearized(a_res->msgs[i]->dn)));
	}

	for (i=0; i < c_res->count; i++) {
		werr = dsdb_class_from_ldb(ldap_schema, c_res->msgs[i]);
		torture_assert_werr_ok(tctx, werr,
				       talloc_asprintf(tctx,
						       "dsdb_class_from_ldb() failed for: %s",
						       ldb_dn_get_linearized(c_res->msgs[i]->dn)));
	}

	talloc_free(a_res);
	talloc_free(c_res);

	ret = dsdb_set_schema(ldb, ldap_schema);
	if (ret != LDB_SUCCESS) {
		torture_fail(tctx,
			     talloc_asprintf(tctx, "dsdb_set_schema() failed: %s", ldb_strerror(ret)));
	}

	return true;
}
Esempio n. 24
0
/*
  get metadata version 2 info for a specified object DN
*/
static WERROR kccdrs_replica_get_info_obj_metadata2(TALLOC_CTX *mem_ctx,
						    struct ldb_context *samdb,
						    struct drsuapi_DsReplicaGetInfo *r,
						    union drsuapi_DsReplicaInfo *reply,
						    struct ldb_dn *dn,
						    uint32_t base_index)
{
	WERROR status;
	struct replPropertyMetaDataBlob omd_ctr;
	struct replPropertyMetaData1 *attr;
	struct drsuapi_DsReplicaObjMetaData2Ctr *metadata2;
	const struct dsdb_schema *schema;

	uint32_t i, j;

	DEBUG(0, ("kccdrs_replica_get_info_obj_metadata2() called\n"));

	if (!dn) {
		return WERR_INVALID_PARAMETER;
	}

	if (!ldb_dn_validate(dn)) {
		return WERR_DS_DRA_BAD_DN;
	}

	status = get_repl_prop_metadata_ctr(mem_ctx, samdb, dn, &omd_ctr);
	W_ERROR_NOT_OK_RETURN(status);

	schema = dsdb_get_schema(samdb, reply);
	if (!schema) {
		DEBUG(0,(__location__": Failed to get the schema\n"));
		return WERR_INTERNAL_ERROR;
	}

	reply->objmetadata2 = talloc_zero(mem_ctx, struct drsuapi_DsReplicaObjMetaData2Ctr);
	W_ERROR_HAVE_NO_MEMORY(reply->objmetadata2);
	metadata2 = reply->objmetadata2;
	metadata2->enumeration_context = 0;

	/* For each replicated attribute of the object */
	for (i = 0, j = 0; i < omd_ctr.ctr.ctr1.count; i++) {
		const struct dsdb_attribute *schema_attr;
		uint32_t attr_version;
		NTTIME attr_change_time;
		uint32_t attr_originating_usn;

		/*
		  attr := attrsSeq[i]
		  s := AttrStamp(object, attr)
		*/
		/* get a reference to the attribute on 'omd_ctr' */
		attr = &omd_ctr.ctr.ctr1.array[j];

		schema_attr = dsdb_attribute_by_attributeID_id(schema, attr->attid);

		DEBUG(0, ("attribute_id = %d, attribute_name: %s\n", attr->attid, schema_attr->lDAPDisplayName));

		/*
		  if (attr in Link Attributes of object and
		    dwInVersion = 2 and DS_REPL_INFO_FLAG_IMPROVE_LINKED_ATTRS in msgIn.ulFlags)
		*/
		if (schema_attr &&
		    schema_attr->linkID != 0 && /* Checks if attribute is a linked attribute */
		    (schema_attr->linkID % 2) == 0 && /* is it a forward link? only forward links have the LinkValueStamp */
		    r->in.level == 2 &&
		    (r->in.req->req2.flags & DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE)) /* on MS-DRSR it is DS_REPL_INFO_FLAG_IMPROVE_LINKED_ATTRS */
		{
			/*
			  ls := LinkValueStamp of the most recent
				value change in object!attr
			*/
			status = get_linked_attribute_value_stamp(mem_ctx, samdb, dn, schema_attr->lDAPDisplayName,
								  &attr_version, &attr_change_time, &attr_originating_usn);
			W_ERROR_NOT_OK_RETURN(status);

			/*
			 Aligning to MS-DRSR 4.1.13.3:
			 's' on the doc is 'attr->originating_change_time' here
			 'ls' on the doc is 'attr_change_time' here
			*/

			/* if (ls is more recent than s (based on order in which the change was applied on server)) then */
			if (attr_change_time > attr->originating_change_time) {
				/*
				 Improve the stamp with the link value stamp.
				  s.dwVersion := ls.dwVersion
				  s.timeChanged := ls.timeChanged
				  s.uuidOriginating := NULLGUID
				  s.usnOriginating := ls.usnOriginating
				*/
				attr->version = attr_version;
				attr->originating_change_time = attr_change_time;
				attr->originating_invocation_id = GUID_zero();
				attr->originating_usn = attr_originating_usn;
			}
		}

		if (i < base_index) {
			continue;
		}

		metadata2->array = talloc_realloc(mem_ctx, metadata2->array,
						  struct drsuapi_DsReplicaObjMetaData2, j + 1);
		W_ERROR_HAVE_NO_MEMORY(metadata2->array);
		metadata2->array[j].attribute_name = schema_attr->lDAPDisplayName;
		metadata2->array[j].local_usn = attr->local_usn;
		metadata2->array[j].originating_change_time = attr->originating_change_time;
		metadata2->array[j].originating_invocation_id = attr->originating_invocation_id;
		metadata2->array[j].originating_usn = attr->originating_usn;
		metadata2->array[j].version = attr->version;

		/*
		  originating_dsa_dn := GetDNFromInvocationID(originating_invocation_id)
		  GetDNFromInvocationID() should return the DN of the nTDSDSAobject that has the specified invocation ID
		  See MS-DRSR 4.1.13.3 and 4.1.13.2.1
		*/
		status = get_dn_from_invocation_id(mem_ctx, samdb,
						   &attr->originating_invocation_id,
						   &metadata2->array[j].originating_dsa_dn);
		W_ERROR_NOT_OK_RETURN(status);
		j++;
		metadata2->count = j;

	}

	return WERR_OK;
}
Esempio n. 25
0
WERROR dsdb_extended_replicated_objects_convert(struct ldb_context *ldb,
						const char *partition_dn,
						const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr,
						uint32_t object_count,
						const struct drsuapi_DsReplicaObjectListItemEx *first_object,
						uint32_t linked_attributes_count,
						const struct drsuapi_DsReplicaLinkedAttribute *linked_attributes,
						const struct repsFromTo1 *source_dsa,
						const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector,
						const DATA_BLOB *gensec_skey,
						TALLOC_CTX *mem_ctx,
						struct dsdb_extended_replicated_objects **objects)
{
	WERROR status;
	const struct dsdb_schema *schema;
	struct dsdb_extended_replicated_objects *out;
	const struct drsuapi_DsReplicaObjectListItemEx *cur;
	uint32_t i;

	schema = dsdb_get_schema(ldb);
	if (!schema) {
		return WERR_DS_SCHEMA_NOT_LOADED;
	}

	status = dsdb_schema_pfm_contains_drsuapi_pfm(schema->prefixmap, mapping_ctr);
	W_ERROR_NOT_OK_RETURN(status);

	out = talloc_zero(mem_ctx, struct dsdb_extended_replicated_objects);
	W_ERROR_HAVE_NO_MEMORY(out);
	out->version		= DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION;

	out->partition_dn	= ldb_dn_new(out, ldb, partition_dn);
	W_ERROR_HAVE_NO_MEMORY(out->partition_dn);

	out->source_dsa		= source_dsa;
	out->uptodateness_vector= uptodateness_vector;

	out->num_objects	= object_count;
	out->objects		= talloc_array(out,
					       struct dsdb_extended_replicated_object,
					       out->num_objects);
	W_ERROR_HAVE_NO_MEMORY(out->objects);

	/* pass the linked attributes down to the repl_meta_data
	   module */
	out->linked_attributes_count = linked_attributes_count;
	out->linked_attributes       = linked_attributes;

	for (i=0, cur = first_object; cur; cur = cur->next_object, i++) {
		if (i == out->num_objects) {
			return WERR_FOOBAR;
		}

		status = dsdb_convert_object_ex(ldb, schema,
						cur, gensec_skey,
						out->objects, &out->objects[i]);
		if (!W_ERROR_IS_OK(status)) {
			DEBUG(0,("Failed to convert object %s\n", cur->object.identifier->dn));
			return status;
		}
	}
	if (i != out->num_objects) {
		return WERR_FOOBAR;
	}

	*objects = out;
	return WERR_OK;
}
Esempio n. 26
0
/*
  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;
}
Esempio n. 27
0
WERROR dsdb_origin_objects_commit(struct ldb_context *ldb,
				  TALLOC_CTX *mem_ctx,
				  const struct drsuapi_DsReplicaObjectListItem *first_object,
				  uint32_t *_num,
				  struct drsuapi_DsReplicaObjectIdentifier2 **_ids)
{
	WERROR status;
	const struct dsdb_schema *schema;
	const struct drsuapi_DsReplicaObjectListItem *cur;
	struct ldb_message **objects;
	struct drsuapi_DsReplicaObjectIdentifier2 *ids;
	uint32_t i;
	uint32_t num_objects = 0;
	const char * const attrs[] = {
		"objectGUID",
		"objectSid",
		NULL
	};
	struct ldb_result *res;
	int ret;

	schema = dsdb_get_schema(ldb);
	if (!schema) {
		return WERR_DS_SCHEMA_NOT_LOADED;
	}

	for (cur = first_object; cur; cur = cur->next_object) {
		num_objects++;
	}

	if (num_objects == 0) {
		return WERR_OK;
	}

	ret = ldb_transaction_start(ldb);
	if (ret != LDB_SUCCESS) {
		return WERR_DS_INTERNAL_FAILURE;
	}

	objects	= talloc_array(mem_ctx, struct ldb_message *,
			       num_objects);
	if (objects == NULL) {
		status = WERR_NOMEM;
		goto cancel;
	}

	for (i=0, cur = first_object; cur; cur = cur->next_object, i++) {
		status = dsdb_convert_object(ldb, schema,
					     cur, objects, &objects[i]);
		if (!W_ERROR_IS_OK(status)) {
			goto cancel;
		}
	}

	ids = talloc_array(mem_ctx,
			   struct drsuapi_DsReplicaObjectIdentifier2,
			   num_objects);
	if (ids == NULL) {
		status = WERR_NOMEM;
		goto cancel;
	}

	for (i=0; i < num_objects; i++) {
		struct dom_sid *sid = NULL;
		struct ldb_request *add_req;

		DEBUG(6,(__location__ ": adding %s\n", 
			 ldb_dn_get_linearized(objects[i]->dn)));

		ret = ldb_build_add_req(&add_req,
					ldb,
					objects,
					objects[i],
					NULL,
					NULL,
					ldb_op_default_callback,
					NULL);
		if (ret != LDB_SUCCESS) {
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}

		ret = ldb_request_add_control(add_req, LDB_CONTROL_RELAX_OID, true, NULL);
		if (ret != LDB_SUCCESS) {
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}
		
		ret = ldb_request(ldb, add_req);
		if (ret == LDB_SUCCESS) {
			ret = ldb_wait(add_req->handle, LDB_WAIT_ALL);
		}
		if (ret != LDB_SUCCESS) {
			DEBUG(0,(__location__ ": Failed add of %s - %s\n",
				 ldb_dn_get_linearized(objects[i]->dn), ldb_errstring(ldb)));
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}

		talloc_free(add_req);

		ret = ldb_search(ldb, objects, &res, objects[i]->dn,
				 LDB_SCOPE_BASE, attrs,
				 "(objectClass=*)");
		if (ret != LDB_SUCCESS) {
			status = WERR_DS_INTERNAL_FAILURE;
			goto cancel;
		}
		ids[i].guid = samdb_result_guid(res->msgs[0], "objectGUID");
		sid = samdb_result_dom_sid(objects, res->msgs[0], "objectSid");
		if (sid) {
			ids[i].sid = *sid;
		} else {
			ZERO_STRUCT(ids[i].sid);
		}
	}

	ret = ldb_transaction_commit(ldb);
	if (ret != LDB_SUCCESS) {
		return WERR_DS_INTERNAL_FAILURE;
	}

	talloc_free(objects);

	*_num = num_objects;
	*_ids = ids;
	return WERR_OK;

cancel:
	talloc_free(objects);
	ldb_transaction_cancel(ldb);
	return status;
}
Esempio n. 28
0
static int acl_modify(struct ldb_module *module, struct ldb_request *req)
{
	int ret;
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	const struct dsdb_schema *schema = dsdb_get_schema(ldb);
	int i;
	bool modify_sd = false;
	const struct GUID *guid;
	uint32_t access_granted;
	struct object_tree *root = NULL;
	struct object_tree *new_node = NULL;
	NTSTATUS status;
	struct ldb_result *acl_res;
	struct security_descriptor *sd;
	struct dom_sid *sid = NULL;
	TALLOC_CTX *tmp_ctx = talloc_new(req);
	static const char *acl_attrs[] = {
		"nTSecurityDescriptor",
		"objectClass",
		"objectSid",
		NULL
	};

	/* Don't print this debug statement if elements[0].name is going to be NULL */
	if(req->op.mod.message->num_elements > 0)
	{
		DEBUG(10, ("ldb:acl_modify: %s\n", req->op.mod.message->elements[0].name));
	}
	if (what_is_user(module) == SECURITY_SYSTEM) {
		return ldb_next_request(module, req);
	}
	if (ldb_dn_is_special(req->op.mod.message->dn)) {
		return ldb_next_request(module, req);
	}
	ret = ldb_search(ldb, req, &acl_res, req->op.mod.message->dn,
			 LDB_SCOPE_BASE, acl_attrs, NULL);

	if (ret != LDB_SUCCESS) {
		return ret;
	}

	ret = get_sd_from_ldb_message(req, acl_res->msgs[0], &sd);
	if (ret != LDB_SUCCESS) {
		DEBUG(10, ("acl_modify: cannot get descriptor\n"));
		return ret;
	}
	/* Theoretically we pass the check if the object has no sd */
	if (!sd) {
		return LDB_SUCCESS;
	}

	guid = get_oc_guid_from_message(module,acl_res->msgs[0]);
	if (!guid) {
		DEBUG(10, ("acl_modify: cannot get guid\n"));
		goto fail;
	}

	ret = get_dom_sid_from_ldb_message(req, acl_res->msgs[0], &sid);
	if (ret != LDB_SUCCESS) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	if (!insert_in_object_tree(tmp_ctx, guid, SEC_ADS_WRITE_PROP,
				   &root, &new_node)) {
		DEBUG(10, ("acl_modify: cannot add to object tree\n"));
		goto fail;
	}
	for (i=0; i < req->op.mod.message->num_elements; i++){
		const struct dsdb_attribute *attr;
		/* clearTextPassword is not in schema */
		if (strcmp("clearTextPassword", req->op.mod.message->elements[i].name) == 0) {
			attr = dsdb_attribute_by_lDAPDisplayName(schema, "unicodePwd");
		} else {
			attr = dsdb_attribute_by_lDAPDisplayName(schema,
								 req->op.mod.message->elements[i].name);
		}
		if (strcmp("nTSecurityDescriptor", req->op.mod.message->elements[i].name) == 0) {
			modify_sd = true;
		} else {

			if (!attr) {
				DEBUG(10, ("acl_modify: cannot find attribute %s\n",
					   req->op.mod.message->elements[i].name));
				goto fail;
			}
			if (!insert_in_object_tree(tmp_ctx,
						   &attr->attributeSecurityGUID, SEC_ADS_WRITE_PROP,
						   &new_node, &new_node)) {
				DEBUG(10, ("acl_modify: cannot add to object tree securityGUID\n"));
				goto fail;
			}

			if (!insert_in_object_tree(tmp_ctx,
						   &attr->schemaIDGUID, SEC_ADS_WRITE_PROP, &new_node, &new_node)) {
				DEBUG(10, ("acl_modify: cannot add to object tree attributeGUID\n"));
				goto fail;
			}
		}
	}

	if (root->num_of_children > 0) {
		status = sec_access_check_ds(sd, acl_user_token(module),
					     SEC_ADS_WRITE_PROP,
					     &access_granted,
					     root,
					     sid);

		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(10, ("Object %s nas no write property access\n",
				   ldb_dn_get_linearized(req->op.mod.message->dn)));
			acl_debug(sd,
				  acl_user_token(module),
				  req->op.mod.message->dn,
				  true,
				  10);
			talloc_free(tmp_ctx);
			return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
		}
	}
	if (modify_sd) {
		status = sec_access_check_ds(sd, acl_user_token(module),
					     SEC_STD_WRITE_DAC,
					     &access_granted,
					     NULL,
					     sid);

		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(10, ("Object %s nas no write dacl access\n",
				   ldb_dn_get_linearized(req->op.mod.message->dn)));
			acl_debug(sd,
				  acl_user_token(module),
				  req->op.mod.message->dn,
				  true,
				  10);
			talloc_free(tmp_ctx);
			return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
		}
	}

	talloc_free(tmp_ctx);
	return ldb_next_request(module, req);
fail:
	talloc_free(tmp_ctx);
	return LDB_ERR_OPERATIONS_ERROR;
}
Esempio n. 29
0
static int acl_rename(struct ldb_module *module, struct ldb_request *req)
{
	int ret;
	struct ldb_dn *oldparent = ldb_dn_get_parent(req, req->op.rename.olddn);
	struct ldb_dn *newparent = ldb_dn_get_parent(req, req->op.rename.newdn);
	struct ldb_context *ldb;
	struct security_descriptor *sd = NULL;
	struct dom_sid *sid = NULL;
	struct ldb_result *acl_res;
	const struct GUID *guid;
	struct object_tree *root = NULL;
	struct object_tree *new_node = NULL;
	TALLOC_CTX *tmp_ctx = talloc_new(req);
	NTSTATUS status;
	uint32_t access_granted;
	static const char *acl_attrs[] = {
		"nTSecurityDescriptor",
		"objectClass",
		"objectSid",
		NULL
	};

	DEBUG(10, ("ldb:acl_rename: %s\n", ldb_dn_get_linearized(req->op.rename.olddn)));
	if (what_is_user(module) == SECURITY_SYSTEM) {
		return ldb_next_request(module, req);
	}
	if (ldb_dn_is_special(req->op.rename.olddn)) {
		return ldb_next_request(module, req);
	}
	ldb = ldb_module_get_ctx(module);

	/* TODO search to include deleted objects */
	ret = ldb_search(ldb, req, &acl_res, req->op.rename.olddn,
			 LDB_SCOPE_BASE, acl_attrs, NULL);
	/* we sould be able to find the parent */
	if (ret != LDB_SUCCESS) {
		DEBUG(10,("acl: failed to find object %s\n",
			  ldb_dn_get_linearized(req->op.rename.olddn)));
		return ret;
	}

	guid = get_oc_guid_from_message(module,acl_res->msgs[0]);
	if (!insert_in_object_tree(tmp_ctx, guid, SEC_ADS_WRITE_PROP,
				   &root, &new_node)) {
		return LDB_ERR_OPERATIONS_ERROR;
	};

	guid = attribute_schemaid_guid_by_lDAPDisplayName(dsdb_get_schema(ldb),
							  "name");
	if (!insert_in_object_tree(tmp_ctx, guid, SEC_ADS_WRITE_PROP,
				   &new_node, &new_node)) {
		return LDB_ERR_OPERATIONS_ERROR;
	};

	ret = get_sd_from_ldb_message(req, acl_res->msgs[0], &sd);

	if (ret != LDB_SUCCESS) {
		return LDB_ERR_OPERATIONS_ERROR;
	}
	/* Theoretically we pass the check if the object has no sd */
	if (!sd) {
		return LDB_SUCCESS;
	}
	ret = get_dom_sid_from_ldb_message(req, acl_res->msgs[0], &sid);
	if (ret != LDB_SUCCESS) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	status = sec_access_check_ds(sd, acl_user_token(module),
				     SEC_ADS_WRITE_PROP,
				     &access_granted,
				     root,
				     sid);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("Object %s nas no wp on name\n",
			   ldb_dn_get_linearized(req->op.rename.olddn)));
		acl_debug(sd,
			  acl_user_token(module),
			  req->op.rename.olddn,
			  true,
			  10);
		return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
	}

	if (ldb_dn_compare(oldparent, newparent) == 0) {
		/* regular rename, not move, nothing more to do */
		return ldb_next_request(module, req);
	}

	/* What exactly to do in this case? It would fail anyway.. */
	if ((ldb_dn_compare(req->op.rename.newdn, (ldb_get_schema_basedn(ldb))) == 0) ||
	    (ldb_dn_compare(req->op.rename.newdn, (ldb_get_config_basedn(ldb))) == 0) ||
	    (ldb_dn_compare(req->op.rename.newdn, (ldb_get_root_basedn(ldb))) == 0)) {
		DEBUG(10,("acl:moving as an NC\n"));
		return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
	}
	/* new parent should have create child */
	talloc_free(tmp_ctx);
	tmp_ctx = talloc_new(req);
	root = NULL;
	new_node = NULL;
	guid = get_oc_guid_from_message(module,acl_res->msgs[0]);
	if (!guid) {
		DEBUG(10,("acl:renamed object has no object class\n"));
		return ldb_module_done(req, NULL, NULL,  LDB_ERR_OPERATIONS_ERROR);
	}
	if (!insert_in_object_tree(tmp_ctx, guid, SEC_ADS_CREATE_CHILD,
				   &root, &new_node)) {
		return LDB_ERR_OPERATIONS_ERROR;
	}
	ret = check_access_on_dn(module, req, newparent, SEC_ADS_CREATE_CHILD, root);
	if (ret != LDB_SUCCESS) {
		DEBUG(10,("acl:access_denied renaming %s", ldb_dn_get_linearized(req->op.rename.olddn)));
		return ret;
	}
	/* do we have delete object on the object? */

	status = sec_access_check_ds(sd, acl_user_token(module),
				     SEC_STD_DELETE,
				     &access_granted,
				     NULL,
				     sid);

	if (NT_STATUS_IS_OK(status)) {
		return ldb_next_request(module, req);
	}
	/* what about delete child on the current parent */
	ret = check_access_on_dn(module, req, oldparent, SEC_ADS_DELETE_CHILD, NULL);
	if (ret != LDB_SUCCESS) {
		DEBUG(10,("acl:access_denied renaming %s", ldb_dn_get_linearized(req->op.rename.olddn)));
		return ldb_module_done(req, NULL, NULL, ret);
	}
	return ldb_next_request(module, req);
}
Esempio n. 30
0
/*
  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;
}