📄 samr_accessmask.c
字号:
} return ret;}/* * test if the ACLs are enforced for users. * a normal testuser only gets the rights provided in hte ACL for * Everyone which does not include the SAMR_ACCESS_SHUTDOWN_SERVER * right. If the ACLs are checked when a user connects * a testuser that requests the accessmask with only this bit set * the connect should fail. */static bool test_samr_connect_user_acl_enforced(struct torture_context *tctx, struct dcerpc_pipe *p, struct cli_credentials *test_credentials, const struct dom_sid *test_sid){ NTSTATUS status; struct policy_handle uch; bool ret = true; struct dcerpc_pipe *test_p; const char *binding = torture_setting_string(tctx, "binding", NULL); printf("testing if ACLs are enforced for non domain admin users when connecting to SAMR"); status = dcerpc_pipe_connect(tctx, &test_p, binding, &ndr_table_samr, test_credentials, NULL, tctx->lp_ctx); /* connect to SAMR as the user */ status = torture_samr_Connect5(tctx, test_p, SAMR_ACCESS_SHUTDOWN_SERVER, &uch); if (NT_STATUS_IS_OK(status)) { printf("Connect5 failed - %s\n", nt_errstr(status)); return false; } printf(" OK\n"); /* disconnec the user */ talloc_free(test_p); return ret;}/* check which bits in accessmask allows us to LookupDomain() by default we must specify at least one of : in the access mask to Connect5() in order to be allowed to perform case 5: samr/opendomain case 25: Maximum case 28: GenericAll case 29: GenericExecute LookupDomain() on the policy handle returned from Connect5()*/static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx, struct dcerpc_pipe *p){ NTSTATUS status; struct samr_LookupDomain ld; struct policy_handle ch; struct lsa_String dn; int i; uint32_t mask; printf("testing which bits in Connect5 accessmask allows us to LookupDomain\n"); mask = 1; for (i=0;i<33;i++) { printf("testing Connect5/LookupDomain with access mask 0x%08x", mask); status = torture_samr_Connect5(tctx, p, mask, &ch); mask <<= 1; switch (i) { case 5: case 25: /* Maximum */ case 28: /* GenericAll */ case 29: /* GenericExecute */ /* these bits set are expected to succeed by default */ if (!NT_STATUS_IS_OK(status)) { printf("Connect5 failed - %s\n", nt_errstr(status)); return false; } ld.in.connect_handle = &ch; ld.in.domain_name = &dn; dn.string = lp_workgroup(tctx->lp_ctx); status = dcerpc_samr_LookupDomain(p, tctx, &ld); if (!NT_STATUS_IS_OK(status)) { printf("LookupDomain failed - %s\n", nt_errstr(status)); return false; } status = torture_samr_Close(tctx, p, &ch); if (!NT_STATUS_IS_OK(status)) { printf("Close failed - %s\n", nt_errstr(status)); return false; } break; default: printf(" expecting to fail"); if (!NT_STATUS_IS_OK(status)) { printf(" OK\n"); continue; } ld.in.connect_handle = &ch; ld.in.domain_name = &dn; dn.string = lp_workgroup(tctx->lp_ctx); status = dcerpc_samr_LookupDomain(p, tctx, &ld); if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) { printf("LookupDomain failed - %s\n", nt_errstr(status)); return false; } status = torture_samr_Close(tctx, p, &ch); if (!NT_STATUS_IS_OK(status)) { printf("Close failed - %s\n", nt_errstr(status)); return false; } break; } printf(" OK\n"); } return true;}/* check which bits in accessmask allows us to OpenDomain() by default we must specify at least one of : samr/opendomain Maximum GenericAll GenericExecute in the access mask to Connect5() in order to be allowed to perform OpenDomain() on the policy handle returned from Connect5()*/static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx, struct dcerpc_pipe *p){ NTSTATUS status; struct samr_LookupDomain ld; struct samr_OpenDomain od; struct policy_handle ch; struct policy_handle dh; struct lsa_String dn; int i; uint32_t mask; /* first we must grab the sid of the domain */ status = torture_samr_Connect5(tctx, p, SEC_FLAG_MAXIMUM_ALLOWED, &ch); if (!NT_STATUS_IS_OK(status)) { printf("Connect5 failed - %s\n", nt_errstr(status)); return false; } ld.in.connect_handle = &ch; ld.in.domain_name = &dn; dn.string = lp_workgroup(tctx->lp_ctx); status = dcerpc_samr_LookupDomain(p, tctx, &ld); if (!NT_STATUS_IS_OK(status)) { printf("LookupDomain failed - %s\n", nt_errstr(status)); return false; } printf("testing which bits in Connect5 accessmask allows us to OpenDomain\n"); mask = 1; for (i=0;i<33;i++) { printf("testing Connect5/OpenDomain with access mask 0x%08x", mask); status = torture_samr_Connect5(tctx, p, mask, &ch); mask <<= 1; switch (i) { case 5: case 25: /* Maximum */ case 28: /* GenericAll */ case 29: /* GenericExecute */ /* these bits set are expected to succeed by default */ if (!NT_STATUS_IS_OK(status)) { printf("Connect5 failed - %s\n", nt_errstr(status)); return false; } od.in.connect_handle = &ch; od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; od.in.sid = ld.out.sid; od.out.domain_handle = &dh; status = dcerpc_samr_OpenDomain(p, tctx, &od); if (!NT_STATUS_IS_OK(status)) { printf("OpenDomain failed - %s\n", nt_errstr(status)); return false; } status = torture_samr_Close(tctx, p, &dh); if (!NT_STATUS_IS_OK(status)) { printf("Close failed - %s\n", nt_errstr(status)); return false; } status = torture_samr_Close(tctx, p, &ch); if (!NT_STATUS_IS_OK(status)) { printf("Close failed - %s\n", nt_errstr(status)); return false; } break; default: printf(" expecting to fail"); if (!NT_STATUS_IS_OK(status)) { printf(" OK\n"); continue; } status = torture_samr_Close(tctx, p, &ch); if (!NT_STATUS_IS_OK(status)) { printf("Close failed - %s\n", nt_errstr(status)); return false; } break; } printf(" OK\n"); } return true;}static bool test_samr_connect(struct torture_context *tctx, struct dcerpc_pipe *p){ void *testuser; const char *testuser_passwd; struct cli_credentials *test_credentials; bool ret = true; const struct dom_sid *test_sid; /* create a test user */ testuser = torture_create_testuser(tctx, TEST_USER_NAME, lp_workgroup(tctx->lp_ctx), ACB_NORMAL, &testuser_passwd); if (!testuser) { printf("Failed to create test user\n"); return false; } test_credentials = cli_credentials_init(tctx); cli_credentials_set_workstation(test_credentials, "localhost", CRED_SPECIFIED); cli_credentials_set_domain(test_credentials, lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED); cli_credentials_set_username(test_credentials, TEST_USER_NAME, CRED_SPECIFIED); cli_credentials_set_password(test_credentials, testuser_passwd, CRED_SPECIFIED); test_sid = torture_join_user_sid(testuser); /* test which bits in the accessmask to Connect5 will allow us to connect to the server */ if (!test_samr_accessmask_Connect5(tctx, p)) { ret = false; } /* test which bits in the accessmask to Connect5 will allow * us to call EnumDomains() */ if (!test_samr_accessmask_EnumDomains(tctx, p)) { ret = false; } /* test which bits in the accessmask to Connect5 will allow * us to call LookupDomain() */ if (!test_samr_accessmask_LookupDomain(tctx, p)) { ret = false; } /* test which bits in the accessmask to Connect5 will allow * us to call OpenDomain() */ if (!test_samr_accessmask_OpenDomain(tctx, p)) { ret = false; } /* test if ACLs can be changed for the policy handle * returned by Connect5 */ if (!test_samr_connect_user_acl(tctx, p, test_credentials, test_sid)) { ret = false; } /* test if the ACLs that are reported from the Connect5 * policy handle is enforced. * i.e. an ordinary user only has the same rights as Everybody * ReadControl * Samr/OpenDomain * Samr/EnumDomains * Samr/ConnectToServer * is granted and should therefore not be able to connect when * requesting SAMR_ACCESS_SHUTDOWN_SERVER */ if (!test_samr_connect_user_acl_enforced(tctx, p, test_credentials, test_sid)) { ret = false; } /* remove the test user */ torture_leave_domain(testuser); return ret;}struct torture_suite *torture_rpc_samr_accessmask(TALLOC_CTX *mem_ctx){ struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR_ACCESSMASK"); struct torture_rpc_tcase *tcase; tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr); torture_rpc_tcase_add_test(tcase, "CONNECT", test_samr_connect); return suite;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -