diff options
author | Andreas Schneider <asn@samba.org> | 2016-11-03 16:28:12 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2016-11-15 11:00:26 +0100 |
commit | 2182817c9705c16e39acae3cf4aff8b1c3d27913 (patch) | |
tree | 6d7bda059eb5424f28a260b4411a809b1ae71e6b /libcli/smb | |
parent | 4334f2dad07b610ab8e55a0c7fc9ec2f16ba5ffd (diff) | |
download | samba-2182817c9705c16e39acae3cf4aff8b1c3d27913.tar.gz |
libcli/smb: add smb1cli_session_setup_lm21_send/recv()
This does a session setup for the LANMAN 2(.1) protocol.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'libcli/smb')
-rw-r--r-- | libcli/smb/smb1cli_session.c | 259 | ||||
-rw-r--r-- | libcli/smb/smbXcli_base.h | 20 | ||||
-rwxr-xr-x | libcli/smb/wscript | 1 |
3 files changed, 280 insertions, 0 deletions
diff --git a/libcli/smb/smb1cli_session.c b/libcli/smb/smb1cli_session.c new file mode 100644 index 00000000000..1f6779a6d31 --- /dev/null +++ b/libcli/smb/smb1cli_session.c @@ -0,0 +1,259 @@ +/* + Unix SMB/CIFS implementation. + client connect/disconnect routines + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Andrew Bartlett 2001-2003 + Copyright (C) Volker Lendecke 2011 + Copyright (C) Jeremy Allison 2011 + Copyright (C) Stefan Metzmacher 2016 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "system/network.h" +#include "../lib/util/tevent_ntstatus.h" +#include "../libcli/smb/smb_common.h" +#include "../libcli/smb/smbXcli_base.h" + + +struct smb1cli_session_setup_lm21_state { + struct smbXcli_session *session; + uint16_t vwv[10]; + struct iovec *recv_iov; + uint16_t out_session_id; + uint16_t out_action; + char *out_native_os; + char *out_native_lm; +}; + +static void smb1cli_session_setup_lm21_done(struct tevent_req *subreq); + +struct tevent_req *smb1cli_session_setup_lm21_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn, + uint32_t timeout_msec, + uint32_t pid, + struct smbXcli_session *session, + uint16_t in_buf_size, + uint16_t in_mpx_max, + uint16_t in_vc_num, + uint32_t in_sess_key, + const char *in_user, + const char *in_domain, + const DATA_BLOB in_apassword, + const char *in_native_os, + const char *in_native_lm) +{ + struct tevent_req *req = NULL; + struct smb1cli_session_setup_lm21_state *state = NULL; + struct tevent_req *subreq = NULL; + uint16_t *vwv = NULL; + uint8_t *bytes = NULL; + + req = tevent_req_create(mem_ctx, &state, + struct smb1cli_session_setup_lm21_state); + if (req == NULL) { + return NULL; + } + state->session = session; + vwv = state->vwv; + + if (in_user == NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); + } + + if (in_domain == NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); + } + + if (in_apassword.length > UINT16_MAX) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); + } + + if (in_native_os == NULL && in_native_lm != NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + 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, in_buf_size); + SSVAL(vwv+3, 0, in_mpx_max); + SSVAL(vwv+4, 0, in_vc_num); + SIVAL(vwv+5, 0, in_sess_key); + SSVAL(vwv+7, 0, in_apassword.length); + SSVAL(vwv+8, 0, 0); /* reserved */ + SSVAL(vwv+9, 0, 0); /* reserved */ + + bytes = talloc_array(state, uint8_t, + in_apassword.length); + if (tevent_req_nomem(bytes, req)) { + return tevent_req_post(req, ev); + } + if (in_apassword.length != 0) { + memcpy(bytes, + in_apassword.data, + in_apassword.length); + } + + bytes = smb_bytes_push_str(bytes, + smbXcli_conn_use_unicode(conn), + in_user, strlen(in_user)+1, + NULL); + bytes = smb_bytes_push_str(bytes, + smbXcli_conn_use_unicode(conn), + in_domain, strlen(in_domain)+1, + NULL); + if (in_native_os != NULL) { + bytes = smb_bytes_push_str(bytes, + smbXcli_conn_use_unicode(conn), + in_native_os, strlen(in_native_os)+1, + NULL); + } + if (in_native_lm != NULL) { + bytes = smb_bytes_push_str(bytes, + smbXcli_conn_use_unicode(conn), + in_native_lm, strlen(in_native_lm)+1, + NULL); + } + if (tevent_req_nomem(bytes, req)) { + return tevent_req_post(req, ev); + } + + subreq = smb1cli_req_send(state, ev, conn, + SMBsesssetupX, + 0, /* additional_flags */ + 0, /* clear_flags */ + 0, /* additional_flags2 */ + 0, /* clear_flags2 */ + timeout_msec, + pid, + NULL, /* tcon */ + session, + 10, /* wct */ + vwv, + talloc_get_size(bytes), + bytes); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, smb1cli_session_setup_lm21_done, req); + + return req; +} + +static void smb1cli_session_setup_lm21_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct smb1cli_session_setup_lm21_state *state = + tevent_req_data(req, + struct smb1cli_session_setup_lm21_state); + NTSTATUS status; + uint8_t *inhdr = NULL; + uint8_t wct; + uint16_t *vwv = NULL; + uint32_t num_bytes; + uint8_t *bytes = NULL; + const uint8_t *p = NULL; + size_t ret = 0; + uint16_t flags2; + bool use_unicode = false; + struct smb1cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .wct = 3, + }, + }; + + status = smb1cli_req_recv(subreq, state, + &state->recv_iov, + &inhdr, + &wct, + &vwv, + NULL, /* pvwv_offset */ + &num_bytes, + &bytes, + NULL, /* pbytes_offset */ + NULL, /* pinbuf */ + expected, ARRAY_SIZE(expected)); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + flags2 = SVAL(inhdr, HDR_FLG2); + if (flags2 & FLAGS2_UNICODE_STRINGS) { + use_unicode = true; + } + + state->out_session_id = SVAL(inhdr, HDR_UID); + state->out_action = SVAL(vwv+2, 0); + + p = bytes; + + status = smb_bytes_pull_str(state, &state->out_native_os, + use_unicode, p, + bytes+num_bytes-p, &ret); + if (tevent_req_nterror(req, status)) { + return; + } + p += ret; + + status = smb_bytes_pull_str(state, &state->out_native_lm, + use_unicode, p, + bytes+num_bytes-p, &ret); + if (tevent_req_nterror(req, status)) { + return; + } + p += ret; + + smb1cli_session_set_id(state->session, state->out_session_id); + smb1cli_session_set_action(state->session, state->out_action); + + tevent_req_done(req); +} + +NTSTATUS smb1cli_session_setup_lm21_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + char **out_native_os, + char **out_native_lm) +{ + struct smb1cli_session_setup_lm21_state *state = + tevent_req_data(req, + struct smb1cli_session_setup_lm21_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + if (out_native_os != NULL) { + *out_native_os = talloc_move(mem_ctx, &state->out_native_os); + } + + if (out_native_lm != NULL) { + *out_native_lm = talloc_move(mem_ctx, &state->out_native_lm); + } + + tevent_req_received(req); + return NT_STATUS_OK; +} diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index 16c8848dd12..c1a9c701611 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -201,6 +201,26 @@ NTSTATUS smb1cli_echo_recv(struct tevent_req *req); NTSTATUS smb1cli_echo(struct smbXcli_conn *conn, uint32_t timeout_msec, uint16_t num_echos, DATA_BLOB data); +struct tevent_req *smb1cli_session_setup_lm21_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn, + uint32_t timeout_msec, + uint32_t pid, + struct smbXcli_session *session, + uint16_t in_buf_size, + uint16_t in_mpx_max, + uint16_t in_vc_num, + uint32_t in_sess_key, + const char *in_user, + const char *in_domain, + const DATA_BLOB in_password, + const char *in_native_os, + const char *in_native_lm); +NTSTATUS smb1cli_session_setup_lm21_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + char **out_native_os, + char **out_native_lm); + struct tevent_req *smb1cli_ntcreatex_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct smbXcli_conn *conn, diff --git a/libcli/smb/wscript b/libcli/smb/wscript index aa124457be5..dacf631810d 100755 --- a/libcli/smb/wscript +++ b/libcli/smb/wscript @@ -26,6 +26,7 @@ def build(bld): smb1cli_trans.c smb1cli_echo.c smb1cli_create.c + smb1cli_session.c smb1cli_close.c smb1cli_write.c smb1cli_read.c |