s3:smbd: use PROTOCOL_SMB2_02 instead PROTOCOL_SMB2
[Samba/gebeck_regimport.git] / source3 / libsmb / smb2cli_negprot.c
blob305632283fd3f393890b5e5774cd798f673dadde
1 /*
2 Unix SMB/CIFS implementation.
3 smb2 lib
4 Copyright (C) Volker Lendecke 2011
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "client.h"
22 #include "async_smb.h"
23 #include "smb2cli_base.h"
24 #include "smb2cli.h"
25 #include "libsmb/proto.h"
26 #include "librpc/ndr/libndr.h"
27 #include "lib/util/tevent_ntstatus.h"
29 struct smb2cli_negprot_state {
30 struct cli_state *cli;
31 uint8_t fixed[36];
32 uint8_t dyn[4];
35 static void smb2cli_negprot_done(struct tevent_req *subreq);
37 struct tevent_req *smb2cli_negprot_send(TALLOC_CTX *mem_ctx,
38 struct tevent_context *ev,
39 struct cli_state *cli)
41 struct tevent_req *req, *subreq;
42 struct smb2cli_negprot_state *state;
43 uint8_t *buf;
45 req = tevent_req_create(mem_ctx, &state,
46 struct smb2cli_negprot_state);
47 if (req == NULL) {
48 return NULL;
50 state->cli = cli;
52 buf = state->fixed;
53 SSVAL(buf, 0, 36);
54 SSVAL(buf, 2, 2); /* DialectCount */
55 if (client_is_signing_mandatory(cli)) {
56 SSVAL(buf, 4, SMB2_NEGOTIATE_SIGNING_REQUIRED);
57 } else {
58 SSVAL(buf, 4, SMB2_NEGOTIATE_SIGNING_ENABLED);
60 SSVAL(buf, 6, 0); /* Reserved */
61 SSVAL(buf, 8, 0); /* Capabilities */
62 memset(buf+12, 0, 16); /* ClientGuid */
63 SBVAL(buf, 28, 0); /* ClientStartTime */
65 buf = state->dyn;
66 SSVAL(buf, 0, 0x202); /* SMB2.002 */
67 SSVAL(buf, 2, 0x210); /* SMB2.1 */
69 subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_NEGPROT, 0,
70 state->fixed, sizeof(state->fixed),
71 state->dyn, sizeof(state->dyn));
72 if (tevent_req_nomem(subreq, req)) {
73 return tevent_req_post(req, ev);
75 tevent_req_set_callback(subreq, smb2cli_negprot_done, req);
76 return req;
79 static void smb2cli_negprot_done(struct tevent_req *subreq)
81 struct tevent_req *req =
82 tevent_req_callback_data(subreq,
83 struct tevent_req);
84 struct smb2cli_negprot_state *state =
85 tevent_req_data(req,
86 struct smb2cli_negprot_state);
87 struct cli_state *cli = state->cli;
88 size_t security_offset, security_length;
89 DATA_BLOB blob;
90 NTSTATUS status;
91 struct iovec *iov;
92 uint8_t *body;
94 status = smb2cli_req_recv(subreq, talloc_tos(), &iov, 65);
95 if (!NT_STATUS_IS_OK(status)) {
96 TALLOC_FREE(subreq);
97 tevent_req_nterror(req, status);
98 return;
100 body = (uint8_t *)iov[1].iov_base;
102 cli->smb2.security_mode = SVAL(body, 2);
103 cli->smb2.dialect_revision = SVAL(body, 4);
105 blob = data_blob_const(body + 8, 16);
106 GUID_from_data_blob(&blob, &cli->smb2.server_guid);
108 cli->smb2.server_capabilities = IVAL(body, 24);
109 cli->smb2.max_transact_size = IVAL(body, 28);
110 cli->smb2.max_read_size = IVAL(body, 32);
111 cli->smb2.max_write_size = IVAL(body, 36);
112 cli->smb2.system_time = interpret_long_date((char *)body + 40);
113 cli->smb2.server_start_time = interpret_long_date((char *)body + 48);
115 security_offset = SVAL(body, 56);
116 security_length = SVAL(body, 58);
118 if ((security_offset != SMB2_HDR_BODY + iov[1].iov_len) ||
119 (security_length > iov[2].iov_len)) {
120 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
121 return;
123 cli->secblob = data_blob(iov[1].iov_base, security_length);
125 tevent_req_done(req);
128 NTSTATUS smb2cli_negprot_recv(struct tevent_req *req)
130 return tevent_req_simple_recv_ntstatus(req);
133 NTSTATUS smb2cli_negprot(struct cli_state *cli)
135 TALLOC_CTX *frame = talloc_stackframe();
136 struct event_context *ev;
137 struct tevent_req *req;
138 NTSTATUS status = NT_STATUS_NO_MEMORY;
140 if (cli_has_async_calls(cli)) {
142 * Can't use sync call while an async call is in flight
144 status = NT_STATUS_INVALID_PARAMETER;
145 goto fail;
147 ev = event_context_init(frame);
148 if (ev == NULL) {
149 goto fail;
151 req = smb2cli_negprot_send(frame, ev, cli);
152 if (req == NULL) {
153 goto fail;
155 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
156 goto fail;
158 status = smb2cli_negprot_recv(req);
159 fail:
160 TALLOC_FREE(frame);
161 return status;