doc: Update doc about talloc vs malloc speed
[Samba.git] / libcli / smb / smb1cli_session.c
bloba8ad9b8769597d4893107e5c23b15c99f234dde2
1 /*
2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
8 Copyright (C) Stefan Metzmacher 2016
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "system/network.h"
26 #include "../lib/util/tevent_ntstatus.h"
27 #include "../libcli/smb/smb_common.h"
28 #include "../libcli/smb/smbXcli_base.h"
31 struct smb1cli_session_setup_lm21_state {
32 struct smbXcli_session *session;
33 uint16_t vwv[10];
34 struct iovec *recv_iov;
35 uint16_t out_session_id;
36 uint16_t out_action;
37 char *out_native_os;
38 char *out_native_lm;
41 static void smb1cli_session_setup_lm21_done(struct tevent_req *subreq);
43 struct tevent_req *smb1cli_session_setup_lm21_send(TALLOC_CTX *mem_ctx,
44 struct tevent_context *ev,
45 struct smbXcli_conn *conn,
46 uint32_t timeout_msec,
47 uint32_t pid,
48 struct smbXcli_session *session,
49 uint16_t in_buf_size,
50 uint16_t in_mpx_max,
51 uint16_t in_vc_num,
52 uint32_t in_sess_key,
53 const char *in_user,
54 const char *in_domain,
55 const DATA_BLOB in_apassword,
56 const char *in_native_os,
57 const char *in_native_lm)
59 struct tevent_req *req = NULL;
60 struct smb1cli_session_setup_lm21_state *state = NULL;
61 struct tevent_req *subreq = NULL;
62 uint16_t *vwv = NULL;
63 uint8_t *bytes = NULL;
65 req = tevent_req_create(mem_ctx, &state,
66 struct smb1cli_session_setup_lm21_state);
67 if (req == NULL) {
68 return NULL;
70 state->session = session;
71 vwv = state->vwv;
73 if (in_user == NULL) {
74 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
75 return tevent_req_post(req, ev);
78 if (in_domain == NULL) {
79 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
80 return tevent_req_post(req, ev);
83 if (in_apassword.length > UINT16_MAX) {
84 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
85 return tevent_req_post(req, ev);
88 if (in_native_os == NULL && in_native_lm != NULL) {
89 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
90 return tevent_req_post(req, ev);
93 SCVAL(vwv+0, 0, 0xff);
94 SCVAL(vwv+0, 1, 0);
95 SSVAL(vwv+1, 0, 0);
96 SSVAL(vwv+2, 0, in_buf_size);
97 SSVAL(vwv+3, 0, in_mpx_max);
98 SSVAL(vwv+4, 0, in_vc_num);
99 SIVAL(vwv+5, 0, in_sess_key);
100 SSVAL(vwv+7, 0, in_apassword.length);
101 SSVAL(vwv+8, 0, 0); /* reserved */
102 SSVAL(vwv+9, 0, 0); /* reserved */
104 bytes = talloc_array(state, uint8_t,
105 in_apassword.length);
106 if (tevent_req_nomem(bytes, req)) {
107 return tevent_req_post(req, ev);
109 if (in_apassword.length != 0) {
110 memcpy(bytes,
111 in_apassword.data,
112 in_apassword.length);
115 bytes = smb_bytes_push_str(bytes,
116 smbXcli_conn_use_unicode(conn),
117 in_user, strlen(in_user)+1,
118 NULL);
119 bytes = smb_bytes_push_str(bytes,
120 smbXcli_conn_use_unicode(conn),
121 in_domain, strlen(in_domain)+1,
122 NULL);
123 if (in_native_os != NULL) {
124 bytes = smb_bytes_push_str(bytes,
125 smbXcli_conn_use_unicode(conn),
126 in_native_os, strlen(in_native_os)+1,
127 NULL);
129 if (in_native_lm != NULL) {
130 bytes = smb_bytes_push_str(bytes,
131 smbXcli_conn_use_unicode(conn),
132 in_native_lm, strlen(in_native_lm)+1,
133 NULL);
135 if (tevent_req_nomem(bytes, req)) {
136 return tevent_req_post(req, ev);
139 subreq = smb1cli_req_send(state, ev, conn,
140 SMBsesssetupX,
141 0, /* additional_flags */
142 0, /* clear_flags */
143 0, /* additional_flags2 */
144 0, /* clear_flags2 */
145 timeout_msec,
146 pid,
147 NULL, /* tcon */
148 session,
149 10, /* wct */
150 vwv,
151 talloc_get_size(bytes),
152 bytes);
153 if (tevent_req_nomem(subreq, req)) {
154 return tevent_req_post(req, ev);
156 tevent_req_set_callback(subreq, smb1cli_session_setup_lm21_done, req);
158 return req;
161 static void smb1cli_session_setup_lm21_done(struct tevent_req *subreq)
163 struct tevent_req *req =
164 tevent_req_callback_data(subreq,
165 struct tevent_req);
166 struct smb1cli_session_setup_lm21_state *state =
167 tevent_req_data(req,
168 struct smb1cli_session_setup_lm21_state);
169 NTSTATUS status;
170 uint8_t *inhdr = NULL;
171 uint8_t wct;
172 uint16_t *vwv = NULL;
173 uint32_t num_bytes;
174 uint8_t *bytes = NULL;
175 const uint8_t *p = NULL;
176 size_t ret = 0;
177 uint16_t flags2;
178 bool use_unicode = false;
179 struct smb1cli_req_expected_response expected[] = {
181 .status = NT_STATUS_OK,
182 .wct = 3,
186 status = smb1cli_req_recv(subreq, state,
187 &state->recv_iov,
188 &inhdr,
189 &wct,
190 &vwv,
191 NULL, /* pvwv_offset */
192 &num_bytes,
193 &bytes,
194 NULL, /* pbytes_offset */
195 NULL, /* pinbuf */
196 expected, ARRAY_SIZE(expected));
197 TALLOC_FREE(subreq);
198 if (tevent_req_nterror(req, status)) {
199 return;
202 flags2 = SVAL(inhdr, HDR_FLG2);
203 if (flags2 & FLAGS2_UNICODE_STRINGS) {
204 use_unicode = true;
207 state->out_session_id = SVAL(inhdr, HDR_UID);
208 state->out_action = SVAL(vwv+2, 0);
210 p = bytes;
212 status = smb_bytes_pull_str(state, &state->out_native_os,
213 use_unicode, bytes, num_bytes,
214 p, &ret);
215 if (tevent_req_nterror(req, status)) {
216 return;
218 p += ret;
220 status = smb_bytes_pull_str(state, &state->out_native_lm,
221 use_unicode, bytes, num_bytes,
222 p, &ret);
223 if (tevent_req_nterror(req, status)) {
224 return;
227 smb1cli_session_set_id(state->session, state->out_session_id);
228 smb1cli_session_set_action(state->session, state->out_action);
230 tevent_req_done(req);
233 NTSTATUS smb1cli_session_setup_lm21_recv(struct tevent_req *req,
234 TALLOC_CTX *mem_ctx,
235 char **out_native_os,
236 char **out_native_lm)
238 struct smb1cli_session_setup_lm21_state *state =
239 tevent_req_data(req,
240 struct smb1cli_session_setup_lm21_state);
241 NTSTATUS status;
243 if (tevent_req_is_nterror(req, &status)) {
244 tevent_req_received(req);
245 return status;
248 if (out_native_os != NULL) {
249 *out_native_os = talloc_move(mem_ctx, &state->out_native_os);
252 if (out_native_lm != NULL) {
253 *out_native_lm = talloc_move(mem_ctx, &state->out_native_lm);
256 tevent_req_received(req);
257 return NT_STATUS_OK;
260 struct smb1cli_session_setup_nt1_state {
261 struct smbXcli_session *session;
262 uint16_t vwv[13];
263 struct iovec *recv_iov;
264 uint8_t *inbuf;
265 uint16_t out_session_id;
266 uint16_t out_action;
267 char *out_native_os;
268 char *out_native_lm;
269 char *out_primary_domain;
272 static void smb1cli_session_setup_nt1_done(struct tevent_req *subreq);
274 struct tevent_req *smb1cli_session_setup_nt1_send(TALLOC_CTX *mem_ctx,
275 struct tevent_context *ev,
276 struct smbXcli_conn *conn,
277 uint32_t timeout_msec,
278 uint32_t pid,
279 struct smbXcli_session *session,
280 uint16_t in_buf_size,
281 uint16_t in_mpx_max,
282 uint16_t in_vc_num,
283 uint32_t in_sess_key,
284 const char *in_user,
285 const char *in_domain,
286 const DATA_BLOB in_apassword,
287 const DATA_BLOB in_upassword,
288 uint32_t in_capabilities,
289 const char *in_native_os,
290 const char *in_native_lm)
292 struct tevent_req *req = NULL;
293 struct smb1cli_session_setup_nt1_state *state = NULL;
294 struct tevent_req *subreq = NULL;
295 uint16_t *vwv = NULL;
296 uint8_t *bytes = NULL;
297 size_t align_upassword = 0;
298 size_t apassword_ofs = 0;
299 size_t upassword_ofs = 0;
301 req = tevent_req_create(mem_ctx, &state,
302 struct smb1cli_session_setup_nt1_state);
303 if (req == NULL) {
304 return NULL;
306 state->session = session;
307 vwv = state->vwv;
309 if (in_user == NULL) {
310 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
311 return tevent_req_post(req, ev);
314 if (in_domain == NULL) {
315 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
316 return tevent_req_post(req, ev);
319 if (in_apassword.length > UINT16_MAX) {
320 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
321 return tevent_req_post(req, ev);
324 if (in_upassword.length > UINT16_MAX) {
325 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
326 return tevent_req_post(req, ev);
329 if (in_native_os == NULL && in_native_lm != NULL) {
330 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
331 return tevent_req_post(req, ev);
334 SCVAL(vwv+0, 0, 0xff);
335 SCVAL(vwv+0, 1, 0);
336 SSVAL(vwv+1, 0, 0);
337 SSVAL(vwv+2, 0, in_buf_size);
338 SSVAL(vwv+3, 0, in_mpx_max);
339 SSVAL(vwv+4, 0, in_vc_num);
340 SIVAL(vwv+5, 0, in_sess_key);
341 SSVAL(vwv+7, 0, in_apassword.length);
342 SSVAL(vwv+8, 0, in_upassword.length);
343 SSVAL(vwv+9, 0, 0); /* reserved */
344 SSVAL(vwv+10, 0, 0); /* reserved */
345 SIVAL(vwv+11, 0, in_capabilities);
347 if (in_apassword.length == 0 && in_upassword.length > 0) {
349 * This is plaintext auth with a unicode password,
350 * we need to align the buffer.
352 * This is what smbclient and Windows XP send as
353 * a client. And what smbd expects.
355 * But it doesn't follow [MS-CIFS] (v20160714)
356 * 2.2.4.53.1 SMB_COM_SESSION_SETUP_ANDX Request:
358 * ...
360 * If SMB_FLAGS2_UNICODE is set (1), the value of OEMPasswordLen
361 * MUST be 0x0000 and the password MUST be encoded using
362 * UTF-16LE Unicode. Padding MUST NOT be added to
363 * align this plaintext Unicode string to a word boundary.
365 * ...
367 uint16_t security_mode = smb1cli_conn_server_security_mode(conn);
369 if (!(security_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) {
370 align_upassword = 1;
374 bytes = talloc_array(state, uint8_t,
375 in_apassword.length +
376 align_upassword +
377 in_upassword.length);
378 if (tevent_req_nomem(bytes, req)) {
379 return tevent_req_post(req, ev);
381 if (in_apassword.length != 0) {
382 memcpy(bytes + apassword_ofs,
383 in_apassword.data,
384 in_apassword.length);
385 upassword_ofs += in_apassword.length;
387 if (align_upassword != 0) {
388 memset(bytes + upassword_ofs, 0, align_upassword);
389 upassword_ofs += align_upassword;
391 if (in_upassword.length != 0) {
392 memcpy(bytes + upassword_ofs,
393 in_upassword.data,
394 in_upassword.length);
397 bytes = smb_bytes_push_str(bytes,
398 smbXcli_conn_use_unicode(conn),
399 in_user, strlen(in_user)+1,
400 NULL);
401 bytes = smb_bytes_push_str(bytes,
402 smbXcli_conn_use_unicode(conn),
403 in_domain, strlen(in_domain)+1,
404 NULL);
405 if (in_native_os != NULL) {
406 bytes = smb_bytes_push_str(bytes,
407 smbXcli_conn_use_unicode(conn),
408 in_native_os, strlen(in_native_os)+1,
409 NULL);
411 if (in_native_lm != NULL) {
412 bytes = smb_bytes_push_str(bytes,
413 smbXcli_conn_use_unicode(conn),
414 in_native_lm, strlen(in_native_lm)+1,
415 NULL);
417 if (tevent_req_nomem(bytes, req)) {
418 return tevent_req_post(req, ev);
421 subreq = smb1cli_req_send(state, ev, conn,
422 SMBsesssetupX,
423 0, /* additional_flags */
424 0, /* clear_flags */
425 0, /* additional_flags2 */
426 0, /* clear_flags2 */
427 timeout_msec,
428 pid,
429 NULL, /* tcon */
430 session,
431 13, /* wct */
432 vwv,
433 talloc_get_size(bytes),
434 bytes);
435 if (tevent_req_nomem(subreq, req)) {
436 return tevent_req_post(req, ev);
438 tevent_req_set_callback(subreq, smb1cli_session_setup_nt1_done, req);
440 return req;
443 static void smb1cli_session_setup_nt1_done(struct tevent_req *subreq)
445 struct tevent_req *req =
446 tevent_req_callback_data(subreq,
447 struct tevent_req);
448 struct smb1cli_session_setup_nt1_state *state =
449 tevent_req_data(req,
450 struct smb1cli_session_setup_nt1_state);
451 NTSTATUS status;
452 uint8_t *inhdr = NULL;
453 uint8_t wct;
454 uint16_t *vwv = NULL;
455 uint32_t num_bytes;
456 uint8_t *bytes = NULL;
457 const uint8_t *p = NULL;
458 size_t ret = 0;
459 uint16_t flags2;
460 bool use_unicode = false;
461 struct smb1cli_req_expected_response expected[] = {
463 .status = NT_STATUS_OK,
464 .wct = 3,
468 status = smb1cli_req_recv(subreq, state,
469 &state->recv_iov,
470 &inhdr,
471 &wct,
472 &vwv,
473 NULL, /* pvwv_offset */
474 &num_bytes,
475 &bytes,
476 NULL, /* pbytes_offset */
477 &state->inbuf,
478 expected, ARRAY_SIZE(expected));
479 TALLOC_FREE(subreq);
480 if (tevent_req_nterror(req, status)) {
481 return;
484 flags2 = SVAL(inhdr, HDR_FLG2);
485 if (flags2 & FLAGS2_UNICODE_STRINGS) {
486 use_unicode = true;
489 state->out_session_id = SVAL(inhdr, HDR_UID);
490 state->out_action = SVAL(vwv+2, 0);
492 p = bytes;
494 status = smb_bytes_pull_str(state, &state->out_native_os,
495 use_unicode, bytes, num_bytes,
496 p, &ret);
497 if (tevent_req_nterror(req, status)) {
498 return;
500 p += ret;
502 status = smb_bytes_pull_str(state, &state->out_native_lm,
503 use_unicode, bytes, num_bytes,
504 p, &ret);
505 if (tevent_req_nterror(req, status)) {
506 return;
508 p += ret;
510 status = smb_bytes_pull_str(state, &state->out_primary_domain,
511 use_unicode, bytes, num_bytes,
512 p, &ret);
513 if (tevent_req_nterror(req, status)) {
514 return;
517 smb1cli_session_set_id(state->session, state->out_session_id);
518 smb1cli_session_set_action(state->session, state->out_action);
520 tevent_req_done(req);
523 NTSTATUS smb1cli_session_setup_nt1_recv(struct tevent_req *req,
524 TALLOC_CTX *mem_ctx,
525 struct iovec **precv_iov,
526 const uint8_t **precv_inbuf,
527 char **out_native_os,
528 char **out_native_lm,
529 char **out_primary_domain)
531 struct smb1cli_session_setup_nt1_state *state =
532 tevent_req_data(req,
533 struct smb1cli_session_setup_nt1_state);
534 NTSTATUS status;
535 struct iovec *recv_iov = NULL;
537 if (tevent_req_is_nterror(req, &status)) {
538 tevent_req_received(req);
539 return status;
542 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
543 if (precv_iov != NULL) {
544 *precv_iov = recv_iov;
546 if (precv_inbuf != NULL) {
547 *precv_inbuf = state->inbuf;
550 if (out_native_os != NULL) {
551 *out_native_os = talloc_move(mem_ctx, &state->out_native_os);
554 if (out_native_lm != NULL) {
555 *out_native_lm = talloc_move(mem_ctx, &state->out_native_lm);
558 if (out_primary_domain != NULL) {
559 *out_primary_domain = talloc_move(mem_ctx,
560 &state->out_primary_domain);
563 tevent_req_received(req);
564 return NT_STATUS_OK;
567 struct smb1cli_session_setup_ext_state {
568 struct smbXcli_session *session;
569 uint16_t vwv[12];
570 struct iovec *recv_iov;
571 uint8_t *inbuf;
572 NTSTATUS status;
573 uint16_t out_session_id;
574 uint16_t out_action;
575 DATA_BLOB out_security_blob;
576 char *out_native_os;
577 char *out_native_lm;
580 static void smb1cli_session_setup_ext_done(struct tevent_req *subreq);
582 struct tevent_req *smb1cli_session_setup_ext_send(TALLOC_CTX *mem_ctx,
583 struct tevent_context *ev,
584 struct smbXcli_conn *conn,
585 uint32_t timeout_msec,
586 uint32_t pid,
587 struct smbXcli_session *session,
588 uint16_t in_buf_size,
589 uint16_t in_mpx_max,
590 uint16_t in_vc_num,
591 uint32_t in_sess_key,
592 const DATA_BLOB in_security_blob,
593 uint32_t in_capabilities,
594 const char *in_native_os,
595 const char *in_native_lm)
597 struct tevent_req *req = NULL;
598 struct smb1cli_session_setup_ext_state *state = NULL;
599 struct tevent_req *subreq = NULL;
600 uint16_t *vwv = NULL;
601 uint8_t *bytes = NULL;
603 req = tevent_req_create(mem_ctx, &state,
604 struct smb1cli_session_setup_ext_state);
605 if (req == NULL) {
606 return NULL;
608 state->session = session;
609 vwv = state->vwv;
611 if (in_security_blob.length > UINT16_MAX) {
612 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
613 return tevent_req_post(req, ev);
616 if (in_native_os == NULL && in_native_lm != NULL) {
617 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
618 return tevent_req_post(req, ev);
621 SCVAL(vwv+0, 0, 0xff);
622 SCVAL(vwv+0, 1, 0);
623 SSVAL(vwv+1, 0, 0);
624 SSVAL(vwv+2, 0, in_buf_size);
625 SSVAL(vwv+3, 0, in_mpx_max);
626 SSVAL(vwv+4, 0, in_vc_num);
627 SIVAL(vwv+5, 0, in_sess_key);
628 SSVAL(vwv+7, 0, in_security_blob.length);
629 SSVAL(vwv+8, 0, 0); /* reserved */
630 SSVAL(vwv+9, 0, 0); /* reserved */
631 SIVAL(vwv+10, 0, in_capabilities);
633 bytes = talloc_array(state, uint8_t,
634 in_security_blob.length);
635 if (tevent_req_nomem(bytes, req)) {
636 return tevent_req_post(req, ev);
638 if (in_security_blob.length != 0) {
639 memcpy(bytes,
640 in_security_blob.data,
641 in_security_blob.length);
644 if (in_native_os != NULL) {
645 bytes = smb_bytes_push_str(bytes,
646 smbXcli_conn_use_unicode(conn),
647 in_native_os, strlen(in_native_os)+1,
648 NULL);
650 if (in_native_lm != NULL) {
651 bytes = smb_bytes_push_str(bytes,
652 smbXcli_conn_use_unicode(conn),
653 in_native_lm, strlen(in_native_lm)+1,
654 NULL);
656 if (tevent_req_nomem(bytes, req)) {
657 return tevent_req_post(req, ev);
660 subreq = smb1cli_req_send(state, ev, conn,
661 SMBsesssetupX,
662 0, /* additional_flags */
663 0, /* clear_flags */
664 0, /* additional_flags2 */
665 0, /* clear_flags2 */
666 timeout_msec,
667 pid,
668 NULL, /* tcon */
669 session,
670 12, /* wct */
671 vwv,
672 talloc_get_size(bytes),
673 bytes);
674 if (tevent_req_nomem(subreq, req)) {
675 return tevent_req_post(req, ev);
677 tevent_req_set_callback(subreq, smb1cli_session_setup_ext_done, req);
679 return req;
682 static void smb1cli_session_setup_ext_done(struct tevent_req *subreq)
684 struct tevent_req *req =
685 tevent_req_callback_data(subreq,
686 struct tevent_req);
687 struct smb1cli_session_setup_ext_state *state =
688 tevent_req_data(req,
689 struct smb1cli_session_setup_ext_state);
690 NTSTATUS status;
691 uint8_t *inhdr = NULL;
692 uint8_t wct;
693 uint16_t *vwv = NULL;
694 uint32_t num_bytes;
695 uint8_t *bytes = NULL;
696 const uint8_t *p = NULL;
697 size_t ret = 0;
698 uint16_t flags2;
699 uint16_t out_security_blob_length = 0;
700 bool use_unicode = false;
701 struct smb1cli_req_expected_response expected[] = {
703 .status = NT_STATUS_OK,
704 .wct = 4,
707 .status = NT_STATUS_MORE_PROCESSING_REQUIRED,
708 .wct = 4,
712 status = smb1cli_req_recv(subreq, state,
713 &state->recv_iov,
714 &inhdr,
715 &wct,
716 &vwv,
717 NULL, /* pvwv_offset */
718 &num_bytes,
719 &bytes,
720 NULL, /* pbytes_offset */
721 &state->inbuf,
722 expected, ARRAY_SIZE(expected));
723 TALLOC_FREE(subreq);
724 state->status = status;
725 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
726 status = NT_STATUS_OK;
728 if (tevent_req_nterror(req, status)) {
729 return;
732 flags2 = SVAL(inhdr, HDR_FLG2);
733 if (flags2 & FLAGS2_UNICODE_STRINGS) {
734 use_unicode = true;
737 state->out_session_id = SVAL(inhdr, HDR_UID);
738 state->out_action = SVAL(vwv+2, 0);
739 out_security_blob_length = SVAL(vwv+3, 0);
741 if (out_security_blob_length > num_bytes) {
742 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
743 return;
746 p = bytes;
749 * Note: this points into state->recv_iov!
751 state->out_security_blob = data_blob_const(p, out_security_blob_length);
752 p += out_security_blob_length;
754 status = smb_bytes_pull_str(state, &state->out_native_os,
755 use_unicode, bytes, num_bytes,
756 p, &ret);
757 if (tevent_req_nterror(req, status)) {
758 return;
760 p += ret;
762 status = smb_bytes_pull_str(state, &state->out_native_lm,
763 use_unicode, bytes, num_bytes,
764 p, &ret);
765 if (tevent_req_nterror(req, status)) {
766 return;
768 /* p += ret; */
770 smb1cli_session_set_id(state->session, state->out_session_id);
771 smb1cli_session_set_action(state->session, state->out_action);
773 tevent_req_done(req);
776 NTSTATUS smb1cli_session_setup_ext_recv(struct tevent_req *req,
777 TALLOC_CTX *mem_ctx,
778 struct iovec **precv_iov,
779 const uint8_t **precv_inbuf,
780 DATA_BLOB *out_security_blob,
781 char **out_native_os,
782 char **out_native_lm)
784 struct smb1cli_session_setup_ext_state *state =
785 tevent_req_data(req,
786 struct smb1cli_session_setup_ext_state);
787 NTSTATUS status;
788 struct iovec *recv_iov = NULL;
790 if (tevent_req_is_nterror(req, &status)) {
791 tevent_req_received(req);
792 return status;
795 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
796 if (precv_iov != NULL) {
797 *precv_iov = recv_iov;
799 if (precv_inbuf != NULL) {
800 *precv_inbuf = state->inbuf;
803 *out_security_blob = state->out_security_blob;
805 if (out_native_os != NULL) {
806 *out_native_os = talloc_move(mem_ctx, &state->out_native_os);
809 if (out_native_lm != NULL) {
810 *out_native_lm = talloc_move(mem_ctx, &state->out_native_lm);
814 * Return the status from the server:
815 * NT_STATUS_MORE_PROCESSING_REQUIRED or
816 * NT_STATUS_OK.
818 status = state->status;
819 tevent_req_received(req);
820 return status;