summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2009-05-18 19:37:13 +0200
committerGünther Deschner <gd@samba.org>2009-05-18 22:54:14 +0200
commit0a9049be872a0eaf56c1449f8b362b6d91dd781b (patch)
tree76856cbbbbeed90675b3d34e072ef9ed39e0d41c
parent5fb3b8e377deeb0ce362a7bcb9323542b579fdef (diff)
downloadsamba-0a9049be872a0eaf56c1449f8b362b6d91dd781b.tar.gz
samba-0a9049be872a0eaf56c1449f8b362b6d91dd781b.tar.bz2
samba-0a9049be872a0eaf56c1449f8b362b6d91dd781b.zip
s4-smbtorture: add RPC-SAMR-USERS-PRIVILEGES test.
This test demonstrates the independence of the lsa and samr accounts while remove a samr users that still has privileges granted. Guenther
-rw-r--r--source4/torture/rpc/rpc.c1
-rw-r--r--source4/torture/rpc/samr.c395
2 files changed, 387 insertions, 9 deletions
diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c
index 647d51470d..48a488741f 100644
--- a/source4/torture/rpc/rpc.c
+++ b/source4/torture/rpc/rpc.c
@@ -408,6 +408,7 @@ NTSTATUS torture_rpc_init(void)
torture_suite_add_suite(suite, torture_rpc_svcctl(suite));
torture_suite_add_suite(suite, torture_rpc_samr_accessmask(suite));
torture_suite_add_suite(suite, torture_rpc_samr_passwords_pwdlastset(suite));
+ torture_suite_add_suite(suite, torture_rpc_samr_user_privileges(suite));
torture_suite_add_suite(suite, torture_rpc_epmapper(suite));
torture_suite_add_suite(suite, torture_rpc_initshutdown(suite));
torture_suite_add_suite(suite, torture_rpc_oxidresolve(suite));
diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
index c1535577d6..4037e6b11c 100644
--- a/source4/torture/rpc/samr.c
+++ b/source4/torture/rpc/samr.c
@@ -4,6 +4,7 @@
Copyright (C) Andrew Tridgell 2003
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
+ Copyright (C) Guenther Deschner 2008,2009
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,6 +27,7 @@
#include "librpc/gen_ndr/ndr_netlogon.h"
#include "librpc/gen_ndr/ndr_netlogon_c.h"
#include "librpc/gen_ndr/ndr_samr_c.h"
+#include "librpc/gen_ndr/ndr_lsa_c.h"
#include "../lib/crypto/crypto.h"
#include "libcli/auth/libcli_auth.h"
#include "libcli/security/security.h"
@@ -45,6 +47,7 @@ enum torture_samr_choice {
TORTURE_SAMR_PASSWORDS,
TORTURE_SAMR_PASSWORDS_PWDLASTSET,
TORTURE_SAMR_USER_ATTRIBUTES,
+ TORTURE_SAMR_USER_PRIVILEGES,
TORTURE_SAMR_OTHER
};
@@ -70,6 +73,11 @@ static void init_lsa_String(struct lsa_String *string, const char *s)
string->string = s;
}
+static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
+{
+ string->string = s;
+}
+
static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
{
string->length = length;
@@ -3267,10 +3275,307 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
return ret;
}
+static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
+ struct dcerpc_pipe *lp,
+ struct torture_context *tctx,
+ struct policy_handle *domain_handle,
+ struct policy_handle *lsa_handle,
+ struct policy_handle *user_handle,
+ const struct dom_sid *domain_sid,
+ uint32_t rid,
+ struct cli_credentials *machine_credentials)
+{
+ NTSTATUS status;
+ bool ret = true;
+
+ struct policy_handle lsa_acct_handle;
+ struct dom_sid *user_sid;
+
+ user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
+
+ {
+ struct lsa_EnumAccountRights r;
+ struct lsa_RightSet rights;
+
+ printf("Testing LSA EnumAccountRights\n");
+
+ r.in.handle = lsa_handle;
+ r.in.sid = user_sid;
+ r.out.rights = &rights;
+
+ status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
+ torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
+ "Expected enum rights for account to fail");
+ }
+
+ {
+ struct lsa_RightSet rights;
+ struct lsa_StringLarge names[2];
+ struct lsa_AddAccountRights r;
+
+ printf("Testing LSA AddAccountRights\n");
+
+ init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
+ init_lsa_StringLarge(&names[1], NULL);
+
+ rights.count = 1;
+ rights.names = names;
+
+ r.in.handle = lsa_handle;
+ r.in.sid = user_sid;
+ r.in.rights = &rights;
+
+ status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to add privileges");
+ }
+
+ {
+ struct lsa_EnumAccounts r;
+ uint32_t resume_handle = 0;
+ struct lsa_SidArray lsa_sid_array;
+ int i;
+ bool found_sid = false;
+
+ printf("Testing LSA EnumAccounts\n");
+
+ r.in.handle = lsa_handle;
+ r.in.num_entries = 0x1000;
+ r.in.resume_handle = &resume_handle;
+ r.out.sids = &lsa_sid_array;
+ r.out.resume_handle = &resume_handle;
+
+ status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to enum accounts");
+
+ for (i=0; i < lsa_sid_array.num_sids; i++) {
+ if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
+ found_sid = true;
+ }
+ }
+
+ torture_assert(tctx, found_sid,
+ "failed to list privileged account");
+ }
+
+ {
+ struct lsa_EnumAccountRights r;
+ struct lsa_RightSet user_rights;
+
+ printf("Testing LSA EnumAccountRights\n");
+
+ r.in.handle = lsa_handle;
+ r.in.sid = user_sid;
+ r.out.rights = &user_rights;
+
+ status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to enum rights for account");
+
+ if (user_rights.count < 1) {
+ torture_warning(tctx, "failed to find newly added rights");
+ return false;
+ }
+ }
+
+ {
+ struct lsa_OpenAccount r;
+
+ printf("Testing LSA OpenAccount\n");
+
+ r.in.handle = lsa_handle;
+ r.in.sid = user_sid;
+ r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ r.out.acct_handle = &lsa_acct_handle;
+
+ status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to open lsa account");
+ }
+
+ {
+ struct lsa_GetSystemAccessAccount r;
+ uint32_t access_mask;
+
+ printf("Testing LSA GetSystemAccessAccount\n");
+
+ r.in.handle = &lsa_acct_handle;
+ r.out.access_mask = &access_mask;
+
+ status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to get lsa system access account");
+ }
+
+ {
+ struct lsa_Close r;
+
+ printf("Testing LSA Close\n");
+
+ r.in.handle = &lsa_acct_handle;
+ r.out.handle = &lsa_acct_handle;
+
+ status = dcerpc_lsa_Close(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to close lsa");
+ }
+
+ {
+ struct samr_DeleteUser r;
+
+ printf("Testing SAMR DeleteUser\n");
+
+ r.in.user_handle = user_handle;
+ r.out.user_handle = user_handle;
+
+ status = dcerpc_samr_DeleteUser(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
+ }
+
+ {
+ struct lsa_EnumAccounts r;
+ uint32_t resume_handle = 0;
+ struct lsa_SidArray lsa_sid_array;
+ int i;
+ bool found_sid = false;
+
+ printf("Testing LSA EnumAccounts\n");
+
+ r.in.handle = lsa_handle;
+ r.in.num_entries = 0x1000;
+ r.in.resume_handle = &resume_handle;
+ r.out.sids = &lsa_sid_array;
+ r.out.resume_handle = &resume_handle;
+
+ status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to enum accounts");
+
+ for (i=0; i < lsa_sid_array.num_sids; i++) {
+ if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
+ found_sid = true;
+ }
+ }
+
+ torture_assert(tctx, found_sid,
+ "failed to list privileged account");
+ }
+
+ {
+ struct lsa_EnumAccountRights r;
+ struct lsa_RightSet user_rights;
+
+ printf("Testing LSA EnumAccountRights\n");
+
+ r.in.handle = lsa_handle;
+ r.in.sid = user_sid;
+ r.out.rights = &user_rights;
+
+ status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to enum rights for account");
+
+ if (user_rights.count < 1) {
+ torture_warning(tctx, "failed to find newly added rights");
+ return false;
+ }
+ }
+
+ {
+ struct lsa_OpenAccount r;
+
+ printf("Testing LSA OpenAccount\n");
+
+ r.in.handle = lsa_handle;
+ r.in.sid = user_sid;
+ r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ r.out.acct_handle = &lsa_acct_handle;
+
+ status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to open lsa account");
+ }
+
+ {
+ struct lsa_GetSystemAccessAccount r;
+ uint32_t access_mask;
+
+ printf("Testing LSA GetSystemAccessAccount\n");
+
+ r.in.handle = &lsa_acct_handle;
+ r.out.access_mask = &access_mask;
+
+ status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to get lsa system access account");
+ }
+
+ {
+ struct lsa_DeleteObject r;
+
+ printf("Testing LSA DeleteObject\n");
+
+ r.in.handle = &lsa_acct_handle;
+ r.out.handle = &lsa_acct_handle;
+
+ status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to delete object");
+ }
+
+ {
+ struct lsa_EnumAccounts r;
+ uint32_t resume_handle = 0;
+ struct lsa_SidArray lsa_sid_array;
+ int i;
+ bool found_sid = false;
+
+ printf("Testing LSA EnumAccounts\n");
+
+ r.in.handle = lsa_handle;
+ r.in.num_entries = 0x1000;
+ r.in.resume_handle = &resume_handle;
+ r.out.sids = &lsa_sid_array;
+ r.out.resume_handle = &resume_handle;
+
+ status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "Failed to enum accounts");
+
+ for (i=0; i < lsa_sid_array.num_sids; i++) {
+ if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
+ found_sid = true;
+ }
+ }
+
+ torture_assert(tctx, !found_sid,
+ "should not have listed privileged account");
+ }
+
+ {
+ struct lsa_EnumAccountRights r;
+ struct lsa_RightSet user_rights;
+
+ printf("Testing LSA EnumAccountRights\n");
+
+ r.in.handle = lsa_handle;
+ r.in.sid = user_sid;
+ r.out.rights = &user_rights;
+
+ status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
+ torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
+ "Failed to enum rights for account");
+ }
+
+ return ret;
+}
+
static bool test_user_ops(struct dcerpc_pipe *p,
struct torture_context *tctx,
struct policy_handle *user_handle,
struct policy_handle *domain_handle,
+ const struct dom_sid *domain_sid,
uint32_t base_acct_flags,
const char *base_acct_name, enum torture_samr_choice which_ops,
struct cli_credentials *machine_credentials)
@@ -3469,6 +3774,35 @@ static bool test_user_ops(struct dcerpc_pipe *p,
break;
+ case TORTURE_SAMR_USER_PRIVILEGES: {
+
+ struct dcerpc_pipe *lp;
+ struct policy_handle *lsa_handle;
+
+ status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
+ torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
+
+ if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
+ ret = false;
+ }
+
+ if (!test_DeleteUser_with_privs(p, lp, tctx,
+ domain_handle, lsa_handle, user_handle,
+ domain_sid, rid,
+ machine_credentials)) {
+ ret = false;
+ }
+
+ if (!test_lsa_Close(lp, tctx, lsa_handle)) {
+ ret = false;
+ }
+
+ if (!ret) {
+ torture_warning(tctx, "privileged user delete test failed\n");
+ }
+
+ break;
+ }
case TORTURE_SAMR_OTHER:
/* We just need the account to exist */
break;
@@ -3959,7 +4293,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
}
if (!test_user_ops(p, tctx, &user_handle, domain_handle,
- acct_flags, name.string, which_ops,
+ domain_sid, acct_flags, name.string, which_ops,
machine_credentials)) {
ret = false;
}
@@ -4119,20 +4453,22 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
}
if (!test_user_ops(p, tctx, &user_handle, domain_handle,
- acct_flags, name.string, which_ops,
+ domain_sid, acct_flags, name.string, which_ops,
machine_credentials)) {
ret = false;
}
- printf("Testing DeleteUser (createuser2 test)\n");
+ if (!policy_handle_empty(&user_handle)) {
+ printf("Testing DeleteUser (createuser2 test)\n");
- d.in.user_handle = &user_handle;
- d.out.user_handle = &user_handle;
+ d.in.user_handle = &user_handle;
+ d.out.user_handle = &user_handle;
- status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
- if (!NT_STATUS_IS_OK(status)) {
- printf("DeleteUser failed - %s\n", nt_errstr(status));
- ret = false;
+ status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("DeleteUser failed - %s\n", nt_errstr(status));
+ ret = false;
+ }
}
}
talloc_free(user_ctx);
@@ -5719,6 +6055,7 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
switch (which_ops) {
case TORTURE_SAMR_USER_ATTRIBUTES:
+ case TORTURE_SAMR_USER_PRIVILEGES:
case TORTURE_SAMR_PASSWORDS:
if (!torture_setting_bool(tctx, "samba3", false)) {
ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
@@ -6127,3 +6464,43 @@ struct torture_suite *torture_rpc_samr_passwords_pwdlastset(struct torture_conte
return suite;
}
+
+static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
+ struct dcerpc_pipe *p2,
+ struct cli_credentials *machine_credentials)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p;
+ bool ret = true;
+ struct policy_handle handle;
+
+ status = torture_rpc_connection(torture, &p, &ndr_table_samr);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ ret &= test_Connect(p, torture, &handle);
+
+ ret &= test_EnumDomains(p, torture, &handle,
+ TORTURE_SAMR_USER_PRIVILEGES,
+ machine_credentials);
+
+ ret &= test_samr_handle_Close(p, torture, &handle);
+
+ return ret;
+}
+
+struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
+ struct torture_rpc_tcase *tcase;
+
+ tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
+ &ndr_table_samr,
+ TEST_ACCOUNT_NAME_PWD);
+
+ torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
+ torture_rpc_samr_users_privileges_delete_user);
+
+ return suite;
+}