Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libsmb/clirap.c

    r414 r740  
    2222#include "includes.h"
    2323#include "../libcli/auth/libcli_auth.h"
     24#include "../librpc/gen_ndr/rap.h"
     25#include "../lib/crypto/arcfour.h"
     26#include "../lib/util/tevent_ntstatus.h"
     27#include "async_smb.h"
     28#include "libsmb/libsmb.h"
     29#include "libsmb/clirap.h"
     30#include "trans2.h"
     31
     32#define PIPE_LANMAN   "\\PIPE\\LANMAN"
    2433
    2534/****************************************************************************
     
    3342             char **rdata, unsigned int *rdrcnt)
    3443{
    35         cli_send_trans(cli,SMBtrans,
    36                  PIPE_LANMAN,             /* Name */
    37                  0,0,                     /* fid, flags */
    38                  NULL,0,0,                /* Setup, length, max */
    39                  param, prcnt, mprcnt,    /* Params, length, max */
    40                  data, drcnt, mdrcnt      /* Data, length, max */
    41                 );
    42 
    43         return (cli_receive_trans(cli,SMBtrans,
    44                             rparam, rprcnt,
    45                             rdata, rdrcnt));
     44        NTSTATUS status;
     45
     46        uint8_t *my_rparam, *my_rdata;
     47        uint32_t num_my_rparam, num_my_rdata;
     48
     49        status = cli_trans(talloc_tos(), cli, SMBtrans,
     50                           PIPE_LANMAN, 0, /* name, fid */
     51                           0, 0,           /* function, flags */
     52                           NULL, 0, 0,     /* setup */
     53                           (uint8_t *)param, prcnt, mprcnt, /* Params, length, max */
     54                           (uint8_t *)data, drcnt, mdrcnt,  /* Data, length, max */
     55                           NULL,                 /* recv_flags2 */
     56                           NULL, 0, NULL,        /* rsetup */
     57                           &my_rparam, 0, &num_my_rparam,
     58                           &my_rdata, 0, &num_my_rdata);
     59        if (!NT_STATUS_IS_OK(status)) {
     60                return false;
     61        }
     62
     63        /*
     64         * I know this memcpy massively hurts, but there are just tons
     65         * of callers of cli_api that eventually need changing to
     66         * talloc
     67         */
     68
     69        *rparam = (char *)memdup(my_rparam, num_my_rparam);
     70        if (*rparam == NULL) {
     71                goto fail;
     72        }
     73        *rprcnt = num_my_rparam;
     74        TALLOC_FREE(my_rparam);
     75
     76        *rdata = (char *)memdup(my_rdata, num_my_rdata);
     77        if (*rdata == NULL) {
     78                goto fail;
     79        }
     80        *rdrcnt = num_my_rdata;
     81        TALLOC_FREE(my_rdata);
     82
     83        return true;
     84fail:
     85        TALLOC_FREE(my_rdata);
     86        TALLOC_FREE(my_rparam);
     87        *rparam = NULL;
     88        *rprcnt = 0;
     89        *rdata = NULL;
     90        *rdrcnt = 0;
     91        return false;
    4692}
    4793
     
    496542        data_len = 532;
    497543
    498         if (cli_send_trans(cli,SMBtrans,
    499                     PIPE_LANMAN,                          /* name */
    500                     0,0,                                  /* fid, flags */
    501                     NULL,0,0,                             /* setup, length, max */
    502                     param,param_len,2,                    /* param, length, max */
    503                     (char *)data,data_len,0                       /* data, length, max */
    504                    ) == False) {
     544        if (!cli_api(cli,
     545                     param, param_len, 4,               /* param, length, max */
     546                     (char *)data, data_len, 0,         /* data, length, max */
     547                     &rparam, &rprcnt,
     548                     &rdata, &rdrcnt)) {
    505549                DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n",
    506550                        user ));
     
    508552        }
    509553
    510         if (!cli_receive_trans(cli,SMBtrans,
    511                        &rparam, &rprcnt,
    512                        &rdata, &rdrcnt)) {
    513                 DEBUG(0,("cli_oem_change_password: Failed to recieve reply to password change for user %s\n",
    514                         user ));
    515                 return False;
    516         }
    517 
    518554        if (rparam) {
    519555                cli->rap_error = SVAL(rparam,0);
     
    530566****************************************************************************/
    531567
    532 bool cli_qpathinfo(struct cli_state *cli,
     568struct cli_qpathinfo1_state {
     569        struct cli_state *cli;
     570        uint32_t num_data;
     571        uint8_t *data;
     572};
     573
     574static void cli_qpathinfo1_done(struct tevent_req *subreq);
     575
     576struct tevent_req *cli_qpathinfo1_send(TALLOC_CTX *mem_ctx,
     577                                       struct event_context *ev,
     578                                       struct cli_state *cli,
     579                                       const char *fname)
     580{
     581        struct tevent_req *req = NULL, *subreq = NULL;
     582        struct cli_qpathinfo1_state *state = NULL;
     583
     584        req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo1_state);
     585        if (req == NULL) {
     586                return NULL;
     587        }
     588        state->cli = cli;
     589        subreq = cli_qpathinfo_send(state, ev, cli, fname, SMB_INFO_STANDARD,
     590                                    22, cli->max_xmit);
     591        if (tevent_req_nomem(subreq, req)) {
     592                return tevent_req_post(req, ev);
     593        }
     594        tevent_req_set_callback(subreq, cli_qpathinfo1_done, req);
     595        return req;
     596}
     597
     598static void cli_qpathinfo1_done(struct tevent_req *subreq)
     599{
     600        struct tevent_req *req = tevent_req_callback_data(
     601                subreq, struct tevent_req);
     602        struct cli_qpathinfo1_state *state = tevent_req_data(
     603                req, struct cli_qpathinfo1_state);
     604        NTSTATUS status;
     605
     606        status = cli_qpathinfo_recv(subreq, state, &state->data,
     607                                    &state->num_data);
     608        TALLOC_FREE(subreq);
     609        if (!NT_STATUS_IS_OK(status)) {
     610                tevent_req_nterror(req, status);
     611                return;
     612        }
     613        tevent_req_done(req);
     614}
     615
     616NTSTATUS cli_qpathinfo1_recv(struct tevent_req *req,
     617                             time_t *change_time,
     618                             time_t *access_time,
     619                             time_t *write_time,
     620                             SMB_OFF_T *size,
     621                             uint16 *mode)
     622{
     623        struct cli_qpathinfo1_state *state = tevent_req_data(
     624                req, struct cli_qpathinfo1_state);
     625        NTSTATUS status;
     626
     627        time_t (*date_fn)(const void *buf, int serverzone);
     628
     629        if (tevent_req_is_nterror(req, &status)) {
     630                return status;
     631        }
     632
     633        if (state->cli->win95) {
     634                date_fn = make_unix_date;
     635        } else {
     636                date_fn = make_unix_date2;
     637        }
     638
     639        if (change_time) {
     640                *change_time = date_fn(state->data+0, state->cli->serverzone);
     641        }
     642        if (access_time) {
     643                *access_time = date_fn(state->data+4, state->cli->serverzone);
     644        }
     645        if (write_time) {
     646                *write_time = date_fn(state->data+8, state->cli->serverzone);
     647        }
     648        if (size) {
     649                *size = IVAL(state->data, 12);
     650        }
     651        if (mode) {
     652                *mode = SVAL(state->data, l1_attrFile);
     653        }
     654        return NT_STATUS_OK;
     655}
     656
     657NTSTATUS cli_qpathinfo1(struct cli_state *cli,
    533658                        const char *fname,
    534659                        time_t *change_time,
     
    538663                        uint16 *mode)
    539664{
    540         unsigned int data_len = 0;
    541         unsigned int param_len = 0;
    542         unsigned int rparam_len, rdata_len;
    543         uint16 setup = TRANSACT2_QPATHINFO;
    544         char *param;
    545         char *rparam=NULL, *rdata=NULL;
    546         int count=8;
    547         bool ret;
    548         time_t (*date_fn)(struct cli_state *, const void *);
    549         char *p;
    550         size_t nlen = 2*(strlen(fname)+1);
    551 
    552         param = SMB_MALLOC_ARRAY(char, 6+nlen+2);
    553         if (!param) {
    554                 return false;
    555         }
    556         p = param;
    557         memset(p, '\0', 6);
    558         SSVAL(p, 0, SMB_INFO_STANDARD);
    559         p += 6;
    560         p += clistr_push(cli, p, fname, nlen, STR_TERMINATE);
    561         param_len = PTR_DIFF(p, param);
    562 
    563         do {
    564                 ret = (cli_send_trans(cli, SMBtrans2,
    565                                       NULL,           /* Name */
    566                                       -1, 0,          /* fid, flags */
    567                                       &setup, 1, 0,   /* setup, length, max */
    568                                       param, param_len, 10, /* param, length, max */
    569                                       NULL, data_len, cli->max_xmit /* data, length, max */
    570                                       ) &&
    571                        cli_receive_trans(cli, SMBtrans2,
    572                                          &rparam, &rparam_len,
    573                                          &rdata, &rdata_len));
    574                 if (!cli_is_dos_error(cli)) break;
    575                 if (!ret) {
    576                         /* we need to work around a Win95 bug - sometimes
    577                            it gives ERRSRV/ERRerror temprarily */
    578                         uint8 eclass;
    579                         uint32 ecode;
    580                         cli_dos_error(cli, &eclass, &ecode);
    581                         if (eclass != ERRSRV || ecode != ERRerror) break;
    582                         smb_msleep(100);
    583                 }
    584         } while (count-- && ret==False);
    585 
    586         SAFE_FREE(param);
    587         if (!ret || !rdata || rdata_len < 22) {
    588                 return False;
    589         }
    590 
    591         if (cli->win95) {
    592                 date_fn = cli_make_unix_date;
    593         } else {
    594                 date_fn = cli_make_unix_date2;
    595         }
    596 
    597         if (change_time) {
    598                 *change_time = date_fn(cli, rdata+0);
    599         }
    600         if (access_time) {
    601                 *access_time = date_fn(cli, rdata+4);
    602         }
    603         if (write_time) {
    604                 *write_time = date_fn(cli, rdata+8);
    605         }
    606         if (size) {
    607                 *size = IVAL(rdata, 12);
    608         }
    609         if (mode) {
    610                 *mode = SVAL(rdata,l1_attrFile);
    611         }
    612 
    613         SAFE_FREE(rdata);
    614         SAFE_FREE(rparam);
    615         return True;
     665        TALLOC_CTX *frame = talloc_stackframe();
     666        struct event_context *ev;
     667        struct tevent_req *req;
     668        NTSTATUS status = NT_STATUS_NO_MEMORY;
     669
     670        if (cli_has_async_calls(cli)) {
     671                /*
     672                 * Can't use sync call while an async call is in flight
     673                 */
     674                status = NT_STATUS_INVALID_PARAMETER;
     675                goto fail;
     676        }
     677        ev = event_context_init(frame);
     678        if (ev == NULL) {
     679                goto fail;
     680        }
     681        req = cli_qpathinfo1_send(frame, ev, cli, fname);
     682        if (req == NULL) {
     683                goto fail;
     684        }
     685        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     686                goto fail;
     687        }
     688        status = cli_qpathinfo1_recv(req, change_time, access_time,
     689                                     write_time, size, mode);
     690 fail:
     691        TALLOC_FREE(frame);
     692        if (!NT_STATUS_IS_OK(status)) {
     693                cli_set_error(cli, status);
     694        }
     695        return status;
    616696}
    617697
     
    620700****************************************************************************/
    621701
    622 bool cli_setpathinfo(struct cli_state *cli, const char *fname,
    623                      time_t create_time,
    624                      time_t access_time,
    625                      time_t write_time,
    626                      time_t change_time,
    627                      uint16 mode)
     702NTSTATUS cli_setpathinfo_basic(struct cli_state *cli, const char *fname,
     703                               time_t create_time,
     704                               time_t access_time,
     705                               time_t write_time,
     706                               time_t change_time,
     707                               uint16 mode)
    628708{
    629709        unsigned int data_len = 0;
    630         unsigned int param_len = 0;
    631         unsigned int rparam_len, rdata_len;
    632         uint16 setup = TRANSACT2_SETPATHINFO;
    633         char *param;
    634710        char data[40];
    635         char *rparam=NULL, *rdata=NULL;
    636         int count=8;
    637         bool ret;
    638711        char *p;
    639         size_t nlen = 2*(strlen(fname)+1);
    640 
    641         param = SMB_MALLOC_ARRAY(char, 6+nlen+2);
    642         if (!param) {
    643                 return false;
    644         }
    645         memset(param, '\0', 6);
    646         memset(data, 0, sizeof(data));
    647 
    648         p = param;
    649 
    650         /* Add the information level */
    651         SSVAL(p, 0, SMB_FILE_BASIC_INFORMATION);
    652 
    653         /* Skip reserved */
    654         p += 6;
    655 
    656         /* Add the file name */
    657         p += clistr_push(cli, p, fname, nlen, STR_TERMINATE);
    658 
    659         param_len = PTR_DIFF(p, param);
    660712
    661713        p = data;
     
    686738        data_len = PTR_DIFF(p, data);
    687739
    688         do {
    689                 ret = (cli_send_trans(cli, SMBtrans2,
    690                                       NULL,           /* Name */
    691                                       -1, 0,          /* fid, flags */
    692                                       &setup, 1, 0,   /* setup, length, max */
    693                                       param, param_len, 10, /* param, length, max */
    694                                       data, data_len, cli->max_xmit /* data, length, max */
    695                                       ) &&
    696                        cli_receive_trans(cli, SMBtrans2,
    697                                          &rparam, &rparam_len,
    698                                          &rdata, &rdata_len));
    699                 if (!cli_is_dos_error(cli)) break;
    700                 if (!ret) {
    701                         /* we need to work around a Win95 bug - sometimes
    702                            it gives ERRSRV/ERRerror temprarily */
    703                         uint8 eclass;
    704                         uint32 ecode;
    705                         cli_dos_error(cli, &eclass, &ecode);
    706                         if (eclass != ERRSRV || ecode != ERRerror) break;
    707                         smb_msleep(100);
    708                 }
    709         } while (count-- && ret==False);
    710 
    711         SAFE_FREE(param);
    712         if (!ret) {
    713                 return False;
    714         }
    715 
    716         SAFE_FREE(rdata);
    717         SAFE_FREE(rparam);
    718         return True;
     740        return cli_setpathinfo(cli, SMB_FILE_BASIC_INFORMATION, fname,
     741                               (uint8_t *)data, data_len);
    719742}
    720743
     
    723746****************************************************************************/
    724747
    725 bool cli_qpathinfo2(struct cli_state *cli, const char *fname,
    726                     struct timespec *create_time,
    727                     struct timespec *access_time,
    728                     struct timespec *write_time,
    729                     struct timespec *change_time,
    730                     SMB_OFF_T *size, uint16 *mode,
    731                     SMB_INO_T *ino)
    732 {
    733         unsigned int data_len = 0;
    734         unsigned int param_len = 0;
    735         uint16 setup = TRANSACT2_QPATHINFO;
    736         char *param;
    737         char *rparam=NULL, *rdata=NULL;
    738         char *p;
    739         size_t nlen = 2*(strlen(fname)+1);
    740 
    741         param = SMB_MALLOC_ARRAY(char, 6+nlen+2);
    742         if (!param) {
    743                 return false;
    744         }
    745         p = param;
    746         memset(param, '\0', 6);
    747         SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO);
    748         p += 6;
    749         p += clistr_push(cli, p, fname, nlen, STR_TERMINATE);
    750 
    751         param_len = PTR_DIFF(p, param);
    752 
    753         if (!cli_send_trans(cli, SMBtrans2,
    754                             NULL,                         /* name */
    755                             -1, 0,                        /* fid, flags */
    756                             &setup, 1, 0,                 /* setup, length, max */
    757                             param, param_len, 10,         /* param, length, max */
    758                             NULL, data_len, cli->max_xmit /* data, length, max */
    759                            )) {
    760                 SAFE_FREE(param);
    761                 return False;
    762         }
    763 
    764         SAFE_FREE(param);
    765         if (!cli_receive_trans(cli, SMBtrans2,
    766                                &rparam, &param_len,
    767                                &rdata, &data_len)) {
    768                 return False;
    769         }
    770 
    771         if (!rdata || data_len < 22) {
    772                 return False;
     748struct cli_qpathinfo2_state {
     749        uint32_t num_data;
     750        uint8_t *data;
     751};
     752
     753static void cli_qpathinfo2_done(struct tevent_req *subreq);
     754
     755struct tevent_req *cli_qpathinfo2_send(TALLOC_CTX *mem_ctx,
     756                                       struct event_context *ev,
     757                                       struct cli_state *cli,
     758                                       const char *fname)
     759{
     760        struct tevent_req *req = NULL, *subreq = NULL;
     761        struct cli_qpathinfo2_state *state = NULL;
     762
     763        req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo2_state);
     764        if (req == NULL) {
     765                return NULL;
     766        }
     767        subreq = cli_qpathinfo_send(state, ev, cli, fname,
     768                                    SMB_QUERY_FILE_ALL_INFO,
     769                                    68, cli->max_xmit);
     770        if (tevent_req_nomem(subreq, req)) {
     771                return tevent_req_post(req, ev);
     772        }
     773        tevent_req_set_callback(subreq, cli_qpathinfo2_done, req);
     774        return req;
     775}
     776
     777static void cli_qpathinfo2_done(struct tevent_req *subreq)
     778{
     779        struct tevent_req *req = tevent_req_callback_data(
     780                subreq, struct tevent_req);
     781        struct cli_qpathinfo2_state *state = tevent_req_data(
     782                req, struct cli_qpathinfo2_state);
     783        NTSTATUS status;
     784
     785        status = cli_qpathinfo_recv(subreq, state, &state->data,
     786                                    &state->num_data);
     787        TALLOC_FREE(subreq);
     788        if (!NT_STATUS_IS_OK(status)) {
     789                tevent_req_nterror(req, status);
     790                return;
     791        }
     792        tevent_req_done(req);
     793}
     794
     795NTSTATUS cli_qpathinfo2_recv(struct tevent_req *req,
     796                             struct timespec *create_time,
     797                             struct timespec *access_time,
     798                             struct timespec *write_time,
     799                             struct timespec *change_time,
     800                             SMB_OFF_T *size, uint16 *mode,
     801                             SMB_INO_T *ino)
     802{
     803        struct cli_qpathinfo2_state *state = tevent_req_data(
     804                req, struct cli_qpathinfo2_state);
     805        NTSTATUS status;
     806
     807        if (tevent_req_is_nterror(req, &status)) {
     808                return status;
    773809        }
    774810
    775811        if (create_time) {
    776                 *create_time = interpret_long_date(rdata+0);
     812                *create_time = interpret_long_date((char *)state->data+0);
    777813        }
    778814        if (access_time) {
    779                 *access_time = interpret_long_date(rdata+8);
     815                *access_time = interpret_long_date((char *)state->data+8);
    780816        }
    781817        if (write_time) {
    782                 *write_time = interpret_long_date(rdata+16);
     818                *write_time = interpret_long_date((char *)state->data+16);
    783819        }
    784820        if (change_time) {
    785                 *change_time = interpret_long_date(rdata+24);
     821                *change_time = interpret_long_date((char *)state->data+24);
    786822        }
    787823        if (mode) {
    788                 *mode = SVAL(rdata, 32);
     824                *mode = SVAL(state->data, 32);
    789825        }
    790826        if (size) {
    791                 *size = IVAL2_TO_SMB_BIG_UINT(rdata,48);
     827                *size = IVAL2_TO_SMB_BIG_UINT(state->data,48);
    792828        }
    793829        if (ino) {
    794                 *ino = IVAL(rdata, 64);
    795         }
    796 
    797         SAFE_FREE(rdata);
    798         SAFE_FREE(rparam);
    799         return True;
     830                *ino = IVAL(state->data, 64);
     831        }
     832        return NT_STATUS_OK;
     833}
     834
     835NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname,
     836                        struct timespec *create_time,
     837                        struct timespec *access_time,
     838                        struct timespec *write_time,
     839                        struct timespec *change_time,
     840                        SMB_OFF_T *size, uint16 *mode,
     841                        SMB_INO_T *ino)
     842{
     843        TALLOC_CTX *frame = talloc_stackframe();
     844        struct event_context *ev;
     845        struct tevent_req *req;
     846        NTSTATUS status = NT_STATUS_NO_MEMORY;
     847
     848        if (cli_has_async_calls(cli)) {
     849                /*
     850                 * Can't use sync call while an async call is in flight
     851                 */
     852                status = NT_STATUS_INVALID_PARAMETER;
     853                goto fail;
     854        }
     855        ev = event_context_init(frame);
     856        if (ev == NULL) {
     857                goto fail;
     858        }
     859        req = cli_qpathinfo2_send(frame, ev, cli, fname);
     860        if (req == NULL) {
     861                goto fail;
     862        }
     863        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     864                goto fail;
     865        }
     866        status = cli_qpathinfo2_recv(req, create_time, access_time,
     867                                     write_time, change_time, size, mode, ino);
     868 fail:
     869        TALLOC_FREE(frame);
     870        if (!NT_STATUS_IS_OK(status)) {
     871                cli_set_error(cli, status);
     872        }
     873        return status;
    800874}
    801875
     
    804878****************************************************************************/
    805879
    806 bool cli_qpathinfo_streams(struct cli_state *cli, const char *fname,
    807                            TALLOC_CTX *mem_ctx,
    808                            unsigned int *pnum_streams,
    809                            struct stream_struct **pstreams)
    810 {
    811         unsigned int data_len = 0;
    812         unsigned int param_len = 0;
    813         uint16 setup = TRANSACT2_QPATHINFO;
    814         char *param;
    815         char *rparam=NULL, *rdata=NULL;
    816         char *p;
     880static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *data,
     881                               size_t data_len,
     882                               unsigned int *pnum_streams,
     883                               struct stream_struct **pstreams);
     884
     885struct cli_qpathinfo_streams_state {
     886        uint32_t num_data;
     887        uint8_t *data;
     888};
     889
     890static void cli_qpathinfo_streams_done(struct tevent_req *subreq);
     891
     892struct tevent_req *cli_qpathinfo_streams_send(TALLOC_CTX *mem_ctx,
     893                                              struct tevent_context *ev,
     894                                              struct cli_state *cli,
     895                                              const char *fname)
     896{
     897        struct tevent_req *req = NULL, *subreq = NULL;
     898        struct cli_qpathinfo_streams_state *state = NULL;
     899
     900        req = tevent_req_create(mem_ctx, &state,
     901                                struct cli_qpathinfo_streams_state);
     902        if (req == NULL) {
     903                return NULL;
     904        }
     905        subreq = cli_qpathinfo_send(state, ev, cli, fname,
     906                                    SMB_FILE_STREAM_INFORMATION,
     907                                    0, cli->max_xmit);
     908        if (tevent_req_nomem(subreq, req)) {
     909                return tevent_req_post(req, ev);
     910        }
     911        tevent_req_set_callback(subreq, cli_qpathinfo_streams_done, req);
     912        return req;
     913}
     914
     915static void cli_qpathinfo_streams_done(struct tevent_req *subreq)
     916{
     917        struct tevent_req *req = tevent_req_callback_data(
     918                subreq, struct tevent_req);
     919        struct cli_qpathinfo_streams_state *state = tevent_req_data(
     920                req, struct cli_qpathinfo_streams_state);
     921        NTSTATUS status;
     922
     923        status = cli_qpathinfo_recv(subreq, state, &state->data,
     924                                    &state->num_data);
     925        TALLOC_FREE(subreq);
     926        if (!NT_STATUS_IS_OK(status)) {
     927                tevent_req_nterror(req, status);
     928                return;
     929        }
     930        tevent_req_done(req);
     931}
     932
     933NTSTATUS cli_qpathinfo_streams_recv(struct tevent_req *req,
     934                                    TALLOC_CTX *mem_ctx,
     935                                    unsigned int *pnum_streams,
     936                                    struct stream_struct **pstreams)
     937{
     938        struct cli_qpathinfo_streams_state *state = tevent_req_data(
     939                req, struct cli_qpathinfo_streams_state);
     940        NTSTATUS status;
     941
     942        if (tevent_req_is_nterror(req, &status)) {
     943                return status;
     944        }
     945        if (!parse_streams_blob(mem_ctx, state->data, state->num_data,
     946                                pnum_streams, pstreams)) {
     947                return NT_STATUS_INVALID_NETWORK_RESPONSE;
     948        }
     949        return NT_STATUS_OK;
     950}
     951
     952NTSTATUS cli_qpathinfo_streams(struct cli_state *cli, const char *fname,
     953                               TALLOC_CTX *mem_ctx,
     954                               unsigned int *pnum_streams,
     955                               struct stream_struct **pstreams)
     956{
     957        TALLOC_CTX *frame = talloc_stackframe();
     958        struct event_context *ev;
     959        struct tevent_req *req;
     960        NTSTATUS status = NT_STATUS_NO_MEMORY;
     961
     962        if (cli_has_async_calls(cli)) {
     963                /*
     964                 * Can't use sync call while an async call is in flight
     965                 */
     966                status = NT_STATUS_INVALID_PARAMETER;
     967                goto fail;
     968        }
     969        ev = event_context_init(frame);
     970        if (ev == NULL) {
     971                goto fail;
     972        }
     973        req = cli_qpathinfo_streams_send(frame, ev, cli, fname);
     974        if (req == NULL) {
     975                goto fail;
     976        }
     977        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     978                goto fail;
     979        }
     980        status = cli_qpathinfo_streams_recv(req, mem_ctx, pnum_streams,
     981                                            pstreams);
     982 fail:
     983        TALLOC_FREE(frame);
     984        if (!NT_STATUS_IS_OK(status)) {
     985                cli_set_error(cli, status);
     986        }
     987        return status;
     988}
     989
     990static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *rdata,
     991                               size_t data_len,
     992                               unsigned int *pnum_streams,
     993                               struct stream_struct **pstreams)
     994{
    817995        unsigned int num_streams;
    818996        struct stream_struct *streams;
    819997        unsigned int ofs;
    820         size_t namelen = 2*(strlen(fname)+1);
    821 
    822         param = SMB_MALLOC_ARRAY(char, 6+namelen+2);
    823         if (param == NULL) {
    824                 return false;
    825         }
    826         p = param;
    827         memset(p, 0, 6);
    828         SSVAL(p, 0, SMB_FILE_STREAM_INFORMATION);
    829         p += 6;
    830         p += clistr_push(cli, p, fname, namelen, STR_TERMINATE);
    831 
    832         param_len = PTR_DIFF(p, param);
    833 
    834         if (!cli_send_trans(cli, SMBtrans2,
    835                             NULL,                     /* name */
    836                             -1, 0,                    /* fid, flags */
    837                             &setup, 1, 0,             /* setup, len, max */
    838                             param, param_len, 10,     /* param, len, max */
    839                             NULL, data_len, cli->max_xmit /* data, len, max */
    840                            )) {
    841                 return false;
    842         }
    843 
    844         if (!cli_receive_trans(cli, SMBtrans2,
    845                                &rparam, &param_len,
    846                                &rdata, &data_len)) {
    847                 return false;
    848         }
    849 
    850         if (!rdata) {
    851                 SAFE_FREE(rparam);
    852                 return false;
    853         }
    854998
    855999        num_streams = 0;
     
    9171061        }
    9181062
    919         SAFE_FREE(rdata);
    920         SAFE_FREE(rparam);
    921 
    9221063        *pnum_streams = num_streams;
    9231064        *pstreams = streams;
     
    9261067 fail:
    9271068        TALLOC_FREE(streams);
    928         SAFE_FREE(rdata);
    929         SAFE_FREE(rparam);
    9301069        return false;
    9311070}
     
    9351074****************************************************************************/
    9361075
    937 bool cli_qfilename(struct cli_state *cli, uint16_t fnum, char *name, size_t namelen)
    938 {
    939         unsigned int data_len = 0;
    940         unsigned int param_len = 0;
    941         uint16 setup = TRANSACT2_QFILEINFO;
    942         char param[4];
    943         char *rparam=NULL, *rdata=NULL;
    944 
    945         param_len = 4;
    946         SSVAL(param, 0, fnum);
    947         SSVAL(param, 2, SMB_QUERY_FILE_NAME_INFO);
    948 
    949         if (!cli_send_trans(cli, SMBtrans2,
    950                             NULL,                         /* name */
    951                             -1, 0,                        /* fid, flags */
    952                             &setup, 1, 0,                 /* setup, length, max */
    953                             param, param_len, 2,          /* param, length, max */
    954                             NULL, data_len, cli->max_xmit /* data, length, max */
    955                            )) {
    956                 return False;
    957         }
    958 
    959         if (!cli_receive_trans(cli, SMBtrans2,
    960                                &rparam, &param_len,
    961                                &rdata, &data_len)) {
    962                 return False;
    963         }
    964 
    965         if (!rdata || data_len < 4) {
    966                 SAFE_FREE(rparam);
    967                 SAFE_FREE(rdata);
    968                 return False;
     1076NTSTATUS cli_qfilename(struct cli_state *cli, uint16_t fnum, char *name,
     1077                       size_t namelen)
     1078{
     1079        uint8_t *rdata;
     1080        uint32_t num_rdata;
     1081        NTSTATUS status;
     1082
     1083        status = cli_qfileinfo(talloc_tos(), cli, fnum,
     1084                               SMB_QUERY_FILE_NAME_INFO,
     1085                               4, cli->max_xmit,
     1086                               &rdata, &num_rdata);
     1087        if (!NT_STATUS_IS_OK(status)) {
     1088                return status;
    9691089        }
    9701090
    9711091        clistr_pull(cli->inbuf, name, rdata+4, namelen, IVAL(rdata, 0),
    9721092                    STR_UNICODE);
    973 
    974         SAFE_FREE(rparam);
    975         SAFE_FREE(rdata);
    976 
    977         return True;
     1093        TALLOC_FREE(rdata);
     1094        return NT_STATUS_OK;
    9781095}
    9791096
     
    9821099****************************************************************************/
    9831100
    984 bool cli_qfileinfo(struct cli_state *cli, uint16_t fnum,
    985                    uint16 *mode, SMB_OFF_T *size,
    986                    struct timespec *create_time,
    987                    struct timespec *access_time,
    988                    struct timespec *write_time,
    989                    struct timespec *change_time,
    990                    SMB_INO_T *ino)
    991 {
    992         unsigned int data_len = 0;
    993         unsigned int param_len = 0;
    994         uint16 setup;
    995         uint8_t param[4];
    996         uint8_t *rparam=NULL, *rdata=NULL;
     1101NTSTATUS cli_qfileinfo_basic(struct cli_state *cli, uint16_t fnum,
     1102                             uint16 *mode, SMB_OFF_T *size,
     1103                             struct timespec *create_time,
     1104                             struct timespec *access_time,
     1105                             struct timespec *write_time,
     1106                             struct timespec *change_time,
     1107                             SMB_INO_T *ino)
     1108{
     1109        uint8_t *rdata;
     1110        uint32_t num_rdata;
    9971111        NTSTATUS status;
    9981112
    9991113        /* if its a win95 server then fail this - win95 totally screws it
    10001114           up */
    1001         if (cli->win95) return False;
    1002 
    1003         param_len = 4;
    1004 
    1005         SSVAL(param, 0, fnum);
    1006         SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO);
    1007 
    1008         SSVAL(&setup, 0, TRANSACT2_QFILEINFO);
    1009 
    1010         status = cli_trans(talloc_tos(), cli, SMBtrans2,
    1011                            NULL, -1, 0, 0, /* name, fid, function, flags */
    1012                            &setup, 1, 0,          /* setup, length, max */
    1013                            param, param_len, 2,   /* param, length, max */
    1014                            NULL, 0, MIN(cli->max_xmit, 0xffff), /* data, length, max */
    1015                            NULL, NULL, /* rsetup, length */
    1016                            &rparam, &param_len, /* rparam, length */
    1017                            &rdata, &data_len);
    1018 
     1115        if (cli->win95) {
     1116                return NT_STATUS_NOT_SUPPORTED;
     1117        }
     1118
     1119        status = cli_qfileinfo(talloc_tos(), cli, fnum,
     1120                               SMB_QUERY_FILE_ALL_INFO,
     1121                               68, MIN(cli->max_xmit, 0xffff),
     1122                               &rdata, &num_rdata);
    10191123        if (!NT_STATUS_IS_OK(status)) {
    1020                 return false;
    1021         }
    1022 
    1023         if (!rdata || data_len < 68) {
    1024                 return False;
     1124                return status;
    10251125        }
    10261126
     
    10481148
    10491149        TALLOC_FREE(rdata);
    1050         TALLOC_FREE(rparam);
    1051         return True;
     1150        return NT_STATUS_OK;
    10521151}
    10531152
     
    10561155****************************************************************************/
    10571156
    1058 bool cli_qpathinfo_basic( struct cli_state *cli, const char *name,
    1059                           SMB_STRUCT_STAT *sbuf, uint32 *attributes )
    1060 {
    1061         unsigned int param_len = 0;
    1062         unsigned int data_len = 0;
    1063         uint16 setup = TRANSACT2_QPATHINFO;
    1064         char *param;
    1065         char *rparam=NULL, *rdata=NULL;
    1066         char *p;
    1067         char *path;
    1068         int len;
    1069         size_t nlen;
     1157struct cli_qpathinfo_basic_state {
     1158        uint32_t num_data;
     1159        uint8_t *data;
     1160};
     1161
     1162static void cli_qpathinfo_basic_done(struct tevent_req *subreq);
     1163
     1164struct tevent_req *cli_qpathinfo_basic_send(TALLOC_CTX *mem_ctx,
     1165                                            struct event_context *ev,
     1166                                            struct cli_state *cli,
     1167                                            const char *fname)
     1168{
     1169        struct tevent_req *req = NULL, *subreq = NULL;
     1170        struct cli_qpathinfo_basic_state *state = NULL;
     1171
     1172        req = tevent_req_create(mem_ctx, &state,
     1173                                struct cli_qpathinfo_basic_state);
     1174        if (req == NULL) {
     1175                return NULL;
     1176        }
     1177        subreq = cli_qpathinfo_send(state, ev, cli, fname,
     1178                                    SMB_QUERY_FILE_BASIC_INFO,
     1179                                    36, cli->max_xmit);
     1180        if (tevent_req_nomem(subreq, req)) {
     1181                return tevent_req_post(req, ev);
     1182        }
     1183        tevent_req_set_callback(subreq, cli_qpathinfo_basic_done, req);
     1184        return req;
     1185}
     1186
     1187static void cli_qpathinfo_basic_done(struct tevent_req *subreq)
     1188{
     1189        struct tevent_req *req = tevent_req_callback_data(
     1190                subreq, struct tevent_req);
     1191        struct cli_qpathinfo_basic_state *state = tevent_req_data(
     1192                req, struct cli_qpathinfo_basic_state);
     1193        NTSTATUS status;
     1194
     1195        status = cli_qpathinfo_recv(subreq, state, &state->data,
     1196                                    &state->num_data);
     1197        TALLOC_FREE(subreq);
     1198        if (!NT_STATUS_IS_OK(status)) {
     1199                tevent_req_nterror(req, status);
     1200                return;
     1201        }
     1202        tevent_req_done(req);
     1203}
     1204
     1205NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req,
     1206                                  SMB_STRUCT_STAT *sbuf, uint32 *attributes)
     1207{
     1208        struct cli_qpathinfo_basic_state *state = tevent_req_data(
     1209                req, struct cli_qpathinfo_basic_state);
     1210        NTSTATUS status;
     1211
     1212        if (tevent_req_is_nterror(req, &status)) {
     1213                return status;
     1214        }
     1215
     1216        sbuf->st_ex_atime = interpret_long_date((char *)state->data+8);
     1217        sbuf->st_ex_mtime = interpret_long_date((char *)state->data+16);
     1218        sbuf->st_ex_ctime = interpret_long_date((char *)state->data+24);
     1219        *attributes = IVAL(state->data, 32);
     1220        return NT_STATUS_OK;
     1221}
     1222
     1223NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name,
     1224                             SMB_STRUCT_STAT *sbuf, uint32 *attributes)
     1225{
    10701226        TALLOC_CTX *frame = talloc_stackframe();
    1071 
    1072         path = talloc_strdup(frame, name);
    1073         if (!path) {
    1074                 TALLOC_FREE(frame);
    1075                 return false;
    1076         }
    1077         /* cleanup */
    1078 
    1079         len = strlen(path);
    1080         if ( path[len-1] == '\\' || path[len-1] == '/') {
    1081                 path[len-1] = '\0';
    1082         }
    1083         nlen = 2*(strlen(path)+1);
    1084 
    1085         param = TALLOC_ARRAY(frame,char,6+nlen+2);
    1086         if (!param) {
    1087                 return false;
    1088         }
    1089         p = param;
    1090         memset(param, '\0', 6);
    1091 
    1092         SSVAL(p, 0, SMB_QUERY_FILE_BASIC_INFO);
    1093         p += 6;
    1094         p += clistr_push(cli, p, path, nlen, STR_TERMINATE);
    1095         param_len = PTR_DIFF(p, param);
    1096 
    1097 
    1098         if (!cli_send_trans(cli, SMBtrans2,
    1099                         NULL,                        /* name */
    1100                         -1, 0,                       /* fid, flags */
    1101                         &setup, 1, 0,                /* setup, length, max */
    1102                         param, param_len, 2,         /* param, length, max */
    1103                         NULL,  0, cli->max_xmit      /* data, length, max */
    1104                         )) {
    1105                 TALLOC_FREE(frame);
    1106                 return False;
    1107         }
    1108 
     1227        struct event_context *ev;
     1228        struct tevent_req *req;
     1229        NTSTATUS status = NT_STATUS_NO_MEMORY;
     1230
     1231        if (cli_has_async_calls(cli)) {
     1232                /*
     1233                 * Can't use sync call while an async call is in flight
     1234                 */
     1235                status = NT_STATUS_INVALID_PARAMETER;
     1236                goto fail;
     1237        }
     1238        ev = event_context_init(frame);
     1239        if (ev == NULL) {
     1240                goto fail;
     1241        }
     1242        req = cli_qpathinfo_basic_send(frame, ev, cli, name);
     1243        if (req == NULL) {
     1244                goto fail;
     1245        }
     1246        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     1247                goto fail;
     1248        }
     1249        status = cli_qpathinfo_basic_recv(req, sbuf, attributes);
     1250 fail:
    11091251        TALLOC_FREE(frame);
    1110 
    1111         if (!cli_receive_trans(cli, SMBtrans2,
    1112                 &rparam, &param_len,
    1113                 &rdata, &data_len)) {
    1114                         return False;
    1115         }
    1116 
    1117         if (data_len < 36) {
    1118                 SAFE_FREE(rdata);
    1119                 SAFE_FREE(rparam);
    1120                 return False;
    1121         }
    1122 
    1123         sbuf->st_ex_atime = interpret_long_date( rdata+8 ); /* Access time. */
    1124         sbuf->st_ex_mtime = interpret_long_date( rdata+16 ); /* Write time. */
    1125         sbuf->st_ex_ctime = interpret_long_date( rdata+24 ); /* Change time. */
    1126 
    1127         *attributes = IVAL( rdata, 32 );
    1128 
    1129         SAFE_FREE(rparam);
    1130         SAFE_FREE(rdata);
    1131 
    1132         return True;
    1133 }
    1134 
    1135 /****************************************************************************
    1136  Send a qfileinfo call.
    1137 ****************************************************************************/
    1138 
    1139 bool cli_qfileinfo_test(struct cli_state *cli, uint16_t fnum, int level, char **poutdata, uint32 *poutlen)
    1140 {
    1141         unsigned int data_len = 0;
    1142         unsigned int param_len = 0;
    1143         uint16 setup = TRANSACT2_QFILEINFO;
    1144         char param[4];
    1145         char *rparam=NULL, *rdata=NULL;
    1146 
    1147         *poutdata = NULL;
    1148         *poutlen = 0;
    1149 
    1150         /* if its a win95 server then fail this - win95 totally screws it
    1151            up */
    1152         if (cli->win95)
    1153                 return False;
    1154 
    1155         param_len = 4;
    1156 
    1157         SSVAL(param, 0, fnum);
    1158         SSVAL(param, 2, level);
    1159 
    1160         if (!cli_send_trans(cli, SMBtrans2,
    1161                             NULL,                           /* name */
    1162                             -1, 0,                          /* fid, flags */
    1163                             &setup, 1, 0,                   /* setup, length, max */
    1164                             param, param_len, 2,            /* param, length, max */
    1165                             NULL, data_len, cli->max_xmit   /* data, length, max */
    1166                            )) {
    1167                 return False;
    1168         }
    1169 
    1170         if (!cli_receive_trans(cli, SMBtrans2,
    1171                                &rparam, &param_len,
    1172                                &rdata, &data_len)) {
    1173                 return False;
    1174         }
    1175 
    1176         *poutdata = (char *)memdup(rdata, data_len);
    1177         if (!*poutdata) {
    1178                 SAFE_FREE(rdata);
    1179                 SAFE_FREE(rparam);
    1180                 return False;
    1181         }
    1182 
    1183         *poutlen = data_len;
    1184 
    1185         SAFE_FREE(rdata);
    1186         SAFE_FREE(rparam);
    1187         return True;
     1252        if (!NT_STATUS_IS_OK(status)) {
     1253                cli_set_error(cli, status);
     1254        }
     1255        return status;
    11881256}
    11891257
     
    11941262NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name)
    11951263{
    1196         unsigned int data_len = 0;
    1197         unsigned int param_len = 0;
    1198         uint16 setup = TRANSACT2_QPATHINFO;
    1199         char *param;
    1200         char *rparam=NULL, *rdata=NULL;
    1201         int count=8;
    1202         char *p;
    1203         bool ret;
     1264        uint8_t *rdata;
     1265        uint32_t num_rdata;
    12041266        unsigned int len;
    1205         size_t nlen = 2*(strlen(fname)+1);
    1206 
    1207         param = SMB_MALLOC_ARRAY(char, 6+nlen+2);
    1208         if (!param) {
     1267        char *converted = NULL;
     1268        size_t converted_size = 0;
     1269        NTSTATUS status;
     1270
     1271        status = cli_qpathinfo(talloc_tos(), cli, fname,
     1272                               SMB_QUERY_FILE_ALT_NAME_INFO,
     1273                               4, cli->max_xmit, &rdata, &num_rdata);
     1274        if (!NT_STATUS_IS_OK(status)) {
     1275                return status;
     1276        }
     1277
     1278        len = IVAL(rdata, 0);
     1279
     1280        if (len > num_rdata - 4) {
     1281                return NT_STATUS_INVALID_NETWORK_RESPONSE;
     1282        }
     1283
     1284        /* The returned data is a pushed string, not raw data. */
     1285        if (!convert_string_talloc(talloc_tos(),
     1286                                   cli_ucs2(cli) ? CH_UTF16LE : CH_DOS,
     1287                                   CH_UNIX,
     1288                                   rdata + 4,
     1289                                   len,
     1290                                   &converted,
     1291                                   &converted_size,
     1292                                   true)) {
    12091293                return NT_STATUS_NO_MEMORY;
    12101294        }
    1211         p = param;
    1212         memset(param, '\0', 6);
    1213         SSVAL(p, 0, SMB_QUERY_FILE_ALT_NAME_INFO);
    1214         p += 6;
    1215         p += clistr_push(cli, p, fname, nlen, STR_TERMINATE);
    1216         param_len = PTR_DIFF(p, param);
    1217 
    1218         do {
    1219                 ret = (cli_send_trans(cli, SMBtrans2,
    1220                                       NULL,           /* Name */
    1221                                       -1, 0,          /* fid, flags */
    1222                                       &setup, 1, 0,   /* setup, length, max */
    1223                                       param, param_len, 10, /* param, length, max */
    1224                                       NULL, data_len, cli->max_xmit /* data, length, max */
    1225                                       ) &&
    1226                        cli_receive_trans(cli, SMBtrans2,
    1227                                          &rparam, &param_len,
    1228                                          &rdata, &data_len));
    1229                 if (!ret && cli_is_dos_error(cli)) {
    1230                         /* we need to work around a Win95 bug - sometimes
    1231                            it gives ERRSRV/ERRerror temprarily */
    1232                         uint8 eclass;
    1233                         uint32 ecode;
    1234                         cli_dos_error(cli, &eclass, &ecode);
    1235                         if (eclass != ERRSRV || ecode != ERRerror) break;
    1236                         smb_msleep(100);
    1237                 }
    1238         } while (count-- && ret==False);
    1239 
    1240         SAFE_FREE(param);
    1241 
    1242         if (!ret || !rdata || data_len < 4) {
    1243                 return NT_STATUS_UNSUCCESSFUL;
    1244         }
    1245 
    1246         len = IVAL(rdata, 0);
    1247 
    1248         if (len > data_len - 4) {
    1249                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
    1250         }
    1251 
    1252         clistr_pull(cli->inbuf, alt_name, rdata+4, sizeof(fstring), len,
    1253                     STR_UNICODE);
    1254 
    1255         SAFE_FREE(rdata);
    1256         SAFE_FREE(rparam);
     1295        fstrcpy(alt_name, converted);
     1296
     1297        TALLOC_FREE(converted);
     1298        TALLOC_FREE(rdata);
    12571299
    12581300        return NT_STATUS_OK;
Note: See TracChangeset for help on using the changeset viewer.