diff options
Diffstat (limited to 'source4')
| -rw-r--r-- | source4/lib/registry/ldb.c | 143 | 
1 files changed, 116 insertions, 27 deletions
diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 0c8a55396e..31b78d8246 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -440,33 +440,6 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,  	return WERR_OK;  } -static WERROR ldb_del_key(const struct hive_key *key, const char *name) -{ -	int ret; -	struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); -	struct ldb_dn *ldap_path; -	TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key"); - -	ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL); - -	ret = ldb_delete(parentkd->ldb, ldap_path); - -	talloc_free(mem_ctx); - -	if (ret == LDB_ERR_NO_SUCH_OBJECT) { -		return WERR_BADFILE; -	} else if (ret != LDB_SUCCESS) { -		DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb))); -		return WERR_FOOBAR; -	} - -	/* reset cache */ -	talloc_free(parentkd->subkeys); -	parentkd->subkeys = NULL; - -	return WERR_OK; -} -  static WERROR ldb_del_value (struct hive_key *key, const char *child)  {  	int ret; @@ -499,6 +472,122 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child)  	return WERR_OK;  } +static WERROR ldb_del_key(const struct hive_key *key, const char *name) +{ +	int i, ret; +	struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); +	struct ldb_dn *ldap_path; +	TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key"); +	struct ldb_context *c = parentkd->ldb; +	struct ldb_result *res_keys; +	struct ldb_result *res_vals; +	WERROR werr; +	struct hive_key *hk; + +	/* Verify key exists by opening it */ +	werr = ldb_open_key(mem_ctx, key, name, &hk); +	if (!W_ERROR_IS_OK(werr)) { +		talloc_free(mem_ctx); +		return werr; +	} + +	ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL); +	if (!ldap_path) { +		talloc_free(mem_ctx); +		return WERR_FOOBAR; +	} + +	/* Search for subkeys */ +	ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL, +			 "(key=*)", NULL, &res_keys); + +	if (ret != LDB_SUCCESS) { +		DEBUG(0, ("Error getting subkeys for '%s': %s\n", +		      ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); +		talloc_free(mem_ctx); +		return WERR_FOOBAR; +	} + +	/* Search for values */ +	ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL, +			 "(value=*)", NULL, &res_vals); + +	if (ret != LDB_SUCCESS) { +		DEBUG(0, ("Error getting values for '%s': %s\n", +		      ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); +		talloc_free(mem_ctx); +		return WERR_FOOBAR; +	} + +	/* Start an explicit transaction */ +	ret = ldb_transaction_start(c); + +	if (ret != LDB_SUCCESS) { +		DEBUG(0, ("ldb_transaction_start: %s\n", ldb_errstring(c))); +		talloc_free(mem_ctx); +		return WERR_FOOBAR; +	} + +	if (res_keys->count || res_vals->count) +	{ +		/* Delete any subkeys */ +		for (i = 0; i < res_keys->count; i++) +		{ +			werr = ldb_del_key(hk, ldb_msg_find_attr_as_string( +							res_keys->msgs[i], +							"key", NULL)); +			if (!W_ERROR_IS_OK(werr)) { +				ret = ldb_transaction_cancel(c); +				talloc_free(mem_ctx); +				return werr; +			} +		} + +		/* Delete any values */ +		for (i = 0; i < res_vals->count; i++) +		{ +			werr = ldb_del_value(hk, ldb_msg_find_attr_as_string( +							res_vals->msgs[i], +							"value", NULL)); +			if (!W_ERROR_IS_OK(werr)) { +				ret = ldb_transaction_cancel(c); +				talloc_free(mem_ctx); +				return werr; +			} +		} +	} + +	/* Delete the key itself */ +	ret = ldb_delete(c, ldap_path); + +	if (ret != LDB_SUCCESS) +	{ +		DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(c))); +		ret = ldb_transaction_cancel(c); +		talloc_free(mem_ctx); +		return WERR_FOOBAR; +	} + +	/* Commit the transaction */ +	ret = ldb_transaction_commit(c); + +	if (ret != LDB_SUCCESS) +	{ +		DEBUG(0, ("ldb_transaction_commit: %s\n", ldb_errstring(c))); +		ret = ldb_transaction_cancel(c); +		talloc_free(mem_ctx); +		return WERR_FOOBAR; +	} + +	talloc_free(mem_ctx); + +	/* reset cache */ +	talloc_free(parentkd->subkeys); +	parentkd->subkeys = NULL; + +	return WERR_OK; +} +  static WERROR ldb_set_value(struct hive_key *parent,  			    const char *name, uint32_t type,  			    const DATA_BLOB data)  | 
