Changeset 883


Ignore:
Timestamp:
May 12, 2015, 2:32:32 PM (10 years ago)
Author:
Silvan Scherrer
Message:

Samba client: update trunk to 3.6 server level, change client version to 2.3

Location:
trunk/client/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/client/src/Makefile.kmk

    r819 r883  
    5353                $(SAMBA)/lib/tevent
    5454
    55 ndpsmb_LIBS = libsmbclient.a socket.a libtalloc.a libtdb.a libwbclient.a z
     55ndpsmb_LIBS = libsmbclient libtalloc libtdb libwbclient libtevent z mmap
    5656ndpsmb_LIBS += $(GCC_LIB)/binmode.obj
    5757ndpsmb_LIBPATH = $(SAMBA)/source3/bin $(Z_LIBDIR)
     
    162162        $(QUIET)$(MKDIR) -p $(PATH_OUT)/dist                             
    163163        $(QUIET)$(RM) -f $@
    164         $(QUIET)$(REDIRECT) -C $(PATH_INST_BIN) -- zip -Sr9 $@ \*
     164        $(QUIET)$(REDIRECT) -C $(PATH_INST_BIN) -- zip -9Sr $@ .
    165165
    166166
  • trunk/client/src/help/changelog.txt

    r819 r883  
    903903:eul.:eul.
    904904#endif
     905
     906#ifdef txt
     907Version 2.3
     908#endif
     909#ifndef txt
     910:h2 res=016.Version 2.3
     911:p.
     912:ul.
     913#endif
     914 <$UL>beta1:
     915#ifndef txt
     916:ul compact.
     917#endif
     918#ifdef en
     919   <$LI> moved to samba 3.6 source base
     920#endif
     921#ifdef fr
     922   <$LI> Passage
     923 la version 3.6 du code du client Samba.
     924#endif
     925#ifdef de
     926   <$LI> Update auf Samba 3.6 Client-Code
     927#endif
     928#ifndef txt
     929:eul.
     930#endif
     931
     932#ifndef txt
     933:eul.:eul.
     934#endif
  • trunk/client/src/help/ndpsmb.ipf

    r764 r883  
    150150:li.:link reftype=hd res=014.Version 2.1:elink.
    151151:li.:link reftype=hd res=015.Version 2.2:elink.
     152:li.:link reftype=hd res=016.Version 2.3:elink.
    152153:eul.
    153154#include <changelog.txt>
  • trunk/client/src/help/ndpsmb_de.ipf

    r764 r883  
    151151:li.:link reftype=hd res=014.Version 2.1:elink.
    152152:li.:link reftype=hd res=015.Version 2.2:elink.
     153:li.:link reftype=hd res=016.Version 2.3:elink.
    153154:eul.
    154155#include <changelog.txt>
  • trunk/client/src/help/ndpsmb_fr.ipf

    r764 r883  
    241241:li.:link reftype=hd res=014.Version 2.1:elink.
    242242:li.:link reftype=hd res=015.Version 2.2:elink.
     243:li.:link reftype=hd res=016.Version 2.3:elink.
    243244:eul.
    244245#include <changelog.txt>
  • trunk/client/src/smbwrp.c

    r818 r883  
    2020
    2121#include "includes.h"
     22#include "rpc_client/cli_pipe.h"
     23#include "librpc/gen_ndr/ndr_srvsvc_c.h"
     24#include "libsmb/libsmb.h"
     25#include "libsmb/clirap.h"
     26#include "trans2.h"
    2227#include "smbwrp.h"
    23 /****************************************************************************
    24  Calculate a safe next_entry_offset.
    25 ****************************************************************************/
    26 
    27 static size_t calc_next_entry_offset(const char *base, const char *pdata_end)
    28 {
    29         size_t next_entry_offset = (size_t)IVAL(base,0);
    30 
    31         if (next_entry_offset == 0 ||
    32                         base + next_entry_offset < base ||
    33                         base + next_entry_offset > pdata_end) {
    34                 next_entry_offset = pdata_end - base;
    35         }
    36         return next_entry_offset;
    37 }
    38 
    39 static int
    40 net_share_enum_rpc(struct cli_state *cli,
    41                 void (*fn)(const char *name,
    42                 uint32 type,
    43                 const char *comment,
    44                 void *state),
    45                 void *state)
    46 {
    47         int i;
    48         NTSTATUS status;
    49         WERROR werr;
    50         uint32_t resume_handle = 0;
    51         uint32_t total_entries = 0;
    52         struct srvsvc_NetShareInfoCtr info_ctr;
    53         struct srvsvc_NetShareCtr1 ctr1;
    54         fstring name = "";
    55         fstring comment = "";
    56         void *mem_ctx;
    57         struct rpc_pipe_client *pipe_hnd;
    58 
    59         /* Open the server service pipe */
    60         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc.syntax_id, &pipe_hnd);
    61         if (!NT_STATUS_IS_OK(status)) {
    62                 DEBUG(1, ("net_share_enum_rpc pipe open fail!\n"));
    63                 return -1;
    64         }
    65 
    66         /* Allocate a context for parsing and for the entries in "ctr" */
    67         mem_ctx = talloc_init("libsmbclient: net_share_enum_rpc");
    68         if (mem_ctx == NULL) {
    69                 DEBUG(0, ("out of memory for net_share_enum_rpc!\n"));
    70                 TALLOC_FREE(pipe_hnd);
    71                 return -1;
    72         }
    73 
    74         /* Issue the NetShareEnum RPC call and retrieve the response */
    75         ZERO_STRUCT(info_ctr);
    76         ZERO_STRUCT(ctr1);
    77         info_ctr.level = 1;
    78         info_ctr.ctr.ctr1 = &ctr1;
    79         status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, mem_ctx,
    80                                                 pipe_hnd->desthost,
    81                                                 &info_ctr,
    82                                                 0xffffffff,
    83                                                 &total_entries,
    84                                                 &resume_handle,
    85                                                 &werr);
    86 
    87         /* Was it successful? */
    88         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr) || info_ctr.ctr.ctr1->count == 0) {
    89                 /*  Nope.  Go clean up. */
    90                 goto done;
    91         }
    92 
    93         /* For each returned entry... */
    94         for (i = 0; i < info_ctr.ctr.ctr1->count; i++) {
    95                 struct srvsvc_NetShareInfo1 info = info_ctr.ctr.ctr1->array[i];
    96 
    97                 /* Add this share to the list */
    98                 (*fn)(info.name, info.type, info.comment, state);
    99         }
    100 
    101 done:
    102         /* Close the server service pipe */
    103         TALLOC_FREE(pipe_hnd);
    104 
    105         /* Free all memory which was allocated for this request */
    106         TALLOC_FREE(mem_ctx);
    107 
    108         /* Tell 'em if it worked */
    109         return W_ERROR_IS_OK(status) ? 0 : -1;
    110 }
    11128
    11229/*
     
    300217#endif
    301218
    302 
    303 /****************************************************************************
    304 send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
    305 ****************************************************************************/
    306 bool cli_qpathinfo3(struct cli_state *cli, const char *fname,
    307                     time_t *c_time, time_t *a_time, time_t *m_time,
    308                     time_t *w_time, off_t *size, uint16 *mode,
    309                     SMB_INO_T *ino)
    310 {
    311         unsigned int data_len = 0;
    312         unsigned int param_len = 0;
    313         uint16 setup = TRANSACT2_QPATHINFO;
    314         char *param;
    315         size_t nlen = 2*(strlen(fname)+1);
    316         char *rparam=NULL, *rdata=NULL;
    317         char *p;
    318 
    319         param = SMB_MALLOC_ARRAY(char, 6+nlen+2);
    320         if (!param) {
    321                 return false;
    322         }
    323 
    324         p = param;
    325         memset(p, '\0', 6);
    326         SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO);
    327         p += 6;
    328         p += clistr_push(cli, p, fname, nlen, STR_TERMINATE);
    329 
    330         param_len = PTR_DIFF(p, param);
    331 
    332         if (!cli_send_trans(cli, SMBtrans2,
    333                         NULL,                           /* name */
    334                         -1, 0,                          /* fid, flags */
    335                         &setup, 1, 0,                   /* setup, length, max */
    336                         param, param_len, 10,           /* param, length, max */
    337                         NULL, data_len, cli->max_xmit   /* data, length, max */
    338                         )) {
    339                 return False;
    340         }
    341 
    342         SAFE_FREE(param);
    343         if (!cli_receive_trans(cli, SMBtrans2,
    344                         &rparam, &param_len,
    345                         &rdata, &data_len)) {
    346                 return False;
    347         }
    348 
    349         if (!rdata || data_len < 22) {
    350                 return False;
    351         }
    352 
    353         if (c_time) {
    354                 *c_time = convert_timespec_to_time_t(interpret_long_date(rdata+0));
    355         }
    356         if (a_time) {
    357                 *a_time = convert_timespec_to_time_t(interpret_long_date(rdata+8));
    358         }
    359         if (m_time) {
    360                 *m_time = convert_timespec_to_time_t(interpret_long_date(rdata+16));
    361         }
    362         if (w_time) {
    363                 *w_time = convert_timespec_to_time_t(interpret_long_date(rdata+24));
    364         }
    365         if (mode) {
    366                 *mode = SVAL(rdata, 32);
    367         }
    368         if (size) {
    369                 *size = IVAL2_TO_SMB_BIG_UINT(rdata, 48);
    370         }
    371         if (ino) {
    372                 *ino = IVAL(rdata, 64);
    373         }
    374 
    375         SAFE_FREE(rdata);
    376         SAFE_FREE(rparam);
    377         return True;
    378 }
    379 
    380 /****************************************************************************
    381 send a qfileinfo call
    382 ****************************************************************************/
    383 bool cli_qfileinfo3(struct cli_state *cli, int fnum,
    384                    uint16 *mode, off_t *size,
    385                    time_t *c_time, time_t *a_time, time_t *m_time,
    386                    time_t *w_time, SMB_INO_T *ino)
    387 {
    388         unsigned int data_len = 0;
    389         unsigned int param_len = 0;
    390         uint16 setup = TRANSACT2_QFILEINFO;
    391         char param[4];
    392         char *rparam=NULL, *rdata=NULL;
    393 
    394         /* if its a win95 server then fail this - win95 totally screws it
    395            up */
    396         if (cli->win95) return False;
    397 
    398         param_len = 4;
    399 
    400         SSVAL(param, 0, fnum);
    401         SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO);
    402 
    403         if (!cli_send_trans(cli, SMBtrans2,
    404                         NULL,                           /* name */
    405                         -1, 0,                          /* fid, flags */
    406                         &setup, 1, 0,                   /* setup, length, max */
    407                         param, param_len, 2,            /* param, length, max */
    408                         NULL, data_len, cli->max_xmit   /* data, length, max */
    409                         )) {
    410                 return False;
    411         }
    412 
    413         if (!cli_receive_trans(cli, SMBtrans2,
    414                         &rparam, &param_len,
    415                         &rdata, &data_len)) {
    416                 return False;
    417         }
    418 
    419         if (!rdata || data_len < 68) {
    420                 return False;
    421         }
    422 
    423         if (c_time) {
    424                 *c_time = convert_timespec_to_time_t(interpret_long_date(rdata+0));
    425         }
    426         if (a_time) {
    427                 *a_time = convert_timespec_to_time_t(interpret_long_date(rdata+8));
    428         }
    429         if (m_time) {
    430                 *m_time = convert_timespec_to_time_t(interpret_long_date(rdata+16));
    431         }
    432         if (w_time) {
    433                 *w_time = convert_timespec_to_time_t(interpret_long_date(rdata+24));
    434         }
    435         if (mode) {
    436                 *mode = SVAL(rdata, 32);
    437         }
    438         if (size) {
    439                 *size = IVAL2_TO_SMB_BIG_UINT(rdata, 48);
    440         }
    441         if (ino) {
    442                 *ino = IVAL(rdata, 64);
    443         }
    444 
    445         SAFE_FREE(rdata);
    446         SAFE_FREE(rparam);
    447         return True;
    448 }
    449 
    450219/*****************************************************
    451220return a connection to a server
     
    671440int _System smbwrp_write(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result)
    672441{
    673         int ret;
     442        NTSTATUS status;
     443        size_t ret;
    674444
    675445        if (!cli || !file || !buf || !result)
     
    680450        *result = 0;
    681451//debuglocal(1,("Write %x %d %lld %d", cli, file->fd, file->offset, count));
    682         ret = cli_write(cli, file->fd, 0, buf, file->offset, count);
    683         if (ret == -1)
    684         {
     452        status = cli_writeall(cli, file->fd, 0, buf, file->offset, count, &ret);
     453        if (!NT_STATUS_IS_OK(status)) {
    685454                return os2cli_errno(cli);
    686455        }
     
    719488        {
    720489                debuglocal(4,"Set pathinfo on close %s %08x %d %d\n", file->fname, file->openattr, file->mtime, file->ctime);
    721                 if (!NT_STATUS_IS_OK(cli_setpathinfo(cli, file->fname, file->ctime, 0, file->mtime, 0, file->openattr)))
     490                if (!NT_STATUS_IS_OK(cli_setpathinfo_basic(cli, file->fname, file->ctime, 0, file->mtime, 0, file->openattr)))
    722491                {
    723492                        debuglocal(4,"Set pathinfo on close failed %d\n", os2cli_errno(cli));
     
    736505}
    737506
    738 /*****************************************************
    739 a wrapper for setfilesize()
    740 *******************************************************/
    741 int cli_setfilenewsize(struct cli_state *cli, int fnum, off_t newsize)
    742 {
    743         unsigned int data_len = 8;
    744         unsigned int param_len = 6;
    745         uint16 setup = TRANSACT2_SETFILEINFO;
    746         char param[6];
    747         unsigned char data[8];
    748         char *rparam=NULL, *rdata=NULL;
    749 
    750         SSVAL(param,0,fnum);
    751         SSVAL(param,2,SMB_SET_FILE_END_OF_FILE_INFO);
    752         SSVAL(param,4,0);
    753 
    754         SBVAL(data, 0, newsize);
    755 
    756         if (!cli_send_trans(cli, SMBtrans2,
    757                                                 NULL,                   /* name */
    758                                                 -1, 0,                    /* fid, flags */
    759                                                 &setup, 1, 0,              /* setup, length, max */
    760                                                 param, param_len, 2,        /* param, length, max */
    761                                                 (char *)&data,  data_len,       /* data, length */
    762                                                 cli->max_xmit /* max */
    763                                                 )) {
    764                 return False;
    765         }
    766 
    767         if (!cli_receive_trans(cli, SMBtrans2,
    768                                                 &rparam, &param_len,
    769                                                 &rdata, &data_len)) {
    770                 return False;
    771         }
    772 
    773         SAFE_FREE(rdata);
    774         SAFE_FREE(rparam);
    775 
    776         return True;
    777 }
    778 
    779507int _System smbwrp_setfilesize(cli_state * cli, smbwrp_file * file, long long newsize)
    780508{
     
    786514
    787515        debuglocal(4,"cli_setnewfilesize(%s) %lld\n", file->fname, newsize);
    788         if (!cli_setfilenewsize(cli, file->fd, newsize))
     516        if (!NT_STATUS_IS_OK(cli_ftruncate(cli, file->fd, newsize)))
    789517        {
    790518                if (newsize)
     
    823551
    824552        debuglocal(1,"Rename <%s> -> <%s>\n", oldname, newname);
    825         //cli_unlink(cli, newname);
    826 //      if (!cli_rename(cli, oldname, newname) && !cli_ntrename(cli, oldname, newname))
    827553        if (!NT_STATUS_IS_OK(cli_rename(cli, oldname, newname)))
    828554        {
     
    913639                        return maperror(EINVAL);
    914640                }
    915                 if (!cli_qfileinfo3(cli, file->fd,
     641                if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd,
    916642                                   NULL, &size, NULL, NULL, NULL,
    917                                    NULL, NULL) &&
     643                                   NULL, NULL)) &&
    918644                    !NT_STATUS_IS_OK(cli_getattrE(cli, file->fd,
    919645                                  NULL, &size, NULL, NULL, NULL)))
     
    936662{
    937663        SMB_INO_T ino = 0;
     664        struct timespec ctime;
     665        struct timespec mtime;
     666        struct timespec atime;
     667
    938668        if (!cli || !finfo || !*finfo->fname)
    939669        {
     
    942672        debuglocal(4,"getattr %d %d <%s>\n", cli->capabilities & CAP_NOPATHINFO2, cli->capabilities & CAP_NT_SMBS, finfo->fname);
    943673        if (!(cli->capabilities & CAP_NOPATHINFO2) &&
    944                 cli_qpathinfo3(cli, finfo->fname, (time_t *)&finfo->ctime, (time_t *)&finfo->atime, (time_t *)&finfo->mtime, NULL,
     674                cli_qpathinfo2(cli, finfo->fname, &ctime, &atime, &mtime, NULL,
    945675                           (off_t *)&finfo->size, (unsigned short *)&finfo->attr, &ino))
    946676        {
    947677                finfo->attr &= 0x7F;
    948 //debuglocal(2,("gotattr %08x <%s>\n", finfo->attr, finfo->fname));
    949 //              finfo->ctime -= get_time_zone(finfo->ctime);
    950 //              finfo->atime -= get_time_zone(finfo->atime);
    951 //              finfo->mtime -= get_time_zone(finfo->mtime);
     678                finfo->ctime = convert_timespec_to_time_t(ctime);
     679                finfo->atime = convert_timespec_to_time_t(atime);
     680                finfo->mtime = convert_timespec_to_time_t(mtime);
    952681                return 0;
    953682        }
    954 //debuglocal(2,("getattr rc1 %d\n", os2cli_errno(cli)));
    955683
    956684        if (cli->fd == -1)
     
    961689
    962690        /* If the path is not on a share (it is a workgroup or a server),
    963          * then cli_qpathinfo3 obviously fails. Return some fake information
     691         * then cli_qpathinfo2 obviously fails. Return some fake information
    964692         * about the directory.
    965693         */
     
    1013741int _System smbwrp_fgetattr(cli_state * cli, smbwrp_file *file, smbwrp_fileinfo *finfo)
    1014742{
     743        struct timespec ctime;
     744        struct timespec mtime;
     745        struct timespec atime;
    1015746        SMB_INO_T ino = 0;
     747
    1016748        if (!cli || !file || !finfo)
    1017749        {
     
    1020752
    1021753        strncpy(finfo->fname, file->fname, sizeof(finfo->fname) - 1);
    1022         if (!cli_qfileinfo3(cli, file->fd,
    1023                            (unsigned short *)&finfo->attr, (off_t *)&finfo->size, (time_t *)&finfo->ctime, (time_t *)&finfo->atime, (time_t *)&finfo->mtime, NULL,
    1024                            &ino))
     754        if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd,
     755                           (unsigned short *)&finfo->attr, (off_t *)&finfo->size, &ctime, &atime, &mtime, NULL,
     756                           &ino)))
    1025757        {
    1026758                if (!NT_STATUS_IS_OK(cli_getattrE(cli, file->fd,
     
    1038770        else
    1039771        {
    1040 //              finfo->ctime -= get_time_zone(finfo->ctime);
    1041 //              finfo->atime -= get_time_zone(finfo->atime);
    1042 //              finfo->mtime -= get_time_zone(finfo->mtime);
     772                finfo->ctime = convert_timespec_to_time_t(ctime);
     773                finfo->atime = convert_timespec_to_time_t(atime);
     774                finfo->mtime = convert_timespec_to_time_t(mtime);
    1043775        }
    1044776
     
    1118850
    1119851/****************************************************************************
    1120  Interpret a long filename structure - this is mostly guesses at the moment.
    1121  The length of the structure is returned
    1122  The structure of a long filename depends on the info level. 260 is used
    1123  by NT and 2 is used by OS/2
     852 Do a directory listing, calling fn on each file found.
     853 Modified from cli_list
    1124854****************************************************************************/
    1125 // YD from libsmb\clilist.c
    1126 static size_t _os2_interpret_long_filename(TALLOC_CTX *ctx, struct cli_state *cli,
    1127                                    int level,const char *p, const char *pdata_end, smbwrp_fileinfo *finfo,
    1128                                         uint32 *p_resume_key, DATA_BLOB *p_last_name_raw)
    1129 {
    1130         int len;
    1131         const char *base = p;
    1132         size_t ret;
    1133         char *fname;
    1134        
    1135         data_blob_free(p_last_name_raw);
    1136 
    1137         if (p_resume_key) {
    1138                 *p_resume_key = 0;
    1139         }
    1140 
    1141 /*      ZERO_STRUCTP(finfo); */
    1142         finfo->atime = 0;
    1143         finfo->ctime = 0;
    1144         finfo->mtime = 0;
    1145         *finfo->fname = '\0';
    1146        
    1147         switch (level) {
    1148                 case SMB_FIND_INFO_STANDARD: /* OS/2 understands this */
    1149                         /* these dates are converted to GMT by
    1150                            make_unix_date */
    1151                         if (pdata_end - base < 27) {
    1152                                 return pdata_end - base;
    1153                         }
    1154                         finfo->ctime = cli_make_unix_date2(cli, p+4) - cli->serverzone;
    1155                         finfo->atime = cli_make_unix_date2(cli, p+8) - cli->serverzone;
    1156                         finfo->mtime = cli_make_unix_date2(cli, p+12) - cli->serverzone;
    1157                         finfo->size = IVAL(p,16);
    1158                         finfo->attr = CVAL(p,24);
    1159                         len = CVAL(p, 26);
    1160                         p += 27;
    1161                         p += clistr_align_in(cli, p, 0);
    1162 
    1163                         /* We can safely use len here (which is required by OS/2)
    1164                          * and the NAS-BASIC server instead of +2 or +1 as the
    1165                          * STR_TERMINATE flag below is
    1166                          * actually used as the length calculation.
    1167                          * The len is merely an upper bound.
    1168                          * Due to the explicit 2 byte null termination
    1169                          * in cli_receive_trans/cli_receive_nt_trans
    1170                          * we know this is safe. JRA + kukks
    1171                          */
    1172 
    1173                         if (p + len > pdata_end) {
    1174                                 return pdata_end - base;
    1175                         }
    1176 
    1177                         /* the len+2 below looks strange but it is
    1178                            important to cope with the differences
    1179                            between win2000 and win9x for this call
    1180                            (tridge) */
    1181                         ret = clistr_pull_talloc(ctx, cli->inbuf, &fname, p,
    1182                                          len+2,
    1183                                          STR_TERMINATE);
    1184                         if (ret == (size_t)-1) {
    1185                                 return pdata_end - base;
    1186                         }
    1187                         p += ret;
    1188                         finfo->easize = -1;
    1189                         strncat(finfo->fname, fname, sizeof(finfo->fname) -1);
    1190                         return PTR_DIFF(p, base);
    1191 
    1192                 case SMB_FIND_EA_SIZE: /* this is what OS/2 uses mostly */
    1193                         /* these dates are converted to GMT by
    1194                            make_unix_date */
    1195                         if (pdata_end - base < 31) {
    1196                                 return pdata_end - base;
    1197                         }
    1198                         finfo->ctime = cli_make_unix_date2(cli, p+4) - cli->serverzone;
    1199                         finfo->atime = cli_make_unix_date2(cli, p+8) - cli->serverzone;
    1200                         finfo->mtime = cli_make_unix_date2(cli, p+12) - cli->serverzone;
    1201                         finfo->size = IVAL(p,16);
    1202                         finfo->attr = CVAL(p,24);
    1203                         finfo->easize = IVAL(p,26);
    1204                         len = CVAL(p, 30);
    1205                         p += 31;
    1206                         /* check for unisys! */
    1207                         if (p + len + 1 > pdata_end) {
    1208                                 return pdata_end - base;
    1209                         }
    1210                         ret = clistr_pull_talloc(ctx, cli->inbuf, &fname, p,
    1211                                          len,
    1212                                          STR_NOALIGN);
    1213                         if (ret == (size_t)-1) {
    1214                                 return pdata_end - base;
    1215                         }
    1216                         p += ret;
    1217                         strncat(finfo->fname, fname, sizeof(finfo->fname) -1);
    1218                         return PTR_DIFF(p, base) + 1;
    1219                        
    1220                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: /* NT uses this, but also accepts 2 */
    1221                 {
    1222                         size_t namelen, slen;
    1223 
    1224                         if (pdata_end - base < 94) {
    1225                                 return pdata_end - base;
    1226                         }
    1227 
    1228                         p += 4; /* next entry offset */
    1229 
    1230                         if (p_resume_key) {
    1231                                 *p_resume_key = IVAL(p,0);
    1232                         }
    1233 
    1234                         p += 4; /* fileindex */
    1235                                
    1236                         /* Offset zero is "create time", not "change time". */
    1237                         p += 8;
    1238                         finfo->atime = interpret_long_date(p).tv_sec;
    1239                         p += 8;
    1240                         finfo->mtime = interpret_long_date(p).tv_sec;
    1241                         p += 8;
    1242                         finfo->ctime = interpret_long_date(p).tv_sec;
    1243                         p += 8;
    1244                         finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0);
    1245                         p += 8;
    1246                         p += 8; /* alloc size */
    1247                         finfo->attr = CVAL(p,0);
    1248                         p += 4;
    1249                         namelen = IVAL(p,0);
    1250                         p += 4;
    1251                         finfo->easize = IVAL(p,0);
    1252                         p += 4; /* EA size */
    1253                         slen = SVAL(p, 0);
    1254                         if (slen > 24) {
    1255                                 /* Bad short name length. */
    1256                                 return pdata_end - base;
    1257                         }
    1258                         p += 2;
    1259 #if 0                   
    1260                         {
    1261                                 /* stupid NT bugs. grr */
    1262                                 int flags = 0;
    1263                                 if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE;
    1264                                 clistr_pull(cli, finfo->short_name, p,
    1265                                             sizeof(finfo->short_name),
    1266                                             slen, flags);
    1267                         }
    1268 #endif
    1269                         p += 24; /* short name? */
    1270                         if (p + namelen < p || p + namelen > pdata_end) {
    1271                                 return pdata_end - base;
    1272                         }         
    1273                         ret = clistr_pull_talloc(ctx, cli->inbuf, &fname, p,
    1274                                     namelen, 0);
    1275                         if (ret == (size_t)-1) {
    1276                                 return pdata_end - base;
    1277                         }
    1278                         strncat(finfo->fname, fname, sizeof(finfo->fname) -1);
    1279 
    1280                         /* To be robust in the face of unicode conversion failures
    1281                            we need to copy the raw bytes of the last name seen here.
    1282                            Namelen doesn't include the terminating unicode null, so
    1283                            copy it here. */
    1284 #if 0
    1285                         if (p_last_name_raw) {
    1286                                 *p_last_name_raw = data_blob(NULL, namelen+2);
    1287                                 memcpy(p_last_name_raw->data, p, namelen);
    1288                                 SSVAL(p_last_name_raw->data, namelen, 0);
    1289                         }
    1290 #endif
    1291                         return calc_next_entry_offset(base, pdata_end);
    1292                 }
    1293         }
    1294        
    1295         debuglocal(1,"Unknown long filename format %d\n",level);
    1296         return calc_next_entry_offset(base, pdata_end);
    1297 }
    1298 
    1299 /****************************************************************************
    1300  Do a directory listing, calling fn on each file found.
    1301  Modified from cli_list_new
    1302 ****************************************************************************/
    1303 
    1304 static int list_files(struct cli_state *cli, const char *Mask, uint16 attribute,
    1305                  void (*fn)(const char*, smbwrp_fileinfo *, const char *, void *), void *state)
    1306 {
    1307 #if 1
    1308         int max_matches = 1366; /* Match W2k - was 512. */
    1309 #else
    1310         int max_matches = 512;
    1311 #endif
    1312         int info_level;
    1313         char *p, *p2, *rdata_end;
    1314         char *mask=NULL;
    1315         smbwrp_fileinfo finfo;
    1316         int i;
    1317         char *dirlist = NULL;
    1318         int dirlist_len = 0;
    1319         int total_received = -1;
    1320         bool First = True;
    1321         int ff_searchcount=0;
    1322         int ff_eos=0;
    1323         int ff_dir_handle=0;
    1324         int loop_count = 0;
    1325         char *rparam=NULL, *rdata=NULL;
    1326         unsigned int param_len, data_len;       
    1327         uint16 setup;
    1328         char *param;
    1329         uint32 resume_key = 0;
     855static int list_files(struct cli_state *cli, const char *mask, uint16 attribute,
     856                  void (*fn)(const char *, smbwrp_fileinfo *, const char *,
     857                             void *), void *state)
     858{
    1330859        TALLOC_CTX *frame = talloc_stackframe();
    1331         DATA_BLOB last_name_raw = data_blob(NULL, 0);
    1332 
    1333         /* NT uses SMB_FIND_FILE_BOTH_DIRECTORY_INFO,
    1334          OS/2 uses SMB_FIND_EA_SIZE. Both accept SMB_FIND_INFO_STANDARD. */
    1335         info_level = (cli->capabilities&CAP_NT_SMBS)?
    1336            SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_EA_SIZE;
    1337        
    1338         debuglocal(4,"list_files level %d. mask <%s>\n", info_level, Mask);
    1339    
    1340         mask = SMB_STRDUP(Mask);
    1341         if (!mask) {
    1342                 TALLOC_FREE(frame);
    1343                 return -1;
    1344         }
     860        struct event_context *ev;
     861        struct tevent_req *req;
     862        NTSTATUS status = NT_STATUS_NO_MEMORY;
     863        struct file_info *finfo;
     864        size_t i, num_finfo;
     865        uint16_t info_level;
     866        void *dircachectx = NULL;
     867        smbwrp_fileinfo wrpfinfo;
    1345868
    1346869        /* Try to get the listing from cache. */
    1347         if (dircache_list_files(fn, state, &total_received))
     870        if (dircache_list_files(fn, state, &num_finfo))
    1348871        {
    1349872                /* Got from cache. */
    1350                 return(total_received);
    1351         }
    1352 
    1353         while (ff_eos == 0) {
    1354                 size_t nlen = 2*(strlen(mask)+1);
    1355 
    1356                 loop_count++;
    1357                 if (loop_count > 200) {
    1358                         debuglocal(0,"Error: Looping in FIND_NEXT??\n");
    1359                         break;
    1360                 }
    1361 
    1362                 param = SMB_MALLOC_ARRAY(char, 12+nlen+last_name_raw.length+2);
    1363                 if (!param) {
    1364                         break;
    1365                 }
    1366 
    1367                 if (First) {
    1368                         setup = TRANSACT2_FINDFIRST;
    1369                         SSVAL(param,0,attribute); /* attribute */
    1370                         SSVAL(param,2,max_matches); /* max count */
    1371                         SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */
    1372                         SSVAL(param,6,info_level);
    1373                         SIVAL(param,8,0);
    1374                         p = param+12;
    1375                         p += clistr_push(cli, param+12, mask, nlen,
    1376                                          STR_TERMINATE);
    1377                 } else {
    1378                         setup = TRANSACT2_FINDNEXT;
    1379                         SSVAL(param,0,ff_dir_handle);
    1380                         SSVAL(param,2,max_matches); /* max count */
    1381                         SSVAL(param,4,info_level);
    1382                         /* For W2K servers serving out FAT filesystems we *must* set the
    1383                            resume key. If it's not FAT then it's returned as zero. */
    1384                         SIVAL(param,6,resume_key); /* ff_resume_key */
    1385                         /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren
    1386                            can miss filenames. Use last filename continue instead. JRA */
    1387                         SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END));        /* resume required + close on end */
    1388                         p = param+12;
    1389                         if (last_name_raw.length) {
    1390                                 memcpy(p, last_name_raw.data, last_name_raw.length);
    1391                                 p += last_name_raw.length;
    1392                         } else {
    1393                                 p += clistr_push(cli, param+12, mask,
    1394                                               nlen, STR_TERMINATE);
    1395                         }
    1396                 }
    1397 
    1398                 param_len = PTR_DIFF(p, param);
    1399 
    1400                 if (!cli_send_trans(cli, SMBtrans2,
    1401                                     NULL,                  /* Name */
    1402                                     -1, 0,                /* fid, flags */
    1403                                     &setup, 1, 0,          /* setup, length, max */
    1404                                     param, param_len, 10,   /* param, length, max */
    1405                                     NULL, 0,
    1406 #if 0
    1407                                     /* w2k value. */
    1408                                     MIN(16384,cli->max_xmit) /* data, length, max. */
    1409 #else
    1410                                     cli->max_xmit           /* data, length, max. */
    1411 #endif
    1412                                     )) {
    1413                         SAFE_FREE(param);
    1414                         TALLOC_FREE(frame);
    1415                         break;
    1416                 }
    1417 
    1418                 SAFE_FREE(param);
    1419 
    1420                 if (!cli_receive_trans(cli, SMBtrans2,
    1421                                        &rparam, &param_len,
    1422                                        &rdata, &data_len) &&
    1423                     cli_is_dos_error(cli)) {
    1424                         /* we need to work around a Win95 bug - sometimes
    1425                            it gives ERRSRV/ERRerror temprarily */
    1426                         uint8 eclass;
    1427                         uint32 ecode;
    1428 
    1429                         SAFE_FREE(rdata);
    1430                         SAFE_FREE(rparam);
    1431 
    1432                         cli_dos_error(cli, &eclass, &ecode);
    1433 
    1434                         /*
    1435                          * OS/2 might return "no more files",
    1436                          * which just tells us, that searchcount is zero
    1437                          * in this search.
    1438                          * Guenter Kukkukk <linux@kukkukk.com>
    1439                          */
    1440 
    1441                         if (eclass == ERRDOS && ecode == ERRnofiles) {
    1442                                 ff_searchcount = 0;
    1443                                 cli_reset_error(cli);
    1444                                 break;
    1445                         }
    1446 
    1447                         if (eclass != ERRSRV || ecode != ERRerror)
    1448                                 break;
    1449                         smb_msleep(100);
    1450                         continue;
    1451                 }
    1452 
    1453                 if (cli_is_error(cli) || !rdata || !rparam)
    1454                 {
    1455                         if (First && info_level == SMB_FIND_EA_SIZE)
    1456                         {
    1457                                 // we have tried query ea size, but now will try without ea size
    1458                                 info_level = SMB_FIND_INFO_STANDARD;
    1459                                 debuglocal(4,"list_files fallback to level %d\n", info_level);
    1460                                 continue;
    1461                         }
    1462                         SAFE_FREE(rdata);
    1463                         SAFE_FREE(rparam);
    1464                         break;
    1465                 }
    1466 
    1467                 if (total_received == -1)
    1468                         total_received = 0;
    1469 
    1470                 /* parse out some important return info */
    1471                 p = rparam;
    1472                 if (First) {
    1473                         ff_dir_handle = SVAL(p,0);
    1474                         ff_searchcount = SVAL(p,2);
    1475                         ff_eos = SVAL(p,4);
    1476                 } else {
    1477                         ff_searchcount = SVAL(p,0);
    1478                         ff_eos = SVAL(p,2);
    1479                 }
    1480                 debuglocal(4,"list_files %d %d %d %d\n", ff_searchcount, ff_eos, "(ff_lastname)", First);
    1481 
    1482                 if (ff_searchcount == 0) {
    1483                         SAFE_FREE(rdata);
    1484                         SAFE_FREE(rparam);
    1485                         break;
    1486                 }
    1487 
    1488                 /* point to the data bytes */
    1489                 p = rdata;
    1490                 rdata_end = rdata + data_len;
    1491 
    1492                 memset(&finfo, 0, sizeof(finfo));
    1493                 finfo.easize = -1;
    1494                 /* we might need the lastname for continuations */
    1495                 for (p2=p,i=0;i<ff_searchcount  && p2 < rdata_end;i++) {
    1496                         if ((info_level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) &&
    1497                                         (i == ff_searchcount-1)) {
    1498                                 /* Last entry - fixup the last offset length. */
    1499                                 SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2));
    1500                         }
    1501                         p2 += _os2_interpret_long_filename(frame, cli, info_level, p2, rdata_end, &finfo,
    1502                                                         &resume_key, &last_name_raw);
    1503 
    1504                         if (!finfo.fname) {
    1505                                 debuglocal(0,"Error: unable to parse name from info level %d\n",
    1506                                         info_level);
    1507                                 ff_eos = 1;
    1508                                 break;
    1509                         }
    1510 
    1511                         if (!First && *mask && strcsequal(finfo.fname, mask)) {
    1512                                 debuglocal(0,"Error: Looping in FIND_NEXT as name %s has already been seen?\n",
    1513                                         finfo.fname);
    1514                                 ff_eos = 1;
    1515                                 break;
    1516                         }
    1517                 }
    1518 
    1519                 SAFE_FREE(mask);
    1520                 if (ff_searchcount > 0 && ff_eos == 0 && finfo.fname) {
    1521                         mask = SMB_STRDUP(finfo.fname);
    1522                 } else {
    1523                         mask = SMB_STRDUP("");
    1524                 }
    1525                 if (!mask) {
    1526                         SAFE_FREE(rdata);
    1527                         SAFE_FREE(rparam);
    1528                         break;
    1529                 }
    1530 
    1531                 /* grab the data for later use */
    1532                 /* and add them to the dirlist pool */
    1533                 dirlist = (char *)SMB_REALLOC(dirlist,dirlist_len + data_len);
    1534 
    1535                 if (!dirlist) {
    1536                         debuglocal(0,"cli_list_new: Failed to expand dirlist\n");
    1537                         SAFE_FREE(rdata);
    1538                         SAFE_FREE(rparam);
    1539                         break;
    1540                 }
    1541 
    1542                 memcpy(dirlist+dirlist_len,p,data_len);
    1543                 dirlist_len += data_len;
    1544 
    1545                 total_received += ff_searchcount;
    1546 
    1547                 SAFE_FREE(rdata);
    1548                 SAFE_FREE(rparam);
    1549 
    1550                 debuglocal(3,"received %d entries (eos=%d)\n",
    1551                          ff_searchcount,ff_eos);
    1552 
    1553                 if (ff_searchcount > 0)
    1554                         loop_count = 0;
    1555 
    1556                 First = False;
    1557         }
    1558 
    1559         /* see if the server disconnected or the connection otherwise failed */
    1560         if (cli_is_error(cli)) {
    1561                 total_received = -1;
    1562         } else {
    1563                 void *dircachectx = dircache_write_begin(state, total_received);
    1564 
    1565                 /* no connection problem.  let user function add each entry */
    1566                 rdata_end = dirlist + dirlist_len;
    1567                 for (p=dirlist,i=0;i<total_received;i++) {
    1568                         p += _os2_interpret_long_filename(frame, cli, info_level, p, rdata_end,
    1569                                                      &finfo,NULL,NULL);
    1570 
    1571                         if (!finfo.fname) {
    1572                                 debuglocal(0,"list_new: unable to parse name from info level %d\n",
    1573                                         info_level);
    1574                                 break;
    1575                         }
    1576                         fn(cli->dfs_mountpoint,&finfo, Mask, state );
    1577 
    1578                         /* Also add the entry to the cache. */
    1579                         dircache_write_entry(dircachectx, &finfo);
    1580                 }
    1581 
    1582                 dircache_write_end(dircachectx);
    1583 
    1584         }
    1585 
    1586         /* free up the dirlist buffer and last name raw blob */
    1587         SAFE_FREE(dirlist);
    1588         data_blob_free(&last_name_raw);
    1589         SAFE_FREE(mask);
     873                return(num_finfo);
     874        }
     875
     876        if (cli_has_async_calls(cli)) {
     877                /*
     878                 * Can't use sync call while an async call is in flight
     879                 */
     880                status = NT_STATUS_INVALID_PARAMETER;
     881                goto fail;
     882        }
     883        ev = event_context_init(frame);
     884        if (ev == NULL) {
     885                goto fail;
     886        }
     887
     888        info_level = (cli->capabilities & CAP_NT_SMBS)
     889                ? SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_EA_SIZE;
     890
     891        debuglocal(4,"list_files level %d. mask <%s>\n", info_level, mask);
     892
     893        req = cli_list_send(frame, ev, cli, mask, attribute, info_level);
     894        if (req == NULL) {
     895                goto fail;
     896        }
     897        if (!tevent_req_poll(req, ev)) {
     898                status = map_nt_error_from_unix(errno);
     899                goto fail;
     900        }
     901
     902        status = cli_list_recv(req, frame, &finfo, &num_finfo);
     903        if (!NT_STATUS_IS_OK(status)) {
     904                goto fail;
     905        }
     906
     907        dircachectx = dircache_write_begin(state, num_finfo);
     908
     909        debuglocal(4,"list_files: got %d files\n", num_finfo);
     910
     911
     912        for (i=0; i<num_finfo; i++) {
     913                //as samba and this client have different finfo, we need to convert
     914                memset(&wrpfinfo, 0, sizeof(wrpfinfo));
     915                wrpfinfo.size = finfo[i].size;
     916                wrpfinfo.attr = finfo[i].mode;
     917                wrpfinfo.ctime = convert_timespec_to_time_t(finfo[i].ctime_ts);
     918                wrpfinfo.mtime = convert_timespec_to_time_t(finfo[i].mtime_ts);
     919                wrpfinfo.atime = convert_timespec_to_time_t(finfo[i].atime_ts);
     920                wrpfinfo.easize = finfo[i].easize;
     921                strncpy(wrpfinfo.fname, finfo[i].name, sizeof(wrpfinfo.fname) -1);
     922
     923                fn(cli->dfs_mountpoint, &wrpfinfo, mask, state);
     924                // Also add the entry to the cache.
     925                dircache_write_entry(dircachectx, &wrpfinfo);
     926        }
     927
     928        dircache_write_end(dircachectx);
     929 fail:
    1590930        TALLOC_FREE(frame);
    1591         return(total_received);
    1592 }
    1593 
     931        return num_finfo;
     932}
    1594933
    1595934/*****************************************************
     
    1640979        else
    1641980        {
    1642 #if 0
    1643                 if (strcmp(path,"\\") == 0) {
    1644                         smbwrp_special_add(".", state);
    1645                         smbwrp_special_add("..", state);
    1646                 }
    1647 #endif
    1648 #if 0
    1649                 if (cli_list(cli, state->mask, aHIDDEN|aSYSTEM|aDIR,
    1650                              smbwrp_dir_add_old, state) < 0)
    1651 #else
    1652981                if (list_files(cli, state->mask, aHIDDEN|aSYSTEM|aDIR,
    1653982                             smbwrp_dir_add, state) < 0)
    1654 #endif
    1655983                {                                                                             
    1656984                        return os2cli_errno(cli);
     
    17691097#pragma pack()
    17701098
    1771 static int unilistea(cli_state * cli, char *fname, smbwrp_file *file, void * buffer, unsigned long size)
     1099static int unilistea(cli_state * cli, char *fname, void * buffer, unsigned long size)
    17721100{
    17731101        int fnum, i;
     
    17841112        pfealist->cbList = 0;
    17851113
    1786         if (file)
    1787         {
    1788                 if (!cli_get_ea_list_fnum(cli, file->fd, mem_ctx, &num_eas, &ea_list))
    1789                 {
    1790                         debuglocal(4,"ea_get_fnum list failed - %s\n", cli_errstr(cli));
    1791                         talloc_destroy(mem_ctx);
    1792                         return os2cli_errno(cli);
    1793                 }
    1794         }
    1795         else
    1796         {
    1797                 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list))
    1798                 {
    1799                         debuglocal(4,"ea_get_file list failed - %s\n", cli_errstr(cli));
    1800                         talloc_destroy(mem_ctx);
    1801                         return os2cli_errno(cli);
    1802                 }
     1114        if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list))
     1115        {
     1116                debuglocal(4,"ea_get_file list failed - %s\n", cli_errstr(cli));
     1117                talloc_destroy(mem_ctx);
     1118                return os2cli_errno(cli);
    18031119        }
    18041120
     
    18471163
    18481164        debuglocal(4,"EALIst for <%s>\n", fname);
    1849         return unilistea(cli, fname, NULL, buffer, size);
     1165        return unilistea(cli, fname, buffer, size);
    18501166}
    18511167
     
    18601176        }
    18611177
    1862         debuglocal(4,"FEALIst for <%s>/%d\n", file->fname, file->fd);
    1863         return unilistea(cli, NULL, file, buffer, size);
     1178        debuglocal(4,"FEALIst for <%s>\n", file->fname);
     1179        return unilistea(cli, file->fname, buffer, size);
    18641180}
    18651181
Note: See TracChangeset for help on using the changeset viewer.