2 Unix SMB/CIFS implementation.
3 client transaction calls
4 Copyright (C) Andrew Tridgell 1994-1998
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/>.
21 #include "libsmb/libsmb.h"
22 #include "../lib/util/tevent_ntstatus.h"
23 #include "async_smb.h"
25 struct trans_recvblob
{
27 uint32_t max
, total
, received
;
30 struct cli_trans_state
{
31 struct cli_state
*cli
;
32 struct tevent_context
*ev
;
35 const char *pipe_name
;
36 uint8_t *pipe_name_conv
;
37 size_t pipe_name_conv_len
;
42 uint8_t num_setup
, max_setup
;
44 uint32_t num_param
, param_sent
;
46 uint32_t num_data
, data_sent
;
50 struct trans_recvblob rparam
;
51 struct trans_recvblob rdata
;
59 struct tevent_req
*primary_subreq
;
62 static void cli_trans_cleanup_primary(struct cli_trans_state
*state
)
64 if (state
->primary_subreq
) {
65 cli_smb_req_set_mid(state
->primary_subreq
, 0);
66 cli_smb_req_unset_pending(state
->primary_subreq
);
67 TALLOC_FREE(state
->primary_subreq
);
71 static int cli_trans_state_destructor(struct cli_trans_state
*state
)
73 cli_trans_cleanup_primary(state
);
77 static NTSTATUS
cli_pull_trans(uint8_t *inbuf
,
78 uint8_t wct
, uint16_t *vwv
,
79 uint16_t num_bytes
, uint8_t *bytes
,
80 uint8_t smb_cmd
, bool expect_first_reply
,
81 uint8_t *pnum_setup
, uint16_t **psetup
,
82 uint32_t *ptotal_param
, uint32_t *pnum_param
,
83 uint32_t *pparam_disp
, uint8_t **pparam
,
84 uint32_t *ptotal_data
, uint32_t *pnum_data
,
85 uint32_t *pdata_disp
, uint8_t **pdata
)
87 uint32_t param_ofs
, data_ofs
;
89 if (expect_first_reply
) {
90 if ((wct
!= 0) || (num_bytes
!= 0)) {
91 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
100 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
102 *ptotal_param
= SVAL(vwv
+ 0, 0);
103 *ptotal_data
= SVAL(vwv
+ 1, 0);
104 *pnum_param
= SVAL(vwv
+ 3, 0);
105 param_ofs
= SVAL(vwv
+ 4, 0);
106 *pparam_disp
= SVAL(vwv
+ 5, 0);
107 *pnum_data
= SVAL(vwv
+ 6, 0);
108 data_ofs
= SVAL(vwv
+ 7, 0);
109 *pdata_disp
= SVAL(vwv
+ 8, 0);
110 *pnum_setup
= CVAL(vwv
+ 9, 0);
111 if (wct
< 10 + (*pnum_setup
)) {
112 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
119 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
121 *ptotal_param
= IVAL(vwv
, 3);
122 *ptotal_data
= IVAL(vwv
, 7);
123 *pnum_param
= IVAL(vwv
, 11);
124 param_ofs
= IVAL(vwv
, 15);
125 *pparam_disp
= IVAL(vwv
, 19);
126 *pnum_data
= IVAL(vwv
, 23);
127 data_ofs
= IVAL(vwv
, 27);
128 *pdata_disp
= IVAL(vwv
, 31);
129 *pnum_setup
= CVAL(vwv
, 35);
134 return NT_STATUS_INTERNAL_ERROR
;
138 * Check for buffer overflows. data_ofs needs to be checked against
139 * the incoming buffer length, data_disp against the total
140 * length. Likewise for param_ofs/param_disp.
143 if (smb_buffer_oob(smb_len_nbt(inbuf
), param_ofs
, *pnum_param
)
144 || smb_buffer_oob(*ptotal_param
, *pparam_disp
, *pnum_param
)
145 || smb_buffer_oob(smb_len_nbt(inbuf
), data_ofs
, *pnum_data
)
146 || smb_buffer_oob(*ptotal_data
, *pdata_disp
, *pnum_data
)) {
147 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
150 *pparam
= (uint8_t *)inbuf
+ 4 + param_ofs
;
151 *pdata
= (uint8_t *)inbuf
+ 4 + data_ofs
;
156 static NTSTATUS
cli_trans_pull_blob(TALLOC_CTX
*mem_ctx
,
157 struct trans_recvblob
*blob
,
158 uint32_t total
, uint32_t thistime
,
159 uint8_t *buf
, uint32_t displacement
)
161 if (blob
->data
== NULL
) {
162 if (total
> blob
->max
) {
163 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
166 blob
->data
= talloc_array(mem_ctx
, uint8_t, total
);
167 if (blob
->data
== NULL
) {
168 return NT_STATUS_NO_MEMORY
;
172 if (total
> blob
->total
) {
173 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
177 memcpy(blob
->data
+ displacement
, buf
, thistime
);
178 blob
->received
+= thistime
;
184 static void cli_trans_format(struct cli_trans_state
*state
, uint8_t *pwct
,
187 struct cli_state
*cli
= state
->cli
;
189 struct iovec
*iov
= state
->iov
;
190 uint8_t *pad
= state
->pad
;
191 uint16_t *vwv
= state
->vwv
;
192 uint32_t param_offset
;
193 uint32_t this_param
= 0;
195 uint32_t data_offset
;
196 uint32_t this_data
= 0;
198 uint32_t useable_space
;
203 if ((state
->param_sent
!= 0) || (state
->data_sent
!= 0)) {
204 /* The secondary commands are one after the primary ones */
208 param_offset
= MIN_SMB_SIZE
;
213 iov
[0].iov_base
= (void *)pad
;
215 iov
[1].iov_base
= (void *)state
->pipe_name_conv
;
216 iov
[1].iov_len
= state
->pipe_name_conv_len
;
217 wct
= 14 + state
->num_setup
;
218 param_offset
+= iov
[0].iov_len
+ iov
[1].iov_len
;
223 pad
[1] = 'D'; /* Copy this from "old" 3.0 behaviour */
225 iov
[0].iov_base
= (void *)pad
;
227 wct
= 14 + state
->num_setup
;
238 wct
= 19 + state
->num_setup
;
245 param_offset
+= wct
* sizeof(uint16_t);
246 useable_space
= cli_state_available_size(cli
, param_offset
);
248 param_pad
= param_offset
% 4;
250 param_pad
= MIN(param_pad
, useable_space
);
251 iov
[0].iov_base
= (void *)state
->zero_pad
;
252 iov
[0].iov_len
= param_pad
;
254 param_offset
+= param_pad
;
256 useable_space
= cli_state_available_size(cli
, param_offset
);
258 if (state
->param_sent
< state
->num_param
) {
259 this_param
= MIN(state
->num_param
- state
->param_sent
,
261 iov
[0].iov_base
= (void *)(state
->param
+ state
->param_sent
);
262 iov
[0].iov_len
= this_param
;
266 data_offset
= param_offset
+ this_param
;
267 useable_space
= cli_state_available_size(cli
, data_offset
);
269 data_pad
= data_offset
% 4;
271 data_pad
= MIN(data_pad
, useable_space
);
272 iov
[0].iov_base
= (void *)state
->zero_pad
;
273 iov
[0].iov_len
= data_pad
;
275 data_offset
+= data_pad
;
277 useable_space
= cli_state_available_size(cli
, data_offset
);
279 if (state
->data_sent
< state
->num_data
) {
280 this_data
= MIN(state
->num_data
- state
->data_sent
,
282 iov
[0].iov_base
= (void *)(state
->data
+ state
->data_sent
);
283 iov
[0].iov_len
= this_data
;
287 DEBUG(10, ("num_setup=%u, max_setup=%u, "
288 "param_total=%u, this_param=%u, max_param=%u, "
289 "data_total=%u, this_data=%u, max_data=%u, "
290 "param_offset=%u, param_pad=%u, param_disp=%u, "
291 "data_offset=%u, data_pad=%u, data_disp=%u\n",
292 (unsigned)state
->num_setup
, (unsigned)state
->max_setup
,
293 (unsigned)state
->num_param
, (unsigned)this_param
,
294 (unsigned)state
->rparam
.max
,
295 (unsigned)state
->num_data
, (unsigned)this_data
,
296 (unsigned)state
->rdata
.max
,
297 (unsigned)param_offset
, (unsigned)param_pad
,
298 (unsigned)state
->param_sent
,
299 (unsigned)data_offset
, (unsigned)data_pad
,
300 (unsigned)state
->data_sent
));
305 SSVAL(vwv
+ 0, 0, state
->num_param
);
306 SSVAL(vwv
+ 1, 0, state
->num_data
);
307 SSVAL(vwv
+ 2, 0, state
->rparam
.max
);
308 SSVAL(vwv
+ 3, 0, state
->rdata
.max
);
309 SCVAL(vwv
+ 4, 0, state
->max_setup
);
310 SCVAL(vwv
+ 4, 1, 0); /* reserved */
311 SSVAL(vwv
+ 5, 0, state
->flags
);
312 SIVAL(vwv
+ 6, 0, 0); /* timeout */
313 SSVAL(vwv
+ 8, 0, 0); /* reserved */
314 SSVAL(vwv
+ 9, 0, this_param
);
315 SSVAL(vwv
+10, 0, param_offset
);
316 SSVAL(vwv
+11, 0, this_data
);
317 SSVAL(vwv
+12, 0, data_offset
);
318 SCVAL(vwv
+13, 0, state
->num_setup
);
319 SCVAL(vwv
+13, 1, 0); /* reserved */
320 memcpy(vwv
+ 14, state
->setup
,
321 sizeof(uint16_t) * state
->num_setup
);
325 SSVAL(vwv
+ 0, 0, state
->num_param
);
326 SSVAL(vwv
+ 1, 0, state
->num_data
);
327 SSVAL(vwv
+ 2, 0, this_param
);
328 SSVAL(vwv
+ 3, 0, param_offset
);
329 SSVAL(vwv
+ 4, 0, state
->param_sent
);
330 SSVAL(vwv
+ 5, 0, this_data
);
331 SSVAL(vwv
+ 6, 0, data_offset
);
332 SSVAL(vwv
+ 7, 0, state
->data_sent
);
333 if (cmd
== SMBtranss2
) {
334 SSVAL(vwv
+ 8, 0, state
->fid
);
338 SCVAL(vwv
+ 0, 0, state
->max_setup
);
339 SSVAL(vwv
+ 0, 1, 0); /* reserved */
340 SIVAL(vwv
+ 1, 1, state
->num_param
);
341 SIVAL(vwv
+ 3, 1, state
->num_data
);
342 SIVAL(vwv
+ 5, 1, state
->rparam
.max
);
343 SIVAL(vwv
+ 7, 1, state
->rdata
.max
);
344 SIVAL(vwv
+ 9, 1, this_param
);
345 SIVAL(vwv
+11, 1, param_offset
);
346 SIVAL(vwv
+13, 1, this_data
);
347 SIVAL(vwv
+15, 1, data_offset
);
348 SCVAL(vwv
+17, 1, state
->num_setup
);
349 SSVAL(vwv
+18, 0, state
->function
);
350 memcpy(vwv
+ 19, state
->setup
,
351 sizeof(uint16_t) * state
->num_setup
);
354 SSVAL(vwv
+ 0, 0, 0); /* reserved */
355 SCVAL(vwv
+ 1, 0, 0); /* reserved */
356 SIVAL(vwv
+ 1, 1, state
->num_param
);
357 SIVAL(vwv
+ 3, 1, state
->num_data
);
358 SIVAL(vwv
+ 5, 1, this_param
);
359 SIVAL(vwv
+ 7, 1, param_offset
);
360 SIVAL(vwv
+ 9, 1, state
->param_sent
);
361 SIVAL(vwv
+11, 1, this_data
);
362 SIVAL(vwv
+13, 1, data_offset
);
363 SIVAL(vwv
+15, 1, state
->data_sent
);
364 SCVAL(vwv
+17, 1, 0); /* reserved */
368 state
->param_sent
+= this_param
;
369 state
->data_sent
+= this_data
;
372 *piov_count
= iov
- state
->iov
;
375 static void cli_trans_done(struct tevent_req
*subreq
);
377 struct tevent_req
*cli_trans_send(
378 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
379 struct cli_state
*cli
, uint8_t cmd
,
380 const char *pipe_name
, uint16_t fid
, uint16_t function
, int flags
,
381 uint16_t *setup
, uint8_t num_setup
, uint8_t max_setup
,
382 uint8_t *param
, uint32_t num_param
, uint32_t max_param
,
383 uint8_t *data
, uint32_t num_data
, uint32_t max_data
)
385 struct tevent_req
*req
, *subreq
;
386 struct cli_trans_state
*state
;
391 req
= tevent_req_create(mem_ctx
, &state
, struct cli_trans_state
);
396 if ((cmd
== SMBtrans
) || (cmd
== SMBtrans2
)) {
397 if ((num_param
> 0xffff) || (max_param
> 0xffff)
398 || (num_data
> 0xffff) || (max_data
> 0xffff)) {
399 DEBUG(3, ("Attempt to send invalid trans2 request "
400 "(setup %u, params %u/%u, data %u/%u)\n",
402 (unsigned)num_param
, (unsigned)max_param
,
403 (unsigned)num_data
, (unsigned)max_data
));
404 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
405 return tevent_req_post(req
, ev
);
410 * The largest wct will be for nttrans (19+num_setup). Make sure we
411 * don't overflow state->vwv in cli_trans_format.
414 if ((num_setup
+ 19) > ARRAY_SIZE(state
->vwv
)) {
415 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
416 return tevent_req_post(req
, ev
);
422 state
->flags
= flags
;
423 state
->num_rsetup
= 0;
424 state
->rsetup
= NULL
;
425 ZERO_STRUCT(state
->rparam
);
426 ZERO_STRUCT(state
->rdata
);
428 if ((pipe_name
!= NULL
)
429 && (!convert_string_talloc(state
, CH_UNIX
,
430 cli_ucs2(cli
) ? CH_UTF16LE
: CH_DOS
,
431 pipe_name
, strlen(pipe_name
) + 1,
432 &state
->pipe_name_conv
,
433 &state
->pipe_name_conv_len
))) {
434 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
435 return tevent_req_post(req
, ev
);
437 state
->fid
= fid
; /* trans2 */
438 state
->function
= function
; /* nttrans */
440 state
->setup
= setup
;
441 state
->num_setup
= num_setup
;
442 state
->max_setup
= max_setup
;
444 state
->param
= param
;
445 state
->num_param
= num_param
;
446 state
->param_sent
= 0;
447 state
->rparam
.max
= max_param
;
450 state
->num_data
= num_data
;
451 state
->data_sent
= 0;
452 state
->rdata
.max
= max_data
;
454 cli_trans_format(state
, &wct
, &iov_count
);
456 subreq
= cli_smb_req_create(state
, ev
, cli
, cmd
, 0, wct
, state
->vwv
,
457 iov_count
, state
->iov
);
458 if (tevent_req_nomem(subreq
, req
)) {
459 return tevent_req_post(req
, ev
);
461 status
= cli_smb_req_send(subreq
);
462 if (!NT_STATUS_IS_OK(status
)) {
463 tevent_req_nterror(req
, status
);
464 return tevent_req_post(req
, state
->ev
);
466 tevent_req_set_callback(subreq
, cli_trans_done
, req
);
469 * Now get the MID of the primary request
470 * and mark it as persistent. This means
471 * we will able to send and receive multiple
472 * SMB pdus using this MID in both directions
473 * (including correct SMB signing).
475 state
->mid
= cli_smb_req_mid(subreq
);
476 cli_smb_req_set_mid(subreq
, state
->mid
);
477 state
->primary_subreq
= subreq
;
478 talloc_set_destructor(state
, cli_trans_state_destructor
);
483 static void cli_trans_done2(struct tevent_req
*subreq
);
485 static void cli_trans_done(struct tevent_req
*subreq
)
487 struct tevent_req
*req
= tevent_req_callback_data(
488 subreq
, struct tevent_req
);
489 struct cli_trans_state
*state
= tevent_req_data(
490 req
, struct cli_trans_state
);
493 const uint8_t *inhdr
;
499 uint8_t num_setup
= 0;
500 uint16_t *setup
= NULL
;
501 uint32_t total_param
= 0;
502 uint32_t num_param
= 0;
503 uint32_t param_disp
= 0;
504 uint32_t total_data
= 0;
505 uint32_t num_data
= 0;
506 uint32_t data_disp
= 0;
507 uint8_t *param
= NULL
;
508 uint8_t *data
= NULL
;
510 status
= cli_smb_recv(subreq
, state
, &inbuf
, 0, &wct
, &vwv
,
513 * Do not TALLOC_FREE(subreq) here, we might receive more than
514 * one response for the same mid.
518 * We can receive something like STATUS_MORE_ENTRIES, so don't use
519 * !NT_STATUS_IS_OK(status) here.
522 if (NT_STATUS_IS_ERR(status
)) {
525 inhdr
= inbuf
+ NBT_HDR_SIZE
;
527 sent_all
= ((state
->param_sent
== state
->num_param
)
528 && (state
->data_sent
== state
->num_data
));
530 status
= cli_pull_trans(
531 inbuf
, wct
, vwv
, num_bytes
, bytes
,
532 state
->cmd
, !sent_all
, &num_setup
, &setup
,
533 &total_param
, &num_param
, ¶m_disp
, ¶m
,
534 &total_data
, &num_data
, &data_disp
, &data
);
536 if (!NT_STATUS_IS_OK(status
)) {
542 struct tevent_req
*subreq2
;
544 cli_trans_format(state
, &wct
, &iov_count
);
546 subreq2
= cli_smb_req_create(state
, state
->ev
, state
->cli
,
547 state
->cmd
+ 1, 0, wct
, state
->vwv
,
548 iov_count
, state
->iov
);
549 if (tevent_req_nomem(subreq2
, req
)) {
552 cli_smb_req_set_mid(subreq2
, state
->mid
);
554 status
= cli_smb_req_send(subreq2
);
556 if (!NT_STATUS_IS_OK(status
)) {
559 tevent_req_set_callback(subreq2
, cli_trans_done2
, req
);
564 status
= cli_trans_pull_blob(
565 state
, &state
->rparam
, total_param
, num_param
, param
,
568 if (!NT_STATUS_IS_OK(status
)) {
569 DEBUG(10, ("Pulling params failed: %s\n", nt_errstr(status
)));
573 status
= cli_trans_pull_blob(
574 state
, &state
->rdata
, total_data
, num_data
, data
,
577 if (!NT_STATUS_IS_OK(status
)) {
578 DEBUG(10, ("Pulling data failed: %s\n", nt_errstr(status
)));
582 if ((state
->rparam
.total
== state
->rparam
.received
)
583 && (state
->rdata
.total
== state
->rdata
.received
)) {
584 state
->recv_flags2
= SVAL(inhdr
, HDR_FLG2
);
585 cli_trans_cleanup_primary(state
);
586 tevent_req_done(req
);
595 cli_trans_cleanup_primary(state
);
596 tevent_req_nterror(req
, status
);
599 static void cli_trans_done2(struct tevent_req
*subreq2
)
601 struct tevent_req
*req
= tevent_req_callback_data(
602 subreq2
, struct tevent_req
);
603 struct cli_trans_state
*state
= tevent_req_data(
604 req
, struct cli_trans_state
);
611 * First backup the seqnum of the secondary request
612 * and attach it to the primary request.
614 seqnum
= cli_smb_req_seqnum(subreq2
);
615 cli_smb_req_set_seqnum(state
->primary_subreq
, seqnum
);
617 status
= cli_smb_recv(subreq2
, state
, NULL
, 0, &wct
, NULL
,
619 TALLOC_FREE(subreq2
);
621 if (!NT_STATUS_IS_OK(status
)) {
626 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
630 sent_all
= ((state
->param_sent
== state
->num_param
)
631 && (state
->data_sent
== state
->num_data
));
636 cli_trans_format(state
, &wct
, &iov_count
);
638 subreq2
= cli_smb_req_create(state
, state
->ev
, state
->cli
,
639 state
->cmd
+ 1, 0, wct
, state
->vwv
,
640 iov_count
, state
->iov
);
641 if (tevent_req_nomem(subreq2
, req
)) {
644 cli_smb_req_set_mid(subreq2
, state
->mid
);
646 status
= cli_smb_req_send(subreq2
);
648 if (!NT_STATUS_IS_OK(status
)) {
651 tevent_req_set_callback(subreq2
, cli_trans_done2
, req
);
658 cli_trans_cleanup_primary(state
);
659 tevent_req_nterror(req
, status
);
662 NTSTATUS
cli_trans_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
663 uint16_t *recv_flags2
,
664 uint16_t **setup
, uint8_t min_setup
,
666 uint8_t **param
, uint32_t min_param
,
668 uint8_t **data
, uint32_t min_data
,
671 struct cli_trans_state
*state
= tevent_req_data(
672 req
, struct cli_trans_state
);
675 cli_trans_cleanup_primary(state
);
677 if (tevent_req_is_nterror(req
, &status
)) {
681 if ((state
->num_rsetup
< min_setup
)
682 || (state
->rparam
.total
< min_param
)
683 || (state
->rdata
.total
< min_data
)) {
684 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
687 if (recv_flags2
!= NULL
) {
688 *recv_flags2
= state
->recv_flags2
;
692 *setup
= talloc_move(mem_ctx
, &state
->rsetup
);
693 *num_setup
= state
->num_rsetup
;
695 TALLOC_FREE(state
->rsetup
);
699 *param
= talloc_move(mem_ctx
, &state
->rparam
.data
);
700 *num_param
= state
->rparam
.total
;
702 TALLOC_FREE(state
->rparam
.data
);
706 *data
= talloc_move(mem_ctx
, &state
->rdata
.data
);
707 *num_data
= state
->rdata
.total
;
709 TALLOC_FREE(state
->rdata
.data
);
715 NTSTATUS
cli_trans(TALLOC_CTX
*mem_ctx
, struct cli_state
*cli
,
717 const char *pipe_name
, uint16_t fid
, uint16_t function
,
719 uint16_t *setup
, uint8_t num_setup
, uint8_t max_setup
,
720 uint8_t *param
, uint32_t num_param
, uint32_t max_param
,
721 uint8_t *data
, uint32_t num_data
, uint32_t max_data
,
722 uint16_t *recv_flags2
,
723 uint16_t **rsetup
, uint8_t min_rsetup
, uint8_t *num_rsetup
,
724 uint8_t **rparam
, uint32_t min_rparam
, uint32_t *num_rparam
,
725 uint8_t **rdata
, uint32_t min_rdata
, uint32_t *num_rdata
)
727 TALLOC_CTX
*frame
= talloc_stackframe();
728 struct tevent_context
*ev
;
729 struct tevent_req
*req
;
730 NTSTATUS status
= NT_STATUS_OK
;
732 if (cli_has_async_calls(cli
)) {
734 * Can't use sync call while an async call is in flight
736 status
= NT_STATUS_INVALID_PARAMETER
;
740 ev
= tevent_context_init(frame
);
742 status
= NT_STATUS_NO_MEMORY
;
746 req
= cli_trans_send(frame
, ev
, cli
, trans_cmd
,
747 pipe_name
, fid
, function
, flags
,
748 setup
, num_setup
, max_setup
,
749 param
, num_param
, max_param
,
750 data
, num_data
, max_data
);
752 status
= NT_STATUS_NO_MEMORY
;
756 if (!tevent_req_poll(req
, ev
)) {
757 status
= map_nt_error_from_unix_common(errno
);
761 status
= cli_trans_recv(req
, mem_ctx
, recv_flags2
,
762 rsetup
, min_rsetup
, num_rsetup
,
763 rparam
, min_rparam
, num_rparam
,
764 rdata
, min_rdata
, num_rdata
);