1/* 2 Unix SMB/CIFS implementation. 3 client transaction calls 4 Copyright (C) Andrew Tridgell 1994-1998 5 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 2 of the License, or 9 (at your option) any later version. 10 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. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19*/ 20 21#define NO_SYSLOG 22 23#include "includes.h" 24 25 26/**************************************************************************** 27 Send a SMB trans or trans2 request. 28****************************************************************************/ 29 30BOOL cli_send_trans(struct cli_state *cli, int trans, 31 const char *pipe_name, 32 int fid, int flags, 33 uint16 *setup, unsigned int lsetup, unsigned int msetup, 34 const char *param, unsigned int lparam, unsigned int mparam, 35 const char *data, unsigned int ldata, unsigned int mdata) 36{ 37 unsigned int i; 38 unsigned int this_ldata,this_lparam; 39 unsigned int tot_data=0,tot_param=0; 40 char *outdata,*outparam; 41 char *p; 42 int pipe_name_len=0; 43 uint16 mid; 44 45 this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ 46 this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); 47 48 memset(cli->outbuf,'\0',smb_size); 49 set_message(cli->outbuf,14+lsetup,0,True); 50 SCVAL(cli->outbuf,smb_com,trans); 51 SSVAL(cli->outbuf,smb_tid, cli->cnum); 52 cli_setup_packet(cli); 53 54 /* 55 * Save the mid we're using. We need this for finding 56 * signing replies. 57 */ 58 59 mid = cli->mid; 60 61 if (pipe_name) { 62 pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE); 63 } 64 65 outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len : 3); 66 outdata = outparam+this_lparam; 67 68 /* primary request */ 69 SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ 70 SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ 71 SSVAL(cli->outbuf,smb_mprcnt,mparam); /* mprcnt */ 72 SSVAL(cli->outbuf,smb_mdrcnt,mdata); /* mdrcnt */ 73 SCVAL(cli->outbuf,smb_msrcnt,msetup); /* msrcnt */ 74 SSVAL(cli->outbuf,smb_flags,flags); /* flags */ 75 SIVAL(cli->outbuf,smb_timeout,0); /* timeout */ 76 SSVAL(cli->outbuf,smb_pscnt,this_lparam); /* pscnt */ 77 SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */ 78 SSVAL(cli->outbuf,smb_dscnt,this_ldata); /* dscnt */ 79 SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ 80 SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ 81 for (i=0;i<lsetup;i++) /* setup[] */ 82 SSVAL(cli->outbuf,smb_setup+i*2,setup[i]); 83 p = smb_buf(cli->outbuf); 84 if (trans != SMBtrans) { 85 *p++ = 0; /* put in a null smb_name */ 86 *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ 87 } 88 if (this_lparam) /* param[] */ 89 memcpy(outparam,param,this_lparam); 90 if (this_ldata) /* data[] */ 91 memcpy(outdata,data,this_ldata); 92 cli_setup_bcc(cli, outdata+this_ldata); 93 94 show_msg(cli->outbuf); 95 96 if (!cli_send_smb(cli)) { 97 return False; 98 } 99 100 if (this_ldata < ldata || this_lparam < lparam) { 101 /* receive interim response */ 102 if (!cli_receive_smb(cli) || cli_is_error(cli)) { 103 return(False); 104 } 105 106 tot_data = this_ldata; 107 tot_param = this_lparam; 108 109 while (tot_data < ldata || tot_param < lparam) { 110 this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ 111 this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); 112 113 set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); 114 SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2)); 115 116 outparam = smb_buf(cli->outbuf); 117 outdata = outparam+this_lparam; 118 119 /* secondary request */ 120 SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ 121 SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ 122 SSVAL(cli->outbuf,smb_spscnt,this_lparam); /* pscnt */ 123 SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */ 124 SSVAL(cli->outbuf,smb_spsdisp,tot_param); /* psdisp */ 125 SSVAL(cli->outbuf,smb_sdscnt,this_ldata); /* dscnt */ 126 SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ 127 SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ 128 if (trans==SMBtrans2) 129 SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ 130 if (this_lparam) /* param[] */ 131 memcpy(outparam,param+tot_param,this_lparam); 132 if (this_ldata) /* data[] */ 133 memcpy(outdata,data+tot_data,this_ldata); 134 cli_setup_bcc(cli, outdata+this_ldata); 135 136 /* 137 * Save the mid we're using. We need this for finding 138 * signing replies. 139 */ 140 mid = cli->mid; 141 142 show_msg(cli->outbuf); 143 if (!cli_send_smb(cli)) { 144 return False; 145 } 146 147 /* Ensure we use the same mid for the secondaries. */ 148 cli->mid = mid; 149 150 tot_data += this_ldata; 151 tot_param += this_lparam; 152 } 153 } 154 155 /* Note we're in a trans state. Save the sequence 156 * numbers for replies. */ 157 158 cli_signing_trans_start(cli, mid); 159 return(True); 160} 161 162/**************************************************************************** 163 Receive a SMB trans or trans2 response allocating the necessary memory. 164****************************************************************************/ 165 166BOOL cli_receive_trans(struct cli_state *cli,int trans, 167 char **param, unsigned int *param_len, 168 char **data, unsigned int *data_len) 169{ 170 unsigned int total_data=0; 171 unsigned int total_param=0; 172 unsigned int this_data,this_param; 173 NTSTATUS status; 174 char *tdata; 175 char *tparam; 176 177 *data_len = *param_len = 0; 178 179 if (!cli_receive_smb(cli)) { 180 cli_signing_trans_stop(cli); 181 return False; 182 } 183 184 show_msg(cli->inbuf); 185 186 /* sanity check */ 187 if (CVAL(cli->inbuf,smb_com) != trans) { 188 DEBUG(0,("Expected %s response, got command 0x%02x\n", 189 trans==SMBtrans?"SMBtrans":"SMBtrans2", 190 CVAL(cli->inbuf,smb_com))); 191 cli_signing_trans_stop(cli); 192 return(False); 193 } 194 195 /* 196 * An NT RPC pipe call can return ERRDOS, ERRmoredata 197 * to a trans call. This is not an error and should not 198 * be treated as such. Note that STATUS_NO_MORE_FILES is 199 * returned when a trans2 findfirst/next finishes. 200 */ 201 status = cli_nt_error(cli); 202 203 if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) { 204 cli_signing_trans_stop(cli); 205 return False; 206 } 207 208 /* parse out the lengths */ 209 total_data = SVAL(cli->inbuf,smb_tdrcnt); 210 total_param = SVAL(cli->inbuf,smb_tprcnt); 211 212 /* allocate it */ 213 if (total_data!=0) { 214 tdata = SMB_REALLOC(*data,total_data); 215 if (!tdata) { 216 DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); 217 cli_signing_trans_stop(cli); 218 return False; 219 } 220 else 221 *data = tdata; 222 } 223 224 if (total_param!=0) { 225 tparam = SMB_REALLOC(*param,total_param); 226 if (!tparam) { 227 DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); 228 cli_signing_trans_stop(cli); 229 return False; 230 } 231 else 232 *param = tparam; 233 } 234 235 for (;;) { 236 this_data = SVAL(cli->inbuf,smb_drcnt); 237 this_param = SVAL(cli->inbuf,smb_prcnt); 238 239 if (this_data + *data_len > total_data || 240 this_param + *param_len > total_param) { 241 DEBUG(1,("Data overflow in cli_receive_trans\n")); 242 cli_signing_trans_stop(cli); 243 return False; 244 } 245 246 if (this_data + *data_len < this_data || 247 this_data + *data_len < *data_len || 248 this_param + *param_len < this_param || 249 this_param + *param_len < *param_len) { 250 DEBUG(1,("Data overflow in cli_receive_trans\n")); 251 cli_signing_trans_stop(cli); 252 return False; 253 } 254 255 if (this_data) { 256 unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp); 257 unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff); 258 259 if (data_offset_out > total_data || 260 data_offset_out + this_data > total_data || 261 data_offset_out + this_data < data_offset_out || 262 data_offset_out + this_data < this_data) { 263 DEBUG(1,("Data overflow in cli_receive_trans\n")); 264 cli_signing_trans_stop(cli); 265 return False; 266 } 267 if (data_offset_in > cli->bufsize || 268 data_offset_in + this_data > cli->bufsize || 269 data_offset_in + this_data < data_offset_in || 270 data_offset_in + this_data < this_data) { 271 DEBUG(1,("Data overflow in cli_receive_trans\n")); 272 cli_signing_trans_stop(cli); 273 return False; 274 } 275 276 memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); 277 } 278 if (this_param) { 279 unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp); 280 unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff); 281 282 if (param_offset_out > total_param || 283 param_offset_out + this_param > total_param || 284 param_offset_out + this_param < param_offset_out || 285 param_offset_out + this_param < this_param) { 286 DEBUG(1,("Param overflow in cli_receive_trans\n")); 287 cli_signing_trans_stop(cli); 288 return False; 289 } 290 if (param_offset_in > cli->bufsize || 291 param_offset_in + this_param > cli->bufsize || 292 param_offset_in + this_param < param_offset_in || 293 param_offset_in + this_param < this_param) { 294 DEBUG(1,("Param overflow in cli_receive_trans\n")); 295 cli_signing_trans_stop(cli); 296 return False; 297 } 298 299 memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); 300 } 301 *data_len += this_data; 302 *param_len += this_param; 303 304 if (total_data <= *data_len && total_param <= *param_len) 305 break; 306 307 if (!cli_receive_smb(cli)) { 308 cli_signing_trans_stop(cli); 309 return False; 310 } 311 312 show_msg(cli->inbuf); 313 314 /* sanity check */ 315 if (CVAL(cli->inbuf,smb_com) != trans) { 316 DEBUG(0,("Expected %s response, got command 0x%02x\n", 317 trans==SMBtrans?"SMBtrans":"SMBtrans2", 318 CVAL(cli->inbuf,smb_com))); 319 cli_signing_trans_stop(cli); 320 return(False); 321 } 322 if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { 323 cli_signing_trans_stop(cli); 324 return(False); 325 } 326 327 /* parse out the total lengths again - they can shrink! */ 328 if (SVAL(cli->inbuf,smb_tdrcnt) < total_data) 329 total_data = SVAL(cli->inbuf,smb_tdrcnt); 330 if (SVAL(cli->inbuf,smb_tprcnt) < total_param) 331 total_param = SVAL(cli->inbuf,smb_tprcnt); 332 333 if (total_data <= *data_len && total_param <= *param_len) 334 break; 335 336 } 337 338 cli_signing_trans_stop(cli); 339 return(True); 340} 341 342/**************************************************************************** 343 Send a SMB nttrans request. 344****************************************************************************/ 345 346BOOL cli_send_nt_trans(struct cli_state *cli, 347 int function, 348 int flags, 349 uint16 *setup, unsigned int lsetup, unsigned int msetup, 350 char *param, unsigned int lparam, unsigned int mparam, 351 char *data, unsigned int ldata, unsigned int mdata) 352{ 353 unsigned int i; 354 unsigned int this_ldata,this_lparam; 355 unsigned int tot_data=0,tot_param=0; 356 uint16 mid; 357 char *outdata,*outparam; 358 359 this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ 360 this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); 361 362 memset(cli->outbuf,'\0',smb_size); 363 set_message(cli->outbuf,19+lsetup,0,True); 364 SCVAL(cli->outbuf,smb_com,SMBnttrans); 365 SSVAL(cli->outbuf,smb_tid, cli->cnum); 366 cli_setup_packet(cli); 367 368 /* 369 * Save the mid we're using. We need this for finding 370 * signing replies. 371 */ 372 373 mid = cli->mid; 374 375 outparam = smb_buf(cli->outbuf)+3; 376 outdata = outparam+this_lparam; 377 378 /* primary request */ 379 SCVAL(cli->outbuf,smb_nt_MaxSetupCount,msetup); 380 SCVAL(cli->outbuf,smb_nt_Flags,flags); 381 SIVAL(cli->outbuf,smb_nt_TotalParameterCount, lparam); 382 SIVAL(cli->outbuf,smb_nt_TotalDataCount, ldata); 383 SIVAL(cli->outbuf,smb_nt_MaxParameterCount, mparam); 384 SIVAL(cli->outbuf,smb_nt_MaxDataCount, mdata); 385 SIVAL(cli->outbuf,smb_nt_ParameterCount, this_lparam); 386 SIVAL(cli->outbuf,smb_nt_ParameterOffset, smb_offset(outparam,cli->outbuf)); 387 SIVAL(cli->outbuf,smb_nt_DataCount, this_ldata); 388 SIVAL(cli->outbuf,smb_nt_DataOffset, smb_offset(outdata,cli->outbuf)); 389 SIVAL(cli->outbuf,smb_nt_SetupCount, lsetup); 390 SIVAL(cli->outbuf,smb_nt_Function, function); 391 for (i=0;i<lsetup;i++) /* setup[] */ 392 SSVAL(cli->outbuf,smb_nt_SetupStart+i*2,setup[i]); 393 394 if (this_lparam) /* param[] */ 395 memcpy(outparam,param,this_lparam); 396 if (this_ldata) /* data[] */ 397 memcpy(outdata,data,this_ldata); 398 399 cli_setup_bcc(cli, outdata+this_ldata); 400 401 show_msg(cli->outbuf); 402 if (!cli_send_smb(cli)) { 403 return False; 404 } 405 406 if (this_ldata < ldata || this_lparam < lparam) { 407 /* receive interim response */ 408 if (!cli_receive_smb(cli) || cli_is_error(cli)) { 409 return(False); 410 } 411 412 tot_data = this_ldata; 413 tot_param = this_lparam; 414 415 while (tot_data < ldata || tot_param < lparam) { 416 this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ 417 this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); 418 419 set_message(cli->outbuf,18,0,True); 420 SCVAL(cli->outbuf,smb_com,SMBnttranss); 421 422 /* XXX - these should probably be aligned */ 423 outparam = smb_buf(cli->outbuf); 424 outdata = outparam+this_lparam; 425 426 /* secondary request */ 427 SIVAL(cli->outbuf,smb_nts_TotalParameterCount,lparam); 428 SIVAL(cli->outbuf,smb_nts_TotalDataCount,ldata); 429 SIVAL(cli->outbuf,smb_nts_ParameterCount,this_lparam); 430 SIVAL(cli->outbuf,smb_nts_ParameterOffset,smb_offset(outparam,cli->outbuf)); 431 SIVAL(cli->outbuf,smb_nts_ParameterDisplacement,tot_param); 432 SIVAL(cli->outbuf,smb_nts_DataCount,this_ldata); 433 SIVAL(cli->outbuf,smb_nts_DataOffset,smb_offset(outdata,cli->outbuf)); 434 SIVAL(cli->outbuf,smb_nts_DataDisplacement,tot_data); 435 if (this_lparam) /* param[] */ 436 memcpy(outparam,param+tot_param,this_lparam); 437 if (this_ldata) /* data[] */ 438 memcpy(outdata,data+tot_data,this_ldata); 439 cli_setup_bcc(cli, outdata+this_ldata); 440 441 /* 442 * Save the mid we're using. We need this for finding 443 * signing replies. 444 */ 445 mid = cli->mid; 446 447 show_msg(cli->outbuf); 448 449 if (!cli_send_smb(cli)) { 450 return False; 451 } 452 453 /* Ensure we use the same mid for the secondaries. */ 454 cli->mid = mid; 455 456 tot_data += this_ldata; 457 tot_param += this_lparam; 458 } 459 } 460 461 /* Note we're in a trans state. Save the sequence 462 * numbers for replies. */ 463 464 cli_signing_trans_start(cli, mid); 465 return(True); 466} 467 468/**************************************************************************** 469 receive a SMB nttrans response allocating the necessary memory 470 ****************************************************************************/ 471 472BOOL cli_receive_nt_trans(struct cli_state *cli, 473 char **param, unsigned int *param_len, 474 char **data, unsigned int *data_len) 475{ 476 unsigned int total_data=0; 477 unsigned int total_param=0; 478 unsigned int this_data,this_param; 479 uint8 eclass; 480 uint32 ecode; 481 char *tdata; 482 char *tparam; 483 484 *data_len = *param_len = 0; 485 486 if (!cli_receive_smb(cli)) { 487 cli_signing_trans_stop(cli); 488 return False; 489 } 490 491 show_msg(cli->inbuf); 492 493 /* sanity check */ 494 if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { 495 DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", 496 CVAL(cli->inbuf,smb_com))); 497 cli_signing_trans_stop(cli); 498 return(False); 499 } 500 501 /* 502 * An NT RPC pipe call can return ERRDOS, ERRmoredata 503 * to a trans call. This is not an error and should not 504 * be treated as such. 505 */ 506 if (cli_is_dos_error(cli)) { 507 cli_dos_error(cli, &eclass, &ecode); 508 if (cli->nt_pipe_fnum[cli->pipe_idx] == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { 509 cli_signing_trans_stop(cli); 510 return(False); 511 } 512 } 513 514 /* 515 * Likewise for NT_STATUS_BUFFER_TOO_SMALL 516 */ 517 if (cli_is_nt_error(cli)) { 518 if (!NT_STATUS_EQUAL(cli_nt_error(cli), 519 NT_STATUS_BUFFER_TOO_SMALL)) { 520 cli_signing_trans_stop(cli); 521 return(False); 522 } 523 } 524 525 /* parse out the lengths */ 526 total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); 527 total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); 528 529 /* allocate it */ 530 if (total_data) { 531 tdata = SMB_REALLOC(*data,total_data); 532 if (!tdata) { 533 DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); 534 cli_signing_trans_stop(cli); 535 return False; 536 } else { 537 *data = tdata; 538 } 539 } 540 541 if (total_param) { 542 tparam = SMB_REALLOC(*param,total_param); 543 if (!tparam) { 544 DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); 545 cli_signing_trans_stop(cli); 546 return False; 547 } else { 548 *param = tparam; 549 } 550 } 551 552 while (1) { 553 this_data = SVAL(cli->inbuf,smb_ntr_DataCount); 554 this_param = SVAL(cli->inbuf,smb_ntr_ParameterCount); 555 556 if (this_data + *data_len > total_data || 557 this_param + *param_len > total_param) { 558 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 559 cli_signing_trans_stop(cli); 560 return False; 561 } 562 563 if (this_data + *data_len < this_data || 564 this_data + *data_len < *data_len || 565 this_param + *param_len < this_param || 566 this_param + *param_len < *param_len) { 567 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 568 cli_signing_trans_stop(cli); 569 return False; 570 } 571 572 if (this_data) { 573 unsigned int data_offset_out = SVAL(cli->inbuf,smb_ntr_DataDisplacement); 574 unsigned int data_offset_in = SVAL(cli->inbuf,smb_ntr_DataOffset); 575 576 if (data_offset_out > total_data || 577 data_offset_out + this_data > total_data || 578 data_offset_out + this_data < data_offset_out || 579 data_offset_out + this_data < this_data) { 580 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 581 cli_signing_trans_stop(cli); 582 return False; 583 } 584 if (data_offset_in > cli->bufsize || 585 data_offset_in + this_data > cli->bufsize || 586 data_offset_in + this_data < data_offset_in || 587 data_offset_in + this_data < this_data) { 588 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 589 cli_signing_trans_stop(cli); 590 return False; 591 } 592 593 memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); 594 } 595 596 if (this_param) { 597 unsigned int param_offset_out = SVAL(cli->inbuf,smb_ntr_ParameterDisplacement); 598 unsigned int param_offset_in = SVAL(cli->inbuf,smb_ntr_ParameterOffset); 599 600 if (param_offset_out > total_param || 601 param_offset_out + this_param > total_param || 602 param_offset_out + this_param < param_offset_out || 603 param_offset_out + this_param < this_param) { 604 DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); 605 cli_signing_trans_stop(cli); 606 return False; 607 } 608 if (param_offset_in > cli->bufsize || 609 param_offset_in + this_param > cli->bufsize || 610 param_offset_in + this_param < param_offset_in || 611 param_offset_in + this_param < this_param) { 612 DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); 613 cli_signing_trans_stop(cli); 614 return False; 615 } 616 617 memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); 618 } 619 620 *data_len += this_data; 621 *param_len += this_param; 622 623 if (total_data <= *data_len && total_param <= *param_len) 624 break; 625 626 if (!cli_receive_smb(cli)) { 627 cli_signing_trans_stop(cli); 628 return False; 629 } 630 631 show_msg(cli->inbuf); 632 633 /* sanity check */ 634 if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { 635 DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", 636 CVAL(cli->inbuf,smb_com))); 637 cli_signing_trans_stop(cli); 638 return(False); 639 } 640 if (cli_is_dos_error(cli)) { 641 cli_dos_error(cli, &eclass, &ecode); 642 if(cli->nt_pipe_fnum[cli->pipe_idx] == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { 643 cli_signing_trans_stop(cli); 644 return(False); 645 } 646 } 647 /* parse out the total lengths again - they can shrink! */ 648 if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) 649 total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); 650 if (SVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) 651 total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); 652 653 if (total_data <= *data_len && total_param <= *param_len) 654 break; 655 } 656 657 cli_signing_trans_stop(cli); 658 return(True); 659} 660