関数 | |
BOOL | cli_send_trans (struct cli_state *cli, int trans, const char *pipe_name, int fid, int flags, uint16 *setup, unsigned int lsetup, unsigned int msetup, const char *param, unsigned int lparam, unsigned int mparam, const char *data, unsigned int ldata, unsigned int mdata) |
BOOL | cli_receive_trans (struct cli_state *cli, int trans, char **param, unsigned int *param_len, char **data, unsigned int *data_len) |
BOOL | cli_send_nt_trans (struct cli_state *cli, int function, int flags, uint16 *setup, unsigned int lsetup, unsigned int msetup, char *param, unsigned int lparam, unsigned int mparam, char *data, unsigned int ldata, unsigned int mdata) |
BOOL | cli_receive_nt_trans (struct cli_state *cli, char **param, unsigned int *param_len, char **data, unsigned int *data_len) |
BOOL cli_send_trans | ( | struct cli_state * | cli, | |
int | trans, | |||
const char * | pipe_name, | |||
int | fid, | |||
int | flags, | |||
uint16 * | setup, | |||
unsigned int | lsetup, | |||
unsigned int | msetup, | |||
const char * | param, | |||
unsigned int | lparam, | |||
unsigned int | mparam, | |||
const char * | data, | |||
unsigned int | ldata, | |||
unsigned int | mdata | |||
) |
clitrans.c の 28 行で定義されています。
参照先 cli・cli_is_error()・cli_receive_smb()・cli_send_smb()・cli_setup_bcc()・cli_setup_packet()・client_set_trans_sign_state_off()・client_set_trans_sign_state_on()・cli_state::cnum・cli_state::max_xmit・cli_state::mid・cli_state::outbuf・set_message()・show_msg().
参照元 cli_api()・cli_api_pipe()・cli_dfs_get_referral()・cli_get_ea_list()・cli_get_fs_attr_info()・cli_get_fs_quota_info()・cli_get_fs_volume_info()・cli_get_fs_volume_info_old()・cli_link_internal()・cli_list_new()・cli_nt_delete_on_close()・cli_oem_change_password()・cli_posix_lock_internal()・cli_posix_open_internal()・cli_posix_unlink_internal()・cli_qfileinfo()・cli_qfileinfo_test()・cli_qfilename()・cli_qpathinfo()・cli_qpathinfo2()・cli_qpathinfo_alt_name()・cli_qpathinfo_basic()・cli_set_ea()・cli_set_fs_quota_info()・cli_set_unix_extensions_capabilities()・cli_setpathinfo()・cli_unix_chmod_chown_internal()・cli_unix_extensions_version()・cli_unix_getfacl()・cli_unix_stat()・try_trans2().
00034 { 00035 unsigned int i; 00036 unsigned int this_ldata,this_lparam; 00037 unsigned int tot_data=0,tot_param=0; 00038 char *outdata,*outparam; 00039 char *p; 00040 int pipe_name_len=0; 00041 uint16 mid; 00042 00043 this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ 00044 this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); 00045 00046 memset(cli->outbuf,'\0',smb_size); 00047 set_message(cli->outbuf,14+lsetup,0,True); 00048 SCVAL(cli->outbuf,smb_com,trans); 00049 SSVAL(cli->outbuf,smb_tid, cli->cnum); 00050 cli_setup_packet(cli); 00051 00052 /* 00053 * Save the mid we're using. We need this for finding 00054 * signing replies. 00055 */ 00056 00057 mid = cli->mid; 00058 00059 if (pipe_name) { 00060 pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE); 00061 } 00062 00063 outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len : 3); 00064 outdata = outparam+this_lparam; 00065 00066 /* primary request */ 00067 SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ 00068 SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ 00069 SSVAL(cli->outbuf,smb_mprcnt,mparam); /* mprcnt */ 00070 SSVAL(cli->outbuf,smb_mdrcnt,mdata); /* mdrcnt */ 00071 SCVAL(cli->outbuf,smb_msrcnt,msetup); /* msrcnt */ 00072 SSVAL(cli->outbuf,smb_flags,flags); /* flags */ 00073 SIVAL(cli->outbuf,smb_timeout,0); /* timeout */ 00074 SSVAL(cli->outbuf,smb_pscnt,this_lparam); /* pscnt */ 00075 SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */ 00076 SSVAL(cli->outbuf,smb_dscnt,this_ldata); /* dscnt */ 00077 SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ 00078 SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ 00079 for (i=0;i<lsetup;i++) /* setup[] */ 00080 SSVAL(cli->outbuf,smb_setup+i*2,setup[i]); 00081 p = smb_buf(cli->outbuf); 00082 if (trans != SMBtrans) { 00083 *p++ = 0; /* put in a null smb_name */ 00084 *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ 00085 } 00086 if (this_lparam) /* param[] */ 00087 memcpy(outparam,param,this_lparam); 00088 if (this_ldata) /* data[] */ 00089 memcpy(outdata,data,this_ldata); 00090 cli_setup_bcc(cli, outdata+this_ldata); 00091 00092 show_msg(cli->outbuf); 00093 00094 if (!cli_send_smb(cli)) { 00095 return False; 00096 } 00097 00098 /* Note we're in a trans state. Save the sequence 00099 * numbers for replies. */ 00100 client_set_trans_sign_state_on(cli, mid); 00101 00102 if (this_ldata < ldata || this_lparam < lparam) { 00103 /* receive interim response */ 00104 if (!cli_receive_smb(cli) || cli_is_error(cli)) { 00105 client_set_trans_sign_state_off(cli, mid); 00106 return(False); 00107 } 00108 00109 tot_data = this_ldata; 00110 tot_param = this_lparam; 00111 00112 while (tot_data < ldata || tot_param < lparam) { 00113 this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ 00114 this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); 00115 00116 client_set_trans_sign_state_off(cli, mid); 00117 client_set_trans_sign_state_on(cli, mid); 00118 00119 set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); 00120 SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2)); 00121 00122 outparam = smb_buf(cli->outbuf); 00123 outdata = outparam+this_lparam; 00124 00125 /* secondary request */ 00126 SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ 00127 SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ 00128 SSVAL(cli->outbuf,smb_spscnt,this_lparam); /* pscnt */ 00129 SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */ 00130 SSVAL(cli->outbuf,smb_spsdisp,tot_param); /* psdisp */ 00131 SSVAL(cli->outbuf,smb_sdscnt,this_ldata); /* dscnt */ 00132 SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ 00133 SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ 00134 if (trans==SMBtrans2) 00135 SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ 00136 if (this_lparam) /* param[] */ 00137 memcpy(outparam,param+tot_param,this_lparam); 00138 if (this_ldata) /* data[] */ 00139 memcpy(outdata,data+tot_data,this_ldata); 00140 cli_setup_bcc(cli, outdata+this_ldata); 00141 00142 /* 00143 * Save the mid we're using. We need this for finding 00144 * signing replies. 00145 */ 00146 mid = cli->mid; 00147 00148 show_msg(cli->outbuf); 00149 if (!cli_send_smb(cli)) { 00150 client_set_trans_sign_state_off(cli, mid); 00151 return False; 00152 } 00153 00154 /* Ensure we use the same mid for the secondaries. */ 00155 cli->mid = mid; 00156 00157 tot_data += this_ldata; 00158 tot_param += this_lparam; 00159 } 00160 } 00161 00162 return(True); 00163 }
BOOL cli_receive_trans | ( | struct cli_state * | cli, | |
int | trans, | |||
char ** | param, | |||
unsigned int * | param_len, | |||
char ** | data, | |||
unsigned int * | data_len | |||
) |
clitrans.c の 169 行で定義されています。
参照先 cli_state::bufsize・cli・cli_nt_error()・cli_receive_smb()・cli_state::inbuf・show_msg()・status.
参照元 cli_api()・cli_api_pipe()・cli_dfs_get_referral()・cli_get_ea_list()・cli_get_fs_attr_info()・cli_get_fs_quota_info()・cli_get_fs_volume_info()・cli_get_fs_volume_info_old()・cli_link_internal()・cli_list_new()・cli_nt_delete_on_close()・cli_oem_change_password()・cli_posix_lock_internal()・cli_posix_open_internal()・cli_posix_unlink_internal()・cli_qfileinfo()・cli_qfileinfo_test()・cli_qfilename()・cli_qpathinfo()・cli_qpathinfo2()・cli_qpathinfo_alt_name()・cli_qpathinfo_basic()・cli_set_ea()・cli_set_fs_quota_info()・cli_set_unix_extensions_capabilities()・cli_setpathinfo()・cli_unix_chmod_chown_internal()・cli_unix_extensions_version()・cli_unix_getfacl()・cli_unix_stat()・try_trans2().
00172 { 00173 unsigned int total_data=0; 00174 unsigned int total_param=0; 00175 unsigned int this_data,this_param; 00176 NTSTATUS status; 00177 BOOL ret = False; 00178 00179 *data_len = *param_len = 0; 00180 00181 if (!cli_receive_smb(cli)) { 00182 return False; 00183 } 00184 00185 show_msg(cli->inbuf); 00186 00187 /* sanity check */ 00188 if (CVAL(cli->inbuf,smb_com) != trans) { 00189 DEBUG(0,("Expected %s response, got command 0x%02x\n", 00190 trans==SMBtrans?"SMBtrans":"SMBtrans2", 00191 CVAL(cli->inbuf,smb_com))); 00192 return False; 00193 } 00194 00195 /* 00196 * An NT RPC pipe call can return ERRDOS, ERRmoredata 00197 * to a trans call. This is not an error and should not 00198 * be treated as such. Note that STATUS_NO_MORE_FILES is 00199 * returned when a trans2 findfirst/next finishes. 00200 */ 00201 status = cli_nt_error(cli); 00202 00203 if (NT_STATUS_IS_ERR(status) || 00204 NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES) || 00205 NT_STATUS_EQUAL(status,STATUS_INACCESSIBLE_SYSTEM_SHORTCUT)) { 00206 goto out; 00207 } 00208 00209 /* parse out the lengths */ 00210 total_data = SVAL(cli->inbuf,smb_tdrcnt); 00211 total_param = SVAL(cli->inbuf,smb_tprcnt); 00212 00213 /* allocate it */ 00214 if (total_data!=0) { 00215 *data = (char *)SMB_REALLOC(*data,total_data); 00216 if (!(*data)) { 00217 DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); 00218 goto out; 00219 } 00220 } 00221 00222 if (total_param!=0) { 00223 *param = (char *)SMB_REALLOC(*param,total_param); 00224 if (!(*param)) { 00225 DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); 00226 goto out; 00227 } 00228 } 00229 00230 for (;;) { 00231 this_data = SVAL(cli->inbuf,smb_drcnt); 00232 this_param = SVAL(cli->inbuf,smb_prcnt); 00233 00234 if (this_data + *data_len > total_data || 00235 this_param + *param_len > total_param) { 00236 DEBUG(1,("Data overflow in cli_receive_trans\n")); 00237 goto out; 00238 } 00239 00240 if (this_data + *data_len < this_data || 00241 this_data + *data_len < *data_len || 00242 this_param + *param_len < this_param || 00243 this_param + *param_len < *param_len) { 00244 DEBUG(1,("Data overflow in cli_receive_trans\n")); 00245 goto out; 00246 } 00247 00248 if (this_data) { 00249 unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp); 00250 unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff); 00251 00252 if (data_offset_out > total_data || 00253 data_offset_out + this_data > total_data || 00254 data_offset_out + this_data < data_offset_out || 00255 data_offset_out + this_data < this_data) { 00256 DEBUG(1,("Data overflow in cli_receive_trans\n")); 00257 goto out; 00258 } 00259 if (data_offset_in > cli->bufsize || 00260 data_offset_in + this_data > cli->bufsize || 00261 data_offset_in + this_data < data_offset_in || 00262 data_offset_in + this_data < this_data) { 00263 DEBUG(1,("Data overflow in cli_receive_trans\n")); 00264 goto out; 00265 } 00266 00267 memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); 00268 } 00269 if (this_param) { 00270 unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp); 00271 unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff); 00272 00273 if (param_offset_out > total_param || 00274 param_offset_out + this_param > total_param || 00275 param_offset_out + this_param < param_offset_out || 00276 param_offset_out + this_param < this_param) { 00277 DEBUG(1,("Param overflow in cli_receive_trans\n")); 00278 goto out; 00279 } 00280 if (param_offset_in > cli->bufsize || 00281 param_offset_in + this_param > cli->bufsize || 00282 param_offset_in + this_param < param_offset_in || 00283 param_offset_in + this_param < this_param) { 00284 DEBUG(1,("Param overflow in cli_receive_trans\n")); 00285 goto out; 00286 } 00287 00288 memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); 00289 } 00290 *data_len += this_data; 00291 *param_len += this_param; 00292 00293 if (total_data <= *data_len && total_param <= *param_len) { 00294 ret = True; 00295 break; 00296 } 00297 00298 if (!cli_receive_smb(cli)) { 00299 goto out; 00300 } 00301 00302 show_msg(cli->inbuf); 00303 00304 /* sanity check */ 00305 if (CVAL(cli->inbuf,smb_com) != trans) { 00306 DEBUG(0,("Expected %s response, got command 0x%02x\n", 00307 trans==SMBtrans?"SMBtrans":"SMBtrans2", 00308 CVAL(cli->inbuf,smb_com))); 00309 goto out; 00310 } 00311 if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { 00312 goto out; 00313 } 00314 00315 /* parse out the total lengths again - they can shrink! */ 00316 if (SVAL(cli->inbuf,smb_tdrcnt) < total_data) 00317 total_data = SVAL(cli->inbuf,smb_tdrcnt); 00318 if (SVAL(cli->inbuf,smb_tprcnt) < total_param) 00319 total_param = SVAL(cli->inbuf,smb_tprcnt); 00320 00321 if (total_data <= *data_len && total_param <= *param_len) { 00322 ret = True; 00323 break; 00324 } 00325 } 00326 00327 out: 00328 00329 client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); 00330 return ret; 00331 }
BOOL cli_send_nt_trans | ( | struct cli_state * | cli, | |
int | function, | |||
int | flags, | |||
uint16 * | setup, | |||
unsigned int | lsetup, | |||
unsigned int | msetup, | |||
char * | param, | |||
unsigned int | lparam, | |||
unsigned int | mparam, | |||
char * | data, | |||
unsigned int | ldata, | |||
unsigned int | mdata | |||
) |
clitrans.c の 337 行で定義されています。
参照先 cli・cli_is_error()・cli_receive_smb()・cli_send_smb()・cli_setup_bcc()・cli_setup_packet()・client_set_trans_sign_state_off()・client_set_trans_sign_state_on()・cli_state::cnum・cli_state::max_xmit・cli_state::mid・cli_state::outbuf・set_message()・show_msg().
参照元 cli_get_user_quota()・cli_list_user_quota()・cli_query_secdesc()・cli_set_secdesc()・cli_set_user_quota()・try_nttrans().
00343 { 00344 unsigned int i; 00345 unsigned int this_ldata,this_lparam; 00346 unsigned int tot_data=0,tot_param=0; 00347 uint16 mid; 00348 char *outdata,*outparam; 00349 00350 this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ 00351 this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); 00352 00353 memset(cli->outbuf,'\0',smb_size); 00354 set_message(cli->outbuf,19+lsetup,0,True); 00355 SCVAL(cli->outbuf,smb_com,SMBnttrans); 00356 SSVAL(cli->outbuf,smb_tid, cli->cnum); 00357 cli_setup_packet(cli); 00358 00359 /* 00360 * Save the mid we're using. We need this for finding 00361 * signing replies. 00362 */ 00363 00364 mid = cli->mid; 00365 00366 outparam = smb_buf(cli->outbuf)+3; 00367 outdata = outparam+this_lparam; 00368 00369 /* primary request */ 00370 SCVAL(cli->outbuf,smb_nt_MaxSetupCount,msetup); 00371 SCVAL(cli->outbuf,smb_nt_Flags,flags); 00372 SIVAL(cli->outbuf,smb_nt_TotalParameterCount, lparam); 00373 SIVAL(cli->outbuf,smb_nt_TotalDataCount, ldata); 00374 SIVAL(cli->outbuf,smb_nt_MaxParameterCount, mparam); 00375 SIVAL(cli->outbuf,smb_nt_MaxDataCount, mdata); 00376 SIVAL(cli->outbuf,smb_nt_ParameterCount, this_lparam); 00377 SIVAL(cli->outbuf,smb_nt_ParameterOffset, smb_offset(outparam,cli->outbuf)); 00378 SIVAL(cli->outbuf,smb_nt_DataCount, this_ldata); 00379 SIVAL(cli->outbuf,smb_nt_DataOffset, smb_offset(outdata,cli->outbuf)); 00380 SIVAL(cli->outbuf,smb_nt_SetupCount, lsetup); 00381 SIVAL(cli->outbuf,smb_nt_Function, function); 00382 for (i=0;i<lsetup;i++) /* setup[] */ 00383 SSVAL(cli->outbuf,smb_nt_SetupStart+i*2,setup[i]); 00384 00385 if (this_lparam) /* param[] */ 00386 memcpy(outparam,param,this_lparam); 00387 if (this_ldata) /* data[] */ 00388 memcpy(outdata,data,this_ldata); 00389 00390 cli_setup_bcc(cli, outdata+this_ldata); 00391 00392 show_msg(cli->outbuf); 00393 if (!cli_send_smb(cli)) { 00394 return False; 00395 } 00396 00397 /* Note we're in a trans state. Save the sequence 00398 * numbers for replies. */ 00399 client_set_trans_sign_state_on(cli, mid); 00400 00401 if (this_ldata < ldata || this_lparam < lparam) { 00402 /* receive interim response */ 00403 if (!cli_receive_smb(cli) || cli_is_error(cli)) { 00404 client_set_trans_sign_state_off(cli, mid); 00405 return(False); 00406 } 00407 00408 tot_data = this_ldata; 00409 tot_param = this_lparam; 00410 00411 while (tot_data < ldata || tot_param < lparam) { 00412 this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ 00413 this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); 00414 00415 set_message(cli->outbuf,18,0,True); 00416 SCVAL(cli->outbuf,smb_com,SMBnttranss); 00417 00418 /* XXX - these should probably be aligned */ 00419 outparam = smb_buf(cli->outbuf); 00420 outdata = outparam+this_lparam; 00421 00422 /* secondary request */ 00423 SIVAL(cli->outbuf,smb_nts_TotalParameterCount,lparam); 00424 SIVAL(cli->outbuf,smb_nts_TotalDataCount,ldata); 00425 SIVAL(cli->outbuf,smb_nts_ParameterCount,this_lparam); 00426 SIVAL(cli->outbuf,smb_nts_ParameterOffset,smb_offset(outparam,cli->outbuf)); 00427 SIVAL(cli->outbuf,smb_nts_ParameterDisplacement,tot_param); 00428 SIVAL(cli->outbuf,smb_nts_DataCount,this_ldata); 00429 SIVAL(cli->outbuf,smb_nts_DataOffset,smb_offset(outdata,cli->outbuf)); 00430 SIVAL(cli->outbuf,smb_nts_DataDisplacement,tot_data); 00431 if (this_lparam) /* param[] */ 00432 memcpy(outparam,param+tot_param,this_lparam); 00433 if (this_ldata) /* data[] */ 00434 memcpy(outdata,data+tot_data,this_ldata); 00435 cli_setup_bcc(cli, outdata+this_ldata); 00436 00437 /* 00438 * Save the mid we're using. We need this for finding 00439 * signing replies. 00440 */ 00441 mid = cli->mid; 00442 00443 show_msg(cli->outbuf); 00444 00445 if (!cli_send_smb(cli)) { 00446 client_set_trans_sign_state_off(cli, mid); 00447 return False; 00448 } 00449 00450 /* Ensure we use the same mid for the secondaries. */ 00451 cli->mid = mid; 00452 00453 tot_data += this_ldata; 00454 tot_param += this_lparam; 00455 } 00456 } 00457 00458 return(True); 00459 }
BOOL cli_receive_nt_trans | ( | struct cli_state * | cli, | |
char ** | param, | |||
unsigned int * | param_len, | |||
char ** | data, | |||
unsigned int * | data_len | |||
) |
clitrans.c の 465 行で定義されています。
参照先 cli_state::bufsize・cli・cli_dos_error()・cli_is_dos_error()・cli_is_nt_error()・cli_nt_error()・cli_receive_smb()・client_set_trans_sign_state_off()・cli_state::inbuf・show_msg().
参照元 cli_get_user_quota()・cli_list_user_quota()・cli_query_secdesc()・cli_set_secdesc()・cli_set_user_quota()・try_nttrans().
00468 { 00469 unsigned int total_data=0; 00470 unsigned int total_param=0; 00471 unsigned int this_data,this_param; 00472 uint8 eclass; 00473 uint32 ecode; 00474 BOOL ret = False; 00475 00476 *data_len = *param_len = 0; 00477 00478 if (!cli_receive_smb(cli)) { 00479 return False; 00480 } 00481 00482 show_msg(cli->inbuf); 00483 00484 /* sanity check */ 00485 if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { 00486 DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", 00487 CVAL(cli->inbuf,smb_com))); 00488 return(False); 00489 } 00490 00491 /* 00492 * An NT RPC pipe call can return ERRDOS, ERRmoredata 00493 * to a trans call. This is not an error and should not 00494 * be treated as such. 00495 */ 00496 if (cli_is_dos_error(cli)) { 00497 cli_dos_error(cli, &eclass, &ecode); 00498 if (!(eclass == ERRDOS && ecode == ERRmoredata)) { 00499 goto out; 00500 } 00501 } 00502 00503 /* 00504 * Likewise for NT_STATUS_BUFFER_TOO_SMALL 00505 */ 00506 if (cli_is_nt_error(cli)) { 00507 if (!NT_STATUS_EQUAL(cli_nt_error(cli), 00508 NT_STATUS_BUFFER_TOO_SMALL)) { 00509 goto out; 00510 } 00511 } 00512 00513 /* parse out the lengths */ 00514 total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); 00515 total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); 00516 00517 /* allocate it */ 00518 if (total_data) { 00519 *data = (char *)SMB_REALLOC(*data,total_data); 00520 if (!(*data)) { 00521 DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); 00522 goto out; 00523 } 00524 } 00525 00526 if (total_param) { 00527 *param = (char *)SMB_REALLOC(*param,total_param); 00528 if (!(*param)) { 00529 DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); 00530 goto out; 00531 } 00532 } 00533 00534 while (1) { 00535 this_data = SVAL(cli->inbuf,smb_ntr_DataCount); 00536 this_param = SVAL(cli->inbuf,smb_ntr_ParameterCount); 00537 00538 if (this_data + *data_len > total_data || 00539 this_param + *param_len > total_param) { 00540 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 00541 goto out; 00542 } 00543 00544 if (this_data + *data_len < this_data || 00545 this_data + *data_len < *data_len || 00546 this_param + *param_len < this_param || 00547 this_param + *param_len < *param_len) { 00548 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 00549 goto out; 00550 } 00551 00552 if (this_data) { 00553 unsigned int data_offset_out = SVAL(cli->inbuf,smb_ntr_DataDisplacement); 00554 unsigned int data_offset_in = SVAL(cli->inbuf,smb_ntr_DataOffset); 00555 00556 if (data_offset_out > total_data || 00557 data_offset_out + this_data > total_data || 00558 data_offset_out + this_data < data_offset_out || 00559 data_offset_out + this_data < this_data) { 00560 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 00561 goto out; 00562 } 00563 if (data_offset_in > cli->bufsize || 00564 data_offset_in + this_data > cli->bufsize || 00565 data_offset_in + this_data < data_offset_in || 00566 data_offset_in + this_data < this_data) { 00567 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 00568 goto out; 00569 } 00570 00571 memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); 00572 } 00573 00574 if (this_param) { 00575 unsigned int param_offset_out = SVAL(cli->inbuf,smb_ntr_ParameterDisplacement); 00576 unsigned int param_offset_in = SVAL(cli->inbuf,smb_ntr_ParameterOffset); 00577 00578 if (param_offset_out > total_param || 00579 param_offset_out + this_param > total_param || 00580 param_offset_out + this_param < param_offset_out || 00581 param_offset_out + this_param < this_param) { 00582 DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); 00583 goto out; 00584 } 00585 if (param_offset_in > cli->bufsize || 00586 param_offset_in + this_param > cli->bufsize || 00587 param_offset_in + this_param < param_offset_in || 00588 param_offset_in + this_param < this_param) { 00589 DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); 00590 goto out; 00591 } 00592 00593 memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); 00594 } 00595 00596 *data_len += this_data; 00597 *param_len += this_param; 00598 00599 if (total_data <= *data_len && total_param <= *param_len) { 00600 ret = True; 00601 break; 00602 } 00603 00604 if (!cli_receive_smb(cli)) { 00605 goto out; 00606 } 00607 00608 show_msg(cli->inbuf); 00609 00610 /* sanity check */ 00611 if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { 00612 DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", 00613 CVAL(cli->inbuf,smb_com))); 00614 goto out; 00615 } 00616 if (cli_is_dos_error(cli)) { 00617 cli_dos_error(cli, &eclass, &ecode); 00618 if(!(eclass == ERRDOS && ecode == ERRmoredata)) { 00619 goto out; 00620 } 00621 } 00622 /* 00623 * Likewise for NT_STATUS_BUFFER_TOO_SMALL 00624 */ 00625 if (cli_is_nt_error(cli)) { 00626 if (!NT_STATUS_EQUAL(cli_nt_error(cli), 00627 NT_STATUS_BUFFER_TOO_SMALL)) { 00628 goto out; 00629 } 00630 } 00631 00632 /* parse out the total lengths again - they can shrink! */ 00633 if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) 00634 total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); 00635 if (SVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) 00636 total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); 00637 00638 if (total_data <= *data_len && total_param <= *param_len) { 00639 ret = True; 00640 break; 00641 } 00642 } 00643 00644 out: 00645 00646 client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); 00647 return ret; 00648 }