示例#1
0
static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_context *ldb;

	ldb = ldb_module_get_ctx(module);

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

	if (ldb_msg_find_element(req->op.mod.message, "name")) {
		ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead",
				       ldb_dn_get_linearized(req->op.mod.message->dn));
		return LDB_ERR_NOT_ALLOWED_ON_RDN;
	}

	if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) {
		ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead",
				       ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn));
		return LDB_ERR_NOT_ALLOWED_ON_RDN;
	}

	/* All OK, they kept their fingers out of the special attributes */
	return ldb_next_request(module, req);
}
示例#2
0
static int subtree_delete(struct ldb_module *module, struct ldb_request *req)
{
	static const char * const attrs[] = { NULL };
	int ret;
	struct ldb_result *res = NULL;

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

	/* see if we have any children */
	ret = dsdb_module_search(module, req, &res, req->op.del.dn, LDB_SCOPE_ONELEVEL, attrs,
				 DSDB_SEARCH_SHOW_DELETED, NULL);
	if (ret != LDB_SUCCESS) {
		talloc_free(res);
		return ret;
	}
	if (res->count > 0) {
		ldb_asprintf_errstring(ldb_module_get_ctx(module),
				       "Cannot delete %s, not a leaf node "
				       "(has %d children)\n",
				       ldb_dn_get_linearized(req->op.del.dn),
				       res->count);
		talloc_free(res);
		return LDB_ERR_NOT_ALLOWED_ON_NON_LEAF;
	}
	talloc_free(res);

	return ldb_next_request(module, req);
}
示例#3
0
/* Rename a record. */
int ldb_map_rename(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_request *search_req = NULL;
	struct ldb_context *ldb;
	struct map_context *ac;
	int ret;

	ldb = ldb_module_get_ctx(module);

	/* Do not manipulate our control entries */
	if (ldb_dn_is_special(req->op.rename.olddn)) {
		return ldb_next_request(module, req);
	}

	/* No mapping requested (perhaps no DN mapping specified).
	 * Skip to next module */
	if ((!ldb_dn_check_local(module, req->op.rename.olddn)) &&
	    (!ldb_dn_check_local(module, req->op.rename.newdn))) {
		return ldb_next_request(module, req);
	}

	/* Rename into/out of the mapped partition requested, bail out */
	if (!ldb_dn_check_local(module, req->op.rename.olddn) ||
	    !ldb_dn_check_local(module, req->op.rename.newdn)) {
		return LDB_ERR_AFFECTS_MULTIPLE_DSAS;
	}

	/* Prepare context and handle */
	ac = map_init_context(module, req);
	if (ac == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* Prepare the remote operation */
	ret = ldb_build_rename_req(&ac->remote_req, ldb, ac,
				   ldb_dn_map_local(module, ac, req->op.rename.olddn),
				   ldb_dn_map_local(module, ac, req->op.rename.newdn),
				   req->controls,
				   ac, map_op_remote_callback,
				   req);
	LDB_REQ_SET_LOCATION(ac->remote_req);
	if (ret != LDB_SUCCESS) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* No local db, just run the remote request */
	if (!map_check_local_db(ac->module)) {
		/* Do the remote request. */
		return ldb_next_remote_request(ac->module, ac->remote_req);
	}

	/* Prepare the search operation */
	ret = map_search_self_req(&search_req, ac, req->op.rename.olddn);
	if (ret != LDB_SUCCESS) {
		map_oom(module);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	return ldb_next_request(module, search_req);
}
示例#4
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);
}
示例#5
0
/* Rename the local record. */
static int map_rename_do_local(struct map_context *ac)
{
	struct ldb_request *local_req;
	struct ldb_context *ldb;
	int ret;

	ldb = ldb_module_get_ctx(ac->module);

	/* No local record, continue remotely */
	if (ac->local_dn == NULL) {
		/* Do the remote request. */
		return ldb_next_remote_request(ac->module, ac->remote_req);
	}

	/* Prepare the local operation */
	ret = ldb_build_rename_req(&local_req, ldb, ac,
				   ac->req->op.rename.olddn,
				   ac->req->op.rename.newdn,
				   ac->req->controls,
				   ac,
				   map_rename_local_callback,
				   ac->req);
	LDB_REQ_SET_LOCATION(local_req);
	if (ret != LDB_SUCCESS) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	return ldb_next_request(ac->module, local_req);
}
示例#6
0
文件: acl.c 项目: 0x24bin/winexe-1
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);
}
示例#7
0
static int wins_ldb_verify(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	struct winsdb_handle *h = talloc_get_type(ldb_get_opaque(ldb, "winsdb_handle"),
						  struct winsdb_handle);
	const struct ldb_message *msg;

	switch (req->operation) {
	case LDB_ADD:
		msg = req->op.add.message;
		break;
		
	case LDB_MODIFY:
		msg = req->op.mod.message;
		break;

	default:
		return ldb_next_request(module, req);
	}

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

	if (!h) {
		ldb_debug_set(ldb, LDB_DEBUG_FATAL, "%s", "WINS_LDB: INTERNAL ERROR: no winsdb_handle present!");
		return LDB_ERR_OTHER;
	}

	switch (h->caller) {
	case WINSDB_HANDLE_CALLER_NBTD:
	case WINSDB_HANDLE_CALLER_WREPL:
		/* we trust our nbt and wrepl code ... */
		return ldb_next_request(module, req);

	case WINSDB_HANDLE_CALLER_ADMIN:
		ldb_debug(ldb, LDB_DEBUG_WARNING, "%s\n", "WINS_LDB: TODO verify add/modify for WINSDB_HANDLE_CALLER_ADMIN");
		return ldb_next_request(module, req);
	}

	return LDB_ERR_OTHER;
}
示例#8
0
文件: acl.c 项目: 0x24bin/winexe-1
static int acl_search(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_context *ldb;
	struct acl_context *ac;
	struct ldb_request *down_req;
	struct acl_private *data;
	int ret, i;

	ldb = ldb_module_get_ctx(module);

	ac = talloc_zero(req, struct acl_context);
	if (ac == NULL) {
		ldb_oom(ldb);
		return LDB_ERR_OPERATIONS_ERROR;
	}
	data = talloc_get_type(ldb_module_get_private(module), struct acl_private);

	ac->module = module;
	ac->req = req;
	ac->user_type = what_is_user(module);
	ac->allowedAttributes = ldb_attr_in_list(req->op.search.attrs, "allowedAttributes");
	ac->allowedAttributesEffective = ldb_attr_in_list(req->op.search.attrs, "allowedAttributesEffective");
	ac->allowedChildClasses = ldb_attr_in_list(req->op.search.attrs, "allowedChildClasses");
	ac->allowedChildClassesEffective = ldb_attr_in_list(req->op.search.attrs, "allowedChildClassesEffective");
	ac->sDRightsEffective = ldb_attr_in_list(req->op.search.attrs, "sDRightsEffective");

	/* replace any attributes in the parse tree that are private,
	   so we don't allow a search for 'userPassword=penguin',
	   just as we would not allow that attribute to be returned */
	if (ac->user_type != SECURITY_SYSTEM) {
		/* FIXME: We should copy the tree and keep the original unmodified. */
		/* remove password attributes */
		if (data && data->password_attrs) {
			for (i = 0; data->password_attrs[i]; i++) {
				ldb_parse_tree_attr_replace(req->op.search.tree,
							    data->password_attrs[i],
							    "kludgeACLredactedattribute");
			}
		}
	}
	ret = ldb_build_search_req_ex(&down_req,
				      ldb, ac,
				      req->op.search.base,
				      req->op.search.scope,
				      req->op.search.tree,
				      req->op.search.attrs,
				      req->controls,
				      ac, acl_search_callback,
				      req);
	if (ret != LDB_SUCCESS) {
		return ret;
	}
	/* perform the search */
	return ldb_next_request(module, down_req);
}
示例#9
0
/* TODO: free old DNs and messages? */
int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request)
{
	const struct ldb_map_context *data = map_get_context(module);
	struct ldb_context *ldb;
	struct ldb_message *msg;

	ldb = ldb_module_get_ctx(module);

	switch (request->operation) {
	case LDB_SEARCH:
		if (request->op.search.base) {
			request->op.search.base = ldb_dn_rebase_remote(request, data, request->op.search.base);
		} else {
			request->op.search.base = data->remote_base_dn;
			/* TODO: adjust scope? */
		}
		break;

	case LDB_ADD:
		msg = ldb_msg_copy_shallow(request, request->op.add.message);
		if (msg == NULL) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
		msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn);
		request->op.add.message = msg;
		break;

	case LDB_MODIFY:
		msg = ldb_msg_copy_shallow(request, request->op.mod.message);
		if (msg == NULL) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
		msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn);
		request->op.mod.message = msg;
		break;

	case LDB_DELETE:
		request->op.del.dn = ldb_dn_rebase_remote(request, data, request->op.del.dn);
		break;

	case LDB_RENAME:
		request->op.rename.olddn = ldb_dn_rebase_remote(request, data, request->op.rename.olddn);
		request->op.rename.newdn = ldb_dn_rebase_remote(request, data, request->op.rename.newdn);
		break;

	default:
		ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
			  "Invalid remote request!");
		return LDB_ERR_OPERATIONS_ERROR;
	}

	return ldb_next_request(module, request);
}
示例#10
0
static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_context *ldb;
	struct rename_context *ac;
	struct ldb_request *down_req;
	int ret;

	ldb = ldb_module_get_ctx(module);

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

	ac = talloc_zero(req, struct rename_context);
	if (ac == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ac->module = module;
	ac->req = req;

	ret = ldb_build_rename_req(&down_req,
				   ldb,
				   ac,
				   req->op.rename.olddn,
				   req->op.rename.newdn,
				   req->controls,
				   ac,
				   rdn_rename_callback,
				   req);

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

	/* rename first, modify "name" if rename is ok */
	return ldb_next_request(module, down_req);
}
示例#11
0
static int sample_modify(struct ldb_module *mod, struct ldb_request *req)
{
	struct ldb_control *control;

	/* check if there's a relax control */
	control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID);
	if (control != NULL) {
		return LDB_ERR_UNWILLING_TO_PERFORM;
	}

	/* not found go on */
	return ldb_next_request(mod, req);
}
/* deny instancetype modification */
static int instancetype_mod(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	struct ldb_message_element *el;

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

	ldb_debug(ldb, LDB_DEBUG_TRACE, "instancetype_mod\n");

	el = ldb_msg_find_element(req->op.mod.message, "instanceType");
	if (el != NULL) {
		/* Except to allow dbcheck to fix things, this must never be modified */
		if (!ldb_request_get_control(req, DSDB_CONTROL_DBCHECK)) {
			ldb_set_errstring(ldb, "instancetype: the 'instanceType' attribute can never be changed!");
			return LDB_ERR_CONSTRAINT_VIOLATION;
		}
	}
	return ldb_next_request(module, req);
}
示例#13
0
/* Modify the local record. */
static int map_modify_do_local(struct map_context *ac)
{
	struct ldb_request *local_req;
	struct ldb_context *ldb;
	int ret;

	ldb = ldb_module_get_ctx(ac->module);

	if (ac->local_dn == NULL) {
		/* No local record present, add it instead */
		/* Add local 'IS_MAPPED' */
		/* TODO: use GUIDs here instead */
		if (ldb_msg_add_empty(ac->local_msg, IS_MAPPED,
					LDB_FLAG_MOD_ADD, NULL) != 0) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
		ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED,
						ac->remote_req->op.mod.message->dn);
		if (ret != 0) {
			return LDB_ERR_OPERATIONS_ERROR;
		}

		/* Prepare the local operation */
		ret = ldb_build_add_req(&local_req, ldb, ac,
					ac->local_msg,
					ac->req->controls,
					ac,
					map_op_local_callback,
					ac->req);
		LDB_REQ_SET_LOCATION(local_req);
		if (ret != LDB_SUCCESS) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
	} else {
		/* Prepare the local operation */
		ret = ldb_build_mod_req(&local_req, ldb, ac,
					ac->local_msg,
					ac->req->controls,
					ac,
					map_op_local_callback,
					ac->req);
		LDB_REQ_SET_LOCATION(local_req);
		if (ret != LDB_SUCCESS) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
	}

	return ldb_next_request(ac->module, local_req);
}
示例#14
0
/* Add the local record. */
int map_add_do_local(struct ldb_handle *handle)
{
	struct map_context *ac;

	ac = talloc_get_type(handle->private_data, struct map_context);

	ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->local_req);

	ac->step = MAP_ADD_LOCAL;

	handle->state = LDB_ASYNC_INIT;
	handle->status = LDB_SUCCESS;

	return ldb_next_request(ac->module, ac->local_req);
}
示例#15
0
文件: acl.c 项目: 0x24bin/winexe-1
/* similar to the modify for the time being.
 * We need to concider the special delete tree case, though - TODO */
static int acl_delete(struct ldb_module *module, struct ldb_request *req)
{
	int ret;
	struct ldb_dn *parent = ldb_dn_get_parent(req, req->op.del.dn);
	struct ldb_context *ldb;

	DEBUG(10, ("ldb:acl_delete: %s\n", ldb_dn_get_linearized(req->op.del.dn)));
	if (what_is_user(module) == SECURITY_SYSTEM) {
		return ldb_next_request(module, req);
	}

	if (ldb_dn_is_special(req->op.del.dn)) {
		return ldb_next_request(module, req);
	}
	ldb = ldb_module_get_ctx(module);
	/* first check if we have delete object right */
	ret = check_access_on_dn(module, req, req->op.del.dn, SEC_STD_DELETE, NULL);
	if (ret == LDB_SUCCESS) {
		return ldb_next_request(module, req);
	}

	/* Nope, we don't have delete object. Lets check if we have delete child on the parent */
	/* No parent, so check fails */
	if ((ldb_dn_compare(req->op.del.dn, (ldb_get_schema_basedn(ldb))) == 0) ||
	    (ldb_dn_compare(req->op.del.dn, (ldb_get_config_basedn(ldb))) == 0) ||
	    (ldb_dn_compare(req->op.del.dn, (ldb_get_root_basedn(ldb))) == 0)) {
		DEBUG(10,("acl:deleting an NC\n"));
		return ldb_module_done(req, NULL, NULL, LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS);
	}

	ret = check_access_on_dn(module, req, parent, SEC_ADS_DELETE_CHILD, NULL);
	if (ret != LDB_SUCCESS) {
		return ret;
	}
	return ldb_next_request(module, req);
}
示例#16
0
int sample_add(struct ldb_module *mod, struct ldb_request *req)
{
	struct ldb_control *control;
	struct ldb_control *controls;
	ldb_msg_add_fmt(req->op.add.message, "touchedBy", "sample");


	/* check if there's a relax control */
	control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID);
	if (control == NULL) {
		/* not found go on */
		return ldb_next_request(mod, req);
	} else {
		return LDB_ERR_UNWILLING_TO_PERFORM;
	}
}
示例#17
0
/* Update the local 'IS_MAPPED' attribute. */
static int map_rename_do_fixup(struct map_context *ac)
{
	struct ldb_request *local_req;

	/* Prepare the fixup operation */
	/* TODO: use GUIDs here instead -- or skip it when GUIDs are used. */
	local_req = map_build_fixup_req(ac,
					ac->req->op.rename.newdn,
					ac->remote_req->op.rename.newdn,
					ac,
					map_op_local_callback);
	if (local_req == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	return ldb_next_request(ac->module, local_req);
}
示例#18
0
/* Add the local record. */
static int map_add_do_local(struct map_context *ac)
{
	struct ldb_request *local_req;
	struct ldb_context *ldb;
	int ret;

	ldb = ldb_module_get_ctx(ac->module);

	/* Prepare the local operation */
	ret = ldb_build_add_req(&local_req, ldb, ac,
				ac->local_msg,
				ac->req->controls,
				ac,
				map_op_local_callback,
				ac->req);
	LDB_REQ_SET_LOCATION(local_req);
	if (ret != LDB_SUCCESS) {
		return LDB_ERR_OPERATIONS_ERROR;
	}
	return ldb_next_request(ac->module, local_req);
}
示例#19
0
static int sample_add(struct ldb_module *mod, struct ldb_request *req)
{
	struct ldb_context *ldb = ldb_module_get_ctx(mod);
	struct ldb_control *control = NULL;
	struct ldb_message *msg = NULL;
	struct ldb_request *down_req = NULL;
	int ret;

	/* check if there's a relax control */
	control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID);
	if (control != NULL) {
		return LDB_ERR_UNWILLING_TO_PERFORM;
	}

	msg = ldb_msg_copy_shallow(req, req->op.add.message);
	if (msg == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ret = ldb_msg_add_fmt(msg, "touchedBy", "sample");
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	ret = ldb_build_add_req(&down_req, ldb, req,
				msg,
				req->controls,
				req, sample_add_callback,
				req);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	talloc_steal(down_req, msg);

	/* go on with the call chain */
	return ldb_next_request(mod, down_req);
}
示例#20
0
/* Add a record. */
int map_add(struct ldb_module *module, struct ldb_request *req)
{
	const struct ldb_message *msg = req->op.add.message;
	struct ldb_handle *h;
	struct map_context *ac;
	struct ldb_message *local, *remote;
	const char *dn;

	/* Do not manipulate our control entries */
	if (ldb_dn_is_special(msg->dn)) {
		return ldb_next_request(module, req);
	}

	/* No mapping requested (perhaps no DN mapping specified), skip to next module */
	if (!ldb_dn_check_local(module, msg->dn)) {
		return ldb_next_request(module, req);
	}

	/* No mapping needed, fail */
	if (!ldb_msg_check_remote(module, msg)) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* Prepare context and handle */
	h = map_init_handle(req, module);
	if (h == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}
	ac = talloc_get_type(h->private_data, struct map_context);

	/* Prepare the local operation */
	ac->local_req = talloc(ac, struct ldb_request);
	if (ac->local_req == NULL) {
		goto oom;
	}

	*(ac->local_req) = *req;	/* copy the request */

	ac->local_req->context = NULL;
	ac->local_req->callback = NULL;

	/* Prepare the remote operation */
	ac->remote_req = talloc(ac, struct ldb_request);
	if (ac->remote_req == NULL) {
		goto oom;
	}

	*(ac->remote_req) = *req;	/* copy the request */

	ac->remote_req->context = NULL;
	ac->remote_req->callback = NULL;

	/* Prepare the local message */
	local = ldb_msg_new(ac->local_req);
	if (local == NULL) {
		goto oom;
	}
	local->dn = msg->dn;

	/* Prepare the remote message */
	remote = ldb_msg_new(ac->remote_req);
	if (remote == NULL) {
		goto oom;
	}
	remote->dn = ldb_dn_map_local(ac->module, remote, msg->dn);

	/* Split local from remote message */
	ldb_msg_partition(module, local, remote, msg);
	ac->local_req->op.add.message = local;
	ac->remote_req->op.add.message = remote;

	if ((local->num_elements == 0) || (!map_check_local_db(ac->module))) {
		/* No local data or db, just run the remote request */
		talloc_free(ac->local_req);
		req->handle = h;	/* return our own handle to deal with this call */
		return map_add_do_remote(h);
	}

	/* Store remote DN in 'IS_MAPPED' */
	/* TODO: use GUIDs here instead */
	dn = ldb_dn_linearize(local, remote->dn);
	if (ldb_msg_add_string(local, IS_MAPPED, dn) != 0) {
		goto failed;
	}

	req->handle = h;		/* return our own handle to deal with this call */
	return map_add_do_local(h);

oom:
	map_oom(module);
failed:
	talloc_free(h);
	return LDB_ERR_OPERATIONS_ERROR;
}
示例#21
0
/*
  search for attrs on one DN, in the modules below
 */
int dsdb_module_search_dn(struct ldb_module *module,
			  TALLOC_CTX *mem_ctx,
			  struct ldb_result **_res,
			  struct ldb_dn *basedn,
			  const char * const *attrs,
			  uint32_t dsdb_flags,
			  struct ldb_request *parent)
{
	int ret;
	struct ldb_request *req;
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;

	tmp_ctx = talloc_new(mem_ctx);

	res = talloc_zero(tmp_ctx, struct ldb_result);
	if (!res) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb_module_get_ctx(module));
	}

	ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
				   basedn,
				   LDB_SCOPE_BASE,
				   NULL,
				   attrs,
				   NULL,
				   res,
				   ldb_search_default_callback,
				   parent);
	LDB_REQ_SET_LOCATION(req);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	ret = dsdb_request_add_controls(req, dsdb_flags);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	if (dsdb_flags & DSDB_FLAG_TRUSTED) {
		ldb_req_mark_trusted(req);
	}

	/* Run the new request */
	if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
		ret = ldb_next_request(module, req);
	} else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
		ret = ldb_request(ldb_module_get_ctx(module), req);
	} else {
		const struct ldb_module_ops *ops = ldb_module_get_ops(module);
		SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
		ret = ops->search(module, req);
	}
	if (ret == LDB_SUCCESS) {
		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
	}

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

	if (res->count != 1) {
		/* we may be reading a DB that does not have the 'check base on search' option... */
		ret = LDB_ERR_NO_SUCH_OBJECT;
		ldb_asprintf_errstring(ldb_module_get_ctx(module), 
				       "dsdb_module_search_dn: did not find base dn %s (%d results)", 
				       ldb_dn_get_linearized(basedn), res->count);
	} else {
		*_res = talloc_steal(mem_ctx, res);
	}
	talloc_free(tmp_ctx);
	return ret;
}
示例#22
0
int dsdb_module_search_tree(struct ldb_module *module,
		       TALLOC_CTX *mem_ctx,
		       struct ldb_result **_res,
		       struct ldb_dn *basedn,
		       enum ldb_scope scope,
		       struct ldb_parse_tree *tree,
		       const char * const *attrs,
		       int dsdb_flags,
		       struct ldb_request *parent)
{
	int ret;
	struct ldb_request *req;
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;

	tmp_ctx = talloc_new(mem_ctx);

	/* cross-partitions searches with a basedn break multi-domain support */
	SMB_ASSERT(basedn == NULL || (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) == 0);

	res = talloc_zero(tmp_ctx, struct ldb_result);
	if (!res) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb_module_get_ctx(module));
	}

	ret = ldb_build_search_req_ex(&req, ldb_module_get_ctx(module), tmp_ctx,
				   basedn,
				   scope,
				   tree,
				   attrs,
				   NULL,
				   res,
				   ldb_search_default_callback,
				   parent);
	LDB_REQ_SET_LOCATION(req);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	ret = dsdb_request_add_controls(req, dsdb_flags);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	if (dsdb_flags & DSDB_FLAG_TRUSTED) {
		ldb_req_mark_trusted(req);
	}

	if (dsdb_flags & DSDB_FLAG_NEXT_MODULE) {
		ret = ldb_next_request(module, req);
	} else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
		ret = ldb_request(ldb_module_get_ctx(module), req);
	} else {
		const struct ldb_module_ops *ops = ldb_module_get_ops(module);
		SMB_ASSERT(dsdb_flags & DSDB_FLAG_OWN_MODULE);
		ret = ops->search(module, req);
	}
	if (ret == LDB_SUCCESS) {
		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
	}

	talloc_free(req);
	if (ret == LDB_SUCCESS) {
		*_res = talloc_steal(mem_ctx, res);
	}
	talloc_free(tmp_ctx);
	return ret;
}
示例#23
0
static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_context *ldb;
	struct ldb_request *down_req;
	struct rename_context *ac;
	struct ldb_message *msg;
	struct ldb_message_element *attribute;
	const struct ldb_schema_attribute *a;
	const char *rdn_name;
	struct ldb_val rdn_val;
	int i, ret;

	ldb = ldb_module_get_ctx(module);

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

	ac = talloc_zero(req, struct rename_context);
	if (ac == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ac->module = module;
	ac->req = req;

	msg = ldb_msg_copy_shallow(req, req->op.add.message);
	if (msg == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	rdn_name = ldb_dn_get_rdn_name(msg->dn);
	if (rdn_name == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}
	
	rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(msg->dn));
	
	/* Perhaps someone above us tried to set this? */
	if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) {
		attribute->num_values = 0;
	}

	if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	attribute = rdn_name_find_attribute(msg, rdn_name);

	if (!attribute) {
		if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
	} else {
		a = ldb_schema_attribute_by_name(ldb, rdn_name);

		for (i = 0; i < attribute->num_values; i++) {
			ret = a->syntax->comparison_fn(ldb, msg,
					&rdn_val, &attribute->values[i]);
			if (ret == 0) {
				/* overwrite so it matches in case */
				attribute->values[i] = rdn_val;
				break;
			}
		}
		if (i == attribute->num_values) {
			char *rdn_errstring = talloc_asprintf(ac,
				"RDN mismatch on %s: %s (%.*s) should match one of:", 
				ldb_dn_get_linearized(msg->dn), rdn_name, 
				(int)rdn_val.length, (const char *)rdn_val.data);
			for (i = 0; i < attribute->num_values; i++) {
				rdn_errstring = talloc_asprintf_append(
					rdn_errstring, " (%.*s)",
					(int)attribute->values[i].length, 
					(const char *)attribute->values[i].data);
			}
			ldb_set_errstring(ldb, rdn_errstring);
			/* Match AD's error here */
			return LDB_ERR_INVALID_DN_SYNTAX;
		}
	}

	ret = ldb_build_add_req(&down_req, ldb, req,
				msg,
				req->controls,
				ac, rdn_name_add_callback,
				req);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	talloc_steal(down_req, msg);

	/* go on with the call chain */
	return ldb_next_request(module, down_req);
}
/* add_record: add instancetype attribute */
static int instancetype_add(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	struct ldb_request *down_req;
	struct ldb_message *msg;
	struct ldb_message_element *el;
	uint32_t instanceType;
	int ret;

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

	ldb_debug(ldb, LDB_DEBUG_TRACE, "instancetype_add\n");

	el = ldb_msg_find_element(req->op.add.message, "instanceType");
	if (el != NULL) {
		if (el->num_values != 1) {
			ldb_set_errstring(ldb, "instancetype: the 'instanceType' attribute is single-valued!");
			return LDB_ERR_UNWILLING_TO_PERFORM;
		}

		instanceType = ldb_msg_find_attr_as_uint(req->op.add.message,
							 "instanceType", 0);
		if (!(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
			/*
			 * If we have no NC add operation (no TYPE_IS_NC_HEAD)
			 * then "instanceType" can only be "0" or "TYPE_WRITE".
			 */
			if ((instanceType != 0) &&
			    ((instanceType & INSTANCE_TYPE_WRITE) == 0)) {
				ldb_set_errstring(ldb, "instancetype: if TYPE_IS_NC_HEAD wasn't set, then only TYPE_WRITE or 0 are allowed!");
				return LDB_ERR_UNWILLING_TO_PERFORM;
			}
		} else {
			/*
			 * If we have a NC add operation then we need also the
			 * "TYPE_WRITE" flag in order to succeed,
			 * unless this NC is not instantiated
			*/
			if (!(instanceType & INSTANCE_TYPE_UNINSTANT) &&
			    !(instanceType & INSTANCE_TYPE_WRITE)) {
				ldb_set_errstring(ldb, "instancetype: if TYPE_IS_NC_HEAD was set, then also TYPE_WRITE is requested!");
				return LDB_ERR_UNWILLING_TO_PERFORM;
			}
		}

		/* we did only tests, so proceed with the original request */
		return ldb_next_request(module, req);
	}

	/* we have to copy the message as the caller might have it as a const */
	msg = ldb_msg_copy_shallow(req, req->op.add.message);
	if (msg == NULL) {
		return ldb_oom(ldb);
	}

	/*
	 * TODO: calculate correct instance type
	 */
	instanceType = INSTANCE_TYPE_WRITE;

	ret = samdb_msg_add_uint(ldb, msg, msg, "instanceType", instanceType);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	ret = ldb_build_add_req(&down_req, ldb, req,
				msg,
				req->controls,
				req, dsdb_next_callback,
				req);
	LDB_REQ_SET_LOCATION(down_req);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	/* go on with the call chain */
	return ldb_next_request(module, down_req);
}
示例#25
0
int sample_add(struct ldb_module *mod, struct ldb_request *req)
{
	ldb_msg_add_fmt(req->op.add.message, "touchedBy", "sample");

	return ldb_next_request(mod, req);
}
示例#26
0
static int samldb_add(struct ldb_module *module, struct ldb_request *req)
{
	const struct ldb_message *msg = req->op.add.message;
	struct ldb_message *msg2 = NULL;
	struct ldb_request *down_req;
	int ret;

	ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_add_record\n");

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

	/* is user or computer? */
	if ((samdb_find_attribute(module->ldb, msg, "objectclass", "user") != NULL) ||
	    (samdb_find_attribute(module->ldb, msg, "objectclass", "computer") != NULL)) {
		/*  add all relevant missing objects */
		ret = samldb_fill_user_or_computer_object(module, msg, &msg2);
		if (ret) {
			return ret;
		}
	}

	/* is group? add all relevant missing objects */
	if ( ! msg2 ) {
		if (samdb_find_attribute(module->ldb, msg, "objectclass", "group") != NULL) {
			ret = samldb_fill_group_object(module, msg, &msg2);
			if (ret) {
				return ret;
			}
		}
	}

	/* perhaps a foreignSecurityPrincipal? */
	if ( ! msg2 ) {
		if (samdb_find_attribute(module->ldb, msg, "objectclass", "foreignSecurityPrincipal") != NULL) {
			ret = samldb_fill_foreignSecurityPrincipal_object(module, msg, &msg2);
			if (ret) {
				return ret;
			}
		}
	}

	if (msg2 == NULL) {
		return ldb_next_request(module, req);
	}

	down_req = talloc(req, struct ldb_request);
	if (down_req == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	*down_req = *req;
	
	down_req->op.add.message = talloc_steal(down_req, msg2);

	ldb_set_timeout_from_prev_req(module->ldb, req, down_req);

	/* go on with the call chain */
	ret = ldb_next_request(module, down_req);

	/* do not free down_req as the call results may be linked to it,
	 * it will be freed when the upper level request get freed */
	if (ret == LDB_SUCCESS) {
		req->handle = down_req->handle;
	}

	return ret;
}
示例#27
0
文件: acl.c 项目: 0x24bin/winexe-1
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;
}
示例#28
0
static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
{
	struct ldb_context *ldb;
	struct rename_context *ac;
	struct ldb_request *mod_req;
	const char *rdn_name;
	struct ldb_val rdn_val;
	struct ldb_message *msg;
	int ret;

	ac = talloc_get_type(req->context, struct rename_context);
	ldb = ldb_module_get_ctx(ac->module);

	if (!ares) {
		goto error;
	}
	if (ares->error != LDB_SUCCESS) {
		return ldb_module_done(ac->req, ares->controls,
					ares->response, ares->error);
	}

	/* the only supported reply right now is a LDB_REPLY_DONE */
	if (ares->type != LDB_REPLY_DONE) {
		goto error;
	}

	/* save reply for caller */
	ac->ares = talloc_steal(ac, ares);

	msg = ldb_msg_new(ac);
	if (msg == NULL) {
		goto error;
	}
	msg->dn = ldb_dn_copy(msg, ac->req->op.rename.newdn);
	if (msg->dn == NULL) {
		goto error;
	}
	rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn);
	if (rdn_name == NULL) {
		goto error;
	}
	
	rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(ac->req->op.rename.newdn));
	
	if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) {
		goto error;
	}
	if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) {
		goto error;
	}
	if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) {
		goto error;
	}
	if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) {
		goto error;
	}

	ret = ldb_build_mod_req(&mod_req, ldb,
				ac, msg, NULL,
				ac, rdn_modify_callback,
				req);
	if (ret != LDB_SUCCESS) {
		return ldb_module_done(ac->req, NULL, NULL, ret);
	}
	talloc_steal(mod_req, msg);

	/* go on with the call chain */
	return ldb_next_request(ac->module, mod_req);

error:
	return ldb_module_done(ac->req, NULL, NULL,
						 LDB_ERR_OPERATIONS_ERROR);
}
示例#29
0
文件: acl.c 项目: 0x24bin/winexe-1
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);
}
示例#30
0
文件: util.c 项目: endisd/samba
/*
  search for attrs on one DN, in the modules below
 */
int dsdb_module_search_dn(struct ldb_module *module,
			  TALLOC_CTX *mem_ctx,
			  struct ldb_result **_res,
			  struct ldb_dn *basedn,
			  const char * const *attrs,
			  uint32_t dsdb_flags)
{
	int ret;
	struct ldb_request *req;
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;

	tmp_ctx = talloc_new(mem_ctx);

	res = talloc_zero(tmp_ctx, struct ldb_result);
	if (!res) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
				   basedn,
				   LDB_SCOPE_BASE,
				   NULL,
				   attrs,
				   NULL,
				   res,
				   ldb_search_default_callback,
				   NULL);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	ret = dsdb_request_add_controls(module, req, dsdb_flags);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

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

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

	if (res->count != 1) {
		/* we may be reading a DB that does not have the 'check base on search' option... */
		ret = LDB_ERR_NO_SUCH_OBJECT;
		ldb_asprintf_errstring(ldb_module_get_ctx(module), 
				       "dsdb_module_search_dn: did not find base dn %s (%d results)", 
				       ldb_dn_get_linearized(basedn), res->count);
	} else {
		*_res = talloc_steal(mem_ctx, res);
	}
	talloc_free(tmp_ctx);
	return ret;
}