[SCM] Samba Shared Repository - branch master updated - tevent-0-9-8-929-ge218a52

Simo Sorce idra at samba.org
Fri Oct 2 15:35:39 MDT 2009


Matthias,
if I am reading this right, you are using a module global variable to
set a per request state.
Unless I am completely mistaken (possible it's late here), then this is
a race condition waiting to happen.

If I am reading it wrong I'd like to know where my reasoning fails.

Simo.


This is the code I've read:

On Fri, 2009-10-02 at 14:30 -0500, Matthias Dieter Wallnöfer wrote:
> diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c
> index 5269a6a..888f355 100644
> --- a/source4/lib/ldb/modules/rdn_name.c
> +++ b/source4/lib/ldb/modules/rdn_name.c
> @@ -3,6 +3,7 @@
>  
>     Copyright (C) Andrew Bartlett 2005-2009
>     Copyright (C) Simo Sorce 2006-2008
> +   Copyright (C) Matthias Dieter Wallnöfer 2009
>  
>       ** NOTE! The following LGPL license applies to the ldb
>       ** library. This does NOT imply that all of Samba is released
> @@ -39,14 +40,33 @@
>  #include "ldb_includes.h"
>  #include "ldb_module.h"
>  
> -struct rename_context {
> +struct rdn_name_private {
> +	/* rename operation? */
> +	bool rename;
> +};
>  
> +struct rename_context {
>  	struct ldb_module *module;
>  	struct ldb_request *req;
>  
>  	struct ldb_reply *ares;
>  };
>  
> +static int rdn_name_init(struct ldb_module *module)
> +{
> +	struct rdn_name_private *rdn_name_private;
> +	struct ldb_context *ldb = ldb_module_get_ctx(module);
> +
> +	rdn_name_private = talloc_zero(module, struct rdn_name_private);
> +	if (rdn_name_private == NULL) {
> +		ldb_oom(ldb);
> +		return LDB_ERR_OPERATIONS_ERROR;
> +	}
> +	ldb_module_set_private(module, rdn_name_private);
> +
> +	return ldb_next_init(module);
> +}
> +
>  static struct ldb_message_element *rdn_name_find_attribute(const struct ldb_message *msg, const char *name)
>  {
>  	int i;
> @@ -115,6 +135,7 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
>  
>  	msg = ldb_msg_copy_shallow(req, req->op.add.message);
>  	if (msg == NULL) {
> +		talloc_free(ac);
>  		return LDB_ERR_OPERATIONS_ERROR;
>  	}
>  
> @@ -179,6 +200,7 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
>  				ac, rdn_name_add_callback,
>  				req);
>  	if (ret != LDB_SUCCESS) {
> +		talloc_free(ac);
>  		return ret;
>  	}
>  
> @@ -190,9 +212,15 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
>  
>  static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
>  {
> +	struct rdn_name_private *rdn_name_private;
>  	struct rename_context *ac;
>  
>  	ac = talloc_get_type(req->context, struct rename_context);
> +	rdn_name_private = talloc_get_type(ldb_module_get_private(ac->module),
> +						struct rdn_name_private);
> +
> +	/* our rename is finished */
> +	rdn_name_private->rename = false;
>  
>  	if (!ares) {
>  		return ldb_module_done(ac->req, NULL, NULL,
> @@ -216,8 +244,9 @@ static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
>  
>  static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
>  {
> -	struct ldb_context *ldb;
> +	struct rdn_name_private *rdn_name_private;
>  	struct rename_context *ac;
> +	struct ldb_context *ldb;
>  	struct ldb_request *mod_req;
>  	const char *rdn_name;
>  	struct ldb_val rdn_val;
> @@ -226,6 +255,8 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
>  
>  	ac = talloc_get_type(req->context, struct rename_context);
>  	ldb = ldb_module_get_ctx(ac->module);
> +	rdn_name_private = talloc_get_type(ldb_module_get_private(ac->module),
> +						struct rdn_name_private);
>  
>  	if (!ares) {
>  		goto error;
> @@ -271,6 +302,9 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
>  		goto error;
>  	}
>  
> +	/* we do a rename */
> +	rdn_name_private->rename = true;
> +
>  	ret = ldb_build_mod_req(&mod_req, ldb,
>  				ac, msg, NULL,
>  				ac, rdn_modify_callback,
> @@ -322,7 +356,8 @@ static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req)
>  				   req);
>  
>  	if (ret != LDB_SUCCESS) {
> -		return LDB_ERR_OPERATIONS_ERROR;
> +		talloc_free(ac);
> +		return ret;
>  	}
>  
>  	/* rename first, modify "name" if rename is ok */
> @@ -331,6 +366,8 @@ static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req)
>  
>  static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req)
>  {
> +	struct rdn_name_private *rdn_name_private =
> +		talloc_get_type(ldb_module_get_private(module), struct rdn_name_private);
>  	struct ldb_context *ldb;
>  
>  	ldb = ldb_module_get_ctx(module);
> @@ -341,13 +378,15 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req)
>  		return ldb_next_request(module, req);
>  	}
>  
> -	if (ldb_msg_find_element(req->op.mod.message, "name")) {
> +	if ((!rdn_name_private->rename)
> +			&& 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))) {
> +	if ((!rdn_name_private->rename)
> +			&& 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;
> @@ -359,7 +398,8 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req)
>  
>  const struct ldb_module_ops ldb_rdn_name_module_ops = {
>  	.name              = "rdn_name",
> +	.init_context	   = rdn_name_init,
>  	.add               = rdn_name_add,
>  	.modify            = rdn_name_modify,
> -	.rename            = rdn_name_rename,
> +	.rename            = rdn_name_rename
>  };




More information about the samba-technical mailing list