libsmb/clitrans.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    client transaction calls
00004    Copyright (C) Andrew Tridgell 1994-1998
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 #include "includes.h"
00022 
00023 
00024 /****************************************************************************
00025  Send a SMB trans or trans2 request.
00026 ****************************************************************************/
00027 
00028 BOOL cli_send_trans(struct cli_state *cli, int trans, 
00029                     const char *pipe_name, 
00030                     int fid, int flags,
00031                     uint16 *setup, unsigned int lsetup, unsigned int msetup,
00032                     const char *param, unsigned int lparam, unsigned int mparam,
00033                     const char *data, unsigned int ldata, unsigned int mdata)
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 }
00164 
00165 /****************************************************************************
00166  Receive a SMB trans or trans2 response allocating the necessary memory.
00167 ****************************************************************************/
00168 
00169 BOOL cli_receive_trans(struct cli_state *cli,int trans,
00170                               char **param, unsigned int *param_len,
00171                               char **data, unsigned int *data_len)
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 }
00332 
00333 /****************************************************************************
00334  Send a SMB nttrans request.
00335 ****************************************************************************/
00336 
00337 BOOL cli_send_nt_trans(struct cli_state *cli, 
00338                        int function, 
00339                        int flags,
00340                        uint16 *setup, unsigned int lsetup, unsigned int msetup,
00341                        char *param, unsigned int lparam, unsigned int mparam,
00342                        char *data, unsigned int ldata, unsigned int mdata)
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 }
00460 
00461 /****************************************************************************
00462  Receive a SMB nttrans response allocating the necessary memory.
00463 ****************************************************************************/
00464 
00465 BOOL cli_receive_nt_trans(struct cli_state *cli,
00466                           char **param, unsigned int *param_len,
00467                           char **data, unsigned int *data_len)
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 }

Sambaに対してSat Aug 29 21:23:05 2009に生成されました。  doxygen 1.4.7