関数 | |
static void | copy_trans_params_and_data (char *outbuf, int align, char *rparam, int param_offset, int param_len, char *rdata, int data_offset, int data_len) |
void | send_trans_reply (char *outbuf, char *rparam, int rparam_len, char *rdata, int rdata_len, BOOL buffer_too_large) |
static BOOL | api_rpc_trans_reply (char *outbuf, smb_np_struct *p) |
static BOOL | api_WNPHS (char *outbuf, smb_np_struct *p, char *param, int param_len) |
static BOOL | api_SNPHS (char *outbuf, smb_np_struct *p, char *param, int param_len) |
static BOOL | api_no_reply (char *outbuf, int max_rdata_len) |
static int | api_fd_reply (connection_struct *conn, uint16 vuid, char *outbuf, uint16 *setup, char *data, char *params, int suwcnt, int tdscnt, int tpscnt, int mdrcnt, int mprcnt) |
static int | named_pipe (connection_struct *conn, uint16 vuid, char *outbuf, char *name, uint16 *setup, char *data, char *params, int suwcnt, int tdscnt, int tpscnt, int msrcnt, int mdrcnt, int mprcnt) |
static NTSTATUS | handle_trans (connection_struct *conn, struct trans_state *state, char *outbuf, int *outsize) |
int | reply_trans (connection_struct *conn, char *inbuf, char *outbuf, int size, int bufsize) |
int | reply_transs (connection_struct *conn, char *inbuf, char *outbuf, int size, int bufsize) |
変数 | |
int | max_send |
int | smb_read_error |
static void copy_trans_params_and_data | ( | char * | outbuf, | |
int | align, | |||
char * | rparam, | |||
int | param_offset, | |||
int | param_len, | |||
char * | rdata, | |||
int | data_offset, | |||
int | data_len | |||
) | [static] |
参照元 send_trans_reply().
00049 { 00050 char *copy_into = smb_buf(outbuf)+1; 00051 00052 if(param_len < 0) 00053 param_len = 0; 00054 00055 if(data_len < 0) 00056 data_len = 0; 00057 00058 DEBUG(5,("copy_trans_params_and_data: params[%d..%d] data[%d..%d]\n", 00059 param_offset, param_offset + param_len, 00060 data_offset , data_offset + data_len)); 00061 00062 if (param_len) 00063 memcpy(copy_into, &rparam[param_offset], param_len); 00064 00065 copy_into += param_len + align; 00066 00067 if (data_len ) 00068 memcpy(copy_into, &rdata[data_offset], data_len); 00069 }
void send_trans_reply | ( | char * | outbuf, | |
char * | rparam, | |||
int | rparam_len, | |||
char * | rdata, | |||
int | rdata_len, | |||
BOOL | buffer_too_large | |||
) |
参照先 copy_trans_params_and_data()・exit_server_cleanly()・max_send・send_smb()・set_message()・show_msg()・smbd_server_fd().
参照元 api_fd_reply()・api_no_reply()・api_rpc_trans_reply()・api_SNPHS()・api_WNPHS().
00079 { 00080 int this_ldata,this_lparam; 00081 int tot_data_sent = 0; 00082 int tot_param_sent = 0; 00083 int align; 00084 00085 int ldata = rdata ? rdata_len : 0; 00086 int lparam = rparam ? rparam_len : 0; 00087 00088 if (buffer_too_large) 00089 DEBUG(5,("send_trans_reply: buffer %d too large\n", ldata )); 00090 00091 this_lparam = MIN(lparam,max_send - 500); /* hack */ 00092 this_ldata = MIN(ldata,max_send - (500+this_lparam)); 00093 00094 align = ((this_lparam)%4); 00095 00096 if (buffer_too_large) { 00097 ERROR_BOTH(STATUS_BUFFER_OVERFLOW,ERRDOS,ERRmoredata); 00098 } 00099 00100 set_message(outbuf,10,1+align+this_ldata+this_lparam,True); 00101 00102 copy_trans_params_and_data(outbuf, align, 00103 rparam, tot_param_sent, this_lparam, 00104 rdata, tot_data_sent, this_ldata); 00105 00106 SSVAL(outbuf,smb_vwv0,lparam); 00107 SSVAL(outbuf,smb_vwv1,ldata); 00108 SSVAL(outbuf,smb_vwv3,this_lparam); 00109 SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf)); 00110 SSVAL(outbuf,smb_vwv5,0); 00111 SSVAL(outbuf,smb_vwv6,this_ldata); 00112 SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,outbuf)); 00113 SSVAL(outbuf,smb_vwv8,0); 00114 SSVAL(outbuf,smb_vwv9,0); 00115 00116 show_msg(outbuf); 00117 if (!send_smb(smbd_server_fd(),outbuf)) 00118 exit_server_cleanly("send_trans_reply: send_smb failed."); 00119 00120 tot_data_sent = this_ldata; 00121 tot_param_sent = this_lparam; 00122 00123 while (tot_data_sent < ldata || tot_param_sent < lparam) 00124 { 00125 this_lparam = MIN(lparam-tot_param_sent, max_send - 500); /* hack */ 00126 this_ldata = MIN(ldata -tot_data_sent, max_send - (500+this_lparam)); 00127 00128 if(this_lparam < 0) 00129 this_lparam = 0; 00130 00131 if(this_ldata < 0) 00132 this_ldata = 0; 00133 00134 align = (this_lparam%4); 00135 00136 set_message(outbuf,10,1+this_ldata+this_lparam+align,False); 00137 00138 copy_trans_params_and_data(outbuf, align, 00139 rparam, tot_param_sent, this_lparam, 00140 rdata, tot_data_sent, this_ldata); 00141 00142 SSVAL(outbuf,smb_vwv3,this_lparam); 00143 SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf)); 00144 SSVAL(outbuf,smb_vwv5,tot_param_sent); 00145 SSVAL(outbuf,smb_vwv6,this_ldata); 00146 SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,outbuf)); 00147 SSVAL(outbuf,smb_vwv8,tot_data_sent); 00148 SSVAL(outbuf,smb_vwv9,0); 00149 00150 show_msg(outbuf); 00151 if (!send_smb(smbd_server_fd(),outbuf)) 00152 exit_server_cleanly("send_trans_reply: send_smb failed."); 00153 00154 tot_data_sent += this_ldata; 00155 tot_param_sent += this_lparam; 00156 } 00157 }
static BOOL api_rpc_trans_reply | ( | char * | outbuf, | |
smb_np_struct * | p | |||
) | [static] |
参照先 smb_np_struct::max_trans_reply・read_from_pipe()・send_trans_reply().
参照元 api_fd_reply().
00164 { 00165 BOOL is_data_outstanding; 00166 char *rdata = (char *)SMB_MALLOC(p->max_trans_reply); 00167 int data_len; 00168 00169 if(rdata == NULL) { 00170 DEBUG(0,("api_rpc_trans_reply: malloc fail.\n")); 00171 return False; 00172 } 00173 00174 if((data_len = read_from_pipe( p, rdata, p->max_trans_reply, 00175 &is_data_outstanding)) < 0) { 00176 SAFE_FREE(rdata); 00177 return False; 00178 } 00179 00180 send_trans_reply(outbuf, NULL, 0, rdata, data_len, is_data_outstanding); 00181 00182 SAFE_FREE(rdata); 00183 return True; 00184 }
static BOOL api_WNPHS | ( | char * | outbuf, | |
smb_np_struct * | p, | |||
char * | param, | |||
int | param_len | |||
) | [static] |
参照先 send_trans_reply()・wait_rpc_pipe_hnd_state().
参照元 api_fd_reply().
00191 { 00192 uint16 priority; 00193 00194 if (!param || param_len < 2) 00195 return False; 00196 00197 priority = SVAL(param,0); 00198 DEBUG(4,("WaitNamedPipeHandleState priority %x\n", priority)); 00199 00200 if (wait_rpc_pipe_hnd_state(p, priority)) { 00201 /* now send the reply */ 00202 send_trans_reply(outbuf, NULL, 0, NULL, 0, False); 00203 return True; 00204 } 00205 return False; 00206 }
static BOOL api_SNPHS | ( | char * | outbuf, | |
smb_np_struct * | p, | |||
char * | param, | |||
int | param_len | |||
) | [static] |
参照先 id・send_trans_reply()・set_rpc_pipe_hnd_state().
参照元 api_fd_reply().
00214 { 00215 uint16 id; 00216 00217 if (!param || param_len < 2) 00218 return False; 00219 00220 id = SVAL(param,0); 00221 DEBUG(4,("SetNamedPipeHandleState to code %x\n", id)); 00222 00223 if (set_rpc_pipe_hnd_state(p, id)) { 00224 /* now send the reply */ 00225 send_trans_reply(outbuf, NULL, 0, NULL, 0, False); 00226 return True; 00227 } 00228 return False; 00229 }
static BOOL api_no_reply | ( | char * | outbuf, | |
int | max_rdata_len | |||
) | [static] |
参照先 send_trans_reply().
参照元 api_fd_reply().
00237 { 00238 char rparam[4]; 00239 00240 /* unsupported */ 00241 SSVAL(rparam,0,NERR_notsupported); 00242 SSVAL(rparam,2,0); /* converter word */ 00243 00244 DEBUG(3,("Unsupported API fd command\n")); 00245 00246 /* now send the reply */ 00247 send_trans_reply(outbuf, rparam, 4, NULL, 0, False); 00248 00249 return -1; 00250 }
static int api_fd_reply | ( | connection_struct * | conn, | |
uint16 | vuid, | |||
char * | outbuf, | |||
uint16 * | setup, | |||
char * | data, | |||
char * | params, | |||
int | suwcnt, | |||
int | tdscnt, | |||
int | tpscnt, | |||
int | mdrcnt, | |||
int | mprcnt | |||
) | [static] |
参照先 api_no_reply()・api_rpc_trans_reply()・api_SNPHS()・api_WNPHS()・get_rpc_pipe()・smb_np_struct::max_trans_reply・smb_np_struct::name・send_trans_reply()・smb_np_struct::vuid・write_to_pipe().
参照元 named_pipe().
00259 { 00260 BOOL reply = False; 00261 smb_np_struct *p = NULL; 00262 int pnum; 00263 int subcommand; 00264 00265 DEBUG(5,("api_fd_reply\n")); 00266 00267 /* First find out the name of this file. */ 00268 if (suwcnt != 2) { 00269 DEBUG(0,("Unexpected named pipe transaction.\n")); 00270 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 00271 } 00272 00273 /* Get the file handle and hence the file name. */ 00274 /* 00275 * NB. The setup array has already been transformed 00276 * via SVAL and so is in gost byte order. 00277 */ 00278 pnum = ((int)setup[1]) & 0xFFFF; 00279 subcommand = ((int)setup[0]) & 0xFFFF; 00280 00281 if(!(p = get_rpc_pipe(pnum))) { 00282 if (subcommand == TRANSACT_WAITNAMEDPIPEHANDLESTATE) { 00283 /* Win9x does this call with a unicode pipe name, not a pnum. */ 00284 /* Just return success for now... */ 00285 DEBUG(3,("Got TRANSACT_WAITNAMEDPIPEHANDLESTATE on text pipe name\n")); 00286 send_trans_reply(outbuf, NULL, 0, NULL, 0, False); 00287 return -1; 00288 } 00289 00290 DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum)); 00291 return ERROR_NT(NT_STATUS_INVALID_HANDLE); 00292 } 00293 00294 if (vuid != p->vuid) { 00295 DEBUG(1, ("Got pipe request (pnum %x) using invalid VUID %d, " 00296 "expected %d\n", pnum, vuid, p->vuid)); 00297 return ERROR_NT(NT_STATUS_INVALID_HANDLE); 00298 } 00299 00300 DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n", subcommand, p->name, pnum)); 00301 00302 /* record maximum data length that can be transmitted in an SMBtrans */ 00303 p->max_trans_reply = mdrcnt; 00304 00305 DEBUG(10,("api_fd_reply: p:%p max_trans_reply: %d\n", p, p->max_trans_reply)); 00306 00307 switch (subcommand) { 00308 case TRANSACT_DCERPCCMD: 00309 /* dce/rpc command */ 00310 reply = write_to_pipe(p, data, tdscnt); 00311 if (reply) 00312 reply = api_rpc_trans_reply(outbuf, p); 00313 break; 00314 case TRANSACT_WAITNAMEDPIPEHANDLESTATE: 00315 /* Wait Named Pipe Handle state */ 00316 reply = api_WNPHS(outbuf, p, params, tpscnt); 00317 break; 00318 case TRANSACT_SETNAMEDPIPEHANDLESTATE: 00319 /* Set Named Pipe Handle state */ 00320 reply = api_SNPHS(outbuf, p, params, tpscnt); 00321 break; 00322 default: 00323 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 00324 } 00325 00326 if (!reply) 00327 return api_no_reply(outbuf, mdrcnt); 00328 00329 return -1; 00330 }
static int named_pipe | ( | connection_struct * | conn, | |
uint16 | vuid, | |||
char * | outbuf, | |||
char * | name, | |||
uint16 * | setup, | |||
char * | data, | |||
char * | params, | |||
int | suwcnt, | |||
int | tdscnt, | |||
int | tpscnt, | |||
int | msrcnt, | |||
int | mdrcnt, | |||
int | mprcnt | |||
) | [static] |
参照先 api_fd_reply()・api_reply()・strequal().
参照元 handle_trans().
00339 { 00340 DEBUG(3,("named pipe command on <%s> name\n", name)); 00341 00342 if (strequal(name,"LANMAN")) 00343 return api_reply(conn,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt); 00344 00345 if (strequal(name,"WKSSVC") || 00346 strequal(name,"SRVSVC") || 00347 strequal(name,"WINREG") || 00348 strequal(name,"SAMR") || 00349 strequal(name,"LSARPC")) 00350 { 00351 DEBUG(4,("named pipe command from Win95 (wow!)\n")); 00352 return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt); 00353 } 00354 00355 if (strlen(name) < 1) 00356 return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt); 00357 00358 if (setup) 00359 DEBUG(3,("unknown named pipe: setup 0x%X setup1=%d\n", (int)setup[0],(int)setup[1])); 00360 00361 return 0; 00362 }
static NTSTATUS handle_trans | ( | connection_struct * | conn, | |
struct trans_state * | state, | |||
char * | outbuf, | |||
int * | outsize | |||
) | [static] |
参照先 close_cnum()・trans_state::close_on_completion・trans_state::data・get_local_machine_name()・trans_state::max_data_return・trans_state::max_param_return・trans_state::max_setup_return・trans_state::name・named_pipe()・trans_state::param・trans_state::setup・trans_state::setup_count・strnequal()・talloc_asprintf()・trans_state::total_data・trans_state::total_param・trans_state::vuid.
参照元 reply_trans()・reply_transs().
00367 { 00368 char *local_machine_name; 00369 int name_offset = 0; 00370 00371 DEBUG(3,("trans <%s> data=%u params=%u setup=%u\n", 00372 state->name,(unsigned int)state->total_data,(unsigned int)state->total_param, 00373 (unsigned int)state->setup_count)); 00374 00375 /* 00376 * WinCE wierdness.... 00377 */ 00378 00379 local_machine_name = talloc_asprintf(state, "\\%s\\", 00380 get_local_machine_name()); 00381 00382 if (local_machine_name == NULL) { 00383 return NT_STATUS_NO_MEMORY; 00384 } 00385 00386 if (strnequal(state->name, local_machine_name, 00387 strlen(local_machine_name))) { 00388 name_offset = strlen(local_machine_name)-1; 00389 } 00390 00391 if (!strnequal(&state->name[name_offset], "\\PIPE", 00392 strlen("\\PIPE"))) { 00393 return NT_STATUS_NOT_SUPPORTED; 00394 } 00395 00396 name_offset += strlen("\\PIPE"); 00397 00398 /* Win9x weirdness. When talking to a unicode server Win9x 00399 only sends \PIPE instead of \PIPE\ */ 00400 00401 if (state->name[name_offset] == '\\') 00402 name_offset++; 00403 00404 DEBUG(5,("calling named_pipe\n")); 00405 *outsize = named_pipe(conn, state->vuid, outbuf, 00406 state->name+name_offset, 00407 state->setup,state->data, 00408 state->param, 00409 state->setup_count,state->total_data, 00410 state->total_param, 00411 state->max_setup_return, 00412 state->max_data_return, 00413 state->max_param_return); 00414 00415 if (*outsize == 0) { 00416 return NT_STATUS_NOT_SUPPORTED; 00417 } 00418 00419 if (state->close_on_completion) 00420 close_cnum(conn,state->vuid); 00421 00422 return NT_STATUS_OK; 00423 }
int reply_trans | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | bufsize | |||
) |
参照先 allow_new_trans()・trans_state::close_on_completion・trans_state::cmd・trans_state::data・handle_trans()・trans_state::max_data_return・trans_state::max_param_return・trans_state::max_setup_return・connection_struct::mem_ctx・trans_state::mid・trans_state::name・nt_errstr()・trans_state::one_way・trans_state::param・connection_struct::pending_trans・trans_state::received_data・trans_state::received_param・result・trans_state::setup・trans_state::setup_count・trans_state::total_data・trans_state::total_param・trans_state::vuid.
00431 { 00432 int outsize = 0; 00433 unsigned int dsoff = SVAL(inbuf, smb_dsoff); 00434 unsigned int dscnt = SVAL(inbuf, smb_dscnt); 00435 unsigned int psoff = SVAL(inbuf, smb_psoff); 00436 unsigned int pscnt = SVAL(inbuf, smb_pscnt); 00437 unsigned int av_size = size-4; 00438 struct trans_state *state; 00439 NTSTATUS result; 00440 00441 START_PROFILE(SMBtrans); 00442 00443 result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid)); 00444 if (!NT_STATUS_IS_OK(result)) { 00445 DEBUG(2, ("Got invalid trans request: %s\n", 00446 nt_errstr(result))); 00447 END_PROFILE(SMBtrans); 00448 return ERROR_NT(result); 00449 } 00450 00451 if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) { 00452 DEBUG(0, ("talloc failed\n")); 00453 END_PROFILE(SMBtrans); 00454 return ERROR_NT(NT_STATUS_NO_MEMORY); 00455 } 00456 00457 state->cmd = SMBtrans; 00458 00459 state->mid = SVAL(inbuf, smb_mid); 00460 state->vuid = SVAL(inbuf, smb_uid); 00461 state->setup_count = CVAL(inbuf, smb_suwcnt); 00462 state->setup = NULL; 00463 state->total_param = SVAL(inbuf, smb_tpscnt); 00464 state->param = NULL; 00465 state->total_data = SVAL(inbuf, smb_tdscnt); 00466 state->data = NULL; 00467 state->max_param_return = SVAL(inbuf, smb_mprcnt); 00468 state->max_data_return = SVAL(inbuf, smb_mdrcnt); 00469 state->max_setup_return = CVAL(inbuf, smb_msrcnt); 00470 state->close_on_completion = BITSETW(inbuf+smb_vwv5,0); 00471 state->one_way = BITSETW(inbuf+smb_vwv5,1); 00472 00473 memset(state->name, '\0',sizeof(state->name)); 00474 srvstr_pull_buf(inbuf, state->name, smb_buf(inbuf), 00475 sizeof(state->name), STR_TERMINATE); 00476 00477 if ((dscnt > state->total_data) || (pscnt > state->total_param)) 00478 goto bad_param; 00479 00480 if (state->total_data) { 00481 /* Can't use talloc here, the core routines do realloc on the 00482 * params and data. Out of paranoia, 100 bytes too many. */ 00483 state->data = (char *)SMB_MALLOC(state->total_data+100); 00484 if (state->data == NULL) { 00485 DEBUG(0,("reply_trans: data malloc fail for %u " 00486 "bytes !\n", (unsigned int)state->total_data)); 00487 TALLOC_FREE(state); 00488 END_PROFILE(SMBtrans); 00489 return(ERROR_DOS(ERRDOS,ERRnomem)); 00490 } 00491 /* null-terminate the slack space */ 00492 memset(&state->data[state->total_data], 0, 100); 00493 00494 if (dscnt > state->total_data || 00495 dsoff+dscnt < dsoff) { 00496 goto bad_param; 00497 } 00498 00499 if (dsoff > av_size || 00500 dscnt > av_size || 00501 dsoff+dscnt > av_size) { 00502 goto bad_param; 00503 } 00504 00505 memcpy(state->data,smb_base(inbuf)+dsoff,dscnt); 00506 } 00507 00508 if (state->total_param) { 00509 /* Can't use talloc here, the core routines do realloc on the 00510 * params and data. Out of paranoia, 100 bytes too many */ 00511 state->param = (char *)SMB_MALLOC(state->total_param+100); 00512 if (state->param == NULL) { 00513 DEBUG(0,("reply_trans: param malloc fail for %u " 00514 "bytes !\n", (unsigned int)state->total_param)); 00515 SAFE_FREE(state->data); 00516 TALLOC_FREE(state); 00517 END_PROFILE(SMBtrans); 00518 return(ERROR_DOS(ERRDOS,ERRnomem)); 00519 } 00520 /* null-terminate the slack space */ 00521 memset(&state->param[state->total_param], 0, 100); 00522 00523 if (pscnt > state->total_param || 00524 psoff+pscnt < psoff) { 00525 goto bad_param; 00526 } 00527 00528 if (psoff > av_size || 00529 pscnt > av_size || 00530 psoff+pscnt > av_size) { 00531 goto bad_param; 00532 } 00533 00534 memcpy(state->param,smb_base(inbuf)+psoff,pscnt); 00535 } 00536 00537 state->received_data = dscnt; 00538 state->received_param = pscnt; 00539 00540 if (state->setup_count) { 00541 unsigned int i; 00542 if((state->setup = TALLOC_ARRAY( 00543 state, uint16, state->setup_count)) == NULL) { 00544 DEBUG(0,("reply_trans: setup malloc fail for %u " 00545 "bytes !\n", (unsigned int) 00546 (state->setup_count * sizeof(uint16)))); 00547 TALLOC_FREE(state); 00548 END_PROFILE(SMBtrans); 00549 return(ERROR_DOS(ERRDOS,ERRnomem)); 00550 } 00551 if (inbuf+smb_vwv14+(state->setup_count*SIZEOFWORD) > 00552 inbuf + size) 00553 goto bad_param; 00554 if ((smb_vwv14+(state->setup_count*SIZEOFWORD) < smb_vwv14) || 00555 (smb_vwv14+(state->setup_count*SIZEOFWORD) < 00556 (state->setup_count*SIZEOFWORD))) 00557 goto bad_param; 00558 00559 for (i=0;i<state->setup_count;i++) 00560 state->setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD); 00561 } 00562 00563 state->received_param = pscnt; 00564 00565 if ((state->received_param == state->total_param) && 00566 (state->received_data == state->total_data)) { 00567 00568 result = handle_trans(conn, state, outbuf, &outsize); 00569 00570 SAFE_FREE(state->data); 00571 SAFE_FREE(state->param); 00572 TALLOC_FREE(state); 00573 00574 if (!NT_STATUS_IS_OK(result)) { 00575 END_PROFILE(SMBtrans); 00576 return ERROR_NT(result); 00577 } 00578 00579 if (outsize == 0) { 00580 END_PROFILE(SMBtrans); 00581 return ERROR_NT(NT_STATUS_INTERNAL_ERROR); 00582 } 00583 00584 END_PROFILE(SMBtrans); 00585 return outsize; 00586 } 00587 00588 DLIST_ADD(conn->pending_trans, state); 00589 00590 /* We need to send an interim response then receive the rest 00591 of the parameter/data bytes */ 00592 outsize = set_message(outbuf,0,0,True); 00593 show_msg(outbuf); 00594 END_PROFILE(SMBtrans); 00595 return outsize; 00596 00597 bad_param: 00598 00599 DEBUG(0,("reply_trans: invalid trans parameters\n")); 00600 SAFE_FREE(state->data); 00601 SAFE_FREE(state->param); 00602 TALLOC_FREE(state); 00603 END_PROFILE(SMBtrans); 00604 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 00605 }
int reply_transs | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | bufsize | |||
) |
参照先 trans_state::cmd・trans_state::data・handle_trans()・trans_state::mid・trans_state::next・trans_state::param・connection_struct::pending_trans・trans_state::received_data・trans_state::received_param・result・show_msg()・trans_state::total_data・trans_state::total_param.
00613 { 00614 int outsize = 0; 00615 unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp; 00616 unsigned int av_size = size-4; 00617 struct trans_state *state; 00618 NTSTATUS result; 00619 00620 START_PROFILE(SMBtranss); 00621 00622 show_msg(inbuf); 00623 00624 for (state = conn->pending_trans; state != NULL; 00625 state = state->next) { 00626 if (state->mid == SVAL(inbuf,smb_mid)) { 00627 break; 00628 } 00629 } 00630 00631 if ((state == NULL) || (state->cmd != SMBtrans)) { 00632 END_PROFILE(SMBtranss); 00633 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 00634 } 00635 00636 /* Revise total_params and total_data in case they have changed 00637 * downwards */ 00638 00639 if (SVAL(inbuf, smb_vwv0) < state->total_param) 00640 state->total_param = SVAL(inbuf,smb_vwv0); 00641 if (SVAL(inbuf, smb_vwv1) < state->total_data) 00642 state->total_data = SVAL(inbuf,smb_vwv1); 00643 00644 pcnt = SVAL(inbuf, smb_spscnt); 00645 poff = SVAL(inbuf, smb_spsoff); 00646 pdisp = SVAL(inbuf, smb_spsdisp); 00647 00648 dcnt = SVAL(inbuf, smb_sdscnt); 00649 doff = SVAL(inbuf, smb_sdsoff); 00650 ddisp = SVAL(inbuf, smb_sdsdisp); 00651 00652 state->received_param += pcnt; 00653 state->received_data += dcnt; 00654 00655 if ((state->received_data > state->total_data) || 00656 (state->received_param > state->total_param)) 00657 goto bad_param; 00658 00659 if (pcnt) { 00660 if (pdisp > state->total_param || 00661 pcnt > state->total_param || 00662 pdisp+pcnt > state->total_param || 00663 pdisp+pcnt < pdisp) { 00664 goto bad_param; 00665 } 00666 00667 if (poff > av_size || 00668 pcnt > av_size || 00669 poff+pcnt > av_size || 00670 poff+pcnt < poff) { 00671 goto bad_param; 00672 } 00673 00674 memcpy(state->param+pdisp,smb_base(inbuf)+poff, 00675 pcnt); 00676 } 00677 00678 if (dcnt) { 00679 if (ddisp > state->total_data || 00680 dcnt > state->total_data || 00681 ddisp+dcnt > state->total_data || 00682 ddisp+dcnt < ddisp) { 00683 goto bad_param; 00684 } 00685 00686 if (doff > av_size || 00687 dcnt > av_size || 00688 doff+dcnt > av_size || 00689 doff+dcnt < doff) { 00690 goto bad_param; 00691 } 00692 00693 memcpy(state->data+ddisp, smb_base(inbuf)+doff, 00694 dcnt); 00695 } 00696 00697 if ((state->received_param < state->total_param) || 00698 (state->received_data < state->total_data)) { 00699 END_PROFILE(SMBtranss); 00700 return -1; 00701 } 00702 00703 /* construct_reply_common has done us the favor to pre-fill the 00704 * command field with SMBtranss which is wrong :-) 00705 */ 00706 SCVAL(outbuf,smb_com,SMBtrans); 00707 00708 result = handle_trans(conn, state, outbuf, &outsize); 00709 00710 DLIST_REMOVE(conn->pending_trans, state); 00711 SAFE_FREE(state->data); 00712 SAFE_FREE(state->param); 00713 TALLOC_FREE(state); 00714 00715 if ((outsize == 0) || !NT_STATUS_IS_OK(result)) { 00716 END_PROFILE(SMBtranss); 00717 return(ERROR_DOS(ERRSRV,ERRnosupport)); 00718 } 00719 00720 END_PROFILE(SMBtranss); 00721 return(outsize); 00722 00723 bad_param: 00724 00725 DEBUG(0,("reply_transs: invalid trans parameters\n")); 00726 DLIST_REMOVE(conn->pending_trans, state); 00727 SAFE_FREE(state->data); 00728 SAFE_FREE(state->param); 00729 TALLOC_FREE(state); 00730 END_PROFILE(SMBtranss); 00731 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 00732 }
int smb_read_error |
util_sock.c の 117 行で定義されています。