/* old style session setup (pre NT1 protocol level) */ static NTSTATUS session_setup_old(struct composite_context *c, struct smbcli_session *session, struct smb_composite_sesssetup *io, struct smbcli_request **req) { NTSTATUS nt_status; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); const char *password = cli_credentials_get_password(io->in.credentials); DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, cli_credentials_get_domain(io->in.credentials)); DATA_BLOB session_key; int flags = 0; if (session->options.lanman_auth) { flags |= CLI_CRED_LANMAN_AUTH; } if (session->options.ntlmv2_auth) { flags |= CLI_CRED_NTLMv2_AUTH; } state->setup.old.level = RAW_SESSSETUP_OLD; state->setup.old.in.bufsize = session->transport->options.max_xmit; state->setup.old.in.mpx_max = session->transport->options.max_mux; state->setup.old.in.vc_num = 1; state->setup.old.in.sesskey = io->in.sesskey; state->setup.old.in.os = "Unix"; state->setup.old.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); cli_credentials_get_ntlm_username_domain(io->in.credentials, state, &state->setup.old.in.user, &state->setup.old.in.domain); if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, &flags, session->transport->negotiate.secblob, names_blob, &state->setup.old.in.password, NULL, NULL, &session_key); NT_STATUS_NOT_OK_RETURN(nt_status); set_user_session_key(session, &session_key); data_blob_free(&session_key); } else if (session->options.plaintext_auth) { state->setup.old.in.password = data_blob_talloc(state, password, strlen(password)); } else { /* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */ return NT_STATUS_INVALID_PARAMETER; } *req = smb_raw_sesssetup_send(session, &state->setup); if (!*req) { return NT_STATUS_NO_MEMORY; } return (*req)->status; }
static bool wbinfo_auth_crap(char *username, const char *pass) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcAuthUserParams params; struct wbcAuthUserInfo *info = NULL; struct wbcAuthErrorInfo *err = NULL; DATA_BLOB lm = data_blob_null; DATA_BLOB nt = data_blob_null; fstring name_user; fstring name_domain; parse_wbinfo_domain_user(username, name_domain, name_user); params.account_name = name_user; params.domain_name = name_domain; params.workstation_name = NULL; params.flags = 0; params.parameter_control= WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT; params.level = WBC_AUTH_USER_LEVEL_RESPONSE; generate_random_buffer(params.password.response.challenge, 8); if (lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; DATA_BLOB names_blob; server_chal = data_blob(params.password.response.challenge, 8); /* Pretend this is a login to 'us', for blob purposes */ names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup()); if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal, &names_blob, &lm, &nt, NULL)) { data_blob_free(&names_blob); data_blob_free(&server_chal); return false; } data_blob_free(&names_blob); data_blob_free(&server_chal); } else { if (lp_client_lanman_auth()) { bool ok; lm = data_blob(NULL, 24); ok = SMBencrypt(pass, params.password.response.challenge, lm.data); if (!ok) { data_blob_free(&lm); } } nt = data_blob(NULL, 24); SMBNTencrypt(pass, params.password.response.challenge, nt.data); } params.password.response.nt_length = nt.length; params.password.response.nt_data = nt.data; params.password.response.lm_length = lm.length; params.password.response.lm_data = lm.data; wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); /* Display response */ d_printf("challenge/response password authentication %s\n", WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); if (wbc_status == WBC_ERR_AUTH_ERROR) { d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n", err->nt_string, err->nt_status, err->display_string); wbcFreeMemory(err); } else if (WBC_ERROR_IS_OK(wbc_status)) { wbcFreeMemory(info); } data_blob_free(&nt); data_blob_free(&lm); return WBC_ERROR_IS_OK(wbc_status); }
/* try a netlogon SamLogon */ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, struct cli_credentials *credentials, struct netlogon_creds_CredentialState *creds) { NTSTATUS status; struct netr_LogonSamLogonEx r; struct netr_NetworkInfo ninfo; union netr_LogonLevel logon; union netr_Validation validation; uint8_t authoritative = 0; uint32_t _flags = 0; DATA_BLOB names_blob, chal, lm_resp, nt_resp; int i; int flags = CLI_CRED_NTLM_AUTH; struct dcerpc_binding_handle *b = p->binding_handle; struct netr_UserSessionKey key; struct netr_LMSessionKey LMSessKey; uint32_t validation_levels[] = { 2, 3 }; struct netr_SamBaseInfo *base = NULL; const char *crypto_alg = ""; bool can_do_validation_6 = true; enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; if (lpcfg_client_lanman_auth(tctx->lp_ctx)) { flags |= CLI_CRED_LANMAN_AUTH; } if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) { flags |= CLI_CRED_NTLMv2_AUTH; } cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx, &ninfo.identity_info.account_name.string, &ninfo.identity_info.domain_name.string); generate_random_buffer(ninfo.challenge, sizeof(ninfo.challenge)); chal = data_blob_const(ninfo.challenge, sizeof(ninfo.challenge)); names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials), cli_credentials_get_domain(credentials)); status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, &flags, chal, names_blob, &lm_resp, &nt_resp, NULL, NULL); torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed"); ninfo.lm.data = lm_resp.data; ninfo.lm.length = lm_resp.length; ninfo.nt.data = nt_resp.data; ninfo.nt.length = nt_resp.length; 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(credentials); logon.network = &ninfo; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.computer_name = cli_credentials_get_workstation(credentials); r.in.logon_level = NetlogonNetworkInformation; r.in.logon= &logon; r.in.flags = &_flags; r.out.validation = &validation; r.out.authoritative = &authoritative; r.out.flags = &_flags; /* - retrieve level6 - save usrsession and lmsession key - retrieve level 2 - calculate, compare - retrieve level 3 - calculate, compare */ if (creds) { if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { crypto_alg = "AES"; } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { crypto_alg = "ARCFOUR"; } } dcerpc_binding_handle_auth_info(b, NULL, &auth_level); if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { r.in.validation_level = 6; torture_comment(tctx, "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", ninfo.identity_info.account_name.string, crypto_alg, r.in.validation_level); torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r), "LogonSamLogonEx failed"); } else { torture_comment(tctx, "Skip auth_level[%u] Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", auth_level, ninfo.identity_info.account_name.string, crypto_alg, r.in.validation_level); r.out.result = NT_STATUS_INVALID_INFO_CLASS; } if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) { can_do_validation_6 = false; } else { torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed"); key = r.out.validation->sam6->base.key; LMSessKey = r.out.validation->sam6->base.LMSessKey; DEBUG(1,("unencrypted session keys from validation_level 6:\n")); dump_data(1, r.out.validation->sam6->base.key.key, 16); dump_data(1, r.out.validation->sam6->base.LMSessKey.key, 8); } for (i=0; i < ARRAY_SIZE(validation_levels); i++) { r.in.validation_level = validation_levels[i]; torture_comment(tctx, "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", ninfo.identity_info.account_name.string, crypto_alg, r.in.validation_level); torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r), "LogonSamLogonEx failed"); torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed"); if (creds == NULL) { /* when this test is called without creds no point in * testing the session keys */ continue; } switch (validation_levels[i]) { case 2: base = &r.out.validation->sam2->base; break; case 3: base = &r.out.validation->sam3->base; break; default: break; } DEBUG(1,("encrypted keys validation_level %d:\n", validation_levels[i])); dump_data(1, base->key.key, 16); dump_data(1, base->LMSessKey.key, 8); if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { netlogon_creds_aes_decrypt(creds, base->key.key, 16); netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8); } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { netlogon_creds_arcfour_crypt(creds, base->key.key, 16); netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8); } DEBUG(1,("decryped keys validation_level %d\n", validation_levels[i])); dump_data(1, base->key.key, 16); dump_data(1, base->LMSessKey.key, 8); if (!can_do_validation_6) { /* we cant compare against unencrypted keys */ continue; } torture_assert_mem_equal(tctx, base->key.key, key.key, 16, "unexpected user session key\n"); torture_assert_mem_equal(tctx, base->LMSessKey.key, LMSessKey.key, 8, "unexpected LM session key\n"); } return true; }
static bool test_lmv2_ntlmv2_broken(enum ntlm_break break_which) { bool pass = True; NTSTATUS nt_status; uint32 flags = 0; DATA_BLOB ntlmv2_response = data_blob_null; DATA_BLOB lmv2_response = data_blob_null; DATA_BLOB ntlmv2_session_key = data_blob_null; DATA_BLOB names_blob = NTLMv2_generate_names_blob(NULL, get_winbind_netbios_name(), get_winbind_domain()); uchar user_session_key[16]; DATA_BLOB chall = get_challenge(); char *error_string; ZERO_STRUCT(user_session_key); flags |= WBFLAG_PAM_USER_SESSION_KEY; if (!SMBNTLMv2encrypt(NULL, opt_username, opt_domain, opt_password, &chall, &names_blob, &lmv2_response, &ntlmv2_response, NULL, &ntlmv2_session_key)) { data_blob_free(&names_blob); return False; } data_blob_free(&names_blob); switch (break_which) { case BREAK_NONE: break; case BREAK_LM: lmv2_response.data[0]++; break; case BREAK_NT: ntlmv2_response.data[0]++; break; case NO_LM: data_blob_free(&lmv2_response); break; case NO_NT: data_blob_free(&ntlmv2_response); break; } nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, &chall, &lmv2_response, &ntlmv2_response, flags, NULL, user_session_key, &error_string, NULL); data_blob_free(&lmv2_response); data_blob_free(&ntlmv2_response); if (!NT_STATUS_IS_OK(nt_status)) { d_printf("%s (0x%x)\n", error_string, NT_STATUS_V(nt_status)); SAFE_FREE(error_string); return break_which == BREAK_NT; } if (break_which != NO_NT && break_which != BREAK_NT && memcmp(ntlmv2_session_key.data, user_session_key, sizeof(user_session_key)) != 0) { DEBUG(1, ("USER (NTLMv2) Session Key does not match expectations!\n")); DEBUG(1, ("user_session_key:\n")); dump_data(1, user_session_key, 16); DEBUG(1, ("expected:\n")); dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length); pass = False; } return pass; }
NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, enum auth_password_state to_state, const struct auth_usersupplied_info *user_info_in, const struct auth_usersupplied_info **user_info_encrypted) { NTSTATUS nt_status; struct auth_usersupplied_info *user_info_temp; switch (to_state) { case AUTH_PASSWORD_RESPONSE: switch (user_info_in->password_state) { case AUTH_PASSWORD_PLAIN: { const struct auth_usersupplied_info *user_info_temp2; nt_status = encrypt_user_info(mem_ctx, auth_context, AUTH_PASSWORD_HASH, user_info_in, &user_info_temp2); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } user_info_in = user_info_temp2; /* fall through */ } case AUTH_PASSWORD_HASH: { const uint8_t *challenge; DATA_BLOB chall_blob; user_info_temp = talloc(mem_ctx, struct auth_usersupplied_info); if (!user_info_temp) { return NT_STATUS_NO_MEMORY; } if (!talloc_reference(user_info_temp, user_info_in)) { return NT_STATUS_NO_MEMORY; } *user_info_temp = *user_info_in; user_info_temp->mapped_state = to_state; nt_status = auth_get_challenge(auth_context, &challenge); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } chall_blob = data_blob_talloc(mem_ctx, challenge, 8); if (lp_client_ntlmv2_auth(auth_context->lp_ctx)) { DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx, lp_netbios_name(auth_context->lp_ctx), lp_workgroup(auth_context->lp_ctx)); DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key, ntlmv2_session_key; if (!SMBNTLMv2encrypt_hash(user_info_temp, user_info_in->client.account_name, user_info_in->client.domain_name, user_info_in->password.hash.nt->hash, &chall_blob, &names_blob, &lmv2_response, &ntlmv2_response, &lmv2_session_key, &ntlmv2_session_key)) { data_blob_free(&names_blob); return NT_STATUS_NO_MEMORY; } data_blob_free(&names_blob); user_info_temp->password.response.lanman = lmv2_response; user_info_temp->password.response.nt = ntlmv2_response; data_blob_free(&lmv2_session_key); data_blob_free(&ntlmv2_session_key); } else { DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); SMBOWFencrypt(user_info_in->password.hash.nt->hash, challenge, blob.data); user_info_temp->password.response.nt = blob; if (lp_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) { DATA_BLOB lm_blob = data_blob_talloc(mem_ctx, NULL, 24); SMBOWFencrypt(user_info_in->password.hash.lanman->hash, challenge, blob.data); user_info_temp->password.response.lanman = lm_blob; } else { /* if not sending the LM password, send the NT password twice */ user_info_temp->password.response.lanman = user_info_temp->password.response.nt; } } user_info_in = user_info_temp; /* fall through */ } case AUTH_PASSWORD_RESPONSE: *user_info_encrypted = user_info_in; } break; case AUTH_PASSWORD_HASH: { switch (user_info_in->password_state) { case AUTH_PASSWORD_PLAIN: { struct samr_Password lanman; struct samr_Password nt; user_info_temp = talloc(mem_ctx, struct auth_usersupplied_info); if (!user_info_temp) { return NT_STATUS_NO_MEMORY; } if (!talloc_reference(user_info_temp, user_info_in)) { return NT_STATUS_NO_MEMORY; } *user_info_temp = *user_info_in; user_info_temp->mapped_state = to_state; if (E_deshash(user_info_in->password.plaintext, lanman.hash)) { user_info_temp->password.hash.lanman = talloc(user_info_temp, struct samr_Password); *user_info_temp->password.hash.lanman = lanman; } else { user_info_temp->password.hash.lanman = NULL; } E_md4hash(user_info_in->password.plaintext, nt.hash); user_info_temp->password.hash.nt = talloc(user_info_temp, struct samr_Password); *user_info_temp->password.hash.nt = nt; user_info_in = user_info_temp; /* fall through */ } case AUTH_PASSWORD_HASH: *user_info_encrypted = user_info_in; break; default: return NT_STATUS_INVALID_PARAMETER; break; } break; }
/* try a netlogon SamLogon */ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, struct cli_credentials *credentials, struct netlogon_creds_CredentialState *creds) { NTSTATUS status; struct netr_LogonSamLogonEx r; struct netr_NetworkInfo ninfo; union netr_LogonLevel logon; union netr_Validation validation; uint8_t authoritative = 0; uint32_t _flags = 0; DATA_BLOB names_blob, chal, lm_resp, nt_resp; int i; int flags = CLI_CRED_NTLM_AUTH; struct dcerpc_binding_handle *b = p->binding_handle; if (lpcfg_client_lanman_auth(tctx->lp_ctx)) { flags |= CLI_CRED_LANMAN_AUTH; } if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) { flags |= CLI_CRED_NTLMv2_AUTH; } cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx, &ninfo.identity_info.account_name.string, &ninfo.identity_info.domain_name.string); generate_random_buffer(ninfo.challenge, sizeof(ninfo.challenge)); chal = data_blob_const(ninfo.challenge, sizeof(ninfo.challenge)); names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials), cli_credentials_get_domain(credentials)); status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, &flags, chal, names_blob, &lm_resp, &nt_resp, NULL, NULL); torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed"); ninfo.lm.data = lm_resp.data; ninfo.lm.length = lm_resp.length; ninfo.nt.data = nt_resp.data; ninfo.nt.length = nt_resp.length; 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(credentials); logon.network = &ninfo; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.computer_name = cli_credentials_get_workstation(credentials); r.in.logon_level = 2; r.in.logon= &logon; r.in.flags = &_flags; r.out.validation = &validation; r.out.authoritative = &authoritative; r.out.flags = &_flags; torture_comment(tctx, "Testing LogonSamLogonEx with name %s\n", ninfo.identity_info.account_name.string); for (i=2;i<3;i++) { r.in.validation_level = i; torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r), "LogonSamLogon failed"); torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed"); } return true; }
static bool wbinfo_auth_crap(struct loadparm_context *lp_ctx, char *username) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; fstring name_user; fstring name_domain; fstring pass; char *p; /* Send off request */ ZERO_STRUCT(request); ZERO_STRUCT(response); p = strchr(username, '%'); if (p) { *p = 0; fstrcpy(pass, p + 1); } parse_wbinfo_domain_user(username, name_domain, name_user); request.data.auth_crap.logon_parameters = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT; fstrcpy(request.data.auth_crap.user, name_user); fstrcpy(request.data.auth_crap.domain, name_domain); generate_random_buffer(request.data.auth_crap.chal, 8); if (lp_client_ntlmv2_auth(lp_ctx)) { DATA_BLOB server_chal; DATA_BLOB names_blob; DATA_BLOB lm_response; DATA_BLOB nt_response; TALLOC_CTX *mem_ctx; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { d_printf("talloc_new failed\n"); return false; } server_chal = data_blob(request.data.auth_crap.chal, 8); /* Pretend this is a login to 'us', for blob purposes */ names_blob = NTLMv2_generate_names_blob(mem_ctx, lp_netbios_name(lp_ctx), lp_workgroup(lp_ctx)); if (!SMBNTLMv2encrypt(mem_ctx, name_user, name_domain, pass, &server_chal, &names_blob, &lm_response, &nt_response, NULL, NULL)) { data_blob_free(&names_blob); data_blob_free(&server_chal); return false; } data_blob_free(&names_blob); data_blob_free(&server_chal); memcpy(request.data.auth_crap.nt_resp, nt_response.data, MIN(nt_response.length, sizeof(request.data.auth_crap.nt_resp))); request.data.auth_crap.nt_resp_len = nt_response.length; memcpy(request.data.auth_crap.lm_resp, lm_response.data, MIN(lm_response.length, sizeof(request.data.auth_crap.lm_resp))); request.data.auth_crap.lm_resp_len = lm_response.length; data_blob_free(&nt_response); data_blob_free(&lm_response); } else { if (lp_client_lanman_auth(lp_ctx) && SMBencrypt(pass, request.data.auth_crap.chal, (unsigned char *)request.data.auth_crap.lm_resp)) { request.data.auth_crap.lm_resp_len = 24; } else { request.data.auth_crap.lm_resp_len = 0; } SMBNTencrypt(pass, request.data.auth_crap.chal, (unsigned char *)request.data.auth_crap.nt_resp); request.data.auth_crap.nt_resp_len = 24; } result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response); /* Display response */ d_printf("challenge/response password authentication %s\n", (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); if (response.data.auth.nt_status) d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n", response.data.auth.nt_status_string, response.data.auth.nt_status, response.data.auth.error_string); return result == NSS_STATUS_SUCCESS; }
/* try a netlogon SamLogon */ BOOL test_netlogon_ex_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct cli_credentials *credentials, struct creds_CredentialState *creds) { NTSTATUS status; struct netr_LogonSamLogonEx r; struct netr_NetworkInfo ninfo; DATA_BLOB names_blob, chal, lm_resp, nt_resp; int i; BOOL ret = True; int flags = CLI_CRED_NTLM_AUTH; if (lp_client_lanman_auth()) { flags |= CLI_CRED_LANMAN_AUTH; } if (lp_client_ntlmv2_auth()) { flags |= CLI_CRED_NTLMv2_AUTH; } cli_credentials_get_ntlm_username_domain(cmdline_credentials, mem_ctx, &ninfo.identity_info.account_name.string, &ninfo.identity_info.domain_name.string); generate_random_buffer(ninfo.challenge, sizeof(ninfo.challenge)); chal = data_blob_const(ninfo.challenge, sizeof(ninfo.challenge)); names_blob = NTLMv2_generate_names_blob(mem_ctx, cli_credentials_get_workstation(credentials), cli_credentials_get_domain(credentials)); status = cli_credentials_get_ntlm_response(cmdline_credentials, mem_ctx, &flags, chal, names_blob, &lm_resp, &nt_resp, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { printf("cli_credentials_get_ntlm_response failed: %s\n", nt_errstr(status)); return False; } ninfo.lm.data = lm_resp.data; ninfo.lm.length = lm_resp.length; ninfo.nt.data = nt_resp.data; ninfo.nt.length = nt_resp.length; 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(credentials); r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); r.in.computer_name = cli_credentials_get_workstation(credentials); r.in.logon_level = 2; r.in.logon.network = &ninfo; r.in.flags = 0; printf("Testing LogonSamLogonEx with name %s\n", ninfo.identity_info.account_name.string); for (i=2;i<3;i++) { r.in.validation_level = i; status = dcerpc_netr_LogonSamLogonEx(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("LogonSamLogon failed: %s\n", nt_errstr(status)); return False; } } return ret; }
/* send a nt1 style session setup */ static NTSTATUS session_setup_nt1(struct composite_context *c, struct smbcli_session *session, struct smb_composite_sesssetup *io, struct smbcli_request **req) { NTSTATUS nt_status = NT_STATUS_INTERNAL_ERROR; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); const char *domain = cli_credentials_get_domain(io->in.credentials); /* * domain controllers tend to reject the NTLM v2 blob * if the netbiosname is not valid (e.g. IP address or FQDN) * so just leave it away (as Windows client do) */ DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, NULL, domain); DATA_BLOB session_key = data_blob(NULL, 0); int flags = CLI_CRED_NTLM_AUTH; if (session->options.lanman_auth) { flags |= CLI_CRED_LANMAN_AUTH; } if (session->options.ntlmv2_auth) { flags |= CLI_CRED_NTLMv2_AUTH; } state->setup.nt1.level = RAW_SESSSETUP_NT1; state->setup.nt1.in.bufsize = session->transport->options.max_xmit; state->setup.nt1.in.mpx_max = session->transport->options.max_mux; state->setup.nt1.in.vc_num = 1; state->setup.nt1.in.sesskey = io->in.sesskey; state->setup.nt1.in.capabilities = io->in.capabilities; state->setup.nt1.in.os = "Unix"; state->setup.nt1.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING); cli_credentials_get_ntlm_username_domain(io->in.credentials, state, &state->setup.nt1.in.user, &state->setup.nt1.in.domain); if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, &flags, session->transport->negotiate.secblob, names_blob, &state->setup.nt1.in.password1, &state->setup.nt1.in.password2, NULL, &session_key); NT_STATUS_NOT_OK_RETURN(nt_status); } else if (session->options.plaintext_auth) { const char *password = cli_credentials_get_password(io->in.credentials); state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); state->setup.nt1.in.password2 = data_blob(NULL, 0); } else { /* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */ return NT_STATUS_INVALID_PARAMETER; } *req = smb_raw_sesssetup_send(session, &state->setup); if (!*req) { return NT_STATUS_NO_MEMORY; } if (NT_STATUS_IS_OK(nt_status)) { smb1cli_conn_activate_signing(session->transport->conn, session_key, state->setup.nt1.in.password2); nt_status = smb1cli_session_set_session_key(session->smbXcli, session_key); data_blob_free(&session_key); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } } return (*req)->status; }