mirror of
https://github.com/samba-team/samba.git
synced 2025-08-05 12:22:11 +03:00
s3:libsmb: remove unused cli_session_setup_{lanman2,plain,nt1}*
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
committed by
Andreas Schneider
parent
a54d250e09
commit
c758df6b4a
@ -74,225 +74,6 @@ static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
|
|||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/****************************************************************************
|
|
||||||
Do an old lanman2 style session setup.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
struct cli_session_setup_lanman2_state {
|
|
||||||
struct cli_state *cli;
|
|
||||||
uint16_t vwv[10];
|
|
||||||
const char *user;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void cli_session_setup_lanman2_done(struct tevent_req *subreq);
|
|
||||||
|
|
||||||
static struct tevent_req *cli_session_setup_lanman2_send(
|
|
||||||
TALLOC_CTX *mem_ctx, struct tevent_context *ev,
|
|
||||||
struct cli_state *cli, const char *user,
|
|
||||||
const char *pass, size_t passlen,
|
|
||||||
const char *workgroup)
|
|
||||||
{
|
|
||||||
struct tevent_req *req, *subreq;
|
|
||||||
struct cli_session_setup_lanman2_state *state;
|
|
||||||
DATA_BLOB lm_response = data_blob_null;
|
|
||||||
uint16_t *vwv;
|
|
||||||
uint8_t *bytes;
|
|
||||||
char *tmp;
|
|
||||||
uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
|
|
||||||
|
|
||||||
req = tevent_req_create(mem_ctx, &state,
|
|
||||||
struct cli_session_setup_lanman2_state);
|
|
||||||
if (req == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
state->cli = cli;
|
|
||||||
state->user = user;
|
|
||||||
vwv = state->vwv;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if in share level security then don't send a password now
|
|
||||||
*/
|
|
||||||
if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
|
|
||||||
passlen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (passlen > 0
|
|
||||||
&& (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
|
|
||||||
&& passlen != 24) {
|
|
||||||
/*
|
|
||||||
* Encrypted mode needed, and non encrypted password
|
|
||||||
* supplied.
|
|
||||||
*/
|
|
||||||
lm_response = data_blob(NULL, 24);
|
|
||||||
if (tevent_req_nomem(lm_response.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn),
|
|
||||||
(uint8_t *)lm_response.data)) {
|
|
||||||
DEBUG(1, ("Password is > 14 chars in length, and is "
|
|
||||||
"therefore incompatible with Lanman "
|
|
||||||
"authentication\n"));
|
|
||||||
tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
} else if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
|
|
||||||
&& passlen == 24) {
|
|
||||||
/*
|
|
||||||
* Encrypted mode needed, and encrypted password
|
|
||||||
* supplied.
|
|
||||||
*/
|
|
||||||
lm_response = data_blob(pass, passlen);
|
|
||||||
if (tevent_req_nomem(lm_response.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
} else if (passlen > 0) {
|
|
||||||
uint8_t *buf;
|
|
||||||
size_t converted_size;
|
|
||||||
/*
|
|
||||||
* Plaintext mode needed, assume plaintext supplied.
|
|
||||||
*/
|
|
||||||
buf = talloc_array(talloc_tos(), uint8_t, 0);
|
|
||||||
buf = smb_bytes_push_str(buf, smbXcli_conn_use_unicode(cli->conn), pass, passlen+1,
|
|
||||||
&converted_size);
|
|
||||||
if (tevent_req_nomem(buf, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
lm_response = data_blob(pass, passlen);
|
|
||||||
TALLOC_FREE(buf);
|
|
||||||
if (tevent_req_nomem(lm_response.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SCVAL(vwv+0, 0, 0xff);
|
|
||||||
SCVAL(vwv+0, 1, 0);
|
|
||||||
SSVAL(vwv+1, 0, 0);
|
|
||||||
SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
|
|
||||||
SSVAL(vwv+3, 0, 2);
|
|
||||||
SSVAL(vwv+4, 0, 1);
|
|
||||||
SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
|
|
||||||
SSVAL(vwv+7, 0, lm_response.length);
|
|
||||||
|
|
||||||
bytes = talloc_array(state, uint8_t, lm_response.length);
|
|
||||||
if (tevent_req_nomem(bytes, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
if (lm_response.length != 0) {
|
|
||||||
memcpy(bytes, lm_response.data, lm_response.length);
|
|
||||||
}
|
|
||||||
data_blob_free(&lm_response);
|
|
||||||
|
|
||||||
tmp = talloc_strdup_upper(talloc_tos(), user);
|
|
||||||
if (tevent_req_nomem(tmp, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
|
|
||||||
NULL);
|
|
||||||
TALLOC_FREE(tmp);
|
|
||||||
|
|
||||||
tmp = talloc_strdup_upper(talloc_tos(), workgroup);
|
|
||||||
if (tevent_req_nomem(tmp, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
|
|
||||||
NULL);
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
|
|
||||||
|
|
||||||
if (tevent_req_nomem(bytes, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 0, 10, vwv,
|
|
||||||
talloc_get_size(bytes), bytes);
|
|
||||||
if (tevent_req_nomem(subreq, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req);
|
|
||||||
return req;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
|
|
||||||
{
|
|
||||||
struct tevent_req *req = tevent_req_callback_data(
|
|
||||||
subreq, struct tevent_req);
|
|
||||||
struct cli_session_setup_lanman2_state *state = tevent_req_data(
|
|
||||||
req, struct cli_session_setup_lanman2_state);
|
|
||||||
struct cli_state *cli = state->cli;
|
|
||||||
uint32_t num_bytes;
|
|
||||||
uint8_t *in;
|
|
||||||
uint8_t *inhdr;
|
|
||||||
uint8_t *bytes;
|
|
||||||
uint8_t *p;
|
|
||||||
NTSTATUS status;
|
|
||||||
ssize_t ret;
|
|
||||||
uint8_t wct;
|
|
||||||
uint16_t *vwv;
|
|
||||||
|
|
||||||
status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
|
|
||||||
&num_bytes, &bytes);
|
|
||||||
TALLOC_FREE(subreq);
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
inhdr = in + NBT_HDR_SIZE;
|
|
||||||
p = bytes;
|
|
||||||
|
|
||||||
cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
|
|
||||||
smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
|
|
||||||
|
|
||||||
status = smb_bytes_talloc_string(cli,
|
|
||||||
inhdr,
|
|
||||||
&cli->server_os,
|
|
||||||
p,
|
|
||||||
bytes+num_bytes-p,
|
|
||||||
&ret);
|
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += ret;
|
|
||||||
|
|
||||||
status = smb_bytes_talloc_string(cli,
|
|
||||||
inhdr,
|
|
||||||
&cli->server_type,
|
|
||||||
p,
|
|
||||||
bytes+num_bytes-p,
|
|
||||||
&ret);
|
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += ret;
|
|
||||||
|
|
||||||
status = smb_bytes_talloc_string(cli,
|
|
||||||
inhdr,
|
|
||||||
&cli->server_domain,
|
|
||||||
p,
|
|
||||||
bytes+num_bytes-p,
|
|
||||||
&ret);
|
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += ret;
|
|
||||||
|
|
||||||
tevent_req_done(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
|
|
||||||
{
|
|
||||||
return tevent_req_simple_recv_ntstatus(req);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Work out suitable capabilities to offer the server.
|
Work out suitable capabilities to offer the server.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -497,491 +278,6 @@ NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
|
|||||||
return tevent_req_simple_recv_ntstatus(req);
|
return tevent_req_simple_recv_ntstatus(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/****************************************************************************
|
|
||||||
Do a NT1 plaintext session setup.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
struct cli_session_setup_plain_state {
|
|
||||||
struct cli_state *cli;
|
|
||||||
uint16_t vwv[13];
|
|
||||||
const char *user;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void cli_session_setup_plain_done(struct tevent_req *subreq);
|
|
||||||
|
|
||||||
static struct tevent_req *cli_session_setup_plain_send(
|
|
||||||
TALLOC_CTX *mem_ctx, struct tevent_context *ev,
|
|
||||||
struct cli_state *cli,
|
|
||||||
const char *user, const char *pass, const char *workgroup)
|
|
||||||
{
|
|
||||||
struct tevent_req *req, *subreq;
|
|
||||||
struct cli_session_setup_plain_state *state;
|
|
||||||
uint16_t *vwv;
|
|
||||||
uint8_t *bytes;
|
|
||||||
size_t passlen;
|
|
||||||
char *version;
|
|
||||||
|
|
||||||
req = tevent_req_create(mem_ctx, &state,
|
|
||||||
struct cli_session_setup_plain_state);
|
|
||||||
if (req == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
state->cli = cli;
|
|
||||||
state->user = user;
|
|
||||||
vwv = state->vwv;
|
|
||||||
|
|
||||||
SCVAL(vwv+0, 0, 0xff);
|
|
||||||
SCVAL(vwv+0, 1, 0);
|
|
||||||
SSVAL(vwv+1, 0, 0);
|
|
||||||
SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
|
|
||||||
SSVAL(vwv+3, 0, 2);
|
|
||||||
SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
|
|
||||||
SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
|
|
||||||
SSVAL(vwv+7, 0, 0);
|
|
||||||
SSVAL(vwv+8, 0, 0);
|
|
||||||
SSVAL(vwv+9, 0, 0);
|
|
||||||
SSVAL(vwv+10, 0, 0);
|
|
||||||
SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
|
|
||||||
|
|
||||||
bytes = talloc_array(state, uint8_t, 0);
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), pass, strlen(pass)+1,
|
|
||||||
&passlen);
|
|
||||||
if (tevent_req_nomem(bytes, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
SSVAL(vwv + (smbXcli_conn_use_unicode(cli->conn) ? 8 : 7), 0, passlen);
|
|
||||||
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
|
|
||||||
user, strlen(user)+1, NULL);
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
|
|
||||||
workgroup, strlen(workgroup)+1, NULL);
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
|
|
||||||
"Unix", 5, NULL);
|
|
||||||
|
|
||||||
version = talloc_asprintf(talloc_tos(), "Samba %s",
|
|
||||||
samba_version_string());
|
|
||||||
if (tevent_req_nomem(version, req)){
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
|
|
||||||
version, strlen(version)+1, NULL);
|
|
||||||
TALLOC_FREE(version);
|
|
||||||
|
|
||||||
if (tevent_req_nomem(bytes, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 0, 13, vwv,
|
|
||||||
talloc_get_size(bytes), bytes);
|
|
||||||
if (tevent_req_nomem(subreq, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
tevent_req_set_callback(subreq, cli_session_setup_plain_done, req);
|
|
||||||
return req;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cli_session_setup_plain_done(struct tevent_req *subreq)
|
|
||||||
{
|
|
||||||
struct tevent_req *req = tevent_req_callback_data(
|
|
||||||
subreq, struct tevent_req);
|
|
||||||
struct cli_session_setup_plain_state *state = tevent_req_data(
|
|
||||||
req, struct cli_session_setup_plain_state);
|
|
||||||
struct cli_state *cli = state->cli;
|
|
||||||
uint32_t num_bytes;
|
|
||||||
uint8_t *in;
|
|
||||||
uint8_t *inhdr;
|
|
||||||
uint8_t *bytes;
|
|
||||||
uint8_t *p;
|
|
||||||
NTSTATUS status;
|
|
||||||
ssize_t ret;
|
|
||||||
uint8_t wct;
|
|
||||||
uint16_t *vwv;
|
|
||||||
|
|
||||||
status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
|
|
||||||
&num_bytes, &bytes);
|
|
||||||
TALLOC_FREE(subreq);
|
|
||||||
if (tevent_req_nterror(req, status)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
inhdr = in + NBT_HDR_SIZE;
|
|
||||||
p = bytes;
|
|
||||||
|
|
||||||
cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
|
|
||||||
smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
|
|
||||||
|
|
||||||
status = smb_bytes_talloc_string(cli,
|
|
||||||
inhdr,
|
|
||||||
&cli->server_os,
|
|
||||||
p,
|
|
||||||
bytes+num_bytes-p,
|
|
||||||
&ret);
|
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += ret;
|
|
||||||
|
|
||||||
status = smb_bytes_talloc_string(cli,
|
|
||||||
inhdr,
|
|
||||||
&cli->server_type,
|
|
||||||
p,
|
|
||||||
bytes+num_bytes-p,
|
|
||||||
&ret);
|
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += ret;
|
|
||||||
|
|
||||||
status = smb_bytes_talloc_string(cli,
|
|
||||||
inhdr,
|
|
||||||
&cli->server_domain,
|
|
||||||
p,
|
|
||||||
bytes+num_bytes-p,
|
|
||||||
&ret);
|
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += ret;
|
|
||||||
|
|
||||||
tevent_req_done(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
|
|
||||||
{
|
|
||||||
return tevent_req_simple_recv_ntstatus(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
do a NT1 NTLM/LM encrypted session setup - for when extended security
|
|
||||||
is not negotiated.
|
|
||||||
@param cli client state to create do session setup on
|
|
||||||
@param user username
|
|
||||||
@param pass *either* cleartext password (passlen !=24) or LM response.
|
|
||||||
@param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
|
|
||||||
@param workgroup The user's domain.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
struct cli_session_setup_nt1_state {
|
|
||||||
struct cli_state *cli;
|
|
||||||
uint16_t vwv[13];
|
|
||||||
DATA_BLOB response;
|
|
||||||
DATA_BLOB session_key;
|
|
||||||
const char *user;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void cli_session_setup_nt1_done(struct tevent_req *subreq);
|
|
||||||
|
|
||||||
static struct tevent_req *cli_session_setup_nt1_send(
|
|
||||||
TALLOC_CTX *mem_ctx, struct tevent_context *ev,
|
|
||||||
struct cli_state *cli, const char *user,
|
|
||||||
const char *pass, size_t passlen,
|
|
||||||
const char *ntpass, size_t ntpasslen,
|
|
||||||
const char *workgroup)
|
|
||||||
{
|
|
||||||
struct tevent_req *req, *subreq;
|
|
||||||
struct cli_session_setup_nt1_state *state;
|
|
||||||
DATA_BLOB lm_response = data_blob_null;
|
|
||||||
DATA_BLOB nt_response = data_blob_null;
|
|
||||||
DATA_BLOB session_key = data_blob_null;
|
|
||||||
uint16_t *vwv;
|
|
||||||
uint8_t *bytes;
|
|
||||||
char *workgroup_upper;
|
|
||||||
|
|
||||||
req = tevent_req_create(mem_ctx, &state,
|
|
||||||
struct cli_session_setup_nt1_state);
|
|
||||||
if (req == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
state->cli = cli;
|
|
||||||
state->user = user;
|
|
||||||
vwv = state->vwv;
|
|
||||||
|
|
||||||
if (passlen == 0) {
|
|
||||||
/* do nothing - guest login */
|
|
||||||
} else if (passlen != 24) {
|
|
||||||
if (lp_client_ntlmv2_auth()) {
|
|
||||||
DATA_BLOB server_chal;
|
|
||||||
DATA_BLOB names_blob;
|
|
||||||
|
|
||||||
server_chal =
|
|
||||||
data_blob_const(smb1cli_conn_server_challenge(cli->conn),
|
|
||||||
8);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* note that the 'workgroup' here is a best
|
|
||||||
* guess - we don't know the server's domain
|
|
||||||
* at this point. Windows clients also don't
|
|
||||||
* use hostname...
|
|
||||||
*/
|
|
||||||
names_blob = NTLMv2_generate_names_blob(
|
|
||||||
NULL, NULL, workgroup);
|
|
||||||
|
|
||||||
if (tevent_req_nomem(names_blob.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
|
|
||||||
&server_chal, &names_blob,
|
|
||||||
&lm_response, &nt_response,
|
|
||||||
NULL, &session_key)) {
|
|
||||||
data_blob_free(&names_blob);
|
|
||||||
tevent_req_nterror(
|
|
||||||
req, NT_STATUS_ACCESS_DENIED);
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
data_blob_free(&names_blob);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
uchar nt_hash[16];
|
|
||||||
E_md4hash(pass, nt_hash);
|
|
||||||
|
|
||||||
#ifdef LANMAN_ONLY
|
|
||||||
nt_response = data_blob_null;
|
|
||||||
#else
|
|
||||||
nt_response = data_blob(NULL, 24);
|
|
||||||
if (tevent_req_nomem(nt_response.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
SMBNTencrypt(pass, smb1cli_conn_server_challenge(cli->conn),
|
|
||||||
nt_response.data);
|
|
||||||
#endif
|
|
||||||
/* non encrypted password supplied. Ignore ntpass. */
|
|
||||||
if (lp_client_lanman_auth()) {
|
|
||||||
|
|
||||||
lm_response = data_blob(NULL, 24);
|
|
||||||
if (tevent_req_nomem(lm_response.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SMBencrypt(pass,
|
|
||||||
smb1cli_conn_server_challenge(cli->conn),
|
|
||||||
lm_response.data)) {
|
|
||||||
/*
|
|
||||||
* Oops, the LM response is
|
|
||||||
* invalid, just put the NT
|
|
||||||
* response there instead
|
|
||||||
*/
|
|
||||||
data_blob_free(&lm_response);
|
|
||||||
lm_response = data_blob(
|
|
||||||
nt_response.data,
|
|
||||||
nt_response.length);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* LM disabled, place NT# in LM field
|
|
||||||
* instead
|
|
||||||
*/
|
|
||||||
lm_response = data_blob(
|
|
||||||
nt_response.data, nt_response.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tevent_req_nomem(lm_response.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
session_key = data_blob(NULL, 16);
|
|
||||||
if (tevent_req_nomem(session_key.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
#ifdef LANMAN_ONLY
|
|
||||||
E_deshash(pass, session_key.data);
|
|
||||||
memset(&session_key.data[8], '\0', 8);
|
|
||||||
#else
|
|
||||||
SMBsesskeygen_ntv1(nt_hash, session_key.data);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* pre-encrypted password supplied. Only used for
|
|
||||||
security=server, can't do
|
|
||||||
signing because we don't have original key */
|
|
||||||
|
|
||||||
lm_response = data_blob(pass, passlen);
|
|
||||||
if (tevent_req_nomem(lm_response.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
nt_response = data_blob(ntpass, ntpasslen);
|
|
||||||
if (tevent_req_nomem(nt_response.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LANMAN_ONLY
|
|
||||||
state->response = data_blob_talloc(
|
|
||||||
state, lm_response.data, lm_response.length);
|
|
||||||
#else
|
|
||||||
state->response = data_blob_talloc(
|
|
||||||
state, nt_response.data, nt_response.length);
|
|
||||||
#endif
|
|
||||||
if (tevent_req_nomem(state->response.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session_key.data) {
|
|
||||||
state->session_key = data_blob_talloc(
|
|
||||||
state, session_key.data, session_key.length);
|
|
||||||
if (tevent_req_nomem(state->session_key.data, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data_blob_free(&session_key);
|
|
||||||
|
|
||||||
SCVAL(vwv+0, 0, 0xff);
|
|
||||||
SCVAL(vwv+0, 1, 0);
|
|
||||||
SSVAL(vwv+1, 0, 0);
|
|
||||||
SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
|
|
||||||
SSVAL(vwv+3, 0, 2);
|
|
||||||
SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
|
|
||||||
SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
|
|
||||||
SSVAL(vwv+7, 0, lm_response.length);
|
|
||||||
SSVAL(vwv+8, 0, nt_response.length);
|
|
||||||
SSVAL(vwv+9, 0, 0);
|
|
||||||
SSVAL(vwv+10, 0, 0);
|
|
||||||
SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
|
|
||||||
|
|
||||||
bytes = talloc_array(state, uint8_t,
|
|
||||||
lm_response.length + nt_response.length);
|
|
||||||
if (tevent_req_nomem(bytes, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
if (lm_response.length != 0) {
|
|
||||||
memcpy(bytes, lm_response.data, lm_response.length);
|
|
||||||
}
|
|
||||||
if (nt_response.length != 0) {
|
|
||||||
memcpy(bytes + lm_response.length,
|
|
||||||
nt_response.data, nt_response.length);
|
|
||||||
}
|
|
||||||
data_blob_free(&lm_response);
|
|
||||||
data_blob_free(&nt_response);
|
|
||||||
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
|
|
||||||
user, strlen(user)+1, NULL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Upper case here might help some NTLMv2 implementations
|
|
||||||
*/
|
|
||||||
workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
|
|
||||||
if (tevent_req_nomem(workgroup_upper, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
|
|
||||||
workgroup_upper, strlen(workgroup_upper)+1,
|
|
||||||
NULL);
|
|
||||||
TALLOC_FREE(workgroup_upper);
|
|
||||||
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
|
|
||||||
bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
|
|
||||||
if (tevent_req_nomem(bytes, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 0, 13, vwv,
|
|
||||||
talloc_get_size(bytes), bytes);
|
|
||||||
if (tevent_req_nomem(subreq, req)) {
|
|
||||||
return tevent_req_post(req, ev);
|
|
||||||
}
|
|
||||||
tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
|
|
||||||
return req;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cli_session_setup_nt1_done(struct tevent_req *subreq)
|
|
||||||
{
|
|
||||||
struct tevent_req *req = tevent_req_callback_data(
|
|
||||||
subreq, struct tevent_req);
|
|
||||||
struct cli_session_setup_nt1_state *state = tevent_req_data(
|
|
||||||
req, struct cli_session_setup_nt1_state);
|
|
||||||
struct cli_state *cli = state->cli;
|
|
||||||
uint32_t num_bytes;
|
|
||||||
uint8_t *in;
|
|
||||||
uint8_t *inhdr;
|
|
||||||
uint8_t *bytes;
|
|
||||||
uint8_t *p;
|
|
||||||
NTSTATUS status;
|
|
||||||
ssize_t ret;
|
|
||||||
uint8_t wct;
|
|
||||||
uint16_t *vwv;
|
|
||||||
|
|
||||||
status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
|
|
||||||
&num_bytes, &bytes);
|
|
||||||
TALLOC_FREE(subreq);
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
inhdr = in + NBT_HDR_SIZE;
|
|
||||||
p = bytes;
|
|
||||||
|
|
||||||
cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
|
|
||||||
smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
|
|
||||||
|
|
||||||
status = smb_bytes_talloc_string(cli,
|
|
||||||
inhdr,
|
|
||||||
&cli->server_os,
|
|
||||||
p,
|
|
||||||
bytes+num_bytes-p,
|
|
||||||
&ret);
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += ret;
|
|
||||||
|
|
||||||
status = smb_bytes_talloc_string(cli,
|
|
||||||
inhdr,
|
|
||||||
&cli->server_type,
|
|
||||||
p,
|
|
||||||
bytes+num_bytes-p,
|
|
||||||
&ret);
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += ret;
|
|
||||||
|
|
||||||
status = smb_bytes_talloc_string(cli,
|
|
||||||
inhdr,
|
|
||||||
&cli->server_domain,
|
|
||||||
p,
|
|
||||||
bytes+num_bytes-p,
|
|
||||||
&ret);
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
tevent_req_nterror(req, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += ret;
|
|
||||||
|
|
||||||
if (smb1cli_conn_activate_signing(cli->conn, state->session_key, state->response)
|
|
||||||
&& !smb1cli_conn_check_signing(cli->conn, (uint8_t *)in, 1)) {
|
|
||||||
tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (state->session_key.data) {
|
|
||||||
struct smbXcli_session *session = state->cli->smb1.session;
|
|
||||||
|
|
||||||
status = smb1cli_session_set_session_key(session,
|
|
||||||
state->session_key);
|
|
||||||
if (tevent_req_nterror(req, status)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tevent_req_done(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
|
|
||||||
{
|
|
||||||
return tevent_req_simple_recv_ntstatus(req);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The following is calculated from :
|
/* The following is calculated from :
|
||||||
* (smb_size-4) = 35
|
* (smb_size-4) = 35
|
||||||
* (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
|
* (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
|
||||||
|
Reference in New Issue
Block a user