samba3rpc.c
来自「samba最新软件」· C语言 代码 · 共 2,504 行 · 第 1/5 页
C
2,504 行
DCERPC_DEBUG_PRINT_OUT;#endif#if 1 net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL); status = dcerpc_bind_auth(net_pipe, &ndr_table_netlogon, wks_creds, lp_ctx, DCERPC_AUTH_TYPE_SCHANNEL, DCERPC_AUTH_LEVEL_PRIVACY, NULL);#else status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);#endif if (!NT_STATUS_IS_OK(status)) { d_printf("schannel bind failed: %s\n", nt_errstr(status)); goto done; } for (i=2; i<4; i++) { int flags; DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key; struct creds_CredentialState *creds_state; struct netr_Authenticator netr_auth, netr_auth2; struct netr_NetworkInfo ninfo; struct netr_PasswordInfo pinfo; struct netr_LogonSamLogon r; flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH | CLI_CRED_NTLMv2_AUTH; chal = data_blob_talloc(mem_ctx, NULL, 8); if (chal.data == NULL) { d_printf("data_blob_talloc failed\n"); goto done; } generate_random_buffer(chal.data, chal.length); names_blob = NTLMv2_generate_names_blob( mem_ctx, lp_iconv_convenience(lp_ctx), cli_credentials_get_workstation(user_creds), cli_credentials_get_domain(user_creds)); status = cli_credentials_get_ntlm_response( user_creds, mem_ctx, &flags, chal, names_blob, &lm_resp, &nt_resp, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { d_printf("cli_credentials_get_ntlm_response failed:" " %s\n", nt_errstr(status)); goto done; } creds_state = cli_credentials_get_netlogon_creds(wks_creds); creds_client_authenticator(creds_state, &netr_auth); ninfo.identity_info.account_name.string = cli_credentials_get_username(user_creds); ninfo.identity_info.domain_name.string = cli_credentials_get_domain(user_creds); ninfo.identity_info.parameter_control = 0; ninfo.identity_info.logon_id_low = 0; ninfo.identity_info.logon_id_high = 0; ninfo.identity_info.workstation.string = cli_credentials_get_workstation(user_creds); memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge)); ninfo.nt.length = nt_resp.length; ninfo.nt.data = nt_resp.data; ninfo.lm.length = lm_resp.length; ninfo.lm.data = lm_resp.data; r.in.server_name = talloc_asprintf( mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); ZERO_STRUCT(netr_auth2); r.in.computer_name = cli_credentials_get_workstation(wks_creds); r.in.credential = &netr_auth; r.in.return_authenticator = &netr_auth2; r.in.logon_level = 2; r.in.validation_level = i; r.in.logon.network = &ninfo; r.out.return_authenticator = NULL; status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { d_printf("netr_LogonSamLogon failed: %s\n", nt_errstr(status)); goto done; } if ((r.out.return_authenticator == NULL) || (!creds_client_check(creds_state, &r.out.return_authenticator->cred))) { d_printf("Credentials check failed!\n"); goto done; } creds_client_authenticator(creds_state, &netr_auth); pinfo.identity_info = ninfo.identity_info; ZERO_STRUCT(pinfo.lmpassword.hash); E_md4hash(cli_credentials_get_password(user_creds), pinfo.ntpassword.hash); session_key = data_blob_talloc(mem_ctx, creds_state->session_key, 16); arcfour_crypt_blob(pinfo.ntpassword.hash, sizeof(pinfo.ntpassword.hash), &session_key); r.in.logon_level = 1; r.in.logon.password = &pinfo; r.out.return_authenticator = NULL; status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { d_printf("netr_LogonSamLogon failed: %s\n", nt_errstr(status)); goto done; } if ((r.out.return_authenticator == NULL) || (!creds_client_check(creds_state, &r.out.return_authenticator->cred))) { d_printf("Credentials check failed!\n"); goto done; } } { struct netr_ServerPasswordSet s; char *password = generate_random_str(wks_creds, 8); struct creds_CredentialState *creds_state; s.in.server_name = talloc_asprintf( mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); s.in.computer_name = cli_credentials_get_workstation(wks_creds); s.in.account_name = talloc_asprintf( mem_ctx, "%s$", s.in.computer_name); s.in.secure_channel_type = SEC_CHAN_WKSTA; E_md4hash(password, s.in.new_password.hash); creds_state = cli_credentials_get_netlogon_creds(wks_creds); creds_des_encrypt(creds_state, &s.in.new_password); creds_client_authenticator(creds_state, &s.in.credential); status = dcerpc_netr_ServerPasswordSet(net_pipe, mem_ctx, &s); if (!NT_STATUS_IS_OK(status)) { printf("ServerPasswordSet - %s\n", nt_errstr(status)); goto done; } if (!creds_client_check(creds_state, &s.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } cli_credentials_set_password(wks_creds, password, CRED_SPECIFIED); } ret = true; done: talloc_free(mem_ctx); return ret;}/* * Delete the wks account again */static bool leave(struct smbcli_state *cli, struct loadparm_context *lp_ctx, struct cli_credentials *admin_creds, struct cli_credentials *wks_creds){ char *wks_name = talloc_asprintf( NULL, "%s$", cli_credentials_get_workstation(wks_creds)); bool ret; ret = delete_user(cli, lp_ctx, admin_creds, wks_name); talloc_free(wks_name); return ret;}/* * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave */bool torture_netlogon_samba3(struct torture_context *torture){ TALLOC_CTX *mem_ctx; NTSTATUS status; bool ret = false; struct smbcli_state *cli; struct cli_credentials *anon_creds; struct cli_credentials *wks_creds; const char *wks_name; int i; struct smbcli_options options; wks_name = torture_setting_string(torture, "wksname", NULL); if (wks_name == NULL) { wks_name = get_myname(); } mem_ctx = talloc_init("torture_netlogon_samba3"); if (mem_ctx == NULL) { d_printf("talloc_init failed\n"); return false; } if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) { d_printf("create_anon_creds failed\n"); goto done; } lp_smbcli_options(torture->lp_ctx, &options); status = smbcli_full_connection(mem_ctx, &cli, torture_setting_string(torture, "host", NULL), lp_smb_ports(torture->lp_ctx), "IPC$", NULL, anon_creds, lp_resolve_context(torture->lp_ctx), torture->ev, &options); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_full_connection failed: %s\n", nt_errstr(status)); goto done; } wks_creds = cli_credentials_init(mem_ctx); if (wks_creds == NULL) { d_printf("cli_credentials_init failed\n"); goto done; } cli_credentials_set_conf(wks_creds, torture->lp_ctx); cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA); cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED); cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED); cli_credentials_set_password(wks_creds, generate_random_str(wks_creds, 8), CRED_SPECIFIED); if (!join3(cli, torture->lp_ctx, false, cmdline_credentials, wks_creds)) { d_printf("join failed\n"); goto done; } cli_credentials_set_domain( cmdline_credentials, cli_credentials_get_domain(wks_creds), CRED_SPECIFIED); for (i=0; i<2; i++) { /* Do this more than once, the routine "schan" changes * the workstation password using the netlogon * password change routine */ int j; if (!auth2(cli, torture->lp_ctx, wks_creds)) { d_printf("auth2 failed\n"); goto done; } for (j=0; j<2; j++) { if (!schan(cli, torture->lp_ctx, wks_creds, cmdline_credentials)) { d_printf("schan failed\n"); goto done; } } } if (!leave(cli, torture->lp_ctx, cmdline_credentials, wks_creds)) { d_printf("leave failed\n"); goto done; } ret = true; done: talloc_free(mem_ctx); return ret;}/* * Do a simple join, testjoin and leave using specified smb and samr * credentials */static bool test_join3(struct torture_context *tctx, bool use_level25, struct cli_credentials *smb_creds, struct cli_credentials *samr_creds, const char *wks_name){ NTSTATUS status; bool ret = false; struct smbcli_state *cli; struct cli_credentials *wks_creds; struct smbcli_options options; lp_smbcli_options(tctx->lp_ctx, &options); status = smbcli_full_connection(tctx, &cli, torture_setting_string(tctx, "host", NULL), lp_smb_ports(tctx->lp_ctx), "IPC$", NULL, smb_creds, lp_resolve_context(tctx->lp_ctx), tctx->ev, &options); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_full_connection failed: %s\n", nt_errstr(status)); goto done; } wks_creds = cli_credentials_init(cli); if (wks_creds == NULL) { d_printf("cli_credentials_init failed\n"); goto done; } cli_credentials_set_conf(wks_creds, tctx->lp_ctx); cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA); cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED); cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED); cli_credentials_set_password(wks_creds, generate_random_str(wks_creds, 8), CRED_SPECIFIED); if (!join3(cli, tctx->lp_ctx, use_level25, samr_creds, wks_creds)) { d_printf("join failed\n"); goto done; } cli_credentials_set_domain( cmdline_credentials, cli_credentials_get_domain(wks_creds), CRED_SPECIFIED); if (!auth2(cli, tctx->lp_ctx, wks_creds)) { d_printf("auth2 failed\n"); goto done; } if (!leave(cli, tctx->lp_ctx, samr_creds, wks_creds)) { d_printf("leave failed\n"); goto done; } talloc_free(cli); ret = true; done: return ret;}/* * Test the different session key variants. Do it by joining, this uses the * session key in the setpassword routine. Test the join by doing the auth2. */bool torture_samba3_sessionkey(struct torture_context *torture){ bool ret = false; struct cli_credentials *anon_creds; const char *wks_name; wks_name = torture_setting_string(torture, "wksname", get_myname()); if (!(anon_creds = cli_credentials_init_anon(torture))) { d_printf("create_anon_creds failed\n"); goto done; } cli_credentials_set_workstation(anon_creds, wks_name, CRED_SPECIFIED); ret = true; if (!torture_setting_bool(torture, "samba3", false)) { /* Samba3 in the build farm right now does this happily. Need * to fix :-) */ if (test_join3(torture, false, anon_creds, NULL, wks_name)) { d_printf("join using anonymous bind on an anonymous smb " "connection succeeded -- HUH??\n"); ret = false; } } if (!test_join3(torture, false, anon_creds, cmdline_credentials, wks_name)) { d_printf("join using ntlmssp bind on an anonymous smb " "connection failed\n"); ret = false; } if (!test_join3(torture, false, cmdline_credentials, NULL, wks_name)) { d_printf("join using anonymous bind on an authenticated smb " "connection failed\n"); ret = false; } if (!test_join3(torture, false, cmdline_credentials, cmdline_credentials, wks_name)) { d_printf("join using ntlmssp bind on an authenticated smb " "connection failed\n"); ret = false; } /* * The following two are tests for setuserinfolevel 25 */ if (!test_join3(torture, true, anon_creds, cmdline_credentials, wks_name)) { d_printf("join using ntlmssp bind on an anonymous smb " "connection failed\n"); ret = false; } if (!test_join3(torture, true, cmdline_credentials, NULL, wks_name)) { d_printf("join using anonymous bind on an authenticated smb " "connection failed\n"); ret = false; } done: return ret;}/* * open pipe and bind, given an IPC$ context */static NTSTATUS pipe_bind_smb(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct smbcli_tree *tree, const char *pipe_name, const struct ndr_interface_table *iface, struct dcerpc_pipe **p){ struct dcerpc_pipe *result; NTSTATUS status; if (!(result = dcerpc_pipe_init( mem_ctx, tree->session->transport->socket->event.ctx, lp_iconv_convenience(lp_ctx)))) { return NT_STATUS_NO_MEMORY; } status = dcerpc_pipe_open_smb(result, tree, pipe_name); if (!NT_STATUS_IS_OK(status)) { d_printf("dcerpc_pipe_open_smb failed: %s\n", nt_errstr(status)); talloc_free(result); return status; } status = dcerpc_bind_auth_none(result, iface); if (!NT_STATUS_IS_OK(status)) { d_printf("schannel bind failed: %s\n", nt_errstr(status)); talloc_free(result); return status; } *p = result; return NT_STATUS_OK;}/* * Sane wrapper around lsa_LookupNames */static struct dom_sid *name2sid(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p, const char *name, const char *domain){ struct lsa_ObjectAttribute attr; struct lsa_QosInfo qos; struct lsa_OpenPolicy2 r; struct lsa_Close c; NTSTATUS status; struct policy_handle handle; struct lsa_LookupNames l; struct lsa_TransSidArray sids; struct lsa_String lsa_name; uint32_t count = 0; struct dom_sid *result; TALLOC_CTX *tmp_ctx; if (!(tmp_ctx = talloc_new(mem_ctx))) { return NULL; } qos.len = 0; qos.impersonation_level = 2; qos.context_mode = 1; qos.effective_only = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?