[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha2-1195-g3d4cbae

Jelmer Vernooij jelmer at samba.org
Sun Mar 2 23:40:47 GMT 2008


The branch, v4-0-test has been updated
       via  3d4cbaeec6eafc0fec06ba472ac2bd55ae3a0d11 (commit)
       via  f98b59021a5ea39c7970ebc5520d17775e500b8c (commit)
       via  67facda6368eeda88d312f2836a1fdae4a1f605a (commit)
       via  7b7aec9a2f0a684bb27761df71af506cce244b2c (commit)
       via  3885acdee6fa3ec33cf4824826c2b8a98721382c (commit)
       via  d015e595ca82f8fd3941753c00a2f3d816300be9 (commit)
       via  5e905804993df4c2ac28090d056e6db6bb63ac44 (commit)
       via  b0321bad290d1a9399b4aba140a622e3af6d7575 (commit)
       via  6b5fbf7e4e38342bcd80e63f46cd295f89ab1ee9 (commit)
       via  ca796c8fb10598674a5eef31d15863e79bcf3db8 (commit)
      from  4f40c5940b4aa4343152cf367566d4d26765e234 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit 3d4cbaeec6eafc0fec06ba472ac2bd55ae3a0d11
Merge: f98b59021a5ea39c7970ebc5520d17775e500b8c 4f40c5940b4aa4343152cf367566d4d26765e234
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Mar 3 00:40:01 2008 +0100

    Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test

commit f98b59021a5ea39c7970ebc5520d17775e500b8c
Merge: 67facda6368eeda88d312f2836a1fdae4a1f605a 5972308add8b1078e190beab204c1ba4b3a25747
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Mar 3 00:23:09 2008 +0100

    Merge branch 'v4-0-test' into id10ts-registry

commit 67facda6368eeda88d312f2836a1fdae4a1f605a
Author: Andrew Kroeger <andrew at sprocks.gotdns.com>
Date:   Tue Feb 26 21:23:45 2008 -0600

    samba4-knownfail: Only the "*-security" rpc-winreg tests are expected to fail.

commit 7b7aec9a2f0a684bb27761df71af506cce244b2c
Author: Andrew Kroeger <andrew at sprocks.gotdns.com>
Date:   Tue Feb 19 09:18:10 2008 -0600

    torture/rpc-winreg: Split out the security descriptor tests.
    
    The security descriptor functionality has not been implemented yet.  Now that
    the other tests run successfully, the security descriptor tests have been split
    out so they can be separately marked as knownfail.
    
    The tests that test security descriptor functionality are named "*-security",
    while those that don't are named "*-basic".

commit 3885acdee6fa3ec33cf4824826c2b8a98721382c
Author: Andrew Kroeger <andrew at sprocks.gotdns.com>
Date:   Tue Feb 19 09:13:14 2008 -0600

    torture/rpc-winreg: Modify test cases to work with recursive key deletion.

commit d015e595ca82f8fd3941753c00a2f3d816300be9
Author: Andrew Kroeger <andrew at sprocks.gotdns.com>
Date:   Tue Feb 19 09:03:32 2008 -0600

    torture/rpc-winreg: General fixes for a number of tests.
    
    Cleaned up issues with tests being run without the correct state being setup.
    Also corrected an issue with a test expecting the wrong return value to indicate
    a successful test run.

commit 5e905804993df4c2ac28090d056e6db6bb63ac44
Author: Andrew Kroeger <andrew at sprocks.gotdns.com>
Date:   Sat Feb 16 15:21:26 2008 -0600

    registry: Add an explicit test for recursive deletion.

commit b0321bad290d1a9399b4aba140a622e3af6d7575
Author: Andrew Kroeger <andrew at sprocks.gotdns.com>
Date:   Sat Feb 16 15:19:00 2008 -0600

    registry: Implement recursive deletes for regf-backed registry.
    
    When deleting a registry key that contains subkeys or values, Windows performs a
    recursive deletion that removes any subkeys or values.  This update makes
    deletes for an regf-backed registry consistent with Windows.
    
    The regf-backed registry does not have transactional integrity when performing
    multiple operations.  Therefore, if an error occurs during the recursive
    deletion, the regf-backed registry may be left in an inconsistent state.

commit 6b5fbf7e4e38342bcd80e63f46cd295f89ab1ee9
Author: Andrew Kroeger <andrew at sprocks.gotdns.com>
Date:   Sat Feb 16 15:15:50 2008 -0600

    registry: Implement recursive deletes for dir-backed registry.
    
    When deleting a registry key that contains subkeys or values, Windows performs a
    recursive deletion that removes any subkeys or values.  This update makes
    deletes for an dir-backed registry consistent with Windows.
    
    The dir-backed registry relies on the underlying filesystem, which does not
    generally have transactional integrity when performing multiple operations.
    Therefore, if an error occurs during the recursive deletion, the dir-backed
    registry may be left in an inconsistent state.

commit ca796c8fb10598674a5eef31d15863e79bcf3db8
Author: Andrew Kroeger <andrew at sprocks.gotdns.com>
Date:   Sat Feb 16 15:08:28 2008 -0600

    registry: Implement recursive deletes for ldb-backed registry.
    
    When deleting a registry key that contains subkeys or values, Windows performs a
    recursive deletion that removes any subkeys or values.  This update makes
    deletes for an ldb-backed registry consistent with Windows.
    
    Under ldb, the deletion is done using an explicit transaction.  If an error
    occurs during the deletion the entire transaction is cancelled, leaving the
    registry as it was before the deletions started.

-----------------------------------------------------------------------

Summary of changes:
 source/lib/registry/dir.c        |   60 +++++++++-
 source/lib/registry/ldb.c        |  143 +++++++++++++++++++-----
 source/lib/registry/regf.c       |   53 ++++++++-
 source/lib/registry/tests/hive.c |   37 ++++++
 source/samba4-knownfail          |    2 +-
 source/torture/rpc/winreg.c      |  230 +++++++++++++++++++++-----------------
 6 files changed, 383 insertions(+), 142 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/lib/registry/dir.c b/source/lib/registry/dir.c
index 27cae8c..dc3717e 100644
--- a/source/lib/registry/dir.c
+++ b/source/lib/registry/dir.c
@@ -55,18 +55,66 @@ static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx,
 	return WERR_GENERAL_FAILURE;
 }
 
+static WERROR reg_dir_delete_recursive(const char *name)
+{
+	DIR *d;
+	struct dirent *e;
+	WERROR werr;
+
+	d = opendir(name);
+	if (d == NULL) {
+		DEBUG(3,("Unable to open '%s': %s\n", name,
+		      strerror(errno)));
+		return WERR_BADFILE;
+	}
+
+	while((e = readdir(d))) {
+		char *path;
+		struct stat stbuf;
+
+		if (ISDOT(e->d_name) || ISDOTDOT(e->d_name))
+			continue;
+
+		path = talloc_asprintf(name, "%s/%s", name, e->d_name);
+		if (!path)
+			return WERR_NOMEM;
+
+		stat(path, &stbuf);
+
+		if (!S_ISDIR(stbuf.st_mode)) {
+			if (unlink(path) < 0) {
+				talloc_free(path);
+				closedir(d);
+				return WERR_GENERAL_FAILURE;
+			}
+		} else {
+			werr = reg_dir_delete_recursive(path);
+			if (!W_ERROR_IS_OK(werr)) {
+				talloc_free(path);
+				closedir(d);
+				return werr;
+			}
+		}
+
+		talloc_free(path);
+	}
+	closedir(d);
+
+	if (rmdir(name) == 0)
+		return WERR_OK;
+	else if (errno == ENOENT)
+		return WERR_BADFILE;
+	else
+		return WERR_GENERAL_FAILURE;
+}
+
 static WERROR reg_dir_del_key(const struct hive_key *k, const char *name)
 {
 	struct dir_key *dk = talloc_get_type(k, struct dir_key);
 	char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name);
 	WERROR ret;
 
-	if (rmdir(child) == 0)
-		ret = WERR_OK;
-	else if (errno == ENOENT)
-		ret = WERR_BADFILE;
-	else
-		ret = WERR_GENERAL_FAILURE;
+	ret = reg_dir_delete_recursive(child);
 
 	talloc_free(child);
 
diff --git a/source/lib/registry/ldb.c b/source/lib/registry/ldb.c
index dfd368e..a764ca6 100644
--- a/source/lib/registry/ldb.c
+++ b/source/lib/registry/ldb.c
@@ -442,33 +442,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;
@@ -501,6 +474,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)
diff --git a/source/lib/registry/regf.c b/source/lib/registry/regf.c
index cf3e564..a192f3b 100644
--- a/source/lib/registry/regf.c
+++ b/source/lib/registry/regf.c
@@ -1618,10 +1618,55 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name)
 		return WERR_BADFILE;
 	}
 
-	if (key->nk->subkeys_offset != -1 ||
-		key->nk->values_offset != -1) {
-		DEBUG(0, ("Key '%s' is not empty.\n", name));
-		return WERR_FILE_EXISTS;
+	if (key->nk->subkeys_offset != -1) {
+		char *sk_name;
+		struct hive_key *sk = (struct hive_key *)key;
+		int i = key->nk->num_subkeys;
+		while (i--) {
+			/* Get subkey information. */
+			error = regf_get_subkey_by_index(parent_nk, sk, 0,
+							 (const char **)&sk_name,
+							 NULL, NULL);
+			if (!W_ERROR_IS_OK(error)) {
+				DEBUG(0, ("Can't retrieve subkey by index.\n"));
+				return error;
+			}
+
+			/* Delete subkey. */
+			error = regf_del_key(sk, sk_name);
+			if (!W_ERROR_IS_OK(error)) {
+				DEBUG(0, ("Can't delete key '%s'.\n", sk_name));
+				return error;
+			}
+
+			talloc_free(sk_name);
+		}
+	}
+
+	if (key->nk->values_offset != -1) {
+		char *val_name;
+		struct hive_key *sk = (struct hive_key *)key;
+		DATA_BLOB data;
+		int i = key->nk->num_values;
+		while (i--) {
+			/* Get value information. */
+			error = regf_get_value(parent_nk, sk, 0,
+					       (const char **)&val_name,
+					       NULL, &data);
+			if (!W_ERROR_IS_OK(error)) {
+				DEBUG(0, ("Can't retrieve value by index.\n"));
+				return error;
+			}
+
+			/* Delete value. */
+			error = regf_del_value(sk, val_name);
+			if (!W_ERROR_IS_OK(error)) {
+				DEBUG(0, ("Can't delete value '%s'.\n", val_name));
+				return error;
+			}
+
+			talloc_free(val_name);
+		}
 	}
 
 	/* Delete it from the subkey list. */
diff --git a/source/lib/registry/tests/hive.c b/source/lib/registry/tests/hive.c
index 1dcb464..1e56f12 100644
--- a/source/lib/registry/tests/hive.c
+++ b/source/lib/registry/tests/hive.c
@@ -111,6 +111,38 @@ static bool test_add_subkey(struct torture_context *tctx,
 	return true;
 }
 
+static bool test_del_recursive(struct torture_context *tctx,
+			       const void *test_data)
+{
+	WERROR error;
+	struct hive_key *subkey;
+	struct hive_key *subkey2;
+	const struct hive_key *root = (const struct hive_key *)test_data;
+	TALLOC_CTX *mem_ctx = tctx;
+	uint32_t data = 42;
+
+	/* Create a new key under the root */
+	error = hive_key_add_name(mem_ctx, root, "Parent Key", NULL,
+				  NULL, &subkey);
+	torture_assert_werr_ok(tctx, error, "hive_key_add_name");
+
+	/* Create a new key under "Parent Key" */
+	error = hive_key_add_name(mem_ctx, subkey, "Child Key", NULL,
+				  NULL, &subkey2);
+	torture_assert_werr_ok(tctx, error, "hive_key_add_name");
+
+	/* Create a new value under "Child Key" */
+	error = hive_key_set_value(subkey2, "Answer Recursive", REG_DWORD,
+			       data_blob_talloc(mem_ctx, &data, sizeof(data)));
+	torture_assert_werr_ok(tctx, error, "hive_key_set_value");
+
+	/* Deleting "Parent Key" will also delete "Child Key" and the value. */
+	error = hive_key_del(root, "Parent Key");
+	torture_assert_werr_ok(tctx, error, "hive_key_del");
+
+	return true;
+}
+
 static bool test_flush_key(struct torture_context *tctx, void *test_data)
 {
 	struct hive_key *root = (struct hive_key *)test_data;
@@ -273,6 +305,11 @@ static void tcase_add_tests(struct torture_tcase *tcase)
 						test_add_subkey);
 	torture_tcase_add_simple_test(tcase, "flush_key",
 						test_flush_key);
+	/* test_del_recursive() test must run before test_keyinfo_root().
+	   test_keyinfo_root() checks the number of subkeys, which verifies
+	   the recursive delete worked properly. */
+	torture_tcase_add_simple_test_const(tcase, "del_recursive",
+						test_del_recursive);
 	torture_tcase_add_simple_test_const(tcase, "get_info",
 						test_keyinfo_root);
 	torture_tcase_add_simple_test(tcase, "get_info_nums",
diff --git a/source/samba4-knownfail b/source/samba4-knownfail
index 4d850ca..e6a4ea1 100644
--- a/source/samba4-knownfail
+++ b/source/samba4-knownfail
@@ -3,7 +3,7 @@ local.iconv.*.next_codepoint()
 base.delaywrite.finfo update on close
 base.delete.*.deltest20a
 base.delete.*.deltest20b
-rpc.winreg
+rpc.winreg.*security
 local.registry.*.security # Not implemented yet
 rpc.wkssvc
 rpc.handles.*.lsarpc-shared
diff --git a/source/torture/rpc/winreg.c b/source/torture/rpc/winreg.c
index 4695733..8b602ef 100644
--- a/source/torture/rpc/winreg.c
+++ b/source/torture/rpc/winreg.c
@@ -848,7 +848,6 @@ static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
 
  out:
 	test_CloseKey(p, tctx, &new_handle);
-	test_Cleanup(p, tctx, handle, TEST_SUBSUBKEY_SD);
 	test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
 	test_RestoreSecurity(p, tctx, handle, key, sd_orig);
 
@@ -971,7 +970,6 @@ static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
 
  out:
 	test_CloseKey(p, tctx, &new_handle);
-	test_Cleanup(p, tctx, handle, TEST_SUBSUBKEY_SD);
 	test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
 	test_RestoreSecurity(p, tctx, handle, key, sd_orig);
 
@@ -1386,27 +1384,6 @@ static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
 	return true;
 }
 
-/* DeleteKey on a key with subkey(s) should
- * return WERR_ACCESS_DENIED. */
-static bool test_DeleteKeyWithSubkey(struct dcerpc_pipe *p,
-				     struct torture_context *tctx,
-				     struct policy_handle *handle,
-				     const char *key)
-{
-	struct winreg_DeleteKey r;
-
-	r.in.handle = handle;
-	init_winreg_String(&r.in.key, key);
-
-	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey(p, tctx, &r),
-				   "DeleteKeyWithSubkey failed");
-
-	torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
-				  "DeleteKeyWithSubkey failed");
-
-	return true;
-}
-
 static bool test_QueryInfoKey(struct dcerpc_pipe *p,
 			      struct torture_context *tctx,
 			      struct policy_handle *handle, char *class)
@@ -1443,10 +1420,12 @@ static bool test_QueryInfoKey(struct dcerpc_pipe *p,
 }
 
 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
-		     struct policy_handle *handle, int depth);
+		     struct policy_handle *handle, int depth,
+		     bool test_security);
 
 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
-			 struct policy_handle *handle, int depth)
+			 struct policy_handle *handle, int depth,
+			 bool test_security)
 {
 	struct winreg_EnumKey r;
 	struct winreg_StringBuf class, name;
@@ -1479,7 +1458,8 @@ static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
 			if (!test_OpenKey(p, tctx, handle, r.out.name->name,
 					  &key_handle)) {
 			} else {
-				test_key(p, tctx, &key_handle, depth + 1);
+				test_key(p, tctx, &key_handle,
+					 depth + 1, test_security);
 			}
 		}
 
@@ -1676,7 +1656,8 @@ static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
 #define MAX_DEPTH 2		/* Only go this far down the tree */
 
 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
-		     struct policy_handle *handle, int depth)
+		     struct policy_handle *handle, int depth,
+		     bool test_security)
 {
 	if (depth == MAX_DEPTH)
 		return true;
@@ -1687,10 +1668,10 @@ static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
 	if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
 	}
 
-	if (!test_GetKeySecurity(p, tctx, handle, NULL)) {
+	if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
 	}
 
-	if (!test_EnumKey(p, tctx, handle, depth)) {
+	if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
 	}
 
 	if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
@@ -1703,13 +1684,85 @@ static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
 
 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
 
+static bool test_Open_Security(struct torture_context *tctx,
+			       struct dcerpc_pipe *p, void *userdata)
+{
+	struct policy_handle handle, newhandle;
+	bool ret = true, created2 = false;
+	bool created4 = false;
+	struct winreg_OpenHKLM r;
+
+	winreg_open_fn open_fn = userdata;
+
+	r.in.system_name = 0;
+	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	r.out.handle = &handle;
+
+	torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
+				   "open");
+
+	test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
+
+	if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
+		torture_comment(tctx,
+				"CreateKey (TEST_KEY_BASE) failed\n");
+	}
+
+	if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
+			      NULL, &newhandle)) {
+		created2 = true;
+	}
+
+	if (created2 && !test_CloseKey(p, tctx, &newhandle)) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list