samr.c
来自「samba最新软件」· C语言 代码 · 共 2,122 行 · 第 1/5 页
C
2,122 行
old_nt_hash[0]--; E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); r.in.server = &server; r.in.account = &account; r.in.nt_password = &nt_pass; r.in.nt_verifier = &nt_verifier; r.in.lm_change = 1; r.in.lm_password = &lm_pass; r.in.lm_verifier = &lm_verifier; r.in.password3 = NULL; status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) && (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) { printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n", nt_errstr(status)); ret = false; } /* This shouldn't be a valid name */ init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string)); r.in.account = &account_bad; status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n", nt_errstr(status)); ret = false; } E_md4hash(oldpass, old_nt_hash); E_md4hash(newpass, new_nt_hash); E_deshash(oldpass, old_lm_hash); E_deshash(newpass, new_lm_hash); encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE); arcfour_crypt(lm_pass.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash); encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE); arcfour_crypt(nt_pass.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); r.in.server = &server; r.in.account = &account; r.in.nt_password = &nt_pass; r.in.nt_verifier = &nt_verifier; r.in.lm_change = 1; r.in.lm_password = &lm_pass; r.in.lm_verifier = &lm_verifier; r.in.password3 = NULL; unix_to_nt_time(&t, time(NULL)); status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r); if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) && r.out.dominfo && r.out.reject && handle_reject_reason && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) { if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) { if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", SAMR_REJECT_OTHER, r.out.reject->reason); return false; } } /* We tested the order of precendence which is as follows: * pwd min_age * pwd length * pwd complexity * pwd history Guenther */ if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) && (last_password_change + r.out.dominfo->min_password_age > t)) { if (r.out.reject->reason != SAMR_REJECT_OTHER) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", SAMR_REJECT_OTHER, r.out.reject->reason); return false; } } else if ((r.out.dominfo->min_password_length > 0) && (strlen(newpass) < r.out.dominfo->min_password_length)) { if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) { printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", SAMR_REJECT_TOO_SHORT, r.out.reject->reason); return false; } } else if ((r.out.dominfo->password_history_length > 0) && strequal(oldpass, newpass)) { if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) { printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", SAMR_REJECT_IN_HISTORY, r.out.reject->reason); return false; } } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) { if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) { printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", SAMR_REJECT_COMPLEXITY, r.out.reject->reason); return false; } } if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) { /* retry with adjusted size */ return test_ChangePasswordUser3(p, mem_ctx, account_string, r.out.dominfo->min_password_length, password, NULL, 0, false); } } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) { if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", SAMR_REJECT_OTHER, r.out.reject->reason); return false; } /* Perhaps the server has a 'min password age' set? */ } else if (!NT_STATUS_IS_OK(status)) { printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status)); ret = false; } else { *password = talloc_strdup(mem_ctx, newpass); } return ret;}static bool test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *alias_handle){ struct samr_GetMembersInAlias r; struct lsa_SidArray sids; NTSTATUS status; bool ret = true; printf("Testing GetMembersInAlias\n"); r.in.alias_handle = alias_handle; r.out.sids = &sids; status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("GetMembersInAlias failed - %s\n", nt_errstr(status)); ret = false; } return ret;}static bool test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *alias_handle, const struct dom_sid *domain_sid){ struct samr_AddAliasMember r; struct samr_DeleteAliasMember d; NTSTATUS status; bool ret = true; struct dom_sid *sid; sid = dom_sid_add_rid(mem_ctx, domain_sid, 512); printf("testing AddAliasMember\n"); r.in.alias_handle = alias_handle; r.in.sid = sid; status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("AddAliasMember failed - %s\n", nt_errstr(status)); ret = false; } d.in.alias_handle = alias_handle; d.in.sid = sid; status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d); if (!NT_STATUS_IS_OK(status)) { printf("DelAliasMember failed - %s\n", nt_errstr(status)); ret = false; } return ret;}static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *alias_handle){ struct samr_AddMultipleMembersToAlias a; struct samr_RemoveMultipleMembersFromAlias r; NTSTATUS status; bool ret = true; struct lsa_SidArray sids; printf("testing AddMultipleMembersToAlias\n"); a.in.alias_handle = alias_handle; a.in.sids = &sids; sids.num_sids = 3; sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3); sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1"); sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2"); sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3"); status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a); if (!NT_STATUS_IS_OK(status)) { printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status)); ret = false; } printf("testing RemoveMultipleMembersFromAlias\n"); r.in.alias_handle = alias_handle; r.in.sids = &sids; status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status)); ret = false; } /* strange! removing twice doesn't give any error */ status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status)); ret = false; } /* but removing an alias that isn't there does */ sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4"); status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r); if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status)); ret = false; } return ret;}static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *user_handle){ struct samr_TestPrivateFunctionsUser r; NTSTATUS status; bool ret = true; printf("Testing TestPrivateFunctionsUser\n"); r.in.user_handle = user_handle; status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r); if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) { printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status)); ret = false; } 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, uint32_t base_acct_flags, const char *base_acct_name, enum torture_samr_choice which_ops){ char *password = NULL; struct samr_QueryUserInfo q; NTSTATUS status; bool ret = true; int i; uint32_t rid; const uint32_t password_fields[] = { SAMR_FIELD_PASSWORD, SAMR_FIELD_PASSWORD2, SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2, 0 }; status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid); if (!NT_STATUS_IS_OK(status)) { ret = false; } switch (which_ops) { case TORTURE_SAMR_USER_ATTRIBUTES: if (!test_QuerySecurity(p, tctx, user_handle)) { ret = false; } if (!test_QueryUserInfo(p, tctx, user_handle)) { ret = false; } if (!test_QueryUserInfo2(p, tctx, user_handle)) { ret = false; } if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags, base_acct_name)) { ret = false; } if (!test_GetUserPwInfo(p, tctx, user_handle)) { ret = false; } if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) { ret = false; } if (!test_SetUserPass(p, tctx, user_handle, &password)) { ret = false; } break; case TORTURE_SAMR_PASSWORDS: if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) { char simple_pass[9]; char *v = generate_random_str(tctx, 1); ZERO_STRUCT(simple_pass); memset(simple_pass, *v, sizeof(simple_pass) - 1); printf("Testing machine account password policy rules\n"); /* Workstation trust accounts don't seem to need to honour password quality policy */ if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) { ret = false; } if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) { ret = false; } /* reset again, to allow another 'user' password change */ if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) { ret = false; } /* Try a 'short' password */ if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) { ret = false; } } for (i = 0; password_fields[i]; i++) { if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) { ret = false; } /* check it was set right */ if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) { ret = false; } } for (i = 0; password_fields[i]; i++) { if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) { ret = false; } /* check it was set right */ if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) { ret = false; } } if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) { ret = false; } if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) { ret = false; } q.in.user_handle = user_handle; q.in.level = 5; status = dcerpc_samr_QueryUserInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status)) { printf("QueryUserInfo level %u failed - %s\n", q.in.level, nt_errstr(status)); ret = false; } else { uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED); if ((q.out.info->info5.acct_flags) != expected_flags) { printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n", q.out.info->info5.acct_flags, expected_flags); ret = false; } if (q.out.info->info5.rid != rid) { printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n", q.out.info->info5.rid, rid); } } break; case TORTURE_SAMR_OTHER: /* We just need the account to exi
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?