diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 04b21d577c5..8c47b780290 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -74,225 +74,6 @@ static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx, 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. ****************************************************************************/ @@ -497,491 +278,6 @@ NTSTATUS cli_session_setup_guest_recv(struct tevent_req *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 : * (smb_size-4) = 35 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )