libsmb/clirap.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    client RAP calls
00004    Copyright (C) Andrew Tridgell         1994-1998
00005    Copyright (C) Gerald (Jerry) Carter   2004
00006    
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011    
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016    
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 */
00021 
00022 #include "includes.h"
00023 
00024 /****************************************************************************
00025  Call a remote api on an arbitrary pipe.  takes param, data and setup buffers.
00026 ****************************************************************************/
00027 
00028 BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, 
00029                   uint16 *setup, uint32 setup_count, uint32 max_setup_count,
00030                   char *params, uint32 param_count, uint32 max_param_count,
00031                   char *data, uint32 data_count, uint32 max_data_count,
00032                   char **rparam, uint32 *rparam_count,
00033                   char **rdata, uint32 *rdata_count)
00034 {
00035         cli_send_trans(cli, SMBtrans, 
00036                  pipe_name, 
00037                  0,0,                         /* fid, flags */
00038                  setup, setup_count, max_setup_count,
00039                  params, param_count, max_param_count,
00040                  data, data_count, max_data_count);
00041 
00042         return (cli_receive_trans(cli, SMBtrans, 
00043                             rparam, (unsigned int *)rparam_count,
00044                             rdata, (unsigned int *)rdata_count));
00045 }
00046 
00047 /****************************************************************************
00048  Call a remote api
00049 ****************************************************************************/
00050 
00051 BOOL cli_api(struct cli_state *cli,
00052              char *param, int prcnt, int mprcnt,
00053              char *data, int drcnt, int mdrcnt,
00054              char **rparam, unsigned int *rprcnt,
00055              char **rdata, unsigned int *rdrcnt)
00056 {
00057         cli_send_trans(cli,SMBtrans,
00058                  PIPE_LANMAN,             /* Name */
00059                  0,0,                     /* fid, flags */
00060                  NULL,0,0,                /* Setup, length, max */
00061                  param, prcnt, mprcnt,    /* Params, length, max */
00062                  data, drcnt, mdrcnt      /* Data, length, max */ 
00063                 );
00064 
00065         return (cli_receive_trans(cli,SMBtrans,
00066                             rparam, rprcnt,
00067                             rdata, rdrcnt));
00068 }
00069 
00070 /****************************************************************************
00071  Perform a NetWkstaUserLogon.
00072 ****************************************************************************/
00073 
00074 BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
00075 {
00076         char *rparam = NULL;
00077         char *rdata = NULL;
00078         char *p;
00079         unsigned int rdrcnt,rprcnt;
00080         pstring param;
00081 
00082         memset(param, 0, sizeof(param));
00083         
00084         /* send a SMBtrans command with api NetWkstaUserLogon */
00085         p = param;
00086         SSVAL(p,0,132); /* api number */
00087         p += 2;
00088         pstrcpy_base(p,"OOWb54WrLh",param);
00089         p = skip_string(param,sizeof(param),p);
00090         pstrcpy_base(p,"WB21BWDWWDDDDDDDzzzD",param);
00091         p = skip_string(param,sizeof(param),p);
00092         SSVAL(p,0,1);
00093         p += 2;
00094         pstrcpy_base(p,user,param);
00095         strupper_m(p);
00096         p += 21;
00097         p++;
00098         p += 15;
00099         p++; 
00100         pstrcpy_base(p, workstation, param);
00101         strupper_m(p);
00102         p += 16;
00103         SSVAL(p, 0, CLI_BUFFER_SIZE);
00104         p += 2;
00105         SSVAL(p, 0, CLI_BUFFER_SIZE);
00106         p += 2;
00107         
00108         if (cli_api(cli, 
00109                     param, PTR_DIFF(p,param),1024,  /* param, length, max */
00110                     NULL, 0, CLI_BUFFER_SIZE,           /* data, length, max */
00111                     &rparam, &rprcnt,               /* return params, return size */
00112                     &rdata, &rdrcnt                 /* return data, return size */
00113                    )) {
00114                 cli->rap_error = rparam? SVAL(rparam,0) : -1;
00115                 p = rdata;
00116                 
00117                 if (cli->rap_error == 0) {
00118                         DEBUG(4,("NetWkstaUserLogon success\n"));
00119                         cli->privileges = SVAL(p, 24);
00120                         /* The cli->eff_name field used to be set here
00121                            but it wasn't used anywhere else. */
00122                 } else {
00123                         DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error));
00124                 }
00125         }
00126         
00127         SAFE_FREE(rparam);
00128         SAFE_FREE(rdata);
00129         return (cli->rap_error == 0);
00130 }
00131 
00132 /****************************************************************************
00133  Call a NetShareEnum - try and browse available connections on a host.
00134 ****************************************************************************/
00135 
00136 int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state)
00137 {
00138         char *rparam = NULL;
00139         char *rdata = NULL;
00140         char *p;
00141         unsigned int rdrcnt,rprcnt;
00142         pstring param;
00143         int count = -1;
00144 
00145         /* now send a SMBtrans command with api RNetShareEnum */
00146         p = param;
00147         SSVAL(p,0,0); /* api number */
00148         p += 2;
00149         pstrcpy_base(p,"WrLeh",param);
00150         p = skip_string(param,sizeof(param),p);
00151         pstrcpy_base(p,"B13BWz",param);
00152         p = skip_string(param,sizeof(param),p);
00153         SSVAL(p,0,1);
00154         /*
00155          * Win2k needs a *smaller* buffer than 0xFFFF here -
00156          * it returns "out of server memory" with 0xFFFF !!! JRA.
00157          */
00158         SSVAL(p,2,0xFFE0);
00159         p += 4;
00160         
00161         if (cli_api(cli, 
00162                     param, PTR_DIFF(p,param), 1024,  /* Param, length, maxlen */
00163                     NULL, 0, 0xFFE0,            /* data, length, maxlen - Win2k needs a small buffer here too ! */
00164                     &rparam, &rprcnt,                /* return params, length */
00165                     &rdata, &rdrcnt))                /* return data, length */
00166                 {
00167                         int res = rparam? SVAL(rparam,0) : -1;
00168                         
00169                         if (res == 0 || res == ERRmoredata) {
00170                                 int converter=SVAL(rparam,2);
00171                                 int i;
00172                                 
00173                                 count=SVAL(rparam,4);
00174                                 p = rdata;
00175                                 
00176                                 for (i=0;i<count;i++,p+=20) {
00177                                         char *sname = p;
00178                                         int type = SVAL(p,14);
00179                                         int comment_offset = IVAL(p,16) & 0xFFFF;
00180                                         const char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
00181                                         pstring s1, s2;
00182 
00183                                         pull_ascii_pstring(s1, sname);
00184                                         pull_ascii_pstring(s2, cmnt);
00185 
00186                                         fn(s1, type, s2, state);
00187                                 }
00188                         } else {
00189                                 DEBUG(4,("NetShareEnum res=%d\n", res));
00190                         }      
00191                 } else {
00192                         DEBUG(4,("NetShareEnum failed\n"));
00193                 }
00194   
00195         SAFE_FREE(rparam);
00196         SAFE_FREE(rdata);
00197         
00198         return count;
00199 }
00200 
00201 /****************************************************************************
00202  Call a NetServerEnum for the specified workgroup and servertype mask.  This
00203  function then calls the specified callback function for each name returned.
00204 
00205  The callback function takes 4 arguments: the machine name, the server type,
00206  the comment and a state pointer.
00207 ****************************************************************************/
00208 
00209 BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
00210                        void (*fn)(const char *, uint32, const char *, void *),
00211                        void *state)
00212 {
00213         char *rparam = NULL;
00214         char *rdata = NULL;
00215         unsigned int rdrcnt,rprcnt;
00216         char *p;
00217         pstring param;
00218         int uLevel = 1;
00219         int count = -1;
00220         size_t len;
00221 
00222         errno = 0; /* reset */
00223 
00224         /* send a SMBtrans command with api NetServerEnum */
00225         p = param;
00226         SSVAL(p,0,0x68); /* api number */
00227         p += 2;
00228         pstrcpy_base(p,"WrLehDz", param);
00229         p = skip_string(param,sizeof(param),p);
00230   
00231         pstrcpy_base(p,"B16BBDz", param);
00232 
00233         p = skip_string(param,sizeof(param),p);
00234         SSVAL(p,0,uLevel);
00235         SSVAL(p,2,CLI_BUFFER_SIZE);
00236         p += 4;
00237         SIVAL(p,0,stype);
00238         p += 4;
00239 
00240         len = push_ascii(p, workgroup, sizeof(pstring)-PTR_DIFF(p,param)-1, STR_TERMINATE|STR_UPPER);
00241         if (len == (size_t)-1) {
00242                 return false;
00243         }
00244         p += len;
00245         
00246         if (cli_api(cli, 
00247                     param, PTR_DIFF(p,param), 8,        /* params, length, max */
00248                     NULL, 0, CLI_BUFFER_SIZE,               /* data, length, max */
00249                     &rparam, &rprcnt,                   /* return params, return size */
00250                     &rdata, &rdrcnt                     /* return data, return size */
00251                    )) {
00252                 int res = rparam? SVAL(rparam,0) : -1;
00253                         
00254                 if (res == 0 || res == ERRmoredata ||
00255                     (res != -1 && cli_errno(cli) == 0)) {
00256                         int i;
00257                         int converter=SVAL(rparam,2);
00258 
00259                         count=SVAL(rparam,4);
00260                         p = rdata;
00261                                         
00262                         for (i = 0;i < count;i++, p += 26) {
00263                                 char *sname = p;
00264                                 int comment_offset = (IVAL(p,22) & 0xFFFF)-converter;
00265                                 const char *cmnt = comment_offset?(rdata+comment_offset):"";
00266                                 pstring s1, s2;
00267 
00268                                 if (comment_offset < 0 || comment_offset > (int)rdrcnt) continue;
00269 
00270                                 stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
00271 
00272                                 pull_ascii_pstring(s1, sname);
00273                                 pull_ascii_pstring(s2, cmnt);
00274                                 fn(s1, stype, s2, state);
00275                         }
00276                 }
00277         }
00278   
00279         SAFE_FREE(rparam);
00280         SAFE_FREE(rdata);
00281 
00282         if (count < 0) {
00283             errno = cli_errno(cli);
00284         } else {
00285             if (!count) {
00286                 /* this is a very special case, when the domain master for the 
00287                    work group isn't part of the work group itself, there is something
00288                    wild going on */
00289                 errno = ENOENT;
00290             }
00291         }
00292                         
00293         return(count > 0);
00294 }
00295 
00296 /****************************************************************************
00297  Send a SamOEMChangePassword command.
00298 ****************************************************************************/
00299 
00300 BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
00301                              const char *old_password)
00302 {
00303         pstring param;
00304         unsigned char data[532];
00305         char *p = param;
00306         unsigned char old_pw_hash[16];
00307         unsigned char new_pw_hash[16];
00308         unsigned int data_len;
00309         unsigned int param_len = 0;
00310         char *rparam = NULL;
00311         char *rdata = NULL;
00312         unsigned int rprcnt, rdrcnt;
00313 
00314         if (strlen(user) >= sizeof(fstring)-1) {
00315                 DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user));
00316                 return False;
00317         }
00318 
00319         SSVAL(p,0,214); /* SamOEMChangePassword command. */
00320         p += 2;
00321         pstrcpy_base(p, "zsT", param);
00322         p = skip_string(param,sizeof(param),p);
00323         pstrcpy_base(p, "B516B16", param);
00324         p = skip_string(param,sizeof(param),p);
00325         pstrcpy_base(p,user, param);
00326         p = skip_string(param,sizeof(param),p);
00327         SSVAL(p,0,532);
00328         p += 2;
00329 
00330         param_len = PTR_DIFF(p,param);
00331 
00332         /*
00333          * Get the Lanman hash of the old password, we
00334          * use this as the key to make_oem_passwd_hash().
00335          */
00336         E_deshash(old_password, old_pw_hash);
00337 
00338         encode_pw_buffer(data, new_password, STR_ASCII);
00339   
00340 #ifdef DEBUG_PASSWORD
00341         DEBUG(100,("make_oem_passwd_hash\n"));
00342         dump_data(100, (char *)data, 516);
00343 #endif
00344         SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516);
00345 
00346         /* 
00347          * Now place the old password hash in the data.
00348          */
00349         E_deshash(new_password, new_pw_hash);
00350 
00351         E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]);
00352 
00353         data_len = 532;
00354     
00355         if (cli_send_trans(cli,SMBtrans,
00356                     PIPE_LANMAN,                          /* name */
00357                     0,0,                                  /* fid, flags */
00358                     NULL,0,0,                             /* setup, length, max */
00359                     param,param_len,2,                    /* param, length, max */
00360                     (char *)data,data_len,0                       /* data, length, max */
00361                    ) == False) {
00362                 DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n",
00363                         user ));
00364                 return False;
00365         }
00366 
00367         if (!cli_receive_trans(cli,SMBtrans,
00368                        &rparam, &rprcnt,
00369                        &rdata, &rdrcnt)) {
00370                 DEBUG(0,("cli_oem_change_password: Failed to recieve reply to password change for user %s\n",
00371                         user ));
00372                 return False;
00373         }
00374   
00375         if (rparam) {
00376                 cli->rap_error = SVAL(rparam,0);
00377         }
00378   
00379         SAFE_FREE(rparam);
00380         SAFE_FREE(rdata);
00381 
00382         return (cli->rap_error == 0);
00383 }
00384 
00385 /****************************************************************************
00386  Send a qpathinfo call.
00387 ****************************************************************************/
00388 
00389 BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, 
00390                    time_t *change_time,
00391                    time_t *access_time,
00392                    time_t *write_time, 
00393                    SMB_OFF_T *size, uint16 *mode)
00394 {
00395         unsigned int data_len = 0;
00396         unsigned int param_len = 0;
00397         unsigned int rparam_len, rdata_len;
00398         uint16 setup = TRANSACT2_QPATHINFO;
00399         pstring param;
00400         char *rparam=NULL, *rdata=NULL;
00401         int count=8;
00402         BOOL ret;
00403         time_t (*date_fn)(struct cli_state *, void *);
00404         char *p;
00405 
00406         p = param;
00407         memset(p, 0, 6);
00408         SSVAL(p, 0, SMB_INFO_STANDARD);
00409         p += 6;
00410         p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE);
00411 
00412         param_len = PTR_DIFF(p, param);
00413 
00414         do {
00415                 ret = (cli_send_trans(cli, SMBtrans2, 
00416                                       NULL,           /* Name */
00417                                       -1, 0,          /* fid, flags */
00418                                       &setup, 1, 0,   /* setup, length, max */
00419                                       param, param_len, 10, /* param, length, max */
00420                                       NULL, data_len, cli->max_xmit /* data, length, max */
00421                                       ) &&
00422                        cli_receive_trans(cli, SMBtrans2, 
00423                                          &rparam, &rparam_len,
00424                                          &rdata, &rdata_len));
00425                 if (!cli_is_dos_error(cli)) break;
00426                 if (!ret) {
00427                         /* we need to work around a Win95 bug - sometimes
00428                            it gives ERRSRV/ERRerror temprarily */
00429                         uint8 eclass;
00430                         uint32 ecode;
00431                         cli_dos_error(cli, &eclass, &ecode);
00432                         if (eclass != ERRSRV || ecode != ERRerror) break;
00433                         smb_msleep(100);
00434                 }
00435         } while (count-- && ret==False);
00436 
00437         if (!ret || !rdata || rdata_len < 22) {
00438                 return False;
00439         }
00440 
00441         if (cli->win95) {
00442                 date_fn = cli_make_unix_date;
00443         } else {
00444                 date_fn = cli_make_unix_date2;
00445         }
00446 
00447         if (change_time) {
00448                 *change_time = date_fn(cli, rdata+0);
00449         }
00450         if (access_time) {
00451                 *access_time = date_fn(cli, rdata+4);
00452         }
00453         if (write_time) {
00454                 *write_time = date_fn(cli, rdata+8);
00455         }
00456         if (size) {
00457                 *size = IVAL(rdata, 12);
00458         }
00459         if (mode) {
00460                 *mode = SVAL(rdata,l1_attrFile);
00461         }
00462 
00463         SAFE_FREE(rdata);
00464         SAFE_FREE(rparam);
00465         return True;
00466 }
00467 
00468 /****************************************************************************
00469  Send a setpathinfo call.
00470 ****************************************************************************/
00471 
00472 BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, 
00473                      time_t create_time,
00474                      time_t access_time,
00475                      time_t write_time,
00476                      time_t change_time,
00477                      uint16 mode)
00478 {
00479         unsigned int data_len = 0;
00480         unsigned int param_len = 0;
00481         unsigned int rparam_len, rdata_len;
00482         uint16 setup = TRANSACT2_SETPATHINFO;
00483         pstring param;
00484         pstring data;
00485         char *rparam=NULL, *rdata=NULL;
00486         int count=8;
00487         BOOL ret;
00488         char *p;
00489 
00490         memset(param, 0, sizeof(param));
00491         memset(data, 0, sizeof(data));
00492 
00493         p = param;
00494 
00495         /* Add the information level */
00496         SSVAL(p, 0, SMB_FILE_BASIC_INFORMATION);
00497 
00498         /* Skip reserved */
00499         p += 6;
00500 
00501         /* Add the file name */
00502         p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE);
00503 
00504         param_len = PTR_DIFF(p, param);
00505 
00506         p = data;
00507 
00508         /*
00509          * Add the create, last access, modification, and status change times
00510          */
00511         
00512         put_long_date(p, create_time);
00513         p += 8;
00514 
00515         put_long_date(p, access_time);
00516         p += 8;
00517         
00518         put_long_date(p, write_time);
00519         p += 8;
00520         
00521         put_long_date(p, change_time);
00522         p += 8;
00523 
00524         /* Add attributes */
00525         SIVAL(p, 0, mode);
00526         p += 4;
00527 
00528         /* Add padding */
00529         SIVAL(p, 0, 0);
00530         p += 4;
00531 
00532         data_len = PTR_DIFF(p, data);
00533 
00534         do {
00535                 ret = (cli_send_trans(cli, SMBtrans2, 
00536                                       NULL,           /* Name */
00537                                       -1, 0,          /* fid, flags */
00538                                       &setup, 1, 0,   /* setup, length, max */
00539                                       param, param_len, 10, /* param, length, max */
00540                                       data, data_len, cli->max_xmit /* data, length, max */
00541                                       ) &&
00542                        cli_receive_trans(cli, SMBtrans2, 
00543                                          &rparam, &rparam_len,
00544                                          &rdata, &rdata_len));
00545                 if (!cli_is_dos_error(cli)) break;
00546                 if (!ret) {
00547                         /* we need to work around a Win95 bug - sometimes
00548                            it gives ERRSRV/ERRerror temprarily */
00549                         uint8 eclass;
00550                         uint32 ecode;
00551                         cli_dos_error(cli, &eclass, &ecode);
00552                         if (eclass != ERRSRV || ecode != ERRerror) break;
00553                         smb_msleep(100);
00554                 }
00555         } while (count-- && ret==False);
00556 
00557         if (!ret) {
00558                 return False;
00559         }
00560 
00561         SAFE_FREE(rdata);
00562         SAFE_FREE(rparam);
00563         return True;
00564 }
00565 
00566 /****************************************************************************
00567  Send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level.
00568 ****************************************************************************/
00569 
00570 BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, 
00571                     struct timespec *create_time,
00572                     struct timespec *access_time,
00573                     struct timespec *write_time, 
00574                     struct timespec *change_time,
00575                     SMB_OFF_T *size, uint16 *mode,
00576                     SMB_INO_T *ino)
00577 {
00578         unsigned int data_len = 0;
00579         unsigned int param_len = 0;
00580         uint16 setup = TRANSACT2_QPATHINFO;
00581         pstring param;
00582         char *rparam=NULL, *rdata=NULL;
00583         char *p;
00584 
00585         p = param;
00586         memset(p, 0, 6);
00587         SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO);
00588         p += 6;
00589         p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE);
00590 
00591         param_len = PTR_DIFF(p, param);
00592 
00593         if (!cli_send_trans(cli, SMBtrans2, 
00594                             NULL,                         /* name */
00595                             -1, 0,                        /* fid, flags */
00596                             &setup, 1, 0,                 /* setup, length, max */
00597                             param, param_len, 10,         /* param, length, max */
00598                             NULL, data_len, cli->max_xmit /* data, length, max */
00599                            )) {
00600                 return False;
00601         }
00602 
00603         if (!cli_receive_trans(cli, SMBtrans2,
00604                                &rparam, &param_len,
00605                                &rdata, &data_len)) {
00606                 return False;
00607         }
00608 
00609         if (!rdata || data_len < 22) {
00610                 return False;
00611         }
00612         
00613         if (create_time) {
00614                 *create_time = interpret_long_date(rdata+0);
00615         }
00616         if (access_time) {
00617                 *access_time = interpret_long_date(rdata+8);
00618         }
00619         if (write_time) {
00620                 *write_time = interpret_long_date(rdata+16);
00621         }
00622         if (change_time) {
00623                 *change_time = interpret_long_date(rdata+24);
00624         }
00625         if (mode) {
00626                 *mode = SVAL(rdata, 32);
00627         }
00628         if (size) {
00629                 *size = IVAL2_TO_SMB_BIG_UINT(rdata,48);
00630         }
00631         if (ino) {
00632                 *ino = IVAL(rdata, 64);
00633         }
00634 
00635         SAFE_FREE(rdata);
00636         SAFE_FREE(rparam);
00637         return True;
00638 }
00639 
00640 /****************************************************************************
00641  Send a qfileinfo QUERY_FILE_NAME_INFO call.
00642 ****************************************************************************/
00643 
00644 BOOL cli_qfilename(struct cli_state *cli, int fnum, 
00645                    pstring name)
00646 {
00647         unsigned int data_len = 0;
00648         unsigned int param_len = 0;
00649         uint16 setup = TRANSACT2_QFILEINFO;
00650         pstring param;
00651         char *rparam=NULL, *rdata=NULL;
00652 
00653         param_len = 4;
00654         memset(param, 0, param_len);
00655         SSVAL(param, 0, fnum);
00656         SSVAL(param, 2, SMB_QUERY_FILE_NAME_INFO);
00657 
00658         if (!cli_send_trans(cli, SMBtrans2, 
00659                             NULL,                         /* name */
00660                             -1, 0,                        /* fid, flags */
00661                             &setup, 1, 0,                 /* setup, length, max */
00662                             param, param_len, 2,          /* param, length, max */
00663                             NULL, data_len, cli->max_xmit /* data, length, max */
00664                            )) {
00665                 return False;
00666         }
00667 
00668         if (!cli_receive_trans(cli, SMBtrans2,
00669                                &rparam, &param_len,
00670                                &rdata, &data_len)) {
00671                 return False;
00672         }
00673 
00674         if (!rdata || data_len < 4) {
00675                 return False;
00676         }
00677 
00678         clistr_pull(cli, name, rdata+4, sizeof(pstring), IVAL(rdata, 0), STR_UNICODE);
00679 
00680         return True;
00681 }
00682 
00683 /****************************************************************************
00684  Send a qfileinfo call.
00685 ****************************************************************************/
00686 
00687 BOOL cli_qfileinfo(struct cli_state *cli, int fnum, 
00688                    uint16 *mode, SMB_OFF_T *size,
00689                    struct timespec *create_time,
00690                    struct timespec *access_time,
00691                    struct timespec *write_time, 
00692                    struct timespec *change_time,
00693                    SMB_INO_T *ino)
00694 {
00695         unsigned int data_len = 0;
00696         unsigned int param_len = 0;
00697         uint16 setup = TRANSACT2_QFILEINFO;
00698         pstring param;
00699         char *rparam=NULL, *rdata=NULL;
00700 
00701         /* if its a win95 server then fail this - win95 totally screws it
00702            up */
00703         if (cli->win95) return False;
00704 
00705         param_len = 4;
00706 
00707         memset(param, 0, param_len);
00708         SSVAL(param, 0, fnum);
00709         SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO);
00710 
00711         if (!cli_send_trans(cli, SMBtrans2, 
00712                             NULL,                         /* name */
00713                             -1, 0,                        /* fid, flags */
00714                             &setup, 1, 0,                 /* setup, length, max */
00715                             param, param_len, 2,          /* param, length, max */
00716                             NULL, data_len, cli->max_xmit /* data, length, max */
00717                            )) {
00718                 return False;
00719         }
00720 
00721         if (!cli_receive_trans(cli, SMBtrans2,
00722                                &rparam, &param_len,
00723                                &rdata, &data_len)) {
00724                 return False;
00725         }
00726 
00727         if (!rdata || data_len < 68) {
00728                 return False;
00729         }
00730 
00731         if (create_time) {
00732                 *create_time = interpret_long_date(rdata+0);
00733         }
00734         if (access_time) {
00735                 *access_time = interpret_long_date(rdata+8);
00736         }
00737         if (write_time) {
00738                 *write_time = interpret_long_date(rdata+16);
00739         }
00740         if (change_time) {
00741                 *change_time = interpret_long_date(rdata+24);
00742         }
00743         if (mode) {
00744                 *mode = SVAL(rdata, 32);
00745         }
00746         if (size) {
00747                 *size = IVAL2_TO_SMB_BIG_UINT(rdata,48);
00748         }
00749         if (ino) {
00750                 *ino = IVAL(rdata, 64);
00751         }
00752 
00753         SAFE_FREE(rdata);
00754         SAFE_FREE(rparam);
00755         return True;
00756 }
00757 
00758 /****************************************************************************
00759  Send a qpathinfo BASIC_INFO call.
00760 ****************************************************************************/
00761 
00762 BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, 
00763                           SMB_STRUCT_STAT *sbuf, uint32 *attributes )
00764 {
00765         unsigned int param_len = 0;
00766         unsigned int data_len = 0;
00767         uint16 setup = TRANSACT2_QPATHINFO;
00768         char param[sizeof(pstring)+6];
00769         char *rparam=NULL, *rdata=NULL;
00770         char *p;
00771         pstring path;
00772         int len;
00773         
00774         pstrcpy( path, name );
00775         /* cleanup */
00776         
00777         len = strlen( path );
00778         if ( path[len-1] == '\\' || path[len-1] == '/')
00779                 path[len-1] = '\0';
00780 
00781         p = param;
00782         memset(p, 0, 6);
00783         SSVAL(p, 0, SMB_QUERY_FILE_BASIC_INFO);
00784         p += 6;
00785         p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE);
00786         param_len = PTR_DIFF(p, param);
00787 
00788         if (!cli_send_trans(cli, SMBtrans2,
00789                 NULL,                        /* name */
00790                 -1, 0,                       /* fid, flags */
00791                 &setup, 1, 0,                /* setup, length, max */
00792                 param, param_len, 2,         /* param, length, max */
00793                 NULL,  0, cli->max_xmit      /* data, length, max */
00794                 )) {
00795                         return False;
00796         }
00797 
00798         if (!cli_receive_trans(cli, SMBtrans2,
00799                 &rparam, &param_len,
00800                 &rdata, &data_len)) {
00801                         return False;
00802         }
00803 
00804         if (data_len < 36) {
00805                 SAFE_FREE(rdata);
00806                 SAFE_FREE(rparam);
00807                 return False;
00808         }
00809 
00810         set_atimespec(sbuf, interpret_long_date( rdata+8 )); /* Access time. */
00811         set_mtimespec(sbuf, interpret_long_date( rdata+16 )); /* Write time. */
00812         set_ctimespec(sbuf, interpret_long_date( rdata+24 )); /* Change time. */
00813         
00814         *attributes = IVAL( rdata, 32 );
00815         
00816         SAFE_FREE(rparam);
00817         SAFE_FREE(rdata);
00818         
00819         return True;
00820 }
00821 
00822 /****************************************************************************
00823  Send a qfileinfo call.
00824 ****************************************************************************/
00825 
00826 BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutdata, uint32 *poutlen)
00827 {
00828         unsigned int data_len = 0;
00829         unsigned int param_len = 0;
00830         uint16 setup = TRANSACT2_QFILEINFO;
00831         pstring param;
00832         char *rparam=NULL, *rdata=NULL;
00833 
00834         *poutdata = NULL;
00835         *poutlen = 0;
00836 
00837         /* if its a win95 server then fail this - win95 totally screws it
00838            up */
00839         if (cli->win95)
00840                 return False;
00841 
00842         param_len = 4;
00843 
00844         memset(param, 0, param_len);
00845         SSVAL(param, 0, fnum);
00846         SSVAL(param, 2, level);
00847 
00848         if (!cli_send_trans(cli, SMBtrans2, 
00849                             NULL,                           /* name */
00850                             -1, 0,                          /* fid, flags */
00851                             &setup, 1, 0,                   /* setup, length, max */
00852                             param, param_len, 2,            /* param, length, max */
00853                             NULL, data_len, cli->max_xmit   /* data, length, max */
00854                            )) {
00855                 return False;
00856         }
00857 
00858         if (!cli_receive_trans(cli, SMBtrans2,
00859                                &rparam, &param_len,
00860                                &rdata, &data_len)) {
00861                 return False;
00862         }
00863 
00864         *poutdata = (char *)memdup(rdata, data_len);
00865         if (!*poutdata) {
00866                 SAFE_FREE(rdata);
00867                 SAFE_FREE(rparam);
00868                 return False;
00869         }
00870 
00871         *poutlen = data_len;
00872 
00873         SAFE_FREE(rdata);
00874         SAFE_FREE(rparam);
00875         return True;
00876 }
00877 
00878 /****************************************************************************
00879  Send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call.
00880 ****************************************************************************/
00881 
00882 NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name)
00883 {
00884         unsigned int data_len = 0;
00885         unsigned int param_len = 0;
00886         uint16 setup = TRANSACT2_QPATHINFO;
00887         pstring param;
00888         char *rparam=NULL, *rdata=NULL;
00889         int count=8;
00890         char *p;
00891         BOOL ret;
00892         unsigned int len;
00893 
00894         p = param;
00895         memset(p, 0, 6);
00896         SSVAL(p, 0, SMB_QUERY_FILE_ALT_NAME_INFO);
00897         p += 6;
00898         p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE);
00899 
00900         param_len = PTR_DIFF(p, param);
00901 
00902         do {
00903                 ret = (cli_send_trans(cli, SMBtrans2, 
00904                                       NULL,           /* Name */
00905                                       -1, 0,          /* fid, flags */
00906                                       &setup, 1, 0,   /* setup, length, max */
00907                                       param, param_len, 10, /* param, length, max */
00908                                       NULL, data_len, cli->max_xmit /* data, length, max */
00909                                       ) &&
00910                        cli_receive_trans(cli, SMBtrans2, 
00911                                          &rparam, &param_len,
00912                                          &rdata, &data_len));
00913                 if (!ret && cli_is_dos_error(cli)) {
00914                         /* we need to work around a Win95 bug - sometimes
00915                            it gives ERRSRV/ERRerror temprarily */
00916                         uint8 eclass;
00917                         uint32 ecode;
00918                         cli_dos_error(cli, &eclass, &ecode);
00919                         if (eclass != ERRSRV || ecode != ERRerror) break;
00920                         smb_msleep(100);
00921                 }
00922         } while (count-- && ret==False);
00923 
00924         if (!ret || !rdata || data_len < 4) {
00925                 return NT_STATUS_UNSUCCESSFUL;
00926         }
00927 
00928         len = IVAL(rdata, 0);
00929 
00930         if (len > data_len - 4) {
00931                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
00932         }
00933 
00934         clistr_pull(cli, alt_name, rdata+4, sizeof(fstring), len, STR_UNICODE);
00935 
00936         SAFE_FREE(rdata);
00937         SAFE_FREE(rparam);
00938 
00939         return NT_STATUS_OK;
00940 }

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