Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 deleted
14 edited
4 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/torture/smb2/compound.c

    r414 r745  
    2121
    2222#include "includes.h"
    23 #include "librpc/gen_ndr/security.h"
    2423#include "libcli/smb2/smb2.h"
    2524#include "libcli/smb2/smb2_calls.h"
     
    3534        }} while (0)
    3635
     36#define TARGET_IS_W2K8(_tctx) (torture_setting_bool(_tctx, "w2k8", false))
     37#define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false))
     38
    3739static bool test_compound_related1(struct torture_context *tctx,
    3840                                   struct smb2_tree *tree)
     
    4547        bool ret = true;
    4648        struct smb2_request *req[2];
    47         DATA_BLOB data;
     49        uint32_t saved_tid = tree->tid;
     50        uint64_t saved_uid = tree->session->uid;
    4851
    4952        smb2_transport_credits_ask_num(tree->session->transport, 2);
     
    8285        ZERO_STRUCT(cl);
    8386        cl.in.file.handle = hd;
     87
     88        tree->tid = 0xFFFFFFFF;
     89        tree->session->uid = UINT64_MAX;
     90
    8491        req[1] = smb2_close_send(tree, &cl);
    8592
     
    8895        status = smb2_close_recv(req[1], &cl);
    8996        CHECK_STATUS(status, NT_STATUS_OK);
     97
     98        tree->tid = saved_tid;
     99        tree->session->uid = saved_uid;
    90100
    91101        smb2_util_unlink(tree, fname);
     
    104114        bool ret = true;
    105115        struct smb2_request *req[5];
     116        uint32_t saved_tid = tree->tid;
     117        uint64_t saved_uid = tree->session->uid;
    106118
    107119        smb2_transport_credits_ask_num(tree->session->transport, 5);
     
    140152        ZERO_STRUCT(cl);
    141153        cl.in.file.handle = hd;
     154        tree->tid = 0xFFFFFFFF;
     155        tree->session->uid = UINT64_MAX;
     156
    142157        req[1] = smb2_close_send(tree, &cl);
    143158        req[2] = smb2_close_send(tree, &cl);
     
    155170        status = smb2_close_recv(req[4], &cl);
    156171        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     172
     173        tree->tid = saved_tid;
     174        tree->session->uid = saved_uid;
    157175
    158176        smb2_util_unlink(tree, fname);
     
    171189        bool ret = true;
    172190        struct smb2_request *req[5];
    173         uint64_t uid;
    174         uint32_t tid;
    175191
    176192        smb2_transport_credits_ask_num(tree->session->transport, 5);
     
    238254        bool ret = true;
    239255        struct smb2_request *req[2];
    240         DATA_BLOB data;
    241256
    242257        smb2_transport_credits_ask_num(tree->session->transport, 2);
     
    299314        bool ret = true;
    300315        struct smb2_request *req[5];
     316        uint32_t saved_tid = tree->tid;
     317        uint64_t saved_uid = tree->session->uid;
    301318
    302319        smb2_transport_credits_ask_num(tree->session->transport, 5);
     
    335352        ZERO_STRUCT(cl);
    336353        cl.in.file.handle = hd;
     354        tree->tid = 0xFFFFFFFF;
     355        tree->session->uid = UINT64_MAX;
     356
    337357        req[1] = smb2_close_send(tree, &cl);
    338358        /* strange that this is not generating invalid parameter */
     
    353373        status = smb2_close_recv(req[4], &cl);
    354374        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     375
     376        tree->tid = saved_tid;
     377        tree->session->uid = saved_uid;
    355378
    356379        smb2_util_unlink(tree, fname);
     
    426449}
    427450
     451/* Send a compound request where we expect the last request (Create, Notify)
     452 * to go asynchronous. This works against a Win7 server and the reply is
     453 * sent in two different packets. */
     454static bool test_compound_interim1(struct torture_context *tctx,
     455                                   struct smb2_tree *tree)
     456{
     457    struct smb2_handle hd;
     458    struct smb2_create cr;
     459    NTSTATUS status = NT_STATUS_OK;
     460    const char *dname = "compound_interim_dir";
     461    struct smb2_notify nt;
     462    bool ret = true;
     463    struct smb2_request *req[2];
     464
     465    /* Win7 compound request implementation deviates substantially from the
     466     * SMB2 spec as noted in MS-SMB2 <159>, <162>.  This, test currently
     467     * verifies the Windows behavior, not the general spec behavior. */
     468    if (!TARGET_IS_WIN7(tctx) && !TARGET_IS_W2K8(tctx)) {
     469            torture_skip(tctx, "Interim test is specific to Windows server "
     470                               "behavior.\n");
     471    }
     472
     473    smb2_transport_credits_ask_num(tree->session->transport, 5);
     474
     475    smb2_deltree(tree, dname);
     476
     477    smb2_transport_credits_ask_num(tree->session->transport, 1);
     478
     479    ZERO_STRUCT(cr);
     480    cr.in.desired_access        = SEC_RIGHTS_FILE_ALL;
     481    cr.in.create_options        = NTCREATEX_OPTIONS_DIRECTORY;
     482    cr.in.file_attributes       = FILE_ATTRIBUTE_DIRECTORY;
     483    cr.in.share_access          = NTCREATEX_SHARE_ACCESS_READ |
     484                                  NTCREATEX_SHARE_ACCESS_WRITE |
     485                                  NTCREATEX_SHARE_ACCESS_DELETE;
     486    cr.in.create_disposition    = NTCREATEX_DISP_CREATE;
     487    cr.in.fname                 = dname;
     488
     489    smb2_transport_compound_start(tree->session->transport, 2);
     490
     491    req[0] = smb2_create_send(tree, &cr);
     492
     493    smb2_transport_compound_set_related(tree->session->transport, true);
     494
     495    hd.data[0] = UINT64_MAX;
     496    hd.data[1] = UINT64_MAX;
     497
     498    ZERO_STRUCT(nt);
     499    nt.in.recursive          = true;
     500    nt.in.buffer_size        = 0x1000;
     501    nt.in.file.handle        = hd;
     502    nt.in.completion_filter  = FILE_NOTIFY_CHANGE_NAME;
     503    nt.in.unknown            = 0x00000000;
     504
     505    req[1] = smb2_notify_send(tree, &nt);
     506
     507    status = smb2_create_recv(req[0], tree, &cr);
     508    CHECK_STATUS(status, NT_STATUS_OK);
     509
     510    smb2_cancel(req[1]);
     511    status = smb2_notify_recv(req[1], tree, &nt);
     512    CHECK_STATUS(status, NT_STATUS_CANCELLED);
     513
     514    smb2_util_close(tree, cr.out.file.handle);
     515
     516    smb2_deltree(tree, dname);
     517done:
     518    return ret;
     519}
     520
     521/* Send a compound request where we expect the middle request (Create, Notify,
     522 * GetInfo) to go asynchronous. Against Win7 the sync request succeed while
     523 * the async fails. All are returned in the same compound response. */
     524static bool test_compound_interim2(struct torture_context *tctx,
     525                                   struct smb2_tree *tree)
     526{
     527    struct smb2_handle hd;
     528    struct smb2_create cr;
     529    NTSTATUS status = NT_STATUS_OK;
     530    const char *dname = "compound_interim_dir";
     531    struct smb2_getinfo gf;
     532    struct smb2_notify  nt;
     533    bool ret = true;
     534    struct smb2_request *req[3];
     535
     536    /* Win7 compound request implementation deviates substantially from the
     537     * SMB2 spec as noted in MS-SMB2 <159>, <162>.  This, test currently
     538     * verifies the Windows behavior, not the general spec behavior. */
     539    if (!TARGET_IS_WIN7(tctx) && !TARGET_IS_W2K8(tctx)) {
     540            torture_skip(tctx, "Interim test is specific to Windows server "
     541                               "behavior.\n");
     542    }
     543
     544    smb2_transport_credits_ask_num(tree->session->transport, 5);
     545
     546    smb2_deltree(tree, dname);
     547
     548    smb2_transport_credits_ask_num(tree->session->transport, 1);
     549
     550    ZERO_STRUCT(cr);
     551    cr.in.desired_access        = SEC_RIGHTS_FILE_ALL;
     552    cr.in.create_options        = NTCREATEX_OPTIONS_DIRECTORY;
     553    cr.in.file_attributes       = FILE_ATTRIBUTE_DIRECTORY;
     554    cr.in.share_access      = NTCREATEX_SHARE_ACCESS_READ |
     555                      NTCREATEX_SHARE_ACCESS_WRITE |
     556                      NTCREATEX_SHARE_ACCESS_DELETE;
     557    cr.in.create_disposition    = NTCREATEX_DISP_CREATE;
     558    cr.in.fname         = dname;
     559
     560    smb2_transport_compound_start(tree->session->transport, 3);
     561
     562    req[0] = smb2_create_send(tree, &cr);
     563
     564    smb2_transport_compound_set_related(tree->session->transport, true);
     565
     566    hd.data[0] = UINT64_MAX;
     567    hd.data[1] = UINT64_MAX;
     568
     569    ZERO_STRUCT(nt);
     570    nt.in.recursive          = true;
     571    nt.in.buffer_size        = 0x1000;
     572    nt.in.file.handle        = hd;
     573    nt.in.completion_filter  = FILE_NOTIFY_CHANGE_NAME;
     574    nt.in.unknown            = 0x00000000;
     575
     576    req[1] = smb2_notify_send(tree, &nt);
     577
     578    ZERO_STRUCT(gf);
     579    gf.in.file.handle = hd;
     580    gf.in.info_type   = SMB2_GETINFO_FILE;
     581    gf.in.info_class  = 0x04; // FILE_BASIC_INFORMATION
     582    gf.in.output_buffer_length = 0x1000;
     583    gf.in.input_buffer_length = 0;
     584
     585    req[2] = smb2_getinfo_send(tree, &gf);
     586
     587    status = smb2_create_recv(req[0], tree, &cr);
     588    CHECK_STATUS(status, NT_STATUS_OK);
     589
     590    status = smb2_notify_recv(req[1], tree, &nt);
     591    CHECK_STATUS(status, NT_STATUS_INTERNAL_ERROR);
     592
     593    status = smb2_getinfo_recv(req[2], tree, &gf);
     594    CHECK_STATUS(status, NT_STATUS_OK);
     595
     596    smb2_util_close(tree, cr.out.file.handle);
     597
     598    smb2_deltree(tree, dname);
     599done:
     600    return ret;
     601}
     602
    428603struct torture_suite *torture_smb2_compound_init(void)
    429604{
    430         struct torture_suite *suite =
    431             torture_suite_create(talloc_autofree_context(), "COMPOUND");
    432 
    433         torture_suite_add_1smb2_test(suite, "RELATED1", test_compound_related1);
    434         torture_suite_add_1smb2_test(suite, "RELATED2", test_compound_related2);
    435         torture_suite_add_1smb2_test(suite, "UNRELATED1", test_compound_unrelated1);
    436         torture_suite_add_1smb2_test(suite, "INVALID1", test_compound_invalid1);
    437         torture_suite_add_1smb2_test(suite, "INVALID2", test_compound_invalid2);
    438         torture_suite_add_1smb2_test(suite, "INVALID3", test_compound_invalid3);
     605        struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "compound");
     606
     607        torture_suite_add_1smb2_test(suite, "related1", test_compound_related1);
     608        torture_suite_add_1smb2_test(suite, "related2", test_compound_related2);
     609        torture_suite_add_1smb2_test(suite, "unrelated1", test_compound_unrelated1);
     610        torture_suite_add_1smb2_test(suite, "invalid1", test_compound_invalid1);
     611        torture_suite_add_1smb2_test(suite, "invalid2", test_compound_invalid2);
     612        torture_suite_add_1smb2_test(suite, "invalid3", test_compound_invalid3);
     613        torture_suite_add_1smb2_test(suite, "interim1",  test_compound_interim1);
     614        torture_suite_add_1smb2_test(suite, "interim2",  test_compound_interim2);
    439615
    440616        suite->description = talloc_strdup(suite, "SMB2-COMPOUND tests");
  • trunk/server/source4/torture/smb2/connect.c

    r414 r745  
    2121
    2222#include "includes.h"
    23 #include "librpc/gen_ndr/security.h"
    2423#include "libcli/smb2/smb2.h"
    2524#include "libcli/smb2/smb2_calls.h"
  • trunk/server/source4/torture/smb2/create.c

    r414 r745  
    2424#include "libcli/smb2/smb2_calls.h"
    2525#include "torture/torture.h"
     26#include "torture/util.h"
    2627#include "torture/smb2/proto.h"
    2728#include "librpc/gen_ndr/ndr_security.h"
    2829#include "libcli/security/security.h"
    2930
     31#include "system/filesys.h"
     32#include "auth/credentials/credentials.h"
     33#include "lib/cmdline/popt_common.h"
     34#include "librpc/gen_ndr/security.h"
     35#include "lib/events/events.h"
     36
    3037#define FNAME "test_create.dat"
     38#define DNAME "smb2_open"
    3139
    3240#define CHECK_STATUS(status, correct) do { \
    3341        if (!NT_STATUS_EQUAL(status, correct)) { \
    34                 printf("(%s) Incorrect status %s - should be %s\n", \
    35                        __location__, nt_errstr(status), nt_errstr(correct)); \
     42                torture_result(tctx, TORTURE_FAIL, \
     43                        "(%s) Incorrect status %s - should be %s\n", \
     44                         __location__, nt_errstr(status), nt_errstr(correct)); \
    3645                return false; \
    3746        }} while (0)
     
    3948#define CHECK_EQUAL(v, correct) do { \
    4049        if (v != correct) { \
    41                 printf("(%s) Incorrect value for %s 0x%08llx - should be 0x%08llx\n", \
    42                        __location__, #v, (unsigned long long)v, (unsigned long long)correct); \
     50                torture_result(tctx, TORTURE_FAIL, \
     51                        "(%s) Incorrect value for %s 0x%08llx - " \
     52                        "should be 0x%08llx\n", \
     53                         __location__, #v, \
     54                        (unsigned long long)v, \
     55                        (unsigned long long)correct); \
    4356                return false;                                   \
    4457        }} while (0)
    4558
    46 #define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false))
     59#define CHECK_TIME(t, field) do { \
     60        time_t t1, t2; \
     61        finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
     62        finfo.all_info.in.file.handle = h1; \
     63        status = smb2_getinfo_file(tree, tctx, &finfo); \
     64        CHECK_STATUS(status, NT_STATUS_OK); \
     65        t1 = t & ~1; \
     66        t2 = nt_time_to_unix(finfo.all_info.out.field) & ~1; \
     67        if (abs(t1-t2) > 2) { \
     68                torture_result(tctx, TORTURE_FAIL, \
     69                        "(%s) wrong time for field %s  %s - %s\n", \
     70                        __location__, #field, \
     71                        timestring(tctx, t1), \
     72                        timestring(tctx, t2)); \
     73                dump_all_info(tctx, &finfo); \
     74                ret = false; \
     75        }} while (0)
     76
     77#define CHECK_NTTIME(t, field) do { \
     78        NTTIME t2; \
     79        finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
     80        finfo.all_info.in.file.handle = h1; \
     81        status = smb2_getinfo_file(tree, tctx, &finfo); \
     82        CHECK_STATUS(status, NT_STATUS_OK); \
     83        t2 = finfo.all_info.out.field; \
     84        if (t != t2) { \
     85                torture_result(tctx, TORTURE_FAIL, \
     86                        "(%s) wrong time for field %s  %s - %s\n", \
     87                       __location__, #field, \
     88                       nt_time_string(tctx, t), \
     89                       nt_time_string(tctx, t2)); \
     90                dump_all_info(tctx, &finfo); \
     91                ret = false; \
     92        }} while (0)
     93
     94#define CHECK_ALL_INFO(v, field) do { \
     95        finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
     96        finfo.all_info.in.file.handle = h1; \
     97        status = smb2_getinfo_file(tree, tctx, &finfo); \
     98        CHECK_STATUS(status, NT_STATUS_OK); \
     99        if ((v) != (finfo.all_info.out.field)) { \
     100               torture_result(tctx, TORTURE_FAIL, \
     101                        "(%s) wrong value for field %s  0x%x - 0x%x\n", \
     102                        __location__, #field, (int)v,\
     103                        (int)(finfo.all_info.out.field)); \
     104                dump_all_info(tctx, &finfo); \
     105                ret = false; \
     106        }} while (0)
     107
     108#define CHECK_VAL(v, correct) do { \
     109        if ((v) != (correct)) { \
     110                torture_result(tctx, TORTURE_FAIL, \
     111                        "(%s) wrong value for %s  0x%x - should be 0x%x\n", \
     112                       __location__, #v, (int)(v), (int)correct); \
     113                ret = false; \
     114        }} while (0)
     115
     116#define SET_ATTRIB(sattrib) do { \
     117        union smb_setfileinfo sfinfo; \
     118        ZERO_STRUCT(sfinfo.basic_info.in); \
     119        sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION; \
     120        sfinfo.basic_info.in.file.handle = h1; \
     121        sfinfo.basic_info.in.attrib = sattrib; \
     122        status = smb2_setinfo_file(tree, &sfinfo); \
     123        if (!NT_STATUS_IS_OK(status)) { \
     124                torture_comment(tctx, \
     125                    "(%s) Failed to set attrib 0x%x on %s\n", \
     126                       __location__, sattrib, fname); \
     127        }} while (0)
    47128
    48129/*
    49130  test some interesting combinations found by gentest
    50131 */
    51 static bool test_create_gentest(struct torture_context *torture, struct smb2_tree *tree)
     132static bool test_create_gentest(struct torture_context *tctx, struct smb2_tree *tree)
    52133{
    53134        struct smb2_create io;
    54135        NTSTATUS status;
    55         TALLOC_CTX *tmp_ctx = talloc_new(tree);
    56136        uint32_t access_mask, file_attributes_set;
    57137        uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
     
    70150        io.in.fname = FNAME;
    71151
    72         status = smb2_create(tree, tmp_ctx, &io);
     152        status = smb2_create(tree, tctx, &io);
    73153        CHECK_STATUS(status, NT_STATUS_OK);
    74154
     
    77157
    78158        io.in.create_options = 0xF0000000;
    79         status = smb2_create(tree, tmp_ctx, &io);
     159        status = smb2_create(tree, tctx, &io);
    80160        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    81161
     
    83163
    84164        io.in.file_attributes = FILE_ATTRIBUTE_DEVICE;
    85         status = smb2_create(tree, tmp_ctx, &io);
     165        status = smb2_create(tree, tctx, &io);
    86166        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    87167
    88168        io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
    89         status = smb2_create(tree, tmp_ctx, &io);
     169        status = smb2_create(tree, tctx, &io);
    90170        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    91171
    92172        io.in.create_disposition = NTCREATEX_DISP_OPEN;
    93173        io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
    94         status = smb2_create(tree, tmp_ctx, &io);
     174        status = smb2_create(tree, tctx, &io);
    95175        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    96176       
    97177        io.in.create_disposition = NTCREATEX_DISP_CREATE;
    98178        io.in.desired_access = 0x08000000;
    99         status = smb2_create(tree, tmp_ctx, &io);
     179        status = smb2_create(tree, tctx, &io);
    100180        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    101181
    102182        io.in.desired_access = 0x04000000;
    103         status = smb2_create(tree, tmp_ctx, &io);
     183        status = smb2_create(tree, tctx, &io);
    104184        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    105185
     
    119199                                continue;
    120200                        }
    121                         status = smb2_create(tree, tmp_ctx, &io);
     201                        status = smb2_create(tree, tctx, &io);
    122202                        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
    123203                                not_supported_mask |= 1<<i;
     
    132212                        } else {
    133213                                unexpected_mask |= 1<<i;
    134                                 printf("create option 0x%08x returned %s\n", 1<<i, nt_errstr(status));
     214                                torture_comment(tctx,
     215                                    "create option 0x%08x returned %s\n",
     216                                    1<<i, nt_errstr(status));
    135217                        }
    136218                }
     
    151233                for (i=0;i<32;i++) {
    152234                        io.in.desired_access = 1<<i;
    153                         status = smb2_create(tree, tmp_ctx, &io);
     235                        status = smb2_create(tree, tctx, &io);
    154236                        if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
    155237                            NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
     
    163245        }
    164246
    165         if (TARGET_IS_WIN7(torture)) {
     247        if (TARGET_IS_WIN7(tctx)) {
    166248                CHECK_EQUAL(access_mask, 0x0de0fe00);
     249        } else if (torture_setting_bool(tctx, "samba4", false)) {
     250                CHECK_EQUAL(access_mask, 0x0cf0fe00);
    167251        } else {
    168252                CHECK_EQUAL(access_mask, 0x0df0fe00);
     
    184268                        }
    185269                        smb2_deltree(tree, FNAME);
    186                         status = smb2_create(tree, tmp_ctx, &io);
     270                        status = smb2_create(tree, tctx, &io);
    187271                        if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    188272                                invalid_parameter_mask |= 1<<i;
     
    199283                        } else {
    200284                                unexpected_mask |= 1<<i;
    201                                 printf("file attribute 0x%08x returned %s\n", 1<<i, nt_errstr(status));
     285                                torture_comment(tctx,
     286                                    "file attribute 0x%08x returned %s\n",
     287                                    1<<i, nt_errstr(status));
    202288                        }
    203289                }
     
    215301         */
    216302        io.in.file_attributes = FILE_ATTRIBUTE_ENCRYPTED;
    217         status = smb2_create(tree, tmp_ctx, &io);
     303        status = smb2_create(tree, tctx, &io);
    218304        if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    219                 printf("FILE_ATTRIBUTE_ENCRYPTED returned %s\n", nt_errstr(status));
     305                torture_comment(tctx,
     306                    "FILE_ATTRIBUTE_ENCRYPTED returned %s\n",
     307                    nt_errstr(status));
    220308        } else {
    221309                CHECK_STATUS(status, NT_STATUS_OK);
     
    236324        io.in.create_options = 0;
    237325        io.in.fname = FNAME ":stream1";
    238         status = smb2_create(tree, tmp_ctx, &io);
     326        status = smb2_create(tree, tctx, &io);
    239327        CHECK_STATUS(status, NT_STATUS_OK);
    240328
     
    246334        io.in.share_access =
    247335                NTCREATEX_SHARE_ACCESS_READ;
    248         status = smb2_create(tree, tmp_ctx, &io);
     336        status = smb2_create(tree, tctx, &io);
    249337        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    250338
     
    253341        io.in.desired_access  = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA;
    254342        io.in.query_maximal_access = true;
    255         status = smb2_create(tree, tmp_ctx, &io);
     343        status = smb2_create(tree, tctx, &io);
    256344        CHECK_STATUS(status, NT_STATUS_OK);
    257345        CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
     
    259347        q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
    260348        q.access_information.in.file.handle = io.out.file.handle;
    261         status = smb2_getinfo_file(tree, tmp_ctx, &q);
     349        status = smb2_getinfo_file(tree, tctx, &q);
    262350        CHECK_STATUS(status, NT_STATUS_OK);
    263351        CHECK_EQUAL(q.access_information.out.access_flags, io.in.desired_access);
     
    267355        io.in.query_maximal_access = false;
    268356        io.in.share_access = 0;
    269         status = smb2_create(tree, tmp_ctx, &io);
     357        status = smb2_create(tree, tctx, &io);
    270358        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    271359       
    272         talloc_free(tmp_ctx);
    273 
    274360        smb2_deltree(tree, FNAME);
    275        
     361
    276362        return true;
    277363}
     
    281367  try the various request blobs
    282368 */
    283 static bool test_create_blob(struct torture_context *torture, struct smb2_tree *tree)
     369static bool test_create_blob(struct torture_context *tctx, struct smb2_tree *tree)
    284370{
    285371        struct smb2_create io;
    286372        NTSTATUS status;
    287         TALLOC_CTX *tmp_ctx = talloc_new(tree);
    288373
    289374        smb2_deltree(tree, FNAME);
     
    303388        io.in.fname = FNAME;
    304389
    305         status = smb2_create(tree, tmp_ctx, &io);
     390        status = smb2_create(tree, tctx, &io);
    306391        CHECK_STATUS(status, NT_STATUS_OK);
    307392
     
    309394        CHECK_STATUS(status, NT_STATUS_OK);
    310395
    311         printf("testing alloc size\n");
     396        torture_comment(tctx, "Testing alloc size\n");
    312397        io.in.alloc_size = 4096;
    313         status = smb2_create(tree, tmp_ctx, &io);
     398        status = smb2_create(tree, tctx, &io);
    314399        CHECK_STATUS(status, NT_STATUS_OK);
    315400        CHECK_EQUAL(io.out.alloc_size, io.in.alloc_size);
     
    318403        CHECK_STATUS(status, NT_STATUS_OK);
    319404
    320         printf("testing durable open\n");
     405        torture_comment(tctx, "Testing durable open\n");
    321406        io.in.durable_open = true;
    322         status = smb2_create(tree, tmp_ctx, &io);
     407        status = smb2_create(tree, tctx, &io);
    323408        CHECK_STATUS(status, NT_STATUS_OK);
    324409
     
    326411        CHECK_STATUS(status, NT_STATUS_OK);
    327412
    328         printf("testing query maximal access\n");
     413        torture_comment(tctx, "Testing query maximal access\n");
    329414        io.in.query_maximal_access = true;
    330         status = smb2_create(tree, tmp_ctx, &io);
     415        status = smb2_create(tree, tctx, &io);
    331416        CHECK_STATUS(status, NT_STATUS_OK);
    332417        CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
     
    335420        CHECK_STATUS(status, NT_STATUS_OK);
    336421
    337         printf("testing timewarp\n");
     422        torture_comment(tctx, "Testing timewarp\n");
    338423        io.in.timewarp = 10000;
    339         status = smb2_create(tree, tmp_ctx, &io);
     424        status = smb2_create(tree, tctx, &io);
    340425        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    341426        io.in.timewarp = 0;
    342427
    343         printf("testing query_on_disk\n");
     428        torture_comment(tctx, "Testing query_on_disk\n");
    344429        io.in.query_on_disk_id = true;
    345         status = smb2_create(tree, tmp_ctx, &io);
     430        status = smb2_create(tree, tctx, &io);
    346431        CHECK_STATUS(status, NT_STATUS_OK);
    347432
     
    349434        CHECK_STATUS(status, NT_STATUS_OK);
    350435
    351         printf("testing unknown tag\n");
    352         status = smb2_create_blob_add(tmp_ctx, &io.in.blobs,
     436        torture_comment(tctx, "Testing unknown tag\n");
     437        status = smb2_create_blob_add(tctx, &io.in.blobs,
    353438                                      "FooO", data_blob(NULL, 0));
    354439        CHECK_STATUS(status, NT_STATUS_OK);
    355440
    356         status = smb2_create(tree, tmp_ctx, &io);
     441        status = smb2_create(tree, tctx, &io);
    357442        CHECK_STATUS(status, NT_STATUS_OK);
    358443
     
    360445        CHECK_STATUS(status, NT_STATUS_OK);
    361446
    362         printf("testing bad tag length\n");
    363         status = smb2_create_blob_add(tmp_ctx, &io.in.blobs,
     447        torture_comment(tctx, "Testing bad tag length\n");
     448        status = smb2_create_blob_add(tctx, &io.in.blobs,
    364449                                      "xxx", data_blob(NULL, 0));
    365450        CHECK_STATUS(status, NT_STATUS_OK);
    366451
    367         status = smb2_create(tree, tmp_ctx, &io);
     452        status = smb2_create(tree, tctx, &io);
    368453        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    369 
    370         talloc_free(tmp_ctx);
    371454
    372455        smb2_deltree(tree, FNAME);
     
    375458}
    376459
     460#define FAIL_UNLESS(__cond)                                     \
     461        do {                                                    \
     462                if (__cond) {} else {                           \
     463                        torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n",      \
     464                               __location__, #__cond);          \
     465                        ret = false; goto done;                 \
     466                }                                               \
     467        } while(0)
     468
    377469/*
    378470  try creating with acls
    379471 */
    380 static bool test_create_acl(struct torture_context *torture, struct smb2_tree *tree)
     472static bool test_create_acl_ext(struct torture_context *tctx, struct smb2_tree *tree, bool test_dir)
    381473{
     474        bool ret = true;
    382475        struct smb2_create io;
    383476        NTSTATUS status;
    384         TALLOC_CTX *tmp_ctx = talloc_new(tree);
    385477        struct security_ace ace;
    386         struct security_descriptor *sd, *sd2;
     478        struct security_descriptor *sd;
    387479        struct dom_sid *test_sid;
    388         union smb_fileinfo q;
     480        union smb_fileinfo q = {};
     481        uint32_t attrib =
     482            FILE_ATTRIBUTE_HIDDEN |
     483            FILE_ATTRIBUTE_SYSTEM |
     484            (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
     485        NTSTATUS (*delete_func)(struct smb2_tree *, const char *) =
     486            test_dir ? smb2_util_rmdir : smb2_util_unlink;
    389487
    390488        smb2_deltree(tree, FNAME);
     
    393491        io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    394492        io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
    395         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     493        io.in.create_disposition = NTCREATEX_DISP_CREATE;
    396494        io.in.share_access =
    397                 NTCREATEX_SHARE_ACCESS_DELETE|
    398                 NTCREATEX_SHARE_ACCESS_READ|
     495                NTCREATEX_SHARE_ACCESS_DELETE |
     496                NTCREATEX_SHARE_ACCESS_READ |
    399497                NTCREATEX_SHARE_ACCESS_WRITE;
    400         io.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
    401                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
    402                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
    403                                           0x00200000;
     498        io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT | 0x00200000 |
     499            (test_dir ?  NTCREATEX_OPTIONS_DIRECTORY :
     500                (NTCREATEX_OPTIONS_NON_DIRECTORY_FILE));
     501
    404502        io.in.fname = FNAME;
    405503
    406         status = smb2_create(tree, tmp_ctx, &io);
     504        torture_comment(tctx, "basic create\n");
     505
     506        status = smb2_create(tree, tctx, &io);
    407507        CHECK_STATUS(status, NT_STATUS_OK);
    408508
     
    413513                SECINFO_GROUP |
    414514                SECINFO_DACL;
    415         status = smb2_getinfo_file(tree, tmp_ctx, &q);
     515        status = smb2_getinfo_file(tree, tctx, &q);
    416516        CHECK_STATUS(status, NT_STATUS_OK);
    417517        sd = q.query_secdesc.out.sd;
     
    419519        status = smb2_util_close(tree, io.out.file.handle);
    420520        CHECK_STATUS(status, NT_STATUS_OK);
    421 
    422         smb2_util_unlink(tree, FNAME);
    423 
    424         printf("adding a new ACE\n");
    425         test_sid = dom_sid_parse_talloc(tmp_ctx, "S-1-5-32-1234-54321");
     521        status = delete_func(tree, FNAME);
     522        CHECK_STATUS(status, NT_STATUS_OK);
     523
     524        torture_comment(tctx, "adding a new ACE\n");
     525        test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
    426526
    427527        ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
     
    432532        status = security_descriptor_dacl_add(sd, &ace);
    433533        CHECK_STATUS(status, NT_STATUS_OK);
     534
     535        torture_comment(tctx, "creating a file with an initial ACL\n");
     536
     537        io.in.sec_desc = sd;
     538        status = smb2_create(tree, tctx, &io);
     539        CHECK_STATUS(status, NT_STATUS_OK);
     540
     541        FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
     542
     543        status = smb2_util_close(tree, io.out.file.handle);
     544        CHECK_STATUS(status, NT_STATUS_OK);
     545        status = delete_func(tree, FNAME);
     546        CHECK_STATUS(status, NT_STATUS_OK);
     547
     548        torture_comment(tctx, "creating with attributes\n");
     549
     550        io.in.sec_desc = NULL;
     551        io.in.file_attributes = attrib;
     552        status = smb2_create(tree, tctx, &io);
     553        CHECK_STATUS(status, NT_STATUS_OK);
     554
     555        FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
     556
     557        status = smb2_util_close(tree, io.out.file.handle);
     558        CHECK_STATUS(status, NT_STATUS_OK);
     559        status = delete_func(tree, FNAME);
     560        CHECK_STATUS(status, NT_STATUS_OK);
     561
     562        torture_comment(tctx, "creating with attributes and ACL\n");
     563
     564        io.in.sec_desc = sd;
     565        io.in.file_attributes = attrib;
     566        status = smb2_create(tree, tctx, &io);
     567        CHECK_STATUS(status, NT_STATUS_OK);
     568
     569        FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
     570        FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
    434571       
    435         printf("creating a file with an initial ACL\n");
     572        status = smb2_util_close(tree, io.out.file.handle);
     573        CHECK_STATUS(status, NT_STATUS_OK);
     574        status = delete_func(tree, FNAME);
     575        CHECK_STATUS(status, NT_STATUS_OK);
     576
     577        torture_comment(tctx, "creating with attributes, ACL and owner\n");
     578        sd = security_descriptor_dacl_create(tctx,
     579                                        0, SID_WORLD, SID_BUILTIN_USERS,
     580                                        SID_WORLD,
     581                                        SEC_ACE_TYPE_ACCESS_ALLOWED,
     582                                        SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
     583                                        0,
     584                                        NULL);
    436585
    437586        io.in.sec_desc = sd;
    438         status = smb2_create(tree, tmp_ctx, &io);
    439         CHECK_STATUS(status, NT_STATUS_OK);
    440 
    441         q.query_secdesc.in.file.handle = io.out.file.handle;
    442         status = smb2_getinfo_file(tree, tmp_ctx, &q);
    443         CHECK_STATUS(status, NT_STATUS_OK);
    444         sd2 = q.query_secdesc.out.sd;
    445 
    446         if (!security_acl_equal(sd->dacl, sd2->dacl)) {
    447                 printf("%s: security descriptors don't match!\n", __location__);
    448                 printf("got:\n");
    449                 NDR_PRINT_DEBUG(security_descriptor, sd2);
    450                 printf("expected:\n");
    451                 NDR_PRINT_DEBUG(security_descriptor, sd);
    452                 return false;
    453         }
    454 
    455         talloc_free(tmp_ctx);
    456        
    457         return true;
     587        io.in.file_attributes = attrib;
     588        status = smb2_create(tree, tctx, &io);
     589        CHECK_STATUS(status, NT_STATUS_OK);
     590
     591        FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
     592        FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
     593
     594 done:
     595        status = smb2_util_close(tree, io.out.file.handle);
     596        CHECK_STATUS(status, NT_STATUS_OK);
     597        status = delete_func(tree, FNAME);
     598        CHECK_STATUS(status, NT_STATUS_OK);
     599
     600        return ret;
    458601}
    459602
    460 /*
     603/*
     604  test SMB2 open
     605*/
     606static bool test_smb2_open(struct torture_context *tctx,
     607                           struct smb2_tree *tree)
     608{
     609        union smb_open io;
     610        union smb_fileinfo finfo;
     611        const char *fname = DNAME "\\torture_ntcreatex.txt";
     612        const char *dname = DNAME "\\torture_ntcreatex.dir";
     613        NTSTATUS status;
     614        struct smb2_handle h, h1;
     615        bool ret = true;
     616        int i;
     617        struct {
     618                uint32_t create_disp;
     619                bool with_file;
     620                NTSTATUS correct_status;
     621        } open_funcs[] = {
     622                { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
     623                { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
     624                { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
     625                { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     626                { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
     627                { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
     628                { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
     629                { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
     630                { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
     631                { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     632                { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
     633                { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
     634                { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
     635                { 6,                            false, NT_STATUS_INVALID_PARAMETER },
     636        };
     637
     638        torture_comment(tctx, "Checking SMB2 Open\n");
     639
     640        smb2_util_unlink(tree, fname);
     641        smb2_util_rmdir(tree, dname);
     642
     643        status = torture_smb2_testdir(tree, DNAME, &h);
     644        CHECK_STATUS(status, NT_STATUS_OK);
     645
     646        ZERO_STRUCT(io.smb2);
     647        /* reasonable default parameters */
     648        io.generic.level = RAW_OPEN_SMB2;
     649        io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     650        io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
     651        io.smb2.in.alloc_size = 1024*1024;
     652        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     653        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     654        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     655        io.smb2.in.create_options = 0;
     656        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     657        io.smb2.in.security_flags = 0;
     658        io.smb2.in.fname = fname;
     659
     660        /* test the create disposition */
     661        for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     662                if (open_funcs[i].with_file) {
     663                        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     664                        status= smb2_create(tree, tctx, &(io.smb2));
     665                        if (!NT_STATUS_IS_OK(status)) {
     666                                torture_comment(tctx,
     667                                    "Failed to create file %s status %s %d\n",
     668                                    fname, nt_errstr(status), i);
     669
     670                                ret = false;
     671                                goto done;
     672                        }
     673                        smb2_util_close(tree, io.smb2.out.file.handle);
     674                }
     675                io.smb2.in.create_disposition = open_funcs[i].create_disp;
     676                status = smb2_create(tree, tctx, &(io.smb2));
     677                if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
     678                        torture_comment(tctx,
     679                            "(%s) incorrect status %s should be %s (i=%d "
     680                            "with_file=%d open_disp=%d)\n",
     681                         __location__, nt_errstr(status),
     682                        nt_errstr(open_funcs[i].correct_status),
     683                        i, (int)open_funcs[i].with_file,
     684                        (int)open_funcs[i].create_disp);
     685
     686                        ret = false;
     687                        goto done;
     688                }
     689                if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
     690                        smb2_util_close(tree, io.smb2.out.file.handle);
     691                        smb2_util_unlink(tree, fname);
     692                }
     693        }
     694
     695        /* basic field testing */
     696        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     697
     698        status = smb2_create(tree, tctx, &(io.smb2));
     699        CHECK_STATUS(status, NT_STATUS_OK);
     700        h1 = io.smb2.out.file.handle;
     701
     702        CHECK_VAL(io.smb2.out.oplock_level, 0);
     703        CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
     704        CHECK_NTTIME(io.smb2.out.create_time, create_time);
     705        CHECK_NTTIME(io.smb2.out.access_time, access_time);
     706        CHECK_NTTIME(io.smb2.out.write_time, write_time);
     707        CHECK_NTTIME(io.smb2.out.change_time, change_time);
     708        CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
     709        CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
     710        CHECK_ALL_INFO(io.smb2.out.size, size);
     711
     712        /* check fields when the file already existed */
     713        smb2_util_close(tree, h1);
     714        smb2_util_unlink(tree, fname);
     715
     716        status = smb2_create_complex_file(tree, fname, &h1);
     717        CHECK_STATUS(status, NT_STATUS_OK);
     718
     719        smb2_util_close(tree, h1);
     720
     721        io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     722        status = smb2_create(tree, tctx, &(io.smb2));
     723        CHECK_STATUS(status, NT_STATUS_OK);
     724        h1 = io.smb2.out.file.handle;
     725
     726        CHECK_VAL(io.smb2.out.oplock_level, 0);
     727        CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_EXISTED);
     728        CHECK_NTTIME(io.smb2.out.create_time, create_time);
     729        CHECK_NTTIME(io.smb2.out.access_time, access_time);
     730        CHECK_NTTIME(io.smb2.out.write_time, write_time);
     731        CHECK_NTTIME(io.smb2.out.change_time, change_time);
     732        CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
     733        CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
     734        CHECK_ALL_INFO(io.smb2.out.size, size);
     735        smb2_util_close(tree, h1);
     736        smb2_util_unlink(tree, fname);
     737
     738        /* create a directory */
     739        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     740        io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
     741        io.smb2.in.alloc_size = 0;
     742        io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     743        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     744        io.smb2.in.create_options = 0;
     745        io.smb2.in.fname = dname;
     746        fname = dname;
     747
     748        smb2_util_rmdir(tree, fname);
     749        smb2_util_unlink(tree, fname);
     750
     751        io.smb2.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     752        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     753        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     754        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     755                                NTCREATEX_SHARE_ACCESS_WRITE;
     756        status = smb2_create(tree, tctx, &(io.smb2));
     757        CHECK_STATUS(status, NT_STATUS_OK);
     758        h1 = io.smb2.out.file.handle;
     759
     760        CHECK_VAL(io.smb2.out.oplock_level, 0);
     761        CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
     762        CHECK_NTTIME(io.smb2.out.create_time, create_time);
     763        CHECK_NTTIME(io.smb2.out.access_time, access_time);
     764        CHECK_NTTIME(io.smb2.out.write_time, write_time);
     765        CHECK_NTTIME(io.smb2.out.change_time, change_time);
     766        CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
     767        CHECK_VAL(io.smb2.out.file_attr & ~FILE_ATTRIBUTE_NONINDEXED,
     768                  FILE_ATTRIBUTE_DIRECTORY);
     769        CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
     770        CHECK_ALL_INFO(io.smb2.out.size, size);
     771        CHECK_VAL(io.smb2.out.size, 0);
     772        CHECK_VAL(io.smb2.out.alloc_size, 0);
     773        smb2_util_unlink(tree, fname);
     774
     775done:
     776        smb2_util_close(tree, h1);
     777        smb2_util_unlink(tree, fname);
     778        smb2_deltree(tree, DNAME);
     779        return ret;
     780}
     781
     782/*
     783  test with an already opened and byte range locked file
     784*/
     785
     786static bool test_smb2_open_brlocked(struct torture_context *tctx,
     787                                    struct smb2_tree *tree)
     788{
     789        union smb_open io, io1;
     790        union smb_lock io2;
     791        struct smb2_lock_element lock[1];
     792        const char *fname = DNAME "\\torture_ntcreatex.txt";
     793        NTSTATUS status;
     794        bool ret = true;
     795        struct smb2_handle h;
     796        char b = 42;
     797
     798        torture_comment(tctx,
     799                "Testing SMB2 open with a byte range locked file\n");
     800
     801        smb2_util_unlink(tree, fname);
     802
     803        status = torture_smb2_testdir(tree, DNAME, &h);
     804        CHECK_STATUS(status, NT_STATUS_OK);
     805
     806        ZERO_STRUCT(io.smb2);
     807        io.generic.level = RAW_OPEN_SMB2;
     808        io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     809        io.smb2.in.desired_access = 0x2019f;
     810        io.smb2.in.alloc_size = 0;
     811        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     812        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     813                NTCREATEX_SHARE_ACCESS_WRITE;
     814        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     815        io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     816        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
     817        io.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
     818        io.smb2.in.fname = fname;
     819
     820        status = smb2_create(tree, tctx, &(io.smb2));
     821        CHECK_STATUS(status, NT_STATUS_OK);
     822
     823        status = smb2_util_write(tree, io.smb2.out.file.handle, &b, 0, 1);
     824        CHECK_STATUS(status, NT_STATUS_OK);
     825
     826        ZERO_STRUCT(io2.smb2);
     827        io2.smb2.level = RAW_LOCK_SMB2;
     828        io2.smb2.in.file.handle = io.smb2.out.file.handle;
     829        io2.smb2.in.lock_count = 1;
     830
     831        ZERO_STRUCT(lock);
     832        lock[0].offset = 0;
     833        lock[0].length = 1;
     834        lock[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
     835                        SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     836        io2.smb2.in.locks = &lock[0];
     837        status = smb2_lock(tree, &(io2.smb2));
     838        CHECK_STATUS(status, NT_STATUS_OK);
     839
     840        ZERO_STRUCT(io1.smb2);
     841        io1.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     842        io1.smb2.in.desired_access = 0x20196;
     843        io1.smb2.in.alloc_size = 0;
     844        io1.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     845        io1.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     846                NTCREATEX_SHARE_ACCESS_WRITE;
     847        io1.smb2.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     848        io1.smb2.in.create_options = 0;
     849        io1.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
     850        io1.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
     851        io1.smb2.in.fname = fname;
     852
     853        status = smb2_create(tree, tctx, &(io1.smb2));
     854        CHECK_STATUS(status, NT_STATUS_OK);
     855
     856        smb2_util_close(tree, io.smb2.out.file.handle);
     857        smb2_util_close(tree, io1.smb2.out.file.handle);
     858        smb2_util_unlink(tree, fname);
     859        smb2_deltree(tree, DNAME);
     860
     861        return ret;
     862}
     863
     864/* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
     865
     866static bool test_smb2_open_multi(struct torture_context *tctx,
     867                                struct smb2_tree *tree)
     868{
     869        const char *fname = "test_oplock.dat";
     870        NTSTATUS status;
     871        bool ret = true;
     872        union smb_open io;
     873        struct smb2_tree **trees;
     874        struct smb2_request **requests;
     875        union smb_open *ios;
     876        int i, num_files = 3;
     877        int num_ok = 0;
     878        int num_collision = 0;
     879
     880        torture_comment(tctx,
     881                "Testing SMB2 Open with multiple connections\n");
     882        trees = talloc_array(tctx, struct smb2_tree *, num_files);
     883        requests = talloc_array(tctx, struct smb2_request *, num_files);
     884        ios = talloc_array(tctx, union smb_open, num_files);
     885        if ((tctx->ev == NULL) || (trees == NULL) || (requests == NULL) ||
     886            (ios == NULL)) {
     887                torture_comment(tctx, ("talloc failed\n"));
     888                ret = false;
     889                goto done;
     890        }
     891
     892        tree->session->transport->options.request_timeout = 60;
     893
     894        for (i=0; i<num_files; i++) {
     895                if (!torture_smb2_connection(tctx, &(trees[i]))) {
     896                        torture_comment(tctx,
     897                                "Could not open %d'th connection\n", i);
     898                        ret = false;
     899                        goto done;
     900                }
     901                trees[i]->session->transport->options.request_timeout = 60;
     902        }
     903
     904        /* cleanup */
     905        smb2_util_unlink(tree, fname);
     906
     907        /*
     908          base ntcreatex parms
     909        */
     910        ZERO_STRUCT(io.smb2);
     911        io.generic.level = RAW_OPEN_SMB2;
     912        io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
     913        io.smb2.in.alloc_size = 0;
     914        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     915        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
     916                NTCREATEX_SHARE_ACCESS_WRITE|
     917                NTCREATEX_SHARE_ACCESS_DELETE;
     918        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     919        io.smb2.in.create_options = 0;
     920        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     921        io.smb2.in.security_flags = 0;
     922        io.smb2.in.fname = fname;
     923        io.smb2.in.create_flags = 0;
     924
     925        for (i=0; i<num_files; i++) {
     926                ios[i] = io;
     927                requests[i] = smb2_create_send(trees[i], &(ios[i].smb2));
     928                if (requests[i] == NULL) {
     929                        torture_comment(tctx,
     930                                "could not send %d'th request\n", i);
     931                        ret = false;
     932                        goto done;
     933                }
     934        }
     935
     936        torture_comment(tctx, "waiting for replies\n");
     937        while (1) {
     938                bool unreplied = false;
     939                for (i=0; i<num_files; i++) {
     940                        if (requests[i] == NULL) {
     941                                continue;
     942                        }
     943                        if (requests[i]->state < SMB2_REQUEST_DONE) {
     944                                unreplied = true;
     945                                break;
     946                        }
     947                        status = smb2_create_recv(requests[i], tctx,
     948                                                  &(ios[i].smb2));
     949
     950                        torture_comment(tctx,
     951                                "File %d returned status %s\n", i,
     952                                nt_errstr(status));
     953
     954                        if (NT_STATUS_IS_OK(status)) {
     955                                num_ok += 1;
     956                        }
     957
     958                        if (NT_STATUS_EQUAL(status,
     959                                            NT_STATUS_OBJECT_NAME_COLLISION)) {
     960                                num_collision += 1;
     961                        }
     962
     963                        requests[i] = NULL;
     964                }
     965                if (!unreplied) {
     966                        break;
     967                }
     968
     969                if (event_loop_once(tctx->ev) != 0) {
     970                        torture_comment(tctx, "event_loop_once failed\n");
     971                        ret = false;
     972                        goto done;
     973                }
     974        }
     975
     976        if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
     977                ret = false;
     978        }
     979done:
     980        smb2_deltree(tree, fname);
     981
     982        return ret;
     983}
     984
     985/*
     986  test opening for delete on a read-only attribute file.
     987*/
     988
     989static bool test_smb2_open_for_delete(struct torture_context *tctx,
     990                                      struct smb2_tree *tree)
     991{
     992        union smb_open io;
     993        union smb_fileinfo finfo;
     994        const char *fname = DNAME "\\torture_open_for_delete.txt";
     995        NTSTATUS status;
     996        struct smb2_handle h, h1;
     997        bool ret = true;
     998
     999        torture_comment(tctx,
     1000                "Checking SMB2_OPEN for delete on a readonly file.\n");
     1001        smb2_util_unlink(tree, fname);
     1002        smb2_deltree(tree, fname);
     1003
     1004        status = torture_smb2_testdir(tree, DNAME, &h);
     1005        CHECK_STATUS(status, NT_STATUS_OK);
     1006
     1007        /* reasonable default parameters */
     1008        ZERO_STRUCT(io.smb2);
     1009        io.generic.level = RAW_OPEN_SMB2;
     1010        io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     1011        io.smb2.in.alloc_size = 0;
     1012        io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
     1013        io.smb2.in.file_attributes = FILE_ATTRIBUTE_READONLY;
     1014        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     1015        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     1016        io.smb2.in.create_options = 0;
     1017        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     1018        io.smb2.in.security_flags = 0;
     1019        io.smb2.in.fname = fname;
     1020
     1021        /* Create the readonly file. */
     1022
     1023        status = smb2_create(tree, tctx, &(io.smb2));
     1024        CHECK_STATUS(status, NT_STATUS_OK);
     1025        h1 = io.smb2.out.file.handle;
     1026
     1027        CHECK_VAL(io.smb2.out.oplock_level, 0);
     1028        io.smb2.in.create_options = 0;
     1029        CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
     1030        CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
     1031        smb2_util_close(tree, h1);
     1032
     1033        /* Now try and open for delete only - should succeed. */
     1034        io.smb2.in.desired_access = SEC_STD_DELETE;
     1035        io.smb2.in.file_attributes = 0;
     1036        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1037                                NTCREATEX_SHARE_ACCESS_WRITE |
     1038                                NTCREATEX_SHARE_ACCESS_DELETE;
     1039        io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     1040        status = smb2_create(tree, tctx, &(io.smb2));
     1041        CHECK_STATUS(status, NT_STATUS_OK);
     1042
     1043        smb2_util_unlink(tree, fname);
     1044
     1045        smb2_util_close(tree, h1);
     1046        smb2_util_unlink(tree, fname);
     1047        smb2_deltree(tree, DNAME);
     1048
     1049        return ret;
     1050}
     1051
     1052/*
     1053  test SMB2 open with a leading slash on the path.
     1054  Trying to create a directory with a leading slash
     1055  should give NT_STATUS_INVALID_PARAMETER error
     1056*/
     1057static bool test_smb2_leading_slash(struct torture_context *tctx,
     1058                                    struct smb2_tree *tree)
     1059{
     1060        union smb_open io;
     1061        const char *dnameslash = "\\"DNAME;
     1062        NTSTATUS status;
     1063        bool ret = true;
     1064
     1065        torture_comment(tctx,
     1066                "Trying to create a directory with leading slash on path\n");
     1067        smb2_deltree(tree, dnameslash);
     1068
     1069        ZERO_STRUCT(io.smb2);
     1070        io.generic.level = RAW_OPEN_SMB2;
     1071        io.smb2.in.oplock_level = 0;
     1072        io.smb2.in.desired_access = SEC_RIGHTS_DIR_ALL;
     1073        io.smb2.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
     1074        io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     1075        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1076                                NTCREATEX_SHARE_ACCESS_WRITE |
     1077                                NTCREATEX_SHARE_ACCESS_DELETE;
     1078        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     1079        io.smb2.in.fname = dnameslash;
     1080
     1081        status = smb2_create(tree, tree, &(io.smb2));
     1082        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     1083
     1084        smb2_deltree(tree, dnameslash);
     1085        return ret;
     1086}
     1087
     1088
     1089static bool test_create_acl_file(struct torture_context *tctx,
     1090    struct smb2_tree *tree)
     1091{
     1092        torture_comment(tctx, "Testing nttrans create with sec_desc on files\n");
     1093
     1094        return test_create_acl_ext(tctx, tree, false);
     1095}
     1096
     1097static bool test_create_acl_dir(struct torture_context *tctx,
     1098    struct smb2_tree *tree)
     1099{
     1100        torture_comment(tctx, "Testing nttrans create with sec_desc on directories\n");
     1101
     1102        return test_create_acl_ext(tctx, tree, true);
     1103}
     1104
     1105#define CHECK_ACCESS_FLAGS(_fh, flags) do { \
     1106        union smb_fileinfo _q; \
     1107        _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
     1108        _q.access_information.in.file.handle = (_fh); \
     1109        status = smb2_getinfo_file(tree, tctx, &_q); \
     1110        CHECK_STATUS(status, NT_STATUS_OK); \
     1111        if (_q.access_information.out.access_flags != (flags)) { \
     1112                torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
     1113                       __location__, _q.access_information.out.access_flags, (flags)); \
     1114                ret = false; \
     1115                goto done; \
     1116        } \
     1117} while (0)
     1118
     1119/*
     1120 * Test creating a file with a NULL DACL.
     1121 */
     1122static bool test_create_null_dacl(struct torture_context *tctx,
     1123    struct smb2_tree *tree)
     1124{
     1125        NTSTATUS status;
     1126        struct smb2_create io;
     1127        const char *fname = "nulldacl.txt";
     1128        bool ret = true;
     1129        struct smb2_handle handle;
     1130        union smb_fileinfo q;
     1131        union smb_setfileinfo s;
     1132        struct security_descriptor *sd = security_descriptor_initialise(tctx);
     1133        struct security_acl dacl;
     1134
     1135        torture_comment(tctx, "TESTING SEC_DESC WITH A NULL DACL\n");
     1136
     1137        smb2_util_unlink(tree, fname);
     1138
     1139        ZERO_STRUCT(io);
     1140        io.level = RAW_OPEN_SMB2;
     1141        io.in.create_flags = 0;
     1142        io.in.desired_access = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
     1143                | SEC_STD_WRITE_OWNER;
     1144        io.in.create_options = 0;
     1145        io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     1146        io.in.share_access =
     1147                NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
     1148        io.in.alloc_size = 0;
     1149        io.in.create_disposition = NTCREATEX_DISP_CREATE;
     1150        io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     1151        io.in.security_flags = 0;
     1152        io.in.fname = fname;
     1153        io.in.sec_desc = sd;
     1154        /* XXX create_options ? */
     1155        io.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
     1156                                          NTCREATEX_OPTIONS_ASYNC_ALERT |
     1157                                          NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
     1158                                          0x00200000;
     1159
     1160        torture_comment(tctx, "creating a file with a empty sd\n");
     1161        status = smb2_create(tree, tctx, &io);
     1162        CHECK_STATUS(status, NT_STATUS_OK);
     1163        handle = io.out.file.handle;
     1164
     1165        torture_comment(tctx, "get the original sd\n");
     1166        q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     1167        q.query_secdesc.in.file.handle = handle;
     1168        q.query_secdesc.in.secinfo_flags =
     1169                SECINFO_OWNER |
     1170                SECINFO_GROUP |
     1171                SECINFO_DACL;
     1172        status = smb2_getinfo_file(tree, tctx, &q);
     1173        CHECK_STATUS(status, NT_STATUS_OK);
     1174
     1175        /*
     1176         * Testing the created DACL,
     1177         * the server should add the inherited DACL
     1178         * when SEC_DESC_DACL_PRESENT isn't specified
     1179         */
     1180        if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
     1181                ret = false;
     1182                torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
     1183        }
     1184        if (q.query_secdesc.out.sd->dacl == NULL) {
     1185                ret = false;
     1186                torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
     1187        }
     1188
     1189        torture_comment(tctx, "set NULL DACL\n");
     1190        sd->type |= SEC_DESC_DACL_PRESENT;
     1191
     1192        s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     1193        s.set_secdesc.in.file.handle = handle;
     1194        s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     1195        s.set_secdesc.in.sd = sd;
     1196        status = smb2_setinfo_file(tree, &s);
     1197        CHECK_STATUS(status, NT_STATUS_OK);
     1198
     1199        torture_comment(tctx, "get the sd\n");
     1200        q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     1201        q.query_secdesc.in.file.handle = handle;
     1202        q.query_secdesc.in.secinfo_flags =
     1203                SECINFO_OWNER |
     1204                SECINFO_GROUP |
     1205                SECINFO_DACL;
     1206        status = smb2_getinfo_file(tree, tctx, &q);
     1207        CHECK_STATUS(status, NT_STATUS_OK);
     1208
     1209        /* Testing the modified DACL */
     1210        if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
     1211                ret = false;
     1212                torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
     1213        }
     1214        if (q.query_secdesc.out.sd->dacl != NULL) {
     1215                ret = false;
     1216                torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
     1217        }
     1218
     1219        io.in.create_disposition = NTCREATEX_DISP_OPEN;
     1220
     1221        torture_comment(tctx, "try open for read control\n");
     1222        io.in.desired_access = SEC_STD_READ_CONTROL;
     1223        status = smb2_create(tree, tctx, &io);
     1224        CHECK_STATUS(status, NT_STATUS_OK);
     1225        CHECK_ACCESS_FLAGS(io.out.file.handle,
     1226                SEC_STD_READ_CONTROL);
     1227        smb2_util_close(tree, io.out.file.handle);
     1228
     1229        torture_comment(tctx, "try open for write\n");
     1230        io.in.desired_access = SEC_FILE_WRITE_DATA;
     1231        status = smb2_create(tree, tctx, &io);
     1232        CHECK_STATUS(status, NT_STATUS_OK);
     1233        CHECK_ACCESS_FLAGS(io.out.file.handle,
     1234                SEC_FILE_WRITE_DATA);
     1235        smb2_util_close(tree, io.out.file.handle);
     1236
     1237        torture_comment(tctx, "try open for read\n");
     1238        io.in.desired_access = SEC_FILE_READ_DATA;
     1239        status = smb2_create(tree, tctx, &io);
     1240        CHECK_STATUS(status, NT_STATUS_OK);
     1241        CHECK_ACCESS_FLAGS(io.out.file.handle,
     1242                SEC_FILE_READ_DATA);
     1243        smb2_util_close(tree, io.out.file.handle);
     1244
     1245        torture_comment(tctx, "try open for generic write\n");
     1246        io.in.desired_access = SEC_GENERIC_WRITE;
     1247        status = smb2_create(tree, tctx, &io);
     1248        CHECK_STATUS(status, NT_STATUS_OK);
     1249        CHECK_ACCESS_FLAGS(io.out.file.handle,
     1250                SEC_RIGHTS_FILE_WRITE);
     1251        smb2_util_close(tree, io.out.file.handle);
     1252
     1253        torture_comment(tctx, "try open for generic read\n");
     1254        io.in.desired_access = SEC_GENERIC_READ;
     1255        status = smb2_create(tree, tctx, &io);
     1256        CHECK_STATUS(status, NT_STATUS_OK);
     1257        CHECK_ACCESS_FLAGS(io.out.file.handle,
     1258                SEC_RIGHTS_FILE_READ);
     1259        smb2_util_close(tree, io.out.file.handle);
     1260
     1261        torture_comment(tctx, "set DACL with 0 aces\n");
     1262        ZERO_STRUCT(dacl);
     1263        dacl.revision = SECURITY_ACL_REVISION_NT4;
     1264        dacl.num_aces = 0;
     1265        sd->dacl = &dacl;
     1266
     1267        s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     1268        s.set_secdesc.in.file.handle = handle;
     1269        s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     1270        s.set_secdesc.in.sd = sd;
     1271        status = smb2_setinfo_file(tree, &s);
     1272        CHECK_STATUS(status, NT_STATUS_OK);
     1273
     1274        torture_comment(tctx, "get the sd\n");
     1275        q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     1276        q.query_secdesc.in.file.handle = handle;
     1277        q.query_secdesc.in.secinfo_flags =
     1278                SECINFO_OWNER |
     1279                SECINFO_GROUP |
     1280                SECINFO_DACL;
     1281        status = smb2_getinfo_file(tree, tctx, &q);
     1282        CHECK_STATUS(status, NT_STATUS_OK);
     1283
     1284        /* Testing the modified DACL */
     1285        if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
     1286                ret = false;
     1287                torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
     1288        }
     1289        if (q.query_secdesc.out.sd->dacl == NULL) {
     1290                ret = false;
     1291                torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
     1292        }
     1293        if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
     1294                torture_result(tctx, TORTURE_FAIL, "DACL has %u aces!\n",
     1295                       q.query_secdesc.out.sd->dacl->num_aces);
     1296                ret = false;
     1297                goto done;
     1298        }
     1299
     1300        torture_comment(tctx, "try open for read control\n");
     1301        io.in.desired_access = SEC_STD_READ_CONTROL;
     1302        status = smb2_create(tree, tctx, &io);
     1303        CHECK_STATUS(status, NT_STATUS_OK);
     1304        CHECK_ACCESS_FLAGS(io.out.file.handle,
     1305                SEC_STD_READ_CONTROL);
     1306        smb2_util_close(tree, io.out.file.handle);
     1307
     1308        torture_comment(tctx, "try open for write => access_denied\n");
     1309        io.in.desired_access = SEC_FILE_WRITE_DATA;
     1310        status = smb2_create(tree, tctx, &io);
     1311        if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
     1312                CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     1313        } else {
     1314                CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     1315        }
     1316
     1317        torture_comment(tctx, "try open for read => access_denied\n");
     1318        io.in.desired_access = SEC_FILE_READ_DATA;
     1319        status = smb2_create(tree, tctx, &io);
     1320        if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
     1321                CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     1322        } else {
     1323                CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     1324        }
     1325
     1326        torture_comment(tctx, "try open for generic write => access_denied\n");
     1327        io.in.desired_access = SEC_GENERIC_WRITE;
     1328        status = smb2_create(tree, tctx, &io);
     1329        if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
     1330                CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     1331        } else {
     1332                CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     1333        }
     1334
     1335        torture_comment(tctx, "try open for generic read => access_denied\n");
     1336        io.in.desired_access = SEC_GENERIC_READ;
     1337        status = smb2_create(tree, tctx, &io);
     1338        if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
     1339                CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     1340        } else {
     1341                CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     1342        }
     1343
     1344        torture_comment(tctx, "set empty sd\n");
     1345        sd->type &= ~SEC_DESC_DACL_PRESENT;
     1346        sd->dacl = NULL;
     1347
     1348        s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     1349        s.set_secdesc.in.file.handle = handle;
     1350        s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     1351        s.set_secdesc.in.sd = sd;
     1352        status = smb2_setinfo_file(tree, &s);
     1353        CHECK_STATUS(status, NT_STATUS_OK);
     1354
     1355        torture_comment(tctx, "get the sd\n");
     1356        q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     1357        q.query_secdesc.in.file.handle = handle;
     1358        q.query_secdesc.in.secinfo_flags =
     1359                SECINFO_OWNER |
     1360                SECINFO_GROUP |
     1361                SECINFO_DACL;
     1362        status = smb2_getinfo_file(tree, tctx, &q);
     1363        CHECK_STATUS(status, NT_STATUS_OK);
     1364
     1365        /* Testing the modified DACL */
     1366        if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
     1367                ret = false;
     1368                torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
     1369        }
     1370        if (q.query_secdesc.out.sd->dacl != NULL) {
     1371                ret = false;
     1372                torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
     1373        }
     1374done:
     1375        smb2_util_close(tree, handle);
     1376        smb2_util_unlink(tree, fname);
     1377        smb2_tdis(tree);
     1378        smb2_logoff(tree->session);
     1379        return ret;
     1380}
     1381
     1382/*
    4611383   basic testing of SMB2 read
    4621384*/
    4631385struct torture_suite *torture_smb2_create_init(void)
    4641386{
    465         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "CREATE");
    466 
    467         torture_suite_add_1smb2_test(suite, "GENTEST", test_create_gentest);
    468         torture_suite_add_1smb2_test(suite, "BLOB", test_create_blob);
    469         torture_suite_add_1smb2_test(suite, "ACL", test_create_acl);
     1387        struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "create");
     1388
     1389        torture_suite_add_1smb2_test(suite, "gentest", test_create_gentest);
     1390        torture_suite_add_1smb2_test(suite, "blob", test_create_blob);
     1391        torture_suite_add_1smb2_test(suite, "open", test_smb2_open);
     1392        torture_suite_add_1smb2_test(suite, "brlocked", test_smb2_open_brlocked);
     1393        torture_suite_add_1smb2_test(suite, "multi", test_smb2_open_multi);
     1394        torture_suite_add_1smb2_test(suite, "delete", test_smb2_open_for_delete);
     1395        torture_suite_add_1smb2_test(suite, "leading-slash", test_smb2_leading_slash);
     1396        torture_suite_add_1smb2_test(suite, "aclfile", test_create_acl_file);
     1397        torture_suite_add_1smb2_test(suite, "acldir", test_create_acl_dir);
     1398        torture_suite_add_1smb2_test(suite, "nulldacl", test_create_null_dacl);
    4701399
    4711400        suite->description = talloc_strdup(suite, "SMB2-CREATE tests");
  • trunk/server/source4/torture/smb2/dir.c

    r414 r745  
    3535
    3636#include "system/filesys.h"
     37#include "lib/util/tsort.h"
    3738
    3839#define DNAME   "smb2_dir"
     
    109110        NTSTATUS status;
    110111        bool ret = true;
    111         uint_t count;
     112        unsigned int count;
    112113        int i, j, file_count = 0;
    113114
     
    194195        NTSTATUS status;
    195196        bool ret = true;
    196         uint_t count;
     197        unsigned int count;
    197198        int i;
    198199
     
    267268
    268269                        torture_result(tctx, TORTURE_FAIL,
    269                             "(%s): didn't expect %s\n",
    270                             __location__, found);
     270                                       "(%s): didn't expect %s (count=%u)\n",
     271                                       __location__, found, count);
    271272                        ret = false;
    272273                        goto done;
     
    361362                            union smb_search_data *data,
    362363                            union smb_search_data *d,
    363                             uint_t count,
     364                            unsigned int count,
    364365                            uint8_t level,
    365366                            enum smb_search_data_level data_level)
     
    386387                                    int idx,
    387388                                    union smb_search_data *d,
    388                                     uint_t *count,
     389                                    unsigned int *count,
    389390                                    struct smb2_handle *h)
    390391{
     
    417418        NTSTATUS status;
    418419        int i;
    419         uint_t count;
     420        unsigned int count;
    420421        union smb_fileinfo all_info2, alt_info, internal_info;
    421422        union smb_search_data *s;
     
    432433        /* call all the File Information Classes */
    433434        for (i=0;i<ARRAY_SIZE(levels);i++) {
    434                 torture_comment(tctx, "testing %s %d\n", levels[i].name,
     435                torture_comment(tctx, "Testing %s %d\n", levels[i].name,
    435436                                levels[i].level);
    436437
     
    672673        struct smb2_find f;
    673674        bool ret = true;
    674         uint_t count = 0;
     675        unsigned int count = 0;
    675676        union smb_search_data *d;
    676677        NTSTATUS status;
     
    809810                level_sort = search_types[t].level;
    810811
    811                 qsort(result.list, result.count, sizeof(result.list[0]),
    812                       QSORT_CAST  search_compare);
     812                TYPESAFE_QSORT(result.list, result.count, search_compare);
    813813
    814814                for (i=0;i<result.count;i++) {
     
    896896        bool ret = true;
    897897        int i;
    898         uint_t count;
     898        unsigned int count;
    899899
    900900        smb2_deltree(tree, DNAME);
     
    11061106        struct smb2_handle h;
    11071107        union smb_search_data *d;
    1108         int count;
     1108        unsigned count;
    11091109
    11101110        smb2_deltree(tree, DNAME);
     
    12241224        struct smb2_handle h;
    12251225        union smb_search_data *d;
    1226         int count, file_count = 0;
     1226        int i, j, file_count = 0;
    12271227        char **strs = NULL;
    1228         int i, j;
     1228        unsigned count;
    12291229
    12301230        torture_comment(tctx,
     
    13311331{
    13321332        struct torture_suite *suite =
    1333             torture_suite_create(talloc_autofree_context(), "DIR");
    1334 
    1335         torture_suite_add_1smb2_test(suite, "FIND", test_find);
    1336         torture_suite_add_1smb2_test(suite, "FIXED", test_fixed);
    1337         torture_suite_add_1smb2_test(suite, "ONE", test_one_file);
    1338         torture_suite_add_1smb2_test(suite, "MANY", test_many_files);
    1339         torture_suite_add_1smb2_test(suite, "MODIFY", test_modify_search);
    1340         torture_suite_add_1smb2_test(suite, "SORTED", test_sorted);
    1341         torture_suite_add_1smb2_test(suite, "FILE-INDEX", test_file_index);
    1342         torture_suite_add_1smb2_test(suite, "LARGE-FILES", test_large_files);
     1333            torture_suite_create(talloc_autofree_context(), "dir");
     1334
     1335        torture_suite_add_1smb2_test(suite, "find", test_find);
     1336        torture_suite_add_1smb2_test(suite, "fixed", test_fixed);
     1337        torture_suite_add_1smb2_test(suite, "one", test_one_file);
     1338        torture_suite_add_1smb2_test(suite, "many", test_many_files);
     1339        torture_suite_add_1smb2_test(suite, "modify", test_modify_search);
     1340        torture_suite_add_1smb2_test(suite, "sorted", test_sorted);
     1341        torture_suite_add_1smb2_test(suite, "file-index", test_file_index);
     1342        torture_suite_add_1smb2_test(suite, "large-files", test_large_files);
    13431343        suite->description = talloc_strdup(suite, "SMB2-DIR tests");
    13441344
  • trunk/server/source4/torture/smb2/durable_open.c

    r414 r745  
    2121
    2222#include "includes.h"
    23 #include "librpc/gen_ndr/security.h"
    2423#include "libcli/smb2/smb2.h"
    2524#include "libcli/smb2/smb2_calls.h"
     
    435434        lck.in.locks            = el;
    436435        lck.in.lock_count       = 0x0001;
    437         lck.in.reserved         = 0x00000000;
     436        lck.in.lock_sequence    = 0x00000000;
    438437        lck.in.file.handle      = h;
    439438        el[0].offset            = 0;
     
    588587{
    589588        struct torture_suite *suite =
    590             torture_suite_create(talloc_autofree_context(), "DURABLE-OPEN");
    591 
    592         torture_suite_add_2smb2_test(suite, "FILE-POSITION",
     589            torture_suite_create(talloc_autofree_context(), "durable-open");
     590
     591        torture_suite_add_2smb2_test(suite, "file-position",
    593592            test_durable_open_file_position);
    594         torture_suite_add_2smb2_test(suite, "OPLOCK", test_durable_open_oplock);
    595         torture_suite_add_2smb2_test(suite, "LEASE", test_durable_open_lease);
    596         torture_suite_add_1smb2_test(suite, "LOCK", test_durable_open_lock);
    597         torture_suite_add_2smb2_test(suite, "OPEN", test_durable_open_open);
     593        torture_suite_add_2smb2_test(suite, "oplock", test_durable_open_oplock);
     594        torture_suite_add_2smb2_test(suite, "lease", test_durable_open_lease);
     595        torture_suite_add_1smb2_test(suite, "lock", test_durable_open_lock);
     596        torture_suite_add_2smb2_test(suite, "open", test_durable_open_open);
    598597
    599598        suite->description = talloc_strdup(suite, "SMB2-DURABLE-OPEN tests");
  • trunk/server/source4/torture/smb2/lease.c

    r414 r745  
    2121
    2222#include "includes.h"
    23 #include "lib/events/events.h"
    24 #include "librpc/gen_ndr/security.h"
    2523#include "libcli/smb2/smb2.h"
    2624#include "libcli/smb2/smb2_calls.h"
     
    806804
    807805        /* Sleep, use a write to clear the recv queue. */
    808         msleep(250);
     806        smb_msleep(250);
    809807        ZERO_STRUCT(w);
    810808        w.in.file.handle = h3;
     
    835833{
    836834        struct torture_suite *suite =
    837             torture_suite_create(talloc_autofree_context(), "LEASE");
    838 
    839         torture_suite_add_1smb2_test(suite, "REQUEST", test_lease_request);
    840         torture_suite_add_1smb2_test(suite, "UPGRADE", test_lease_upgrade);
    841         torture_suite_add_1smb2_test(suite, "BREAK", test_lease_break);
    842         torture_suite_add_1smb2_test(suite, "OPLOCK", test_lease_oplock);
    843         torture_suite_add_1smb2_test(suite, "MULTIBREAK", test_lease_multibreak);
     835            torture_suite_create(talloc_autofree_context(), "lease");
     836
     837        torture_suite_add_1smb2_test(suite, "request", test_lease_request);
     838        torture_suite_add_1smb2_test(suite, "upgrade", test_lease_upgrade);
     839        torture_suite_add_1smb2_test(suite, "break", test_lease_break);
     840        torture_suite_add_1smb2_test(suite, "oplock", test_lease_oplock);
     841        torture_suite_add_1smb2_test(suite, "multibreak", test_lease_multibreak);
    844842
    845843        suite->description = talloc_strdup(suite, "SMB2-LEASE tests");
  • trunk/server/source4/torture/smb2/lock.c

    r414 r745  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33
     
    55
    66   Copyright (C) Stefan Metzmacher 2006
    7    
     7
    88   This program is free software; you can redistribute it and/or modify
    99   it under the terms of the GNU General Public License as published by
    1010   the Free Software Foundation; either version 3 of the License, or
    1111   (at your option) any later version.
    12    
     12
    1313   This program is distributed in the hope that it will be useful,
    1414   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616   GNU General Public License for more details.
    17    
     17
    1818   You should have received a copy of the GNU General Public License
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2626#include "torture/torture.h"
    2727#include "torture/smb2/proto.h"
    28 
    29 #include "librpc/gen_ndr/ndr_security.h"
    30 
    31 #define TARGET_IS_WINDOWS(_tctx) (torture_setting_bool(_tctx, "win7", false) || torture_setting_bool(torture, "windows", false))
    32 #define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false))
     28#include "torture/util.h"
     29
     30#include "lib/events/events.h"
     31#include "param/param.h"
    3332
    3433#define CHECK_STATUS(status, correct) do { \
     34        const char *_cmt = "(" __location__ ")"; \
     35        torture_assert_ntstatus_equal_goto(torture,status,correct, \
     36                                           ret,done,_cmt); \
     37        } while (0)
     38
     39#define CHECK_STATUS_CMT(status, correct, cmt) do { \
     40        torture_assert_ntstatus_equal_goto(torture,status,correct, \
     41                                           ret,done,cmt); \
     42        } while (0)
     43
     44#define CHECK_STATUS_CONT(status, correct) do { \
    3545        if (!NT_STATUS_EQUAL(status, correct)) { \
    36                 printf("(%s) Incorrect status %s - should be %s\n", \
    37                        __location__, nt_errstr(status), nt_errstr(correct)); \
     46                torture_result(torture, TORTURE_FAIL, \
     47                        "(%s) Incorrect status %s - should be %s\n", \
     48                        __location__, nt_errstr(status), nt_errstr(correct)); \
    3849                ret = false; \
    39                 goto done; \
    4050        }} while (0)
    4151
    4252#define CHECK_VALUE(v, correct) do { \
    43         if ((v) != (correct)) { \
    44                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
    45                        __location__, #v, v, correct); \
    46                 ret = false; \
    47                 goto done; \
    48         }} while (0)
    49 
    50 static bool test_valid_request(struct torture_context *torture, struct smb2_tree *tree)
     53        const char *_cmt = "(" __location__ ")"; \
     54        torture_assert_int_equal_goto(torture,v,correct,ret,done,_cmt); \
     55        } while (0)
     56
     57#define BASEDIR "testlock"
     58
     59#define TARGET_SUPPORTS_INVALID_LOCK_RANGE(_tctx) \
     60    (torture_setting_bool(_tctx, "invalid_lock_range_support", true))
     61#define TARGET_IS_W2K8(_tctx) (torture_setting_bool(_tctx, "w2k8", false))
     62
     63#define WAIT_FOR_ASYNC_RESPONSE(req) \
     64        while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) { \
     65                if (event_loop_once(req->transport->socket->event.ctx) != 0) { \
     66                        break; \
     67                } \
     68        }
     69
     70static bool test_valid_request(struct torture_context *torture,
     71                               struct smb2_tree *tree)
    5172{
    5273        bool ret = true;
     
    6788        lck.in.locks            = el;
    6889
     90        torture_comment(torture, "Test request with 0 locks.\n");
     91
    6992        lck.in.lock_count       = 0x0000;
    70         lck.in.reserved         = 0x00000000;
     93        lck.in.lock_sequence    = 0x00000000;
    7194        lck.in.file.handle      = h;
    7295        el[0].offset            = 0x0000000000000000;
     
    77100        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    78101
    79         lck.in.lock_count       = 0x0001;
    80         lck.in.reserved         = 0x00000000;
     102        lck.in.lock_count       = 0x0000;
     103        lck.in.lock_sequence    = 0x00000000;
     104        lck.in.file.handle      = h;
     105        el[0].offset            = 0;
     106        el[0].length            = 0;
     107        el[0].reserved          = 0x00000000;
     108        el[0].flags             = SMB2_LOCK_FLAG_SHARED;
     109        status = smb2_lock(tree, &lck);
     110        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     111
     112        lck.in.lock_count       = 0x0001;
     113        lck.in.lock_sequence    = 0x00000000;
    81114        lck.in.file.handle      = h;
    82115        el[0].offset            = 0;
     
    85118        el[0].flags             = SMB2_LOCK_FLAG_NONE;
    86119        status = smb2_lock(tree, &lck);
    87         CHECK_STATUS(status, NT_STATUS_OK);
    88         CHECK_VALUE(lck.out.reserved, 0);
     120        if (TARGET_IS_W2K8(torture)) {
     121                CHECK_STATUS(status, NT_STATUS_OK);
     122                torture_warning(torture, "Target has bug validating lock flags "
     123                                         "parameter.\n");
     124        } else {
     125                CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     126        }
     127
     128        torture_comment(torture, "Test >63-bit lock requests.\n");
    89129
    90130        lck.in.file.handle.data[0] +=1;
     
    94134
    95135        lck.in.lock_count       = 0x0001;
    96         lck.in.reserved         = 0x123ab1;
     136        lck.in.lock_sequence    = 0x123ab1;
    97137        lck.in.file.handle      = h;
    98138        el[0].offset            = UINT64_MAX;
    99139        el[0].length            = UINT64_MAX;
    100140        el[0].reserved          = 0x00000000;
    101         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
    102         status = smb2_lock(tree, &lck);
    103         if (TARGET_IS_WIN7(torture)) {
     141        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     142                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     143        status = smb2_lock(tree, &lck);
     144        if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
    104145                CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
    105146        } else {
    106147                CHECK_STATUS(status, NT_STATUS_OK);
     148                CHECK_VALUE(lck.out.reserved, 0);
    107149        }
    108         CHECK_VALUE(lck.out.reserved, 0);
    109 
    110         lck.in.reserved         = 0x123ab2;
    111         status = smb2_lock(tree, &lck);
    112         if (TARGET_IS_WIN7(torture)) {
     150
     151        lck.in.lock_sequence    = 0x123ab2;
     152        status = smb2_lock(tree, &lck);
     153        if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
    113154                CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
    114         } else if (TARGET_IS_WINDOWS(torture)) {
    115                 CHECK_STATUS(status, NT_STATUS_OK);
    116155        } else {
    117156                CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
    118157        }
    119         CHECK_VALUE(lck.out.reserved, 0);
    120 
    121         lck.in.reserved         = 0x123ab3;
    122         status = smb2_lock(tree, &lck);
    123         if (TARGET_IS_WIN7(torture)) {
    124                 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
    125         } else if (TARGET_IS_WINDOWS(torture)) {
    126                 CHECK_STATUS(status, NT_STATUS_OK);
    127         } else {
    128                 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
    129         }
    130         CHECK_VALUE(lck.out.reserved, 0);
    131 
    132         lck.in.reserved         = 0x123ab4;
    133         status = smb2_lock(tree, &lck);
    134         if (TARGET_IS_WIN7(torture)) {
    135                 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
    136         } else if (TARGET_IS_WINDOWS(torture)) {
    137                 CHECK_STATUS(status, NT_STATUS_OK);
    138         } else {
    139                 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
    140         }
    141         CHECK_VALUE(lck.out.reserved, 0);
    142 
    143         lck.in.reserved         = 0x123ab5;
    144         status = smb2_lock(tree, &lck);
    145         if (TARGET_IS_WIN7(torture)) {
    146                 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
    147         } else if (TARGET_IS_WINDOWS(torture)) {
    148                 CHECK_STATUS(status, NT_STATUS_OK);
    149         } else {
    150                 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
    151         }
    152         CHECK_VALUE(lck.out.reserved, 0);
    153 
    154         lck.in.lock_count       = 0x0001;
    155         lck.in.reserved         = 0x12345678;
     158
     159        torture_comment(torture, "Test basic lock stacking.\n");
     160
     161        lck.in.lock_count       = 0x0001;
     162        lck.in.lock_sequence    = 0x12345678;
    156163        lck.in.file.handle      = h;
    157164        el[0].offset            = UINT32_MAX;
    158165        el[0].length            = UINT32_MAX;
    159166        el[0].reserved          = 0x87654321;
    160         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     167        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     168                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
    161169        status = smb2_lock(tree, &lck);
    162170        CHECK_STATUS(status, NT_STATUS_OK);
    163171        CHECK_VALUE(lck.out.reserved, 0);
    164172
    165         status = smb2_lock(tree, &lck);
    166         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
    167 
    168         status = smb2_lock(tree, &lck);
    169         if (TARGET_IS_WINDOWS(torture)) {
    170                 CHECK_STATUS(status, NT_STATUS_OK);
    171         } else {
    172                 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
    173         }
     173        el[0].flags             = SMB2_LOCK_FLAG_SHARED;
     174        status = smb2_lock(tree, &lck);
     175        CHECK_STATUS(status, NT_STATUS_OK);
    174176        CHECK_VALUE(lck.out.reserved, 0);
    175177
    176178        status = smb2_lock(tree, &lck);
    177         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
    178 
    179         status = smb2_lock(tree, &lck);
    180         if (TARGET_IS_WINDOWS(torture)) {
    181                 CHECK_STATUS(status, NT_STATUS_OK);
    182         } else {
    183                 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
    184         }
     179        CHECK_STATUS(status, NT_STATUS_OK);
    185180        CHECK_VALUE(lck.out.reserved, 0);
    186181
    187         el[0].flags             = 0x00000000;
    188         status = smb2_lock(tree, &lck);
    189         CHECK_STATUS(status, NT_STATUS_OK);
    190         CHECK_VALUE(lck.out.reserved, 0);
    191 
    192         status = smb2_lock(tree, &lck);
    193         CHECK_STATUS(status, NT_STATUS_OK);
    194         CHECK_VALUE(lck.out.reserved, 0);
    195 
    196         el[0].flags             = 0x00000001;
    197         status = smb2_lock(tree, &lck);
    198         CHECK_STATUS(status, NT_STATUS_OK);
    199         CHECK_VALUE(lck.out.reserved, 0);
    200 
    201         status = smb2_lock(tree, &lck);
    202         CHECK_STATUS(status, NT_STATUS_OK);
    203         CHECK_VALUE(lck.out.reserved, 0);
    204 
    205         lck.in.lock_count       = 0x0001;
    206         lck.in.reserved         = 0x87654321;
     182        lck.in.lock_count       = 0x0001;
     183        lck.in.lock_sequence    = 0x87654321;
    207184        lck.in.file.handle      = h;
    208185        el[0].offset            = 0x00000000FFFFFFFF;
     
    214191
    215192        lck.in.lock_count       = 0x0001;
    216         lck.in.reserved         = 0x1234567;
     193        lck.in.lock_sequence    = 0x1234567;
    217194        lck.in.file.handle      = h;
    218195        el[0].offset            = 0x00000000FFFFFFFF;
     
    226203        CHECK_STATUS(status, NT_STATUS_OK);
    227204        status = smb2_lock(tree, &lck);
    228         CHECK_STATUS(status, NT_STATUS_OK);
    229         status = smb2_lock(tree, &lck);
    230         CHECK_STATUS(status, NT_STATUS_OK);
    231         status = smb2_lock(tree, &lck);
    232205        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
    233206
    234         lck.in.lock_count       = 0x0001;
    235         lck.in.reserved         = 0;
     207        torture_comment(torture, "Test flags field permutations.\n");
     208
     209        lck.in.lock_count       = 0x0001;
     210        lck.in.lock_sequence    = 0;
    236211        lck.in.file.handle      = h;
    237212        el[0].offset            = 1;
     
    241216
    242217        status = smb2_lock(tree, &lck);
    243         CHECK_STATUS(status, NT_STATUS_OK);
    244 
    245         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
    246         status = smb2_lock(tree, &lck);
    247         CHECK_STATUS(status, NT_STATUS_OK);
     218        if (TARGET_IS_W2K8(torture)) {
     219                CHECK_STATUS(status, NT_STATUS_OK);
     220                torture_warning(torture, "Target has bug validating lock flags "
     221                                         "parameter.\n");
     222        } else {
     223                CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     224        }
     225
     226        if (TARGET_IS_W2K8(torture)) {
     227                el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     228                status = smb2_lock(tree, &lck);
     229                CHECK_STATUS(status, NT_STATUS_OK);
     230        }
    248231
    249232        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     
    251234        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
    252235
    253         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK | SMB2_LOCK_FLAG_EXCLUSIVE;
     236        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK |
     237                                  SMB2_LOCK_FLAG_EXCLUSIVE;
    254238        status = smb2_lock(tree, &lck);
    255239        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    256240
    257         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK | SMB2_LOCK_FLAG_SHARED;
     241        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK |
     242                                  SMB2_LOCK_FLAG_SHARED;
    258243        status = smb2_lock(tree, &lck);
    259244        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    260245
    261         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
    262         status = smb2_lock(tree, &lck);
    263         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     246        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK |
     247                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     248        status = smb2_lock(tree, &lck);
     249        if (TARGET_IS_W2K8(torture)) {
     250                CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     251                torture_warning(torture, "Target has bug validating lock flags "
     252                                         "parameter.\n");
     253        } else {
     254                CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     255        }
     256
     257        torture_comment(torture, "Test return error when 2 locks are "
     258                                 "requested\n");
    264259
    265260        lck.in.lock_count       = 2;
    266         lck.in.reserved         = 0;
     261        lck.in.lock_sequence    = 0;
    267262        lck.in.file.handle      = h;
    268263        el[0].offset            = 9999;
     
    283278        el[1].flags             = 0;
    284279        status = smb2_lock(tree, &lck);
    285         CHECK_STATUS(status, NT_STATUS_OK);
     280        if (TARGET_IS_W2K8(torture)) {
     281                CHECK_STATUS(status, NT_STATUS_OK);
     282                torture_warning(torture, "Target has bug validating lock flags "
     283                                         "parameter.\n");
     284        } else {
     285                CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     286        }
    286287
    287288        lck.in.lock_count       = 2;
     
    289290        el[1].flags             = 0;
    290291        status = smb2_lock(tree, &lck);
    291         CHECK_STATUS(status, NT_STATUS_OK);
     292        if (TARGET_IS_W2K8(torture)) {
     293                CHECK_STATUS(status, NT_STATUS_OK);
     294                torture_warning(torture, "Target has bug validating lock flags "
     295                                         "parameter.\n");
     296        } else {
     297                CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     298        }
    292299
    293300        lck.in.lock_count       = 1;
     
    307314
    308315        lck.in.lock_count       = 1;
    309         el[0].flags             = 0;
     316        el[0].flags             = SMB2_LOCK_FLAG_SHARED;
    310317        status = smb2_lock(tree, &lck);
    311318        CHECK_STATUS(status, NT_STATUS_OK);
     
    324331        status = smb2_lock(tree, &lck);
    325332        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
    326        
    327333
    328334done:
     
    364370
    365371        lck.in.lock_count       = 0x0001;
    366         lck.in.reserved         = 0x00000000;
     372        lck.in.lock_sequence    = 0x00000000;
    367373        lck.in.file.handle      = h1;
    368374        el[0].offset            = 0;
     
    375381
    376382        lck.in.lock_count       = 0x0001;
    377         lck.in.reserved         = 0x00000000;
     383        lck.in.lock_sequence    = 0x00000000;
    378384        lck.in.file.handle      = h1;
    379385        el[0].offset            = ARRAY_SIZE(buf)/2;
     
    390396        cr.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
    391397        cr.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    392         cr.in.share_access = 
     398        cr.in.share_access =
    393399                NTCREATEX_SHARE_ACCESS_DELETE|
    394400                NTCREATEX_SHARE_ACCESS_READ|
     
    435441
    436442        lck.in.lock_count       = 0x0001;
    437         lck.in.reserved         = 0x00000000;
     443        lck.in.lock_sequence    = 0x00000000;
    438444        lck.in.file.handle      = h1;
    439445        el[0].offset            = ARRAY_SIZE(buf)/2;
     
    465471}
    466472
    467 static bool test_lock_rw_none(struct torture_context *torture, struct smb2_tree *tree)
     473static bool test_lock_rw_none(struct torture_context *torture,
     474                              struct smb2_tree *tree)
    468475{
    469476        struct test_lock_read_write_state s = {
     
    476483        };
    477484
     485        if (!TARGET_IS_W2K8(torture)) {
     486                torture_skip(torture, "RW-NONE tests the behavior of a "
     487                             "NONE-type lock, which is the same as a SHARED "
     488                             "lock but is granted due to a bug in W2K8.  If "
     489                             "target is not W2K8 we skip this test.\n");
     490        }
     491
    478492        return test_lock_read_write(torture, tree, &s);
    479493}
    480494
    481 static bool test_lock_rw_shared(struct torture_context *torture, struct smb2_tree *tree)
     495static bool test_lock_rw_shared(struct torture_context *torture,
     496                                struct smb2_tree *tree)
    482497{
    483498        struct test_lock_read_write_state s = {
     
    493508}
    494509
    495 static bool test_lock_rw_exclusiv(struct torture_context *torture, struct smb2_tree *tree)
     510static bool test_lock_rw_exclusive(struct torture_context *torture,
     511                                   struct smb2_tree *tree)
    496512{
    497513        struct test_lock_read_write_state s = {
    498                 .fname                  = "lock_rw_exclusiv.dat",
     514                .fname                  = "lock_rw_exclusive.dat",
    499515                .lock_flags             = SMB2_LOCK_FLAG_EXCLUSIVE,
    500516                .write_h1_status        = NT_STATUS_OK,
     
    507523}
    508524
    509 static bool test_lock_auto_unlock(struct torture_context *torture, struct smb2_tree *tree)
     525static bool test_lock_auto_unlock(struct torture_context *torture,
     526                                  struct smb2_tree *tree)
    510527{
    511528        bool ret = true;
     
    514531        uint8_t buf[200];
    515532        struct smb2_lock lck;
    516         struct smb2_lock_element el[2];
     533        struct smb2_lock_element el[1];
    517534
    518535        ZERO_STRUCT(buf);
     
    525542
    526543        ZERO_STRUCT(lck);
     544        ZERO_STRUCT(el[0]);
    527545        lck.in.locks            = el;
    528546        lck.in.lock_count       = 0x0001;
     
    530548        el[0].offset            = 0;
    531549        el[0].length            = 1;
    532         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
    533         status = smb2_lock(tree, &lck);
    534         CHECK_STATUS(status, NT_STATUS_OK);
    535 
    536         status = smb2_lock(tree, &lck);
    537         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
    538 
    539         status = smb2_lock(tree, &lck);
    540         if (TARGET_IS_WINDOWS(torture)) {
     550        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     551                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     552        status = smb2_lock(tree, &lck);
     553        CHECK_STATUS(status, NT_STATUS_OK);
     554
     555        status = smb2_lock(tree, &lck);
     556        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     557
     558        status = smb2_lock(tree, &lck);
     559        if (TARGET_IS_W2K8(torture)) {
    541560                CHECK_STATUS(status, NT_STATUS_OK);
     561                torture_warning(torture, "Target has \"pretty please\" bug. "
     562                                "A contending lock request on the same handle "
     563                                "unlocks the lock.\n");
    542564        } else {
    543565                CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     
    551573}
    552574
     575/*
     576  test different lock ranges and see if different handles conflict
     577*/
     578static bool test_lock(struct torture_context *torture,
     579                      struct smb2_tree *tree)
     580{
     581        NTSTATUS status;
     582        bool ret = true;
     583        struct smb2_handle h, h2;
     584        uint8_t buf[200];
     585        struct smb2_lock lck;
     586        struct smb2_lock_element el[2];
     587
     588        const char *fname = BASEDIR "\\async.txt";
     589
     590        status = torture_smb2_testdir(tree, BASEDIR, &h);
     591        CHECK_STATUS(status, NT_STATUS_OK);
     592        smb2_util_close(tree, h);
     593
     594        status = torture_smb2_testfile(tree, fname, &h);
     595        CHECK_STATUS(status, NT_STATUS_OK);
     596
     597        ZERO_STRUCT(buf);
     598        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     599        CHECK_STATUS(status, NT_STATUS_OK);
     600
     601        status = torture_smb2_testfile(tree, fname, &h2);
     602        CHECK_STATUS(status, NT_STATUS_OK);
     603
     604        lck.in.locks            = el;
     605
     606        lck.in.lock_count       = 0x0001;
     607        lck.in.lock_sequence    = 0x00000000;
     608        lck.in.file.handle      = h;
     609        el[0].reserved          = 0x00000000;
     610        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     611                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     612
     613        torture_comment(torture, "Trying 0/0 lock\n");
     614        el[0].offset            = 0x0000000000000000;
     615        el[0].length            = 0x0000000000000000;
     616        status = smb2_lock(tree, &lck);
     617        CHECK_STATUS(status, NT_STATUS_OK);
     618        lck.in.file.handle      = h2;
     619        status = smb2_lock(tree, &lck);
     620        CHECK_STATUS(status, NT_STATUS_OK);
     621        lck.in.file.handle      = h;
     622        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     623        status = smb2_lock(tree, &lck);
     624        CHECK_STATUS(status, NT_STATUS_OK);
     625
     626        torture_comment(torture, "Trying 0/1 lock\n");
     627        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     628                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     629        el[0].offset            = 0x0000000000000000;
     630        el[0].length            = 0x0000000000000001;
     631        status = smb2_lock(tree, &lck);
     632        CHECK_STATUS(status, NT_STATUS_OK);
     633        lck.in.file.handle      = h2;
     634        status = smb2_lock(tree, &lck);
     635        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     636        lck.in.file.handle      = h;
     637        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     638        status = smb2_lock(tree, &lck);
     639        CHECK_STATUS(status, NT_STATUS_OK);
     640        status = smb2_lock(tree, &lck);
     641        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     642
     643        torture_comment(torture, "Trying 0xEEFFFFF lock\n");
     644        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     645                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     646        el[0].offset            = 0xEEFFFFFF;
     647        el[0].length            = 4000;
     648        status = smb2_lock(tree, &lck);
     649        CHECK_STATUS(status, NT_STATUS_OK);
     650        lck.in.file.handle      = h2;
     651        status = smb2_lock(tree, &lck);
     652        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     653        lck.in.file.handle      = h;
     654        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     655        status = smb2_lock(tree, &lck);
     656        CHECK_STATUS(status, NT_STATUS_OK);
     657        status = smb2_lock(tree, &lck);
     658        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     659
     660        torture_comment(torture, "Trying 0xEF00000 lock\n");
     661        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     662                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     663        el[0].offset            = 0xEF000000;
     664        el[0].length            = 4000;
     665        status = smb2_lock(tree, &lck);
     666        CHECK_STATUS(status, NT_STATUS_OK);
     667        lck.in.file.handle      = h2;
     668        status = smb2_lock(tree, &lck);
     669        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     670        lck.in.file.handle      = h;
     671        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     672        status = smb2_lock(tree, &lck);
     673        CHECK_STATUS(status, NT_STATUS_OK);
     674        status = smb2_lock(tree, &lck);
     675        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     676
     677        torture_comment(torture, "Trying (2^63 - 1)/1\n");
     678        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     679                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     680        el[0].offset            = 1;
     681        el[0].offset          <<= 63;
     682        el[0].offset--;
     683        el[0].length            = 1;
     684        status = smb2_lock(tree, &lck);
     685        CHECK_STATUS(status, NT_STATUS_OK);
     686        lck.in.file.handle      = h2;
     687        status = smb2_lock(tree, &lck);
     688        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     689        lck.in.file.handle      = h;
     690        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     691        status = smb2_lock(tree, &lck);
     692        CHECK_STATUS(status, NT_STATUS_OK);
     693        status = smb2_lock(tree, &lck);
     694        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     695
     696        torture_comment(torture, "Trying 2^63/1\n");
     697        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     698                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     699        el[0].offset            = 1;
     700        el[0].offset          <<= 63;
     701        el[0].length            = 1;
     702        status = smb2_lock(tree, &lck);
     703        CHECK_STATUS(status, NT_STATUS_OK);
     704        lck.in.file.handle      = h2;
     705        status = smb2_lock(tree, &lck);
     706        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     707        lck.in.file.handle      = h;
     708        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     709        status = smb2_lock(tree, &lck);
     710        CHECK_STATUS(status, NT_STATUS_OK);
     711        status = smb2_lock(tree, &lck);
     712        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     713
     714        torture_comment(torture, "Trying max/0 lock\n");
     715        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     716                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     717        el[0].offset            = ~0;
     718        el[0].length            = 0;
     719        status = smb2_lock(tree, &lck);
     720        CHECK_STATUS(status, NT_STATUS_OK);
     721        lck.in.file.handle      = h2;
     722        status = smb2_lock(tree, &lck);
     723        CHECK_STATUS(status, NT_STATUS_OK);
     724        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     725        status = smb2_lock(tree, &lck);
     726        CHECK_STATUS(status, NT_STATUS_OK);
     727        lck.in.file.handle      = h;
     728        status = smb2_lock(tree, &lck);
     729        CHECK_STATUS(status, NT_STATUS_OK);
     730        status = smb2_lock(tree, &lck);
     731        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     732
     733        torture_comment(torture, "Trying max/1 lock\n");
     734        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     735                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     736        el[0].offset            = ~0;
     737        el[0].length            = 1;
     738        status = smb2_lock(tree, &lck);
     739        CHECK_STATUS(status, NT_STATUS_OK);
     740        lck.in.file.handle      = h2;
     741        status = smb2_lock(tree, &lck);
     742        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     743        lck.in.file.handle      = h;
     744        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     745        status = smb2_lock(tree, &lck);
     746        CHECK_STATUS(status, NT_STATUS_OK);
     747        status = smb2_lock(tree, &lck);
     748        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     749
     750        torture_comment(torture, "Trying max/2 lock\n");
     751        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     752                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     753        el[0].offset            = ~0;
     754        el[0].length            = 2;
     755        status = smb2_lock(tree, &lck);
     756        if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
     757                CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
     758        } else {
     759                CHECK_STATUS(status, NT_STATUS_OK);
     760                el[0].flags     = SMB2_LOCK_FLAG_UNLOCK;
     761                status = smb2_lock(tree, &lck);
     762                CHECK_STATUS(status, NT_STATUS_OK);
     763        }
     764
     765        torture_comment(torture, "Trying wrong handle unlock\n");
     766        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     767                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     768        el[0].offset            = 10001;
     769        el[0].length            = 40002;
     770        status = smb2_lock(tree, &lck);
     771        CHECK_STATUS(status, NT_STATUS_OK);
     772        lck.in.file.handle      = h2;
     773        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     774        status = smb2_lock(tree, &lck);
     775        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     776        lck.in.file.handle      = h;
     777        status = smb2_lock(tree, &lck);
     778        CHECK_STATUS(status, NT_STATUS_OK);
     779
     780done:
     781        smb2_util_close(tree, h2);
     782        smb2_util_close(tree, h);
     783        smb2_deltree(tree, BASEDIR);
     784        return ret;
     785}
     786
     787/*
     788  test SMB2 LOCK async operation
     789*/
     790static bool test_async(struct torture_context *torture,
     791                       struct smb2_tree *tree)
     792{
     793        NTSTATUS status;
     794        bool ret = true;
     795        struct smb2_handle h, h2;
     796        uint8_t buf[200];
     797        struct smb2_lock lck;
     798        struct smb2_lock_element el[2];
     799        struct smb2_request *req = NULL;
     800
     801        const char *fname = BASEDIR "\\async.txt";
     802
     803        status = torture_smb2_testdir(tree, BASEDIR, &h);
     804        CHECK_STATUS(status, NT_STATUS_OK);
     805        smb2_util_close(tree, h);
     806
     807        status = torture_smb2_testfile(tree, fname, &h);
     808        CHECK_STATUS(status, NT_STATUS_OK);
     809
     810        ZERO_STRUCT(buf);
     811        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     812        CHECK_STATUS(status, NT_STATUS_OK);
     813
     814        status = torture_smb2_testfile(tree, fname, &h2);
     815        CHECK_STATUS(status, NT_STATUS_OK);
     816
     817        lck.in.locks            = el;
     818
     819        lck.in.lock_count       = 0x0001;
     820        lck.in.lock_sequence    = 0x00000000;
     821        lck.in.file.handle      = h;
     822        el[0].offset            = 100;
     823        el[0].length            = 50;
     824        el[0].reserved          = 0x00000000;
     825        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
     826
     827        torture_comment(torture, "  Acquire first lock\n");
     828        status = smb2_lock(tree, &lck);
     829        CHECK_STATUS(status, NT_STATUS_OK);
     830
     831        torture_comment(torture, "  Second lock should pend on first\n");
     832        lck.in.file.handle      = h2;
     833        req = smb2_lock_send(tree, &lck);
     834        WAIT_FOR_ASYNC_RESPONSE(req);
     835
     836        torture_comment(torture, "  Unlock first lock\n");
     837        lck.in.file.handle      = h;
     838        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     839        status = smb2_lock(tree, &lck);
     840        CHECK_STATUS(status, NT_STATUS_OK);
     841
     842        torture_comment(torture, "  Second lock should now succeed\n");
     843        lck.in.file.handle      = h2;
     844        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
     845        status = smb2_lock_recv(req, &lck);
     846        CHECK_STATUS(status, NT_STATUS_OK);
     847
     848done:
     849        smb2_util_close(tree, h2);
     850        smb2_util_close(tree, h);
     851        smb2_deltree(tree, BASEDIR);
     852        return ret;
     853}
     854
     855/*
     856  test SMB2 LOCK Cancel operation
     857*/
     858static bool test_cancel(struct torture_context *torture,
     859                        struct smb2_tree *tree)
     860{
     861        NTSTATUS status;
     862        bool ret = true;
     863        struct smb2_handle h, h2;
     864        uint8_t buf[200];
     865        struct smb2_lock lck;
     866        struct smb2_lock_element el[2];
     867        struct smb2_request *req = NULL;
     868
     869        const char *fname = BASEDIR "\\cancel.txt";
     870
     871        status = torture_smb2_testdir(tree, BASEDIR, &h);
     872        CHECK_STATUS(status, NT_STATUS_OK);
     873        smb2_util_close(tree, h);
     874
     875        status = torture_smb2_testfile(tree, fname, &h);
     876        CHECK_STATUS(status, NT_STATUS_OK);
     877
     878        ZERO_STRUCT(buf);
     879        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     880        CHECK_STATUS(status, NT_STATUS_OK);
     881
     882        status = torture_smb2_testfile(tree, fname, &h2);
     883        CHECK_STATUS(status, NT_STATUS_OK);
     884
     885        lck.in.locks            = el;
     886
     887        lck.in.lock_count       = 0x0001;
     888        lck.in.lock_sequence    = 0x00000000;
     889        lck.in.file.handle      = h;
     890        el[0].offset            = 100;
     891        el[0].length            = 10;
     892        el[0].reserved          = 0x00000000;
     893        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
     894
     895        torture_comment(torture, "Testing basic cancel\n");
     896
     897        torture_comment(torture, "  Acquire first lock\n");
     898        status = smb2_lock(tree, &lck);
     899        CHECK_STATUS(status, NT_STATUS_OK);
     900
     901        torture_comment(torture, "  Second lock should pend on first\n");
     902        lck.in.file.handle      = h2;
     903        req = smb2_lock_send(tree, &lck);
     904        WAIT_FOR_ASYNC_RESPONSE(req);
     905
     906        torture_comment(torture, "  Cancel the second lock\n");
     907        smb2_cancel(req);
     908        lck.in.file.handle      = h2;
     909        status = smb2_lock_recv(req, &lck);
     910        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     911
     912        torture_comment(torture, "  Unlock first lock\n");
     913        lck.in.file.handle      = h;
     914        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     915        status = smb2_lock(tree, &lck);
     916        CHECK_STATUS(status, NT_STATUS_OK);
     917
     918
     919        torture_comment(torture, "Testing cancel by unlock\n");
     920
     921        torture_comment(torture, "  Acquire first lock\n");
     922        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
     923        status = smb2_lock(tree, &lck);
     924        CHECK_STATUS(status, NT_STATUS_OK);
     925
     926        torture_comment(torture, "  Second lock should pend on first\n");
     927        lck.in.file.handle      = h2;
     928        req = smb2_lock_send(tree, &lck);
     929        WAIT_FOR_ASYNC_RESPONSE(req);
     930
     931        torture_comment(torture, "  Attempt to unlock pending second lock\n");
     932        lck.in.file.handle      = h2;
     933        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     934        status = smb2_lock(tree, &lck);
     935        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     936
     937        torture_comment(torture, "  Now cancel the second lock\n");
     938        smb2_cancel(req);
     939        lck.in.file.handle      = h2;
     940        status = smb2_lock_recv(req, &lck);
     941        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     942
     943        torture_comment(torture, "  Unlock first lock\n");
     944        lck.in.file.handle      = h;
     945        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     946        status = smb2_lock(tree, &lck);
     947        CHECK_STATUS(status, NT_STATUS_OK);
     948
     949
     950        torture_comment(torture, "Testing cancel by close\n");
     951
     952        torture_comment(torture, "  Acquire first lock\n");
     953        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
     954        status = smb2_lock(tree, &lck);
     955        CHECK_STATUS(status, NT_STATUS_OK);
     956
     957        torture_comment(torture, "  Second lock should pend on first\n");
     958        lck.in.file.handle      = h2;
     959        req = smb2_lock_send(tree, &lck);
     960        WAIT_FOR_ASYNC_RESPONSE(req);
     961
     962        torture_comment(torture, "  Close the second lock handle\n");
     963        smb2_util_close(tree, h2);
     964        CHECK_STATUS(status, NT_STATUS_OK);
     965
     966        torture_comment(torture, "  Check pending lock reply\n");
     967        status = smb2_lock_recv(req, &lck);
     968        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     969
     970        torture_comment(torture, "  Unlock first lock\n");
     971        lck.in.file.handle      = h;
     972        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     973        status = smb2_lock(tree, &lck);
     974        CHECK_STATUS(status, NT_STATUS_OK);
     975
     976done:
     977        smb2_util_close(tree, h2);
     978        smb2_util_close(tree, h);
     979        smb2_deltree(tree, BASEDIR);
     980        return ret;
     981}
     982
     983/*
     984  test SMB2 LOCK Cancel by tree disconnect
     985*/
     986static bool test_cancel_tdis(struct torture_context *torture,
     987                             struct smb2_tree *tree)
     988{
     989        NTSTATUS status;
     990        bool ret = true;
     991        struct smb2_handle h, h2;
     992        uint8_t buf[200];
     993        struct smb2_lock lck;
     994        struct smb2_lock_element el[2];
     995        struct smb2_request *req = NULL;
     996
     997        const char *fname = BASEDIR "\\cancel_tdis.txt";
     998
     999        status = torture_smb2_testdir(tree, BASEDIR, &h);
     1000        CHECK_STATUS(status, NT_STATUS_OK);
     1001        smb2_util_close(tree, h);
     1002
     1003        status = torture_smb2_testfile(tree, fname, &h);
     1004        CHECK_STATUS(status, NT_STATUS_OK);
     1005
     1006        ZERO_STRUCT(buf);
     1007        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     1008        CHECK_STATUS(status, NT_STATUS_OK);
     1009
     1010        status = torture_smb2_testfile(tree, fname, &h2);
     1011        CHECK_STATUS(status, NT_STATUS_OK);
     1012
     1013        lck.in.locks            = el;
     1014
     1015        lck.in.lock_count       = 0x0001;
     1016        lck.in.lock_sequence    = 0x00000000;
     1017        lck.in.file.handle      = h;
     1018        el[0].offset            = 100;
     1019        el[0].length            = 10;
     1020        el[0].reserved          = 0x00000000;
     1021        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
     1022
     1023        torture_comment(torture, "Testing cancel by tree disconnect\n");
     1024
     1025        status = torture_smb2_testfile(tree, fname, &h);
     1026        CHECK_STATUS(status, NT_STATUS_OK);
     1027
     1028        status = torture_smb2_testfile(tree, fname, &h2);
     1029        CHECK_STATUS(status, NT_STATUS_OK);
     1030
     1031        torture_comment(torture, "  Acquire first lock\n");
     1032        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
     1033        status = smb2_lock(tree, &lck);
     1034        CHECK_STATUS(status, NT_STATUS_OK);
     1035
     1036        torture_comment(torture, "  Second lock should pend on first\n");
     1037        lck.in.file.handle      = h2;
     1038        req = smb2_lock_send(tree, &lck);
     1039        WAIT_FOR_ASYNC_RESPONSE(req);
     1040
     1041        torture_comment(torture, "  Disconnect the tree\n");
     1042        smb2_tdis(tree);
     1043        CHECK_STATUS(status, NT_STATUS_OK);
     1044
     1045        torture_comment(torture, "  Check pending lock reply\n");
     1046        status = smb2_lock_recv(req, &lck);
     1047        if (torture_setting_bool(torture, "samba4", false)) {
     1048                /* saying that this lock succeeded is nonsense - the
     1049                 * tree is gone!! */
     1050                CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     1051        } else {
     1052                CHECK_STATUS(status, NT_STATUS_OK);
     1053        }
     1054
     1055        torture_comment(torture, "  Attempt to unlock first lock\n");
     1056        lck.in.file.handle      = h;
     1057        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1058        status = smb2_lock(tree, &lck);
     1059        if (torture_setting_bool(torture, "samba4", false)) {
     1060                /* checking if the tcon supplied are still valid
     1061                 * should happen before you validate a file handle,
     1062                 * so we should return USER_SESSION_DELETED */
     1063                CHECK_STATUS(status, NT_STATUS_NETWORK_NAME_DELETED);
     1064        } else {
     1065                CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
     1066        }
     1067
     1068done:
     1069        smb2_util_close(tree, h2);
     1070        smb2_util_close(tree, h);
     1071        smb2_deltree(tree, BASEDIR);
     1072        return ret;
     1073}
     1074
     1075/*
     1076  test SMB2 LOCK Cancel by user logoff
     1077*/
     1078static bool test_cancel_logoff(struct torture_context *torture,
     1079                               struct smb2_tree *tree)
     1080{
     1081        NTSTATUS status;
     1082        bool ret = true;
     1083        struct smb2_handle h, h2;
     1084        uint8_t buf[200];
     1085        struct smb2_lock lck;
     1086        struct smb2_lock_element el[2];
     1087        struct smb2_request *req = NULL;
     1088
     1089        const char *fname = BASEDIR "\\cancel_tdis.txt";
     1090
     1091        status = torture_smb2_testdir(tree, BASEDIR, &h);
     1092        CHECK_STATUS(status, NT_STATUS_OK);
     1093        smb2_util_close(tree, h);
     1094
     1095        status = torture_smb2_testfile(tree, fname, &h);
     1096        CHECK_STATUS(status, NT_STATUS_OK);
     1097
     1098        ZERO_STRUCT(buf);
     1099        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     1100        CHECK_STATUS(status, NT_STATUS_OK);
     1101
     1102        status = torture_smb2_testfile(tree, fname, &h2);
     1103        CHECK_STATUS(status, NT_STATUS_OK);
     1104
     1105        lck.in.locks            = el;
     1106
     1107        lck.in.lock_count       = 0x0001;
     1108        lck.in.lock_sequence    = 0x00000000;
     1109        lck.in.file.handle      = h;
     1110        el[0].offset            = 100;
     1111        el[0].length            = 10;
     1112        el[0].reserved          = 0x00000000;
     1113        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
     1114
     1115        torture_comment(torture, "Testing cancel by ulogoff\n");
     1116
     1117        torture_comment(torture, "  Acquire first lock\n");
     1118        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
     1119        status = smb2_lock(tree, &lck);
     1120        CHECK_STATUS(status, NT_STATUS_OK);
     1121
     1122        torture_comment(torture, "  Second lock should pend on first\n");
     1123        lck.in.file.handle      = h2;
     1124        req = smb2_lock_send(tree, &lck);
     1125        WAIT_FOR_ASYNC_RESPONSE(req);
     1126
     1127        torture_comment(torture, "  Logoff user\n");
     1128        smb2_logoff(tree->session);
     1129
     1130        torture_comment(torture, "  Check pending lock reply\n");
     1131        status = smb2_lock_recv(req, &lck);
     1132        if (torture_setting_bool(torture, "samba4", false)) {
     1133                /* another bogus 'success' code from windows. The lock
     1134                 * cannot have succeeded, as we are now logged off */
     1135                CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     1136        } else {
     1137                CHECK_STATUS(status, NT_STATUS_OK);
     1138        }
     1139
     1140        torture_comment(torture, "  Attempt to unlock first lock\n");
     1141        lck.in.file.handle      = h;
     1142        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1143        status = smb2_lock(tree, &lck);
     1144        if (torture_setting_bool(torture, "samba4", false)) {
     1145                /* checking if the credential supplied are still valid
     1146                 * should happen before you validate a file handle,
     1147                 * so we should return USER_SESSION_DELETED */
     1148                CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
     1149        } else {
     1150                CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
     1151        }
     1152
     1153done:
     1154        smb2_util_close(tree, h2);
     1155        smb2_util_close(tree, h);
     1156        smb2_deltree(tree, BASEDIR);
     1157        return ret;
     1158}
     1159
     1160/*
     1161 * Test NT_STATUS_LOCK_NOT_GRANTED vs. NT_STATUS_FILE_LOCK_CONFLICT
     1162 *
     1163 * The SMBv1 protocol returns a different error code on lock acquisition
     1164 * failure depending on a number of parameters, including what error code
     1165 * was returned to the previous failure.
     1166 *
     1167 * SMBv2 has cleaned up these semantics and should always return
     1168 * NT_STATUS_LOCK_NOT_GRANTED to failed lock requests, and
     1169 * NT_STATUS_FILE_LOCK_CONFLICT to failed read/write requests due to a lock
     1170 * being held on that range.
     1171*/
     1172static bool test_errorcode(struct torture_context *torture,
     1173                           struct smb2_tree *tree)
     1174{
     1175        NTSTATUS status;
     1176        bool ret = true;
     1177        struct smb2_handle h, h2;
     1178        uint8_t buf[200];
     1179        struct smb2_lock lck;
     1180        struct smb2_lock_element el[2];
     1181
     1182        const char *fname = BASEDIR "\\errorcode.txt";
     1183
     1184        status = torture_smb2_testdir(tree, BASEDIR, &h);
     1185        CHECK_STATUS(status, NT_STATUS_OK);
     1186        smb2_util_close(tree, h);
     1187
     1188        status = torture_smb2_testfile(tree, fname, &h);
     1189        CHECK_STATUS(status, NT_STATUS_OK);
     1190
     1191        ZERO_STRUCT(buf);
     1192        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     1193        CHECK_STATUS(status, NT_STATUS_OK);
     1194
     1195        status = torture_smb2_testfile(tree, fname, &h2);
     1196        CHECK_STATUS(status, NT_STATUS_OK);
     1197
     1198        lck.in.locks            = el;
     1199
     1200        lck.in.lock_count       = 0x0001;
     1201        lck.in.lock_sequence    = 0x00000000;
     1202        lck.in.file.handle      = h;
     1203        el[0].offset            = 100;
     1204        el[0].length            = 10;
     1205        el[0].reserved          = 0x00000000;
     1206        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1207                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1208
     1209        torture_comment(torture, "Testing LOCK_NOT_GRANTED vs. "
     1210                                 "FILE_LOCK_CONFLICT\n");
     1211
     1212        if (TARGET_IS_W2K8(torture)) {
     1213                torture_result(torture, TORTURE_SKIP,
     1214                    "Target has \"pretty please\" bug. A contending lock "
     1215                    "request on the same handle unlocks the lock.");
     1216                goto done;
     1217        }
     1218
     1219        status = smb2_lock(tree, &lck);
     1220        CHECK_STATUS(status, NT_STATUS_OK);
     1221
     1222        /* Demonstrate that the first conflicting lock on each handle gives
     1223         * LOCK_NOT_GRANTED. */
     1224        lck.in.file.handle      = h;
     1225        status = smb2_lock(tree, &lck);
     1226        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1227
     1228        lck.in.file.handle      = h2;
     1229        status = smb2_lock(tree, &lck);
     1230        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1231
     1232        /* Demonstrate that each following conflict also gives
     1233         * LOCK_NOT_GRANTED */
     1234        lck.in.file.handle      = h;
     1235        status = smb2_lock(tree, &lck);
     1236        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1237
     1238        lck.in.file.handle      = h2;
     1239        status = smb2_lock(tree, &lck);
     1240        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1241
     1242        lck.in.file.handle      = h;
     1243        status = smb2_lock(tree, &lck);
     1244        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1245
     1246        lck.in.file.handle      = h2;
     1247        status = smb2_lock(tree, &lck);
     1248        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1249
     1250        /* Demonstrate that the smbpid doesn't matter */
     1251        tree->session->pid++;
     1252        lck.in.file.handle      = h;
     1253        status = smb2_lock(tree, &lck);
     1254        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1255
     1256        lck.in.file.handle      = h2;
     1257        status = smb2_lock(tree, &lck);
     1258        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1259        tree->session->pid--;
     1260
     1261        /* Demonstrate that a 0-byte lock inside the locked range still
     1262         * gives the same error. */
     1263
     1264        el[0].offset            = 102;
     1265        el[0].length            = 0;
     1266        lck.in.file.handle      = h;
     1267        status = smb2_lock(tree, &lck);
     1268        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1269
     1270        lck.in.file.handle      = h2;
     1271        status = smb2_lock(tree, &lck);
     1272        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1273
     1274        /* Demonstrate that a lock inside the locked range still gives the
     1275         * same error. */
     1276
     1277        el[0].offset            = 102;
     1278        el[0].length            = 5;
     1279        lck.in.file.handle      = h;
     1280        status = smb2_lock(tree, &lck);
     1281        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1282
     1283        lck.in.file.handle      = h2;
     1284        status = smb2_lock(tree, &lck);
     1285        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1286
     1287done:
     1288        smb2_util_close(tree, h2);
     1289        smb2_util_close(tree, h);
     1290        smb2_deltree(tree, BASEDIR);
     1291        return ret;
     1292}
     1293
     1294/**
     1295 * Tests zero byte locks.
     1296 */
     1297
     1298struct double_lock_test {
     1299        struct smb2_lock_element lock1;
     1300        struct smb2_lock_element lock2;
     1301        NTSTATUS status;
     1302};
     1303
     1304static struct double_lock_test zero_byte_tests[] = {
     1305        /* {offset, count, reserved, flags},
     1306         * {offset, count, reserved, flags},
     1307         * status */
     1308
     1309        /** First, takes a zero byte lock at offset 10. Then:
     1310        *   - Taking 0 byte lock at 10 should succeed.
     1311        *   - Taking 1 byte locks at 9,10,11 should succeed.
     1312        *   - Taking 2 byte lock at 9 should fail.
     1313        *   - Taking 2 byte lock at 10 should succeed.
     1314        *   - Taking 3 byte lock at 9 should fail.
     1315        */
     1316        {{10, 0, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
     1317        {{10, 0, 0, 0}, {9, 1, 0, 0},  NT_STATUS_OK},
     1318        {{10, 0, 0, 0}, {10, 1, 0, 0}, NT_STATUS_OK},
     1319        {{10, 0, 0, 0}, {11, 1, 0, 0}, NT_STATUS_OK},
     1320        {{10, 0, 0, 0}, {9, 2, 0, 0},  NT_STATUS_LOCK_NOT_GRANTED},
     1321        {{10, 0, 0, 0}, {10, 2, 0, 0}, NT_STATUS_OK},
     1322        {{10, 0, 0, 0}, {9, 3, 0, 0},  NT_STATUS_LOCK_NOT_GRANTED},
     1323
     1324        /** Same, but opposite order. */
     1325        {{10, 0, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
     1326        {{9, 1, 0, 0},  {10, 0, 0, 0}, NT_STATUS_OK},
     1327        {{10, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
     1328        {{11, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
     1329        {{9, 2, 0, 0},  {10, 0, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
     1330        {{10, 2, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
     1331        {{9, 3, 0, 0},  {10, 0, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
     1332
     1333        /** Zero zero case. */
     1334        {{0, 0, 0, 0},  {0, 0, 0, 0},  NT_STATUS_OK},
     1335};
     1336
     1337static bool test_zerobytelength(struct torture_context *torture,
     1338                                struct smb2_tree *tree)
     1339{
     1340        NTSTATUS status;
     1341        bool ret = true;
     1342        struct smb2_handle h, h2;
     1343        uint8_t buf[200];
     1344        struct smb2_lock lck;
     1345        int i;
     1346
     1347        const char *fname = BASEDIR "\\zero.txt";
     1348
     1349        torture_comment(torture, "Testing zero length byte range locks:\n");
     1350
     1351        status = torture_smb2_testdir(tree, BASEDIR, &h);
     1352        CHECK_STATUS(status, NT_STATUS_OK);
     1353        smb2_util_close(tree, h);
     1354
     1355        status = torture_smb2_testfile(tree, fname, &h);
     1356        CHECK_STATUS(status, NT_STATUS_OK);
     1357
     1358        ZERO_STRUCT(buf);
     1359        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     1360        CHECK_STATUS(status, NT_STATUS_OK);
     1361
     1362        status = torture_smb2_testfile(tree, fname, &h2);
     1363        CHECK_STATUS(status, NT_STATUS_OK);
     1364
     1365        /* Setup initial parameters */
     1366        lck.in.lock_count       = 0x0001;
     1367        lck.in.lock_sequence    = 0x00000000;
     1368        lck.in.file.handle      = h;
     1369
     1370        /* Try every combination of locks in zero_byte_tests, using the same
     1371         * handle for both locks. The first lock is assumed to succeed. The
     1372         * second lock may contend, depending on the expected status. */
     1373        for (i = 0; i < ARRAY_SIZE(zero_byte_tests); i++) {
     1374                torture_comment(torture,
     1375                    "  ... {%llu, %llu} + {%llu, %llu} = %s\n",
     1376                    (unsigned long long) zero_byte_tests[i].lock1.offset,
     1377                    (unsigned long long) zero_byte_tests[i].lock1.length,
     1378                    (unsigned long long) zero_byte_tests[i].lock2.offset,
     1379                    (unsigned long long) zero_byte_tests[i].lock2.length,
     1380                    nt_errstr(zero_byte_tests[i].status));
     1381
     1382                /* Lock both locks. */
     1383                lck.in.locks            = &zero_byte_tests[i].lock1;
     1384                lck.in.locks[0].flags   = SMB2_LOCK_FLAG_EXCLUSIVE |
     1385                                          SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1386                status = smb2_lock(tree, &lck);
     1387                CHECK_STATUS(status, NT_STATUS_OK);
     1388
     1389                lck.in.locks            = &zero_byte_tests[i].lock2;
     1390                lck.in.locks[0].flags   = SMB2_LOCK_FLAG_EXCLUSIVE |
     1391                                          SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1392                status = smb2_lock(tree, &lck);
     1393                CHECK_STATUS_CONT(status, zero_byte_tests[i].status);
     1394
     1395                /* Unlock both locks in reverse order. */
     1396                lck.in.locks[0].flags   = SMB2_LOCK_FLAG_UNLOCK;
     1397                if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
     1398                        status = smb2_lock(tree, &lck);
     1399                        CHECK_STATUS(status, NT_STATUS_OK);
     1400                }
     1401
     1402                lck.in.locks            = &zero_byte_tests[i].lock1;
     1403                lck.in.locks[0].flags   = SMB2_LOCK_FLAG_UNLOCK;
     1404                status = smb2_lock(tree, &lck);
     1405                CHECK_STATUS(status, NT_STATUS_OK);
     1406        }
     1407
     1408        /* Try every combination of locks in zero_byte_tests, using two
     1409         * different handles. */
     1410        for (i = 0; i < ARRAY_SIZE(zero_byte_tests); i++) {
     1411                torture_comment(torture,
     1412                    "  ... {%llu, %llu} + {%llu, %llu} = %s\n",
     1413                    (unsigned long long) zero_byte_tests[i].lock1.offset,
     1414                    (unsigned long long) zero_byte_tests[i].lock1.length,
     1415                    (unsigned long long) zero_byte_tests[i].lock2.offset,
     1416                    (unsigned long long) zero_byte_tests[i].lock2.length,
     1417                    nt_errstr(zero_byte_tests[i].status));
     1418
     1419                /* Lock both locks. */
     1420                lck.in.file.handle      = h;
     1421                lck.in.locks            = &zero_byte_tests[i].lock1;
     1422                lck.in.locks[0].flags   = SMB2_LOCK_FLAG_EXCLUSIVE |
     1423                                          SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1424                status = smb2_lock(tree, &lck);
     1425                CHECK_STATUS(status, NT_STATUS_OK);
     1426
     1427                lck.in.file.handle      = h2;
     1428                lck.in.locks            = &zero_byte_tests[i].lock2;
     1429                lck.in.locks[0].flags   = SMB2_LOCK_FLAG_EXCLUSIVE |
     1430                                          SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1431                status = smb2_lock(tree, &lck);
     1432                CHECK_STATUS_CONT(status, zero_byte_tests[i].status);
     1433
     1434                /* Unlock both locks in reverse order. */
     1435                lck.in.file.handle      = h2;
     1436                lck.in.locks[0].flags   = SMB2_LOCK_FLAG_UNLOCK;
     1437                if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
     1438                        status = smb2_lock(tree, &lck);
     1439                        CHECK_STATUS(status, NT_STATUS_OK);
     1440                }
     1441
     1442                lck.in.file.handle      = h;
     1443                lck.in.locks            = &zero_byte_tests[i].lock1;
     1444                lck.in.locks[0].flags   = SMB2_LOCK_FLAG_UNLOCK;
     1445                status = smb2_lock(tree, &lck);
     1446                CHECK_STATUS(status, NT_STATUS_OK);
     1447        }
     1448
     1449done:
     1450        smb2_util_close(tree, h2);
     1451        smb2_util_close(tree, h);
     1452        smb2_deltree(tree, BASEDIR);
     1453        return ret;
     1454}
     1455
     1456static bool test_zerobyteread(struct torture_context *torture,
     1457                              struct smb2_tree *tree)
     1458{
     1459        NTSTATUS status;
     1460        bool ret = true;
     1461        struct smb2_handle h, h2;
     1462        uint8_t buf[200];
     1463        struct smb2_lock lck;
     1464        struct smb2_lock_element el[1];
     1465        struct smb2_read rd;
     1466
     1467        const char *fname = BASEDIR "\\zerobyteread.txt";
     1468
     1469        status = torture_smb2_testdir(tree, BASEDIR, &h);
     1470        CHECK_STATUS(status, NT_STATUS_OK);
     1471        smb2_util_close(tree, h);
     1472
     1473        status = torture_smb2_testfile(tree, fname, &h);
     1474        CHECK_STATUS(status, NT_STATUS_OK);
     1475
     1476        ZERO_STRUCT(buf);
     1477        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     1478        CHECK_STATUS(status, NT_STATUS_OK);
     1479
     1480        status = torture_smb2_testfile(tree, fname, &h2);
     1481        CHECK_STATUS(status, NT_STATUS_OK);
     1482
     1483        /* Setup initial parameters */
     1484        lck.in.locks            = el;
     1485        lck.in.lock_count       = 0x0001;
     1486        lck.in.lock_sequence    = 0x00000000;
     1487        lck.in.file.handle      = h;
     1488
     1489        ZERO_STRUCT(rd);
     1490        rd.in.file.handle = h2;
     1491
     1492        torture_comment(torture, "Testing zero byte read on lock range:\n");
     1493
     1494        /* Take an exclusive lock */
     1495        torture_comment(torture, "  taking exclusive lock.\n");
     1496        el[0].offset            = 0;
     1497        el[0].length            = 10;
     1498        el[0].reserved          = 0x00000000;
     1499        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1500                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1501        status = smb2_lock(tree, &lck);
     1502        CHECK_STATUS(status, NT_STATUS_OK);
     1503        CHECK_VALUE(lck.out.reserved, 0);
     1504
     1505        /* Try a zero byte read */
     1506        torture_comment(torture, "  reading 0 bytes.\n");
     1507        rd.in.offset      = 5;
     1508        rd.in.length      = 0;
     1509        status = smb2_read(tree, tree, &rd);
     1510        torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
     1511                                      "zero byte read did not return 0 bytes");
     1512        CHECK_STATUS(status, NT_STATUS_OK);
     1513
     1514        /* Unlock lock */
     1515        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1516        status = smb2_lock(tree, &lck);
     1517        CHECK_STATUS(status, NT_STATUS_OK);
     1518        CHECK_VALUE(lck.out.reserved, 0);
     1519
     1520        torture_comment(torture, "Testing zero byte read on zero byte lock "
     1521                                 "range:\n");
     1522
     1523        /* Take an exclusive lock */
     1524        torture_comment(torture, "  taking exclusive 0-byte lock.\n");
     1525        el[0].offset            = 5;
     1526        el[0].length            = 0;
     1527        el[0].reserved          = 0x00000000;
     1528        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1529                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1530        status = smb2_lock(tree, &lck);
     1531        CHECK_STATUS(status, NT_STATUS_OK);
     1532        CHECK_VALUE(lck.out.reserved, 0);
     1533
     1534        /* Try a zero byte read before the lock */
     1535        torture_comment(torture, "  reading 0 bytes before the lock.\n");
     1536        rd.in.offset      = 4;
     1537        rd.in.length      = 0;
     1538        status = smb2_read(tree, tree, &rd);
     1539        torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
     1540                                      "zero byte read did not return 0 bytes");
     1541        CHECK_STATUS(status, NT_STATUS_OK);
     1542
     1543        /* Try a zero byte read on the lock */
     1544        torture_comment(torture, "  reading 0 bytes on the lock.\n");
     1545        rd.in.offset      = 5;
     1546        rd.in.length      = 0;
     1547        status = smb2_read(tree, tree, &rd);
     1548        torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
     1549                                      "zero byte read did not return 0 bytes");
     1550        CHECK_STATUS(status, NT_STATUS_OK);
     1551
     1552        /* Try a zero byte read after the lock */
     1553        torture_comment(torture, "  reading 0 bytes after the lock.\n");
     1554        rd.in.offset      = 6;
     1555        rd.in.length      = 0;
     1556        status = smb2_read(tree, tree, &rd);
     1557        torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
     1558                                      "zero byte read did not return 0 bytes");
     1559        CHECK_STATUS(status, NT_STATUS_OK);
     1560
     1561        /* Unlock lock */
     1562        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1563        status = smb2_lock(tree, &lck);
     1564        CHECK_STATUS(status, NT_STATUS_OK);
     1565        CHECK_VALUE(lck.out.reserved, 0);
     1566
     1567done:
     1568        smb2_util_close(tree, h2);
     1569        smb2_util_close(tree, h);
     1570        smb2_deltree(tree, BASEDIR);
     1571        return ret;
     1572}
     1573
     1574static bool test_unlock(struct torture_context *torture,
     1575                        struct smb2_tree *tree)
     1576{
     1577        NTSTATUS status;
     1578        bool ret = true;
     1579        struct smb2_handle h, h2;
     1580        uint8_t buf[200];
     1581        struct smb2_lock lck;
     1582        struct smb2_lock_element el1[1];
     1583        struct smb2_lock_element el2[1];
     1584
     1585        const char *fname = BASEDIR "\\unlock.txt";
     1586
     1587        status = torture_smb2_testdir(tree, BASEDIR, &h);
     1588        CHECK_STATUS(status, NT_STATUS_OK);
     1589        smb2_util_close(tree, h);
     1590
     1591        status = torture_smb2_testfile(tree, fname, &h);
     1592        CHECK_STATUS(status, NT_STATUS_OK);
     1593
     1594        ZERO_STRUCT(buf);
     1595        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     1596        CHECK_STATUS(status, NT_STATUS_OK);
     1597
     1598        status = torture_smb2_testfile(tree, fname, &h2);
     1599        CHECK_STATUS(status, NT_STATUS_OK);
     1600
     1601        /* Setup initial parameters */
     1602        lck.in.locks            = el1;
     1603        lck.in.lock_count       = 0x0001;
     1604        lck.in.lock_sequence    = 0x00000000;
     1605        el1[0].offset           = 0;
     1606        el1[0].length           = 10;
     1607        el1[0].reserved         = 0x00000000;
     1608
     1609        /* Take exclusive lock, then unlock it with a shared-unlock call. */
     1610
     1611        torture_comment(torture, "Testing unlock exclusive with shared\n");
     1612
     1613        torture_comment(torture, "  taking exclusive lock.\n");
     1614        lck.in.file.handle      = h;
     1615        el1[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE;
     1616        status = smb2_lock(tree, &lck);
     1617        CHECK_STATUS(status, NT_STATUS_OK);
     1618
     1619        torture_comment(torture, "  try to unlock the exclusive with a shared "
     1620                                 "unlock call.\n");
     1621        el1[0].flags            = SMB2_LOCK_FLAG_SHARED |
     1622                                  SMB2_LOCK_FLAG_UNLOCK;
     1623        status = smb2_lock(tree, &lck);
     1624        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     1625
     1626        torture_comment(torture, "  try shared lock on h2, to test the "
     1627                                 "unlock.\n");
     1628        lck.in.file.handle      = h2;
     1629        el1[0].flags            = SMB2_LOCK_FLAG_SHARED |
     1630                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1631        status = smb2_lock(tree, &lck);
     1632        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1633
     1634        torture_comment(torture, "  unlock the exclusive lock\n");
     1635        lck.in.file.handle      = h;
     1636        el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
     1637        status = smb2_lock(tree, &lck);
     1638        CHECK_STATUS(status, NT_STATUS_OK);
     1639
     1640        /* Unlock a shared lock with an exclusive-unlock call. */
     1641
     1642        torture_comment(torture, "Testing unlock shared with exclusive\n");
     1643
     1644        torture_comment(torture, "  taking shared lock.\n");
     1645        lck.in.file.handle      = h;
     1646        el1[0].flags            = SMB2_LOCK_FLAG_SHARED;
     1647        status = smb2_lock(tree, &lck);
     1648        CHECK_STATUS(status, NT_STATUS_OK);
     1649
     1650        torture_comment(torture, "  try to unlock the shared with an exclusive "
     1651                                 "unlock call.\n");
     1652        el1[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
     1653                                  SMB2_LOCK_FLAG_UNLOCK;
     1654        status = smb2_lock(tree, &lck);
     1655        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     1656
     1657        torture_comment(torture, "  try exclusive lock on h2, to test the "
     1658                                 "unlock.\n");
     1659        lck.in.file.handle      = h2;
     1660        el1[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
     1661                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1662        status = smb2_lock(tree, &lck);
     1663        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1664
     1665        torture_comment(torture, "  unlock the exclusive lock\n");
     1666        lck.in.file.handle      = h;
     1667        el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
     1668        status = smb2_lock(tree, &lck);
     1669        CHECK_STATUS(status, NT_STATUS_OK);
     1670
     1671        /* Test unlocking of stacked 0-byte locks. SMB2 0-byte lock behavior
     1672         * should be the same as >0-byte behavior.  Exclusive locks should be
     1673         * unlocked before shared. */
     1674
     1675        torture_comment(torture, "Test unlocking stacked 0-byte locks\n");
     1676
     1677        lck.in.locks            = el1;
     1678        lck.in.file.handle      = h;
     1679        el1[0].offset           = 10;
     1680        el1[0].length           = 0;
     1681        el1[0].reserved         = 0x00000000;
     1682        el2[0].offset           = 5;
     1683        el2[0].length           = 10;
     1684        el2[0].reserved         = 0x00000000;
     1685
     1686        /* lock 0-byte exclusive */
     1687        el1[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
     1688                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1689        status = smb2_lock(tree, &lck);
     1690        CHECK_STATUS(status, NT_STATUS_OK);
     1691
     1692        /* lock 0-byte shared */
     1693        el1[0].flags            = SMB2_LOCK_FLAG_SHARED |
     1694                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1695        status = smb2_lock(tree, &lck);
     1696        CHECK_STATUS(status, NT_STATUS_OK);
     1697
     1698        /* test contention */
     1699        lck.in.locks            = el2;
     1700        lck.in.file.handle      = h2;
     1701        el2[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
     1702                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1703        status = smb2_lock(tree, &lck);
     1704        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1705
     1706        lck.in.locks            = el2;
     1707        lck.in.file.handle      = h2;
     1708        el2[0].flags            = SMB2_LOCK_FLAG_SHARED |
     1709                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1710        status = smb2_lock(tree, &lck);
     1711        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1712
     1713        /* unlock */
     1714        lck.in.locks            = el1;
     1715        lck.in.file.handle      = h;
     1716        el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
     1717        status = smb2_lock(tree, &lck);
     1718        CHECK_STATUS(status, NT_STATUS_OK);
     1719
     1720        /* test - can we take a shared lock? */
     1721        lck.in.locks            = el2;
     1722        lck.in.file.handle      = h2;
     1723        el2[0].flags            = SMB2_LOCK_FLAG_SHARED |
     1724                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1725        status = smb2_lock(tree, &lck);
     1726        CHECK_STATUS(status, NT_STATUS_OK);
     1727
     1728        el2[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
     1729        status = smb2_lock(tree, &lck);
     1730        CHECK_STATUS(status, NT_STATUS_OK);
     1731
     1732        /* cleanup */
     1733        lck.in.locks            = el1;
     1734        lck.in.file.handle      = h;
     1735        el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
     1736        status = smb2_lock(tree, &lck);
     1737        CHECK_STATUS(status, NT_STATUS_OK);
     1738
     1739        /* Test unlocking of stacked exclusive, shared locks. Exclusive
     1740         * should be unlocked before any shared. */
     1741
     1742        torture_comment(torture, "Test unlocking stacked exclusive/shared "
     1743                                 "locks\n");
     1744
     1745        lck.in.locks            = el1;
     1746        lck.in.file.handle      = h;
     1747        el1[0].offset           = 10;
     1748        el1[0].length           = 10;
     1749        el1[0].reserved         = 0x00000000;
     1750        el2[0].offset           = 5;
     1751        el2[0].length           = 10;
     1752        el2[0].reserved         = 0x00000000;
     1753
     1754        /* lock exclusive */
     1755        el1[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
     1756                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1757        status = smb2_lock(tree, &lck);
     1758        CHECK_STATUS(status, NT_STATUS_OK);
     1759
     1760        /* lock shared */
     1761        el1[0].flags            = SMB2_LOCK_FLAG_SHARED |
     1762                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1763        status = smb2_lock(tree, &lck);
     1764        CHECK_STATUS(status, NT_STATUS_OK);
     1765
     1766        /* test contention */
     1767        lck.in.locks            = el2;
     1768        lck.in.file.handle      = h2;
     1769        el2[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
     1770                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1771        status = smb2_lock(tree, &lck);
     1772        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1773
     1774        lck.in.locks            = el2;
     1775        lck.in.file.handle      = h2;
     1776        el2[0].flags            = SMB2_LOCK_FLAG_SHARED |
     1777                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1778        status = smb2_lock(tree, &lck);
     1779        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1780
     1781        /* unlock */
     1782        lck.in.locks            = el1;
     1783        lck.in.file.handle      = h;
     1784        el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
     1785        status = smb2_lock(tree, &lck);
     1786        CHECK_STATUS(status, NT_STATUS_OK);
     1787
     1788        /* test - can we take a shared lock? */
     1789        lck.in.locks            = el2;
     1790        lck.in.file.handle      = h2;
     1791        el2[0].flags            = SMB2_LOCK_FLAG_SHARED |
     1792                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1793        status = smb2_lock(tree, &lck);
     1794        CHECK_STATUS(status, NT_STATUS_OK);
     1795
     1796        el2[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
     1797        status = smb2_lock(tree, &lck);
     1798        CHECK_STATUS(status, NT_STATUS_OK);
     1799
     1800        /* cleanup */
     1801        lck.in.locks            = el1;
     1802        lck.in.file.handle      = h;
     1803        el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
     1804        status = smb2_lock(tree, &lck);
     1805        CHECK_STATUS(status, NT_STATUS_OK);
     1806
     1807done:
     1808        smb2_util_close(tree, h2);
     1809        smb2_util_close(tree, h);
     1810        smb2_deltree(tree, BASEDIR);
     1811        return ret;
     1812}
     1813
     1814static bool test_multiple_unlock(struct torture_context *torture,
     1815                                 struct smb2_tree *tree)
     1816{
     1817        NTSTATUS status;
     1818        bool ret = true;
     1819        struct smb2_handle h;
     1820        uint8_t buf[200];
     1821        struct smb2_lock lck;
     1822        struct smb2_lock_element el[2];
     1823
     1824        const char *fname = BASEDIR "\\unlock_multiple.txt";
     1825
     1826        status = torture_smb2_testdir(tree, BASEDIR, &h);
     1827        CHECK_STATUS(status, NT_STATUS_OK);
     1828        smb2_util_close(tree, h);
     1829
     1830        status = torture_smb2_testfile(tree, fname, &h);
     1831        CHECK_STATUS(status, NT_STATUS_OK);
     1832
     1833        ZERO_STRUCT(buf);
     1834        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     1835        CHECK_STATUS(status, NT_STATUS_OK);
     1836
     1837        torture_comment(torture, "Testing multiple unlocks:\n");
     1838
     1839        /* Setup initial parameters */
     1840        lck.in.lock_count       = 0x0002;
     1841        lck.in.lock_sequence    = 0x00000000;
     1842        lck.in.file.handle      = h;
     1843        el[0].offset            = 0;
     1844        el[0].length            = 10;
     1845        el[0].reserved          = 0x00000000;
     1846        el[1].offset            = 10;
     1847        el[1].length            = 10;
     1848        el[1].reserved          = 0x00000000;
     1849
     1850        /* Test1: Acquire second lock, but not first. */
     1851        torture_comment(torture, "  unlock 2 locks, first one not locked. "
     1852                                 "Expect no locks unlocked. \n");
     1853
     1854        lck.in.lock_count       = 0x0001;
     1855        el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1856                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1857        lck.in.locks            = &el[1];
     1858        status = smb2_lock(tree, &lck);
     1859        CHECK_STATUS(status, NT_STATUS_OK);
     1860
     1861        /* Try to unlock both locks */
     1862        lck.in.lock_count       = 0x0002;
     1863        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1864        el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1865        lck.in.locks            = el;
     1866        status = smb2_lock(tree, &lck);
     1867        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     1868
     1869        /* Second lock should not be unlocked. */
     1870        lck.in.lock_count       = 0x0001;
     1871        el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1872                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1873        lck.in.locks            = &el[1];
     1874        status = smb2_lock(tree, &lck);
     1875        if (TARGET_IS_W2K8(torture)) {
     1876                CHECK_STATUS(status, NT_STATUS_OK);
     1877                torture_warning(torture, "Target has \"pretty please\" bug. "
     1878                                "A contending lock request on the same handle "
     1879                                "unlocks the lock.\n");
     1880        } else {
     1881                CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1882        }
     1883
     1884        /* cleanup */
     1885        lck.in.lock_count       = 0x0001;
     1886        el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1887        lck.in.locks            = &el[1];
     1888        status = smb2_lock(tree, &lck);
     1889        CHECK_STATUS(status, NT_STATUS_OK);
     1890
     1891        /* Test2: Acquire first lock, but not second. */
     1892        torture_comment(torture, "  unlock 2 locks, second one not locked. "
     1893                                 "Expect first lock unlocked.\n");
     1894
     1895        lck.in.lock_count       = 0x0001;
     1896        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1897                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1898        lck.in.locks            = &el[0];
     1899        status = smb2_lock(tree, &lck);
     1900        CHECK_STATUS(status, NT_STATUS_OK);
     1901
     1902        /* Try to unlock both locks */
     1903        lck.in.lock_count       = 0x0002;
     1904        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1905        el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1906        lck.in.locks            = el;
     1907        status = smb2_lock(tree, &lck);
     1908        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     1909
     1910        /* First lock should be unlocked. */
     1911        lck.in.lock_count       = 0x0001;
     1912        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1913                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1914        lck.in.locks            = &el[0];
     1915        status = smb2_lock(tree, &lck);
     1916        CHECK_STATUS(status, NT_STATUS_OK);
     1917
     1918        /* cleanup */
     1919        lck.in.lock_count       = 0x0001;
     1920        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1921        lck.in.locks            = &el[0];
     1922        status = smb2_lock(tree, &lck);
     1923        CHECK_STATUS(status, NT_STATUS_OK);
     1924
     1925        /* Test3: Request 2 locks, second will contend.  What happens to the
     1926         * first? */
     1927        torture_comment(torture, "  request 2 locks, second one will contend. "
     1928                                 "Expect both to fail.\n");
     1929
     1930        /* Lock the second range */
     1931        lck.in.lock_count       = 0x0001;
     1932        el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1933                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1934        lck.in.locks            = &el[1];
     1935        status = smb2_lock(tree, &lck);
     1936        CHECK_STATUS(status, NT_STATUS_OK);
     1937
     1938        /* Request both locks */
     1939        lck.in.lock_count       = 0x0002;
     1940        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1941                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1942        lck.in.locks            = el;
     1943        status = smb2_lock(tree, &lck);
     1944        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     1945
     1946        /* First lock should be unlocked. */
     1947        lck.in.lock_count       = 0x0001;
     1948        lck.in.locks            = &el[0];
     1949        status = smb2_lock(tree, &lck);
     1950        CHECK_STATUS(status, NT_STATUS_OK);
     1951
     1952        /* cleanup */
     1953        if (TARGET_IS_W2K8(torture)) {
     1954                lck.in.lock_count       = 0x0001;
     1955                el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1956                lck.in.locks            = &el[0];
     1957                status = smb2_lock(tree, &lck);
     1958                CHECK_STATUS(status, NT_STATUS_OK);
     1959                torture_warning(torture, "Target has \"pretty please\" bug. "
     1960                                "A contending lock request on the same handle "
     1961                                "unlocks the lock.\n");
     1962        } else {
     1963                lck.in.lock_count       = 0x0002;
     1964                el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1965                el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1966                lck.in.locks            = el;
     1967                status = smb2_lock(tree, &lck);
     1968                CHECK_STATUS(status, NT_STATUS_OK);
     1969        }
     1970
     1971        /* Test4: Request unlock and lock.  The lock contends, is the unlock
     1972         * then relocked?  SMB2 doesn't like the lock and unlock requests in the
     1973         * same packet. The unlock will succeed, but the lock will return
     1974         * INVALID_PARAMETER.  This behavior is described in MS-SMB2
     1975         * 3.3.5.14.1 */
     1976        torture_comment(torture, "  request unlock and lock, second one will "
     1977                                 "error. Expect the unlock to succeed.\n");
     1978
     1979        /* Lock both ranges */
     1980        lck.in.lock_count       = 0x0002;
     1981        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1982                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1983        el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1984                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1985        lck.in.locks            = el;
     1986        status = smb2_lock(tree, &lck);
     1987        CHECK_STATUS(status, NT_STATUS_OK);
     1988
     1989        /* Attempt to unlock the first range and lock the second. The lock
     1990         * request will error. */
     1991        lck.in.lock_count       = 0x0002;
     1992        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     1993        el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     1994                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     1995        lck.in.locks            = el;
     1996        status = smb2_lock(tree, &lck);
     1997        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     1998
     1999        /* The first lock should've been unlocked */
     2000        lck.in.lock_count       = 0x0001;
     2001        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2002                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2003        lck.in.locks            = &el[0];
     2004        status = smb2_lock(tree, &lck);
     2005        CHECK_STATUS(status, NT_STATUS_OK);
     2006
     2007        /* cleanup */
     2008        lck.in.lock_count       = 0x0002;
     2009        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2010        el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2011        lck.in.locks            = el;
     2012        status = smb2_lock(tree, &lck);
     2013        CHECK_STATUS(status, NT_STATUS_OK);
     2014
     2015        /* Test10: SMB2 only test. Request unlock and lock in same packet.
     2016         * Neither contend. SMB2 doesn't like lock and unlock requests in the
     2017         * same packet.  The unlock will succeed, but the lock will return
     2018         * INVALID_PARAMETER. */
     2019        torture_comment(torture, "  request unlock and lock.  Unlock will "
     2020                                 "succeed, but lock will fail.\n");
     2021
     2022        /* Lock first range */
     2023        lck.in.lock_count       = 0x0001;
     2024        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2025                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2026        lck.in.locks            = &el[0];
     2027        status = smb2_lock(tree, &lck);
     2028        CHECK_STATUS(status, NT_STATUS_OK);
     2029
     2030        /* Attempt to unlock the first range and lock the second */
     2031        lck.in.lock_count       = 0x0002;
     2032        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2033        el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2034                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2035        lck.in.locks            = el;
     2036        status = smb2_lock(tree, &lck);
     2037        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     2038
     2039        /* Neither lock should still be locked */
     2040        lck.in.lock_count       = 0x0002;
     2041        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2042                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2043        el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2044                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2045        lck.in.locks            = el;
     2046        status = smb2_lock(tree, &lck);
     2047        CHECK_STATUS(status, NT_STATUS_OK);
     2048
     2049        /* cleanup */
     2050        lck.in.lock_count       = 0x0002;
     2051        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2052        el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2053        lck.in.locks            = el;
     2054        status = smb2_lock(tree, &lck);
     2055        CHECK_STATUS(status, NT_STATUS_OK);
     2056
     2057        /* Test11: SMB2 only test. Request lock and unlock in same packet.
     2058         * Neither contend. SMB2 doesn't like lock and unlock requests in the
     2059         * same packet.  The lock will succeed, the unlock will fail with
     2060         * INVALID_PARAMETER, and the lock will be unlocked before return. */
     2061        torture_comment(torture, "  request lock and unlock.  Both will "
     2062                                 "fail.\n");
     2063
     2064        /* Lock second range */
     2065        lck.in.lock_count       = 0x0001;
     2066        el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2067                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2068        lck.in.locks            = &el[1];
     2069        status = smb2_lock(tree, &lck);
     2070        CHECK_STATUS(status, NT_STATUS_OK);
     2071
     2072        /* Attempt to lock the first range and unlock the second */
     2073        lck.in.lock_count       = 0x0002;
     2074        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2075                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2076        el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2077        lck.in.locks            = el;
     2078        status = smb2_lock(tree, &lck);
     2079        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     2080
     2081        /* First range should be unlocked, second locked. */
     2082        lck.in.lock_count       = 0x0001;
     2083        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2084                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2085        lck.in.locks            = &el[0];
     2086        status = smb2_lock(tree, &lck);
     2087        CHECK_STATUS(status, NT_STATUS_OK);
     2088
     2089        lck.in.lock_count       = 0x0001;
     2090        el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2091                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2092        lck.in.locks            = &el[1];
     2093        status = smb2_lock(tree, &lck);
     2094        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     2095
     2096        /* cleanup */
     2097        if (TARGET_IS_W2K8(torture)) {
     2098                lck.in.lock_count       = 0x0001;
     2099                el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2100                lck.in.locks            = &el[0];
     2101                status = smb2_lock(tree, &lck);
     2102                CHECK_STATUS(status, NT_STATUS_OK);
     2103                torture_warning(torture, "Target has \"pretty please\" bug. "
     2104                                "A contending lock request on the same handle "
     2105                                "unlocks the lock.\n");
     2106        } else {
     2107                lck.in.lock_count       = 0x0002;
     2108                el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2109                el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2110                lck.in.locks            = el;
     2111                status = smb2_lock(tree, &lck);
     2112                CHECK_STATUS(status, NT_STATUS_OK);
     2113        }
     2114
     2115done:
     2116        smb2_util_close(tree, h);
     2117        smb2_deltree(tree, BASEDIR);
     2118        return ret;
     2119}
     2120
     2121/**
     2122 * Test lock stacking
     2123 *  - some tests ported from BASE-LOCK-LOCK5
     2124 */
     2125static bool test_stacking(struct torture_context *torture,
     2126                          struct smb2_tree *tree)
     2127{
     2128        NTSTATUS status;
     2129        bool ret = true;
     2130        struct smb2_handle h, h2;
     2131        uint8_t buf[200];
     2132        struct smb2_lock lck;
     2133        struct smb2_lock_element el[1];
     2134
     2135        const char *fname = BASEDIR "\\stacking.txt";
     2136
     2137        status = torture_smb2_testdir(tree, BASEDIR, &h);
     2138        CHECK_STATUS(status, NT_STATUS_OK);
     2139        smb2_util_close(tree, h);
     2140
     2141        status = torture_smb2_testfile(tree, fname, &h);
     2142        CHECK_STATUS(status, NT_STATUS_OK);
     2143
     2144        ZERO_STRUCT(buf);
     2145        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     2146        CHECK_STATUS(status, NT_STATUS_OK);
     2147
     2148        status = torture_smb2_testfile(tree, fname, &h2);
     2149        CHECK_STATUS(status, NT_STATUS_OK);
     2150
     2151        torture_comment(torture, "Testing lock stacking:\n");
     2152
     2153        /* Setup initial parameters */
     2154        lck.in.locks            = el;
     2155        lck.in.lock_count       = 0x0001;
     2156        lck.in.lock_sequence    = 0x00000000;
     2157        lck.in.file.handle      = h;
     2158        el[0].offset            = 0;
     2159        el[0].length            = 10;
     2160        el[0].reserved          = 0x00000000;
     2161
     2162        /* Try to take a shared lock, then a shared lock on same handle */
     2163        torture_comment(torture, "  stacking a shared on top of a shared"
     2164                                 "lock succeeds.\n");
     2165
     2166        el[0].flags             = SMB2_LOCK_FLAG_SHARED |
     2167                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2168        status = smb2_lock(tree, &lck);
     2169        CHECK_STATUS(status, NT_STATUS_OK);
     2170
     2171        el[0].flags             = SMB2_LOCK_FLAG_SHARED |
     2172                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2173        status = smb2_lock(tree, &lck);
     2174        CHECK_STATUS(status, NT_STATUS_OK);
     2175
     2176        /* cleanup */
     2177        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2178        status = smb2_lock(tree, &lck);
     2179        CHECK_STATUS(status, NT_STATUS_OK);
     2180
     2181        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2182        status = smb2_lock(tree, &lck);
     2183        CHECK_STATUS(status, NT_STATUS_OK);
     2184
     2185
     2186        /* Try to take an exclusive lock, then a shared lock on same handle */
     2187        torture_comment(torture, "  stacking a shared on top of an exclusive "
     2188                                 "lock succeeds.\n");
     2189
     2190        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2191                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2192        status = smb2_lock(tree, &lck);
     2193        CHECK_STATUS(status, NT_STATUS_OK);
     2194
     2195        el[0].flags             = SMB2_LOCK_FLAG_SHARED |
     2196                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2197        status = smb2_lock(tree, &lck);
     2198        CHECK_STATUS(status, NT_STATUS_OK);
     2199
     2200        el[0].flags             = SMB2_LOCK_FLAG_SHARED |
     2201                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2202        status = smb2_lock(tree, &lck);
     2203        CHECK_STATUS(status, NT_STATUS_OK);
     2204
     2205        /* stacking a shared from a different handle should fail */
     2206        lck.in.file.handle      = h2;
     2207        el[0].flags             = SMB2_LOCK_FLAG_SHARED |
     2208                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2209        status = smb2_lock(tree, &lck);
     2210        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     2211
     2212        /* cleanup */
     2213        lck.in.file.handle      = h;
     2214        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2215        status = smb2_lock(tree, &lck);
     2216        CHECK_STATUS(status, NT_STATUS_OK);
     2217
     2218        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2219        status = smb2_lock(tree, &lck);
     2220        CHECK_STATUS(status, NT_STATUS_OK);
     2221
     2222        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2223        status = smb2_lock(tree, &lck);
     2224        CHECK_STATUS(status, NT_STATUS_OK);
     2225
     2226        /* ensure the 4th unlock fails */
     2227        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2228        status = smb2_lock(tree, &lck);
     2229        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     2230
     2231        /* ensure a second handle can now take an exclusive lock */
     2232        lck.in.file.handle      = h2;
     2233        el[0].flags             = SMB2_LOCK_FLAG_SHARED |
     2234                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2235        status = smb2_lock(tree, &lck);
     2236        CHECK_STATUS(status, NT_STATUS_OK);
     2237
     2238        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2239        status = smb2_lock(tree, &lck);
     2240        CHECK_STATUS(status, NT_STATUS_OK);
     2241
     2242        /* Try to take an exclusive lock, then a shared lock on a
     2243         * different handle */
     2244        torture_comment(torture, "  stacking a shared on top of an exclusive "
     2245                                 "lock with different handles fails.\n");
     2246
     2247        lck.in.file.handle      = h;
     2248        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2249                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2250        status = smb2_lock(tree, &lck);
     2251        CHECK_STATUS(status, NT_STATUS_OK);
     2252
     2253        lck.in.file.handle      = h2;
     2254        el[0].flags             = SMB2_LOCK_FLAG_SHARED |
     2255                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2256        status = smb2_lock(tree, &lck);
     2257        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     2258
     2259        /* cleanup */
     2260        lck.in.file.handle      = h;
     2261        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2262        status = smb2_lock(tree, &lck);
     2263        CHECK_STATUS(status, NT_STATUS_OK);
     2264
     2265        /* Try to take a shared lock, then stack an exclusive with same
     2266         * handle.  */
     2267        torture_comment(torture, "  stacking an exclusive on top of a shared "
     2268                                 "lock fails.\n");
     2269
     2270        el[0].flags             = SMB2_LOCK_FLAG_SHARED |
     2271                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2272        status = smb2_lock(tree, &lck);
     2273        CHECK_STATUS(status, NT_STATUS_OK);
     2274
     2275        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2276                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2277        status = smb2_lock(tree, &lck);
     2278        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     2279
     2280        /* cleanup */
     2281        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2282        status = smb2_lock(tree, &lck);
     2283        if (TARGET_IS_W2K8(torture)) {
     2284                CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     2285                torture_warning(torture, "Target has \"pretty please\" bug. "
     2286                                "A contending lock request on the same handle "
     2287                                "unlocks the lock.\n");
     2288        } else {
     2289                CHECK_STATUS(status, NT_STATUS_OK);
     2290        }
     2291
     2292        /* Prove that two exclusive locks do not stack on the same handle. */
     2293        torture_comment(torture, "  two exclusive locks do not stack.\n");
     2294
     2295        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2296                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2297        status = smb2_lock(tree, &lck);
     2298        CHECK_STATUS(status, NT_STATUS_OK);
     2299
     2300        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2301                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2302        status = smb2_lock(tree, &lck);
     2303        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     2304
     2305        /* cleanup */
     2306        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2307        status = smb2_lock(tree, &lck);
     2308        if (TARGET_IS_W2K8(torture)) {
     2309                CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     2310                torture_warning(torture, "Target has \"pretty please\" bug. "
     2311                                "A contending lock request on the same handle "
     2312                                "unlocks the lock.\n");
     2313        } else {
     2314                CHECK_STATUS(status, NT_STATUS_OK);
     2315        }
     2316
     2317done:
     2318        smb2_util_close(tree, h2);
     2319        smb2_util_close(tree, h);
     2320        smb2_deltree(tree, BASEDIR);
     2321        return ret;
     2322}
     2323
     2324/**
     2325 * Test lock contention
     2326 * - shared lock should contend with exclusive lock on different handle
     2327 */
     2328static bool test_contend(struct torture_context *torture,
     2329                         struct smb2_tree *tree)
     2330{
     2331        NTSTATUS status;
     2332        bool ret = true;
     2333        struct smb2_handle h, h2;
     2334        uint8_t buf[200];
     2335        struct smb2_lock lck;
     2336        struct smb2_lock_element el[1];
     2337
     2338        const char *fname = BASEDIR "\\contend.txt";
     2339
     2340        status = torture_smb2_testdir(tree, BASEDIR, &h);
     2341        CHECK_STATUS(status, NT_STATUS_OK);
     2342        smb2_util_close(tree, h);
     2343
     2344        status = torture_smb2_testfile(tree, fname, &h);
     2345        CHECK_STATUS(status, NT_STATUS_OK);
     2346
     2347        ZERO_STRUCT(buf);
     2348        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     2349        CHECK_STATUS(status, NT_STATUS_OK);
     2350
     2351        status = torture_smb2_testfile(tree, fname, &h2);
     2352        CHECK_STATUS(status, NT_STATUS_OK);
     2353
     2354        torture_comment(torture, "Testing lock contention:\n");
     2355
     2356        /* Setup initial parameters */
     2357        lck.in.locks            = el;
     2358        lck.in.lock_count       = 0x0001;
     2359        lck.in.lock_sequence    = 0x00000000;
     2360        lck.in.file.handle      = h;
     2361        el[0].offset            = 0;
     2362        el[0].length            = 10;
     2363        el[0].reserved          = 0x00000000;
     2364
     2365        /* Take an exclusive lock, then a shared lock on different handle */
     2366        torture_comment(torture, "  shared should contend on exclusive on "
     2367                                 "different handle.\n");
     2368
     2369        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2370                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2371        status = smb2_lock(tree, &lck);
     2372        CHECK_STATUS(status, NT_STATUS_OK);
     2373
     2374        lck.in.file.handle      = h2;
     2375        el[0].flags             = SMB2_LOCK_FLAG_SHARED |
     2376                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2377        status = smb2_lock(tree, &lck);
     2378        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
     2379
     2380        /* cleanup */
     2381        lck.in.file.handle      = h;
     2382        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2383        status = smb2_lock(tree, &lck);
     2384        CHECK_STATUS(status, NT_STATUS_OK);
     2385
     2386done:
     2387        smb2_util_close(tree, h2);
     2388        smb2_util_close(tree, h);
     2389        smb2_deltree(tree, BASEDIR);
     2390        return ret;
     2391}
     2392
     2393/**
     2394 * Test locker context
     2395 * - test that pid does not affect the locker context
     2396 */
     2397static bool test_context(struct torture_context *torture,
     2398                         struct smb2_tree *tree)
     2399{
     2400        NTSTATUS status;
     2401        bool ret = true;
     2402        struct smb2_handle h, h2;
     2403        uint8_t buf[200];
     2404        struct smb2_lock lck;
     2405        struct smb2_lock_element el[1];
     2406
     2407        const char *fname = BASEDIR "\\context.txt";
     2408
     2409        status = torture_smb2_testdir(tree, BASEDIR, &h);
     2410        CHECK_STATUS(status, NT_STATUS_OK);
     2411        smb2_util_close(tree, h);
     2412
     2413        status = torture_smb2_testfile(tree, fname, &h);
     2414        CHECK_STATUS(status, NT_STATUS_OK);
     2415
     2416        ZERO_STRUCT(buf);
     2417        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     2418        CHECK_STATUS(status, NT_STATUS_OK);
     2419
     2420        status = torture_smb2_testfile(tree, fname, &h2);
     2421        CHECK_STATUS(status, NT_STATUS_OK);
     2422
     2423        torture_comment(torture, "Testing locker context:\n");
     2424
     2425        /* Setup initial parameters */
     2426        lck.in.locks            = el;
     2427        lck.in.lock_count       = 0x0001;
     2428        lck.in.lock_sequence    = 0x00000000;
     2429        lck.in.file.handle      = h;
     2430        el[0].offset            = 0;
     2431        el[0].length            = 10;
     2432        el[0].reserved          = 0x00000000;
     2433
     2434        /* Take an exclusive lock, then try to unlock with a different pid,
     2435         * same handle.  This shows that the pid doesn't affect the locker
     2436         * context in SMB2. */
     2437        torture_comment(torture, "  pid shouldn't affect locker context\n");
     2438
     2439        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2440                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2441        status = smb2_lock(tree, &lck);
     2442        CHECK_STATUS(status, NT_STATUS_OK);
     2443
     2444        tree->session->pid++;
     2445        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2446        status = smb2_lock(tree, &lck);
     2447        CHECK_STATUS(status, NT_STATUS_OK);
     2448
     2449        tree->session->pid--;
     2450        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2451        status = smb2_lock(tree, &lck);
     2452        CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
     2453
     2454done:
     2455        smb2_util_close(tree, h2);
     2456        smb2_util_close(tree, h);
     2457        smb2_deltree(tree, BASEDIR);
     2458        return ret;
     2459}
     2460
     2461/**
     2462 * Test as much of the potential lock range as possible
     2463 *  - test ported from BASE-LOCK-LOCK3
     2464 */
     2465static bool test_range(struct torture_context *torture,
     2466                       struct smb2_tree *tree)
     2467{
     2468        NTSTATUS status;
     2469        bool ret = true;
     2470        struct smb2_handle h, h2;
     2471        uint8_t buf[200];
     2472        struct smb2_lock lck;
     2473        struct smb2_lock_element el[1];
     2474        uint64_t offset, i;
     2475        extern int torture_numops;
     2476
     2477        const char *fname = BASEDIR "\\range.txt";
     2478
     2479#define NEXT_OFFSET offset += (~(uint64_t)0) / torture_numops
     2480
     2481        status = torture_smb2_testdir(tree, BASEDIR, &h);
     2482        CHECK_STATUS(status, NT_STATUS_OK);
     2483        smb2_util_close(tree, h);
     2484
     2485        status = torture_smb2_testfile(tree, fname, &h);
     2486        CHECK_STATUS(status, NT_STATUS_OK);
     2487
     2488        ZERO_STRUCT(buf);
     2489        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     2490        CHECK_STATUS(status, NT_STATUS_OK);
     2491
     2492        status = torture_smb2_testfile(tree, fname, &h2);
     2493        CHECK_STATUS(status, NT_STATUS_OK);
     2494
     2495        torture_comment(torture, "Testing locks spread across the 64-bit "
     2496                                 "offset range\n");
     2497
     2498        if (TARGET_IS_W2K8(torture)) {
     2499                torture_result(torture, TORTURE_SKIP,
     2500                    "Target has \"pretty please\" bug. A contending lock "
     2501                    "request on the same handle unlocks the lock.");
     2502                goto done;
     2503        }
     2504
     2505        /* Setup initial parameters */
     2506        lck.in.locks            = el;
     2507        lck.in.lock_count       = 0x0001;
     2508        lck.in.lock_sequence    = 0x00000000;
     2509        lck.in.file.handle      = h;
     2510        el[0].offset            = 0;
     2511        el[0].length            = 1;
     2512        el[0].reserved          = 0x00000000;
     2513        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2514                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2515
     2516        torture_comment(torture, "  establishing %d locks\n", torture_numops);
     2517
     2518        for (offset=i=0; i<torture_numops; i++) {
     2519                NEXT_OFFSET;
     2520
     2521                lck.in.file.handle      = h;
     2522                el[0].offset            = offset - 1;
     2523                status = smb2_lock(tree, &lck);
     2524                CHECK_STATUS_CMT(status, NT_STATUS_OK,
     2525                                 talloc_asprintf(torture,
     2526                                     "lock h failed at offset %#llx ",
     2527                                     (unsigned long long) el[0].offset));
     2528
     2529                lck.in.file.handle      = h2;
     2530                el[0].offset            = offset - 2;
     2531                status = smb2_lock(tree, &lck);
     2532                CHECK_STATUS_CMT(status, NT_STATUS_OK,
     2533                                 talloc_asprintf(torture,
     2534                                     "lock h2 failed at offset %#llx ",
     2535                                     (unsigned long long) el[0].offset));
     2536        }
     2537
     2538        torture_comment(torture, "  testing %d locks\n", torture_numops);
     2539
     2540        for (offset=i=0; i<torture_numops; i++) {
     2541                NEXT_OFFSET;
     2542
     2543                lck.in.file.handle      = h;
     2544                el[0].offset            = offset - 1;
     2545                status = smb2_lock(tree, &lck);
     2546                CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
     2547                                 talloc_asprintf(torture,
     2548                                     "lock h at offset %#llx should not have "
     2549                                     "succeeded ",
     2550                                     (unsigned long long) el[0].offset));
     2551
     2552                lck.in.file.handle      = h;
     2553                el[0].offset            = offset - 2;
     2554                status = smb2_lock(tree, &lck);
     2555                CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
     2556                                 talloc_asprintf(torture,
     2557                                     "lock h2 at offset %#llx should not have "
     2558                                     "succeeded ",
     2559                                     (unsigned long long) el[0].offset));
     2560
     2561                lck.in.file.handle      = h2;
     2562                el[0].offset            = offset - 1;
     2563                status = smb2_lock(tree, &lck);
     2564                CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
     2565                                 talloc_asprintf(torture,
     2566                                     "lock h at offset %#llx should not have "
     2567                                     "succeeded ",
     2568                                     (unsigned long long) el[0].offset));
     2569
     2570                lck.in.file.handle      = h2;
     2571                el[0].offset            = offset - 2;
     2572                status = smb2_lock(tree, &lck);
     2573                CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
     2574                                 talloc_asprintf(torture,
     2575                                     "lock h2 at offset %#llx should not have "
     2576                                     "succeeded ",
     2577                                     (unsigned long long) el[0].offset));
     2578        }
     2579
     2580        torture_comment(torture, "  removing %d locks\n", torture_numops);
     2581
     2582        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2583
     2584        for (offset=i=0; i<torture_numops; i++) {
     2585                NEXT_OFFSET;
     2586
     2587                lck.in.file.handle      = h;
     2588                el[0].offset            = offset - 1;
     2589                status = smb2_lock(tree, &lck);
     2590                CHECK_STATUS_CMT(status, NT_STATUS_OK,
     2591                                 talloc_asprintf(torture,
     2592                                     "unlock from h failed at offset %#llx ",
     2593                                     (unsigned long long) el[0].offset));
     2594
     2595                lck.in.file.handle      = h2;
     2596                el[0].offset            = offset - 2;
     2597                status = smb2_lock(tree, &lck);
     2598                CHECK_STATUS_CMT(status, NT_STATUS_OK,
     2599                                 talloc_asprintf(torture,
     2600                                     "unlock from h2 failed at offset %#llx ",
     2601                                     (unsigned long long) el[0].offset));
     2602        }
     2603
     2604done:
     2605        smb2_util_close(tree, h2);
     2606        smb2_util_close(tree, h);
     2607        smb2_deltree(tree, BASEDIR);
     2608        return ret;
     2609}
     2610
     2611static NTSTATUS smb2cli_lock(struct smb2_tree *tree, struct smb2_handle h,
     2612                             uint64_t offset, uint64_t length, bool exclusive)
     2613{
     2614        struct smb2_lock lck;
     2615        struct smb2_lock_element el[1];
     2616        NTSTATUS status;
     2617
     2618        lck.in.locks            = el;
     2619        lck.in.lock_count       = 0x0001;
     2620        lck.in.lock_sequence    = 0x00000000;
     2621        lck.in.file.handle      = h;
     2622        el[0].offset            = offset;
     2623        el[0].length            = length;
     2624        el[0].reserved          = 0x00000000;
     2625        el[0].flags             = (exclusive ?
     2626                                  SMB2_LOCK_FLAG_EXCLUSIVE :
     2627                                  SMB2_LOCK_FLAG_SHARED) |
     2628                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2629
     2630        status = smb2_lock(tree, &lck);
     2631
     2632        return status;
     2633}
     2634
     2635static NTSTATUS smb2cli_unlock(struct smb2_tree *tree, struct smb2_handle h,
     2636                               uint64_t offset, uint64_t length)
     2637{
     2638        struct smb2_lock lck;
     2639        struct smb2_lock_element el[1];
     2640        NTSTATUS status;
     2641
     2642        lck.in.locks            = el;
     2643        lck.in.lock_count       = 0x0001;
     2644        lck.in.lock_sequence    = 0x00000000;
     2645        lck.in.file.handle      = h;
     2646        el[0].offset            = offset;
     2647        el[0].length            = length;
     2648        el[0].reserved          = 0x00000000;
     2649        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2650
     2651        status = smb2_lock(tree, &lck);
     2652
     2653        return status;
     2654}
     2655
     2656#define EXPECTED(ret, v) if ((ret) != (v)) { \
     2657        torture_result(torture, TORTURE_FAIL, __location__": subtest failed");\
     2658        torture_comment(torture, "** "); correct = false; \
     2659        }
     2660
     2661/**
     2662 * Test overlapping lock ranges from various lockers
     2663 *  - some tests ported from BASE-LOCK-LOCK4
     2664 */
     2665static bool test_overlap(struct torture_context *torture,
     2666                         struct smb2_tree *tree,
     2667                         struct smb2_tree *tree2)
     2668{
     2669        NTSTATUS status;
     2670        bool ret = true;
     2671        struct smb2_handle h, h2, h3;
     2672        uint8_t buf[200];
     2673        bool correct = true;
     2674
     2675        const char *fname = BASEDIR "\\overlap.txt";
     2676
     2677        status = torture_smb2_testdir(tree, BASEDIR, &h);
     2678        CHECK_STATUS(status, NT_STATUS_OK);
     2679        smb2_util_close(tree, h);
     2680
     2681        status = torture_smb2_testfile(tree, fname, &h);
     2682        CHECK_STATUS(status, NT_STATUS_OK);
     2683
     2684        ZERO_STRUCT(buf);
     2685        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     2686        CHECK_STATUS(status, NT_STATUS_OK);
     2687
     2688        status = torture_smb2_testfile(tree, fname, &h2);
     2689        CHECK_STATUS(status, NT_STATUS_OK);
     2690
     2691        status = torture_smb2_testfile(tree2, fname, &h3);
     2692        CHECK_STATUS(status, NT_STATUS_OK);
     2693
     2694        torture_comment(torture, "Testing overlapping locks:\n");
     2695
     2696        ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 0, 4, true)) &&
     2697              NT_STATUS_IS_OK(smb2cli_lock(tree, h, 2, 4, true));
     2698        EXPECTED(ret, false);
     2699        torture_comment(torture, "the same session/handle %s set overlapping "
     2700                                 "exclusive locks\n", ret?"can":"cannot");
     2701
     2702        ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 10, 4, false)) &&
     2703              NT_STATUS_IS_OK(smb2cli_lock(tree, h, 12, 4, false));
     2704        EXPECTED(ret, true);
     2705        torture_comment(torture, "the same session/handle %s set overlapping "
     2706                                 "shared locks\n", ret?"can":"cannot");
     2707
     2708        ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 20, 4, true)) &&
     2709              NT_STATUS_IS_OK(smb2cli_lock(tree2, h3, 22, 4, true));
     2710        EXPECTED(ret, false);
     2711        torture_comment(torture, "a different session %s set overlapping "
     2712                                 "exclusive locks\n", ret?"can":"cannot");
     2713
     2714        ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 30, 4, false)) &&
     2715              NT_STATUS_IS_OK(smb2cli_lock(tree2, h3, 32, 4, false));
     2716        EXPECTED(ret, true);
     2717        torture_comment(torture, "a different session %s set overlapping "
     2718                                 "shared locks\n", ret?"can":"cannot");
     2719
     2720        ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 40, 4, true)) &&
     2721              NT_STATUS_IS_OK(smb2cli_lock(tree, h2, 42, 4, true));
     2722        EXPECTED(ret, false);
     2723        torture_comment(torture, "a different handle %s set overlapping "
     2724                                 "exclusive locks\n", ret?"can":"cannot");
     2725
     2726        ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 50, 4, false)) &&
     2727              NT_STATUS_IS_OK(smb2cli_lock(tree, h2, 52, 4, false));
     2728        EXPECTED(ret, true);
     2729        torture_comment(torture, "a different handle %s set overlapping "
     2730                                 "shared locks\n", ret?"can":"cannot");
     2731
     2732        ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 110, 4, false)) &&
     2733              NT_STATUS_IS_OK(smb2cli_lock(tree, h, 112, 4, false)) &&
     2734              NT_STATUS_IS_OK(smb2cli_unlock(tree, h, 110, 6));
     2735        EXPECTED(ret, false);
     2736        torture_comment(torture, "the same handle %s coalesce read locks\n",
     2737                                 ret?"can":"cannot");
     2738
     2739        smb2_util_close(tree, h2);
     2740        smb2_util_close(tree, h);
     2741        status = torture_smb2_testfile(tree, fname, &h);
     2742        CHECK_STATUS(status, NT_STATUS_OK);
     2743        status = torture_smb2_testfile(tree, fname, &h2);
     2744        CHECK_STATUS(status, NT_STATUS_OK);
     2745        ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 0, 8, false)) &&
     2746              NT_STATUS_IS_OK(smb2cli_lock(tree, h2, 0, 1, false)) &&
     2747              NT_STATUS_IS_OK(smb2_util_close(tree, h)) &&
     2748              NT_STATUS_IS_OK(torture_smb2_testfile(tree, fname, &h)) &&
     2749              NT_STATUS_IS_OK(smb2cli_lock(tree, h, 7, 1, true));
     2750        EXPECTED(ret, true);
     2751        torture_comment(torture, "the server %s have the NT byte range lock "
     2752                                 "bug\n", !ret?"does":"doesn't");
     2753
     2754done:
     2755        smb2_util_close(tree2, h3);
     2756        smb2_util_close(tree, h2);
     2757        smb2_util_close(tree, h);
     2758        smb2_deltree(tree, BASEDIR);
     2759        return correct;
     2760}
     2761
     2762/**
     2763 * Test truncation of locked file
     2764 *  - some tests ported from BASE-LOCK-LOCK7
     2765 */
     2766static bool test_truncate(struct torture_context *torture,
     2767                          struct smb2_tree *tree)
     2768{
     2769        NTSTATUS status;
     2770        bool ret = true;
     2771        struct smb2_handle h, h2;
     2772        uint8_t buf[200];
     2773        struct smb2_lock lck;
     2774        struct smb2_lock_element el[1];
     2775        struct smb2_create io;
     2776
     2777        const char *fname = BASEDIR "\\truncate.txt";
     2778
     2779        status = torture_smb2_testdir(tree, BASEDIR, &h);
     2780        CHECK_STATUS(status, NT_STATUS_OK);
     2781        smb2_util_close(tree, h);
     2782
     2783        status = torture_smb2_testfile(tree, fname, &h);
     2784        CHECK_STATUS(status, NT_STATUS_OK);
     2785
     2786        ZERO_STRUCT(buf);
     2787        status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
     2788        CHECK_STATUS(status, NT_STATUS_OK);
     2789
     2790        torture_comment(torture, "Testing truncation of locked file:\n");
     2791
     2792        /* Setup initial parameters */
     2793        lck.in.locks            = el;
     2794        lck.in.lock_count       = 0x0001;
     2795        lck.in.lock_sequence    = 0x00000000;
     2796        lck.in.file.handle      = h;
     2797        el[0].offset            = 0;
     2798        el[0].length            = 10;
     2799        el[0].reserved          = 0x00000000;
     2800
     2801        ZERO_STRUCT(io);
     2802        io.in.oplock_level = 0;
     2803        io.in.desired_access = SEC_RIGHTS_FILE_ALL;
     2804        io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
     2805        io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
     2806        io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
     2807                             NTCREATEX_SHARE_ACCESS_READ |
     2808                             NTCREATEX_SHARE_ACCESS_WRITE;
     2809        io.in.create_options = 0;
     2810        io.in.fname = fname;
     2811
     2812        /* Take an exclusive lock */
     2813        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
     2814                                  SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     2815        status = smb2_lock(tree, &lck);
     2816        CHECK_STATUS(status, NT_STATUS_OK);
     2817
     2818        /* On second handle open the file with OVERWRITE disposition */
     2819        torture_comment(torture, "  overwrite disposition is allowed on a "
     2820                                 "locked file.\n");
     2821
     2822        io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
     2823        status = smb2_create(tree, tree, &io);
     2824        CHECK_STATUS(status, NT_STATUS_OK);
     2825        h2 = io.out.file.handle;
     2826        smb2_util_close(tree, h2);
     2827
     2828        /* On second handle open the file with SUPERSEDE disposition */
     2829        torture_comment(torture, "  supersede disposition is allowed on a "
     2830                                 "locked file.\n");
     2831
     2832        io.in.create_disposition = NTCREATEX_DISP_SUPERSEDE;
     2833        status = smb2_create(tree, tree, &io);
     2834        CHECK_STATUS(status, NT_STATUS_OK);
     2835        h2 = io.out.file.handle;
     2836        smb2_util_close(tree, h2);
     2837
     2838        /* cleanup */
     2839        lck.in.file.handle      = h;
     2840        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
     2841        status = smb2_lock(tree, &lck);
     2842        CHECK_STATUS(status, NT_STATUS_OK);
     2843
     2844done:
     2845        smb2_util_close(tree, h2);
     2846        smb2_util_close(tree, h);
     2847        smb2_deltree(tree, BASEDIR);
     2848        return ret;
     2849}
    5532850
    5542851/* basic testing of SMB2 locking
     
    5562853struct torture_suite *torture_smb2_lock_init(void)
    5572854{
    558         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "LOCK");
    559 
    560         torture_suite_add_1smb2_test(suite, "VALID-REQUEST", test_valid_request);
    561         torture_suite_add_1smb2_test(suite, "RW-NONE", test_lock_rw_none);
    562         torture_suite_add_1smb2_test(suite, "RW-SHARED", test_lock_rw_shared);
    563         torture_suite_add_1smb2_test(suite, "RW-EXCLUSIV", test_lock_rw_exclusiv);
    564         torture_suite_add_1smb2_test(suite, "AUTO-UNLOCK", test_lock_auto_unlock);
     2855        struct torture_suite *suite =
     2856            torture_suite_create(talloc_autofree_context(), "lock");
     2857
     2858        torture_suite_add_1smb2_test(suite, "valid-request",
     2859            test_valid_request);
     2860        torture_suite_add_1smb2_test(suite, "rw-none", test_lock_rw_none);
     2861        torture_suite_add_1smb2_test(suite, "rw-shared", test_lock_rw_shared);
     2862        torture_suite_add_1smb2_test(suite, "rw-exclusive",
     2863            test_lock_rw_exclusive);
     2864        torture_suite_add_1smb2_test(suite, "auto-unlock",
     2865            test_lock_auto_unlock);
     2866        torture_suite_add_1smb2_test(suite, "lock", test_lock);
     2867        torture_suite_add_1smb2_test(suite, "async", test_async);
     2868        torture_suite_add_1smb2_test(suite, "cancel", test_cancel);
     2869        torture_suite_add_1smb2_test(suite, "cancel-tdis", test_cancel_tdis);
     2870        torture_suite_add_1smb2_test(suite, "cancel-logoff",
     2871            test_cancel_logoff);
     2872        torture_suite_add_1smb2_test(suite, "errorcode", test_errorcode);
     2873        torture_suite_add_1smb2_test(suite, "zerobytelength",
     2874            test_zerobytelength);
     2875        torture_suite_add_1smb2_test(suite, "zerobyteread",
     2876            test_zerobyteread);
     2877        torture_suite_add_1smb2_test(suite, "unlock", test_unlock);
     2878        torture_suite_add_1smb2_test(suite, "multiple-unlock",
     2879            test_multiple_unlock);
     2880        torture_suite_add_1smb2_test(suite, "stacking", test_stacking);
     2881        torture_suite_add_1smb2_test(suite, "contend", test_contend);
     2882        torture_suite_add_1smb2_test(suite, "context", test_context);
     2883        torture_suite_add_1smb2_test(suite, "range", test_range);
     2884        torture_suite_add_2smb2_test(suite, "overlap", test_overlap);
     2885        torture_suite_add_1smb2_test(suite, "truncate", test_truncate);
    5652886
    5662887        suite->description = talloc_strdup(suite, "SMB2-LOCK tests");
     
    5682889        return suite;
    5692890}
    570 
  • trunk/server/source4/torture/smb2/notify.c

    r414 r745  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33
     
    55
    66   Copyright (C) Stefan Metzmacher 2006
    7    
     7   Copyright (C) Andrew Tridgell 2009
     8
    89   This program is free software; you can redistribute it and/or modify
    910   it under the terms of the GNU General Public License as published by
    1011   the Free Software Foundation; either version 3 of the License, or
    1112   (at your option) any later version.
    12    
     13
    1314   This program is distributed in the hope that it will be useful,
    1415   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1516   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1617   GNU General Public License for more details.
    17    
     18
    1819   You should have received a copy of the GNU General Public License
    1920   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2627#include "torture/torture.h"
    2728#include "torture/smb2/proto.h"
     29#include "librpc/gen_ndr/ndr_security.h"
     30#include "libcli/security/security.h"
     31#include "torture/util.h"
     32
     33#include "system/filesys.h"
     34#include "auth/credentials/credentials.h"
     35#include "lib/cmdline/popt_common.h"
     36#include "librpc/gen_ndr/security.h"
     37
     38#include "lib/events/events.h"
    2839
    2940#include "libcli/raw/libcliraw.h"
    30 #include "lib/events/events.h"
     41#include "libcli/raw/raw_proto.h"
     42#include "libcli/libcli.h"
    3143
    3244#define CHECK_STATUS(status, correct) do { \
    3345        if (!NT_STATUS_EQUAL(status, correct)) { \
    34                 printf("(%s) Incorrect status %s - should be %s\n", \
     46                torture_result(torture, TORTURE_FAIL, \
     47                       "(%s) Incorrect status %s - should be %s\n", \
    3548                       __location__, nt_errstr(status), nt_errstr(correct)); \
    3649                ret = false; \
     
    3851        }} while (0)
    3952
    40 #define CHECK_VALUE(v, correct) do { \
     53#define CHECK_VAL(v, correct) do { \
    4154        if ((v) != (correct)) { \
    42                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
    43                        __location__, #v, v, correct); \
     55                torture_result(torture, TORTURE_FAIL, \
     56                       "(%s) wrong value for %s  0x%x should be 0x%x\n", \
     57                       __location__, #v, (int)v, (int)correct); \
    4458                ret = false; \
    4559                goto done; \
     
    4862#define CHECK_WIRE_STR(field, value) do { \
    4963        if (!field.s || strcmp(field.s, value)) { \
    50                 printf("(%s) %s [%s] != %s\n", \
    51                           __location__, #field, field.s, value); \
     64                torture_result(torture, TORTURE_FAIL, \
     65                        "(%s) %s [%s] != %s\n",  __location__, #field, \
     66                        field.s, value); \
    5267                ret = false; \
    5368                goto done; \
    5469        }} while (0)
    5570
     71#define BASEDIR "test_notify"
    5672#define FNAME "smb2-notify01.dat"
    5773
    58 #define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false))
    59 
    60 static bool test_valid_request(struct torture_context *tctx, struct smb2_tree *tree)
     74static bool test_valid_request(struct torture_context *torture,
     75                               struct smb2_tree *tree)
    6176{
    6277        bool ret = true;
     
    6580        struct smb2_notify n;
    6681        struct smb2_request *req;
    67         uint32_t max_buffer_size = 0x00080000;
    68 
    69         if (TARGET_IS_WIN7(tctx)) {
    70                 max_buffer_size = 0x00010000;
    71         }
     82        uint32_t max_buffer_size;
     83
     84        torture_comment(torture, "TESTING VALIDITY OF CHANGE NOTIFY REQUEST\n");
    7285
    7386        smb2_util_unlink(tree, FNAME);
     
    7588        status = smb2_util_roothandle(tree, &dh);
    7689        CHECK_STATUS(status, NT_STATUS_OK);
     90
     91        /* 0x00080000 is the default max buffer size for Windows servers
     92         * pre-Win7 */
     93        max_buffer_size = torture_setting_ulong(torture, "cn_max_buffer_size",
     94                                                0x00080000);
    7795
    7896        n.in.recursive          = 0x0000;
    7997        n.in.buffer_size        = max_buffer_size;
    8098        n.in.file.handle        = dh;
    81         n.in.completion_filter  = 0x00000FFF;
     99        n.in.completion_filter  = FILE_NOTIFY_CHANGE_ALL;
    82100        n.in.unknown            = 0x00000000;
    83101        req = smb2_notify_send(tree, &n);
     
    92110        CHECK_STATUS(status, NT_STATUS_OK);
    93111
    94         status = smb2_notify_recv(req, tctx, &n);
    95         CHECK_STATUS(status, NT_STATUS_OK);
    96         CHECK_VALUE(n.out.num_changes, 1);
    97         CHECK_VALUE(n.out.changes[0].action, NOTIFY_ACTION_ADDED);
     112        status = smb2_notify_recv(req, torture, &n);
     113        CHECK_STATUS(status, NT_STATUS_OK);
     114        CHECK_VAL(n.out.num_changes, 1);
     115        CHECK_VAL(n.out.changes[0].action, NOTIFY_ACTION_ADDED);
    98116        CHECK_WIRE_STR(n.out.changes[0].name, FNAME);
    99117
    100         /* 
     118        /*
    101119         * if the change response doesn't fit in the buffer
    102120         * NOTIFY_ENUM_DIR is returned.
     
    114132        CHECK_STATUS(status, NT_STATUS_OK);
    115133
    116         status = smb2_notify_recv(req, tctx, &n);
     134        status = smb2_notify_recv(req, torture, &n);
    117135        CHECK_STATUS(status, STATUS_NOTIFY_ENUM_DIR);
    118136
    119         /* 
     137        /*
    120138         * if the change response fits in the buffer we get
    121139         * NT_STATUS_OK again
     
    133151        CHECK_STATUS(status, NT_STATUS_OK);
    134152
    135         status = smb2_notify_recv(req, tctx, &n);
    136         CHECK_STATUS(status, NT_STATUS_OK);
    137         CHECK_VALUE(n.out.num_changes, 3);
    138         CHECK_VALUE(n.out.changes[0].action, NOTIFY_ACTION_REMOVED);
     153        status = smb2_notify_recv(req, torture, &n);
     154        CHECK_STATUS(status, NT_STATUS_OK);
     155        CHECK_VAL(n.out.num_changes, 3);
     156        CHECK_VAL(n.out.changes[0].action, NOTIFY_ACTION_REMOVED);
    139157        CHECK_WIRE_STR(n.out.changes[0].name, FNAME);
    140         CHECK_VALUE(n.out.changes[1].action, NOTIFY_ACTION_ADDED);
     158        CHECK_VAL(n.out.changes[1].action, NOTIFY_ACTION_ADDED);
    141159        CHECK_WIRE_STR(n.out.changes[1].name, FNAME);
    142         CHECK_VALUE(n.out.changes[2].action, NOTIFY_ACTION_MODIFIED);
     160        CHECK_VAL(n.out.changes[2].action, NOTIFY_ACTION_MODIFIED);
    143161        CHECK_WIRE_STR(n.out.changes[2].name, FNAME);
    144162
     
    152170        n.in.buffer_size        = 0x00000001;
    153171        n.in.file.handle        = dh;
    154         n.in.completion_filter  = 0x00000FFF;
     172        n.in.completion_filter  = FILE_NOTIFY_CHANGE_ALL;
    155173        n.in.unknown            = 0x00000000;
    156174        req = smb2_notify_send(tree, &n);
     
    165183        CHECK_STATUS(status, NT_STATUS_OK);
    166184
    167         status = smb2_notify_recv(req, tctx, &n);
     185        status = smb2_notify_recv(req, torture, &n);
    168186        CHECK_STATUS(status, STATUS_NOTIFY_ENUM_DIR);
    169187
    170         n.in.buffer_size        = max_buffer_size;
     188        n.in.buffer_size        = max_buffer_size;
    171189        req = smb2_notify_send(tree, &n);
    172190        while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) {
     
    179197        CHECK_STATUS(status, NT_STATUS_OK);
    180198
    181         status = smb2_notify_recv(req, tctx, &n);
     199        status = smb2_notify_recv(req, torture, &n);
    182200        CHECK_STATUS(status, STATUS_NOTIFY_ENUM_DIR);
    183201
     
    186204        n.in.buffer_size        = max_buffer_size + 1;
    187205        n.in.file.handle        = dh;
    188         n.in.completion_filter  = 0x00000FFF;
     206        n.in.completion_filter  = FILE_NOTIFY_CHANGE_ALL;
    189207        n.in.unknown            = 0x00000000;
    190208        req = smb2_notify_send(tree, &n);
    191         status = smb2_notify_recv(req, tctx, &n);
     209        status = smb2_notify_recv(req, torture, &n);
    192210        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    193211
     
    196214}
    197215
    198 /* basic testing of SMB2 notify
     216/*
     217   basic testing of change notify on directories
    199218*/
    200 bool torture_smb2_notify(struct torture_context *torture)
     219static bool torture_smb2_notify_dir(struct torture_context *torture,
     220                              struct smb2_tree *tree1,
     221                              struct smb2_tree *tree2)
    201222{
    202         struct smb2_tree *tree;
    203223        bool ret = true;
    204 
    205         if (!torture_smb2_connection(torture, &tree)) {
    206                 return false;
     224        NTSTATUS status;
     225        union smb_notify notify;
     226        union smb_open io;
     227        union smb_close cl;
     228        int i, count;
     229        struct smb2_handle h1, h2;
     230        struct smb2_request *req, *req2;
     231        const char *fname = BASEDIR "\\subdir-name";
     232        extern int torture_numops;
     233
     234        torture_comment(torture, "TESTING CHANGE NOTIFY ON DIRECTORIES\n");
     235
     236        smb2_deltree(tree1, BASEDIR);
     237        smb2_util_rmdir(tree1, BASEDIR);
     238        /*
     239          get a handle on the directory
     240        */
     241        ZERO_STRUCT(io.smb2);
     242        io.generic.level = RAW_OPEN_SMB2;
     243        io.smb2.in.create_flags = 0;
     244        io.smb2.in.desired_access = SEC_FILE_ALL;
     245        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     246        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     247        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     248                                NTCREATEX_SHARE_ACCESS_WRITE;
     249        io.smb2.in.alloc_size = 0;
     250        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     251        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     252        io.smb2.in.security_flags = 0;
     253        io.smb2.in.fname = BASEDIR;
     254
     255        status = smb2_create(tree1, torture, &(io.smb2));
     256        CHECK_STATUS(status, NT_STATUS_OK);
     257        h1 = io.smb2.out.file.handle;
     258
     259        io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     260        io.smb2.in.desired_access = SEC_RIGHTS_FILE_READ;
     261        status = smb2_create(tree1, torture, &(io.smb2));
     262        CHECK_STATUS(status, NT_STATUS_OK);
     263        h2 = io.smb2.out.file.handle;
     264
     265        /* ask for a change notify,
     266           on file or directory name changes */
     267        ZERO_STRUCT(notify.smb2);
     268        notify.smb2.level = RAW_NOTIFY_SMB2;
     269        notify.smb2.in.buffer_size = 1000;
     270        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
     271        notify.smb2.in.file.handle = h1;
     272        notify.smb2.in.recursive = true;
     273
     274        torture_comment(torture, "Testing notify cancel\n");
     275
     276        req = smb2_notify_send(tree1, &(notify.smb2));
     277        smb2_cancel(req);
     278        status = smb2_notify_recv(req, torture, &(notify.smb2));
     279        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     280
     281        torture_comment(torture, "Testing notify mkdir\n");
     282
     283        req = smb2_notify_send(tree1, &(notify.smb2));
     284        smb2_util_mkdir(tree2, fname);
     285
     286        status = smb2_notify_recv(req, torture, &(notify.smb2));
     287        CHECK_STATUS(status, NT_STATUS_OK);
     288
     289        CHECK_VAL(notify.smb2.out.num_changes, 1);
     290        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_ADDED);
     291        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     292
     293        torture_comment(torture, "Testing notify rmdir\n");
     294
     295        req = smb2_notify_send(tree1, &(notify.smb2));
     296        smb2_util_rmdir(tree2, fname);
     297
     298        status = smb2_notify_recv(req, torture, &(notify.smb2));
     299        CHECK_STATUS(status, NT_STATUS_OK);
     300        CHECK_VAL(notify.smb2.out.num_changes, 1);
     301        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_REMOVED);
     302        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     303
     304        torture_comment(torture,
     305                "Testing notify mkdir - rmdir - mkdir - rmdir\n");
     306
     307        smb2_util_mkdir(tree2, fname);
     308        smb2_util_rmdir(tree2, fname);
     309        smb2_util_mkdir(tree2, fname);
     310        smb2_util_rmdir(tree2, fname);
     311        smb_msleep(200);
     312        req = smb2_notify_send(tree1, &(notify.smb2));
     313        status = smb2_notify_recv(req, torture, &(notify.smb2));
     314        CHECK_STATUS(status, NT_STATUS_OK);
     315        CHECK_VAL(notify.smb2.out.num_changes, 4);
     316        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_ADDED);
     317        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     318        CHECK_VAL(notify.smb2.out.changes[1].action, NOTIFY_ACTION_REMOVED);
     319        CHECK_WIRE_STR(notify.smb2.out.changes[1].name, "subdir-name");
     320        CHECK_VAL(notify.smb2.out.changes[2].action, NOTIFY_ACTION_ADDED);
     321        CHECK_WIRE_STR(notify.smb2.out.changes[2].name, "subdir-name");
     322        CHECK_VAL(notify.smb2.out.changes[3].action, NOTIFY_ACTION_REMOVED);
     323        CHECK_WIRE_STR(notify.smb2.out.changes[3].name, "subdir-name");
     324
     325        count = torture_numops;
     326        torture_comment(torture,
     327                "Testing buffered notify on create of %d files\n", count);
     328        for (i=0;i<count;i++) {
     329                struct smb2_handle h12;
     330                char *fname2 = talloc_asprintf(torture, BASEDIR "\\test%d.txt",
     331                                              i);
     332
     333                ZERO_STRUCT(io.smb2);
     334                io.generic.level = RAW_OPEN_SMB2;
     335                io.smb2.in.create_flags = 0;
     336                io.smb2.in.desired_access = SEC_FILE_ALL;
     337                io.smb2.in.create_options =
     338                    NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     339                io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     340                io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     341                                        NTCREATEX_SHARE_ACCESS_WRITE;
     342                io.smb2.in.alloc_size = 0;
     343                io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     344                io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     345                io.smb2.in.security_flags = 0;
     346                io.smb2.in.fname = fname2;
     347
     348                status = smb2_create(tree1, torture, &(io.smb2));
     349                if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
     350                        torture_comment(torture, "Failed to create %s \n",
     351                               fname);
     352                        ret = false;
     353                        goto done;
     354                }
     355                h12 = io.smb2.out.file.handle;
     356                talloc_free(fname2);
     357                smb2_util_close(tree1, h12);
    207358        }
    208359
    209         ret &= test_valid_request(torture, tree);
    210 
     360        /* (1st notify) setup a new notify on a different directory handle.
     361           This new notify won't see the events above. */
     362        notify.smb2.in.file.handle = h2;
     363        req2 = smb2_notify_send(tree1, &(notify.smb2));
     364
     365        /* (2nd notify) whereas this notify will see the above buffered events,
     366           and it directly returns the buffered events */
     367        notify.smb2.in.file.handle = h1;
     368        req = smb2_notify_send(tree1, &(notify.smb2));
     369
     370        status = smb2_util_unlink(tree1, BASEDIR "\\nonexistant.txt");
     371        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     372
     373        /* (1st unlink) as the 2nd notify directly returns,
     374           this unlink is only seen by the 1st notify and
     375           the 3rd notify (later) */
     376        torture_comment(torture,
     377                "Testing notify on unlink for the first file\n");
     378        status = smb2_util_unlink(tree2, BASEDIR "\\test0.txt");
     379        CHECK_STATUS(status, NT_STATUS_OK);
     380
     381        /* receive the reply from the 2nd notify */
     382        status = smb2_notify_recv(req, torture, &(notify.smb2));
     383        CHECK_STATUS(status, NT_STATUS_OK);
     384
     385        CHECK_VAL(notify.smb2.out.num_changes, count);
     386        for (i=1;i<count;i++) {
     387                CHECK_VAL(notify.smb2.out.changes[i].action,
     388                          NOTIFY_ACTION_ADDED);
     389        }
     390        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "test0.txt");
     391
     392        torture_comment(torture, "and now from the 1st notify\n");
     393        status = smb2_notify_recv(req2, torture, &(notify.smb2));
     394        CHECK_STATUS(status, NT_STATUS_OK);
     395        CHECK_VAL(notify.smb2.out.num_changes, 1);
     396        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_REMOVED);
     397        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "test0.txt");
     398
     399        torture_comment(torture,
     400                "(3rd notify) this notify will only see the 1st unlink\n");
     401        req = smb2_notify_send(tree1, &(notify.smb2));
     402
     403        status = smb2_util_unlink(tree1, BASEDIR "\\nonexistant.txt");
     404        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     405
     406        for (i=1;i<count;i++) {
     407                char *fname2 = talloc_asprintf(torture,
     408                              BASEDIR "\\test%d.txt", i);
     409                status = smb2_util_unlink(tree2, fname2);
     410                CHECK_STATUS(status, NT_STATUS_OK);
     411                talloc_free(fname2);
     412        }
     413
     414        /* receive the 3rd notify */
     415        status = smb2_notify_recv(req, torture, &(notify.smb2));
     416        CHECK_STATUS(status, NT_STATUS_OK);
     417        CHECK_VAL(notify.smb2.out.num_changes, 1);
     418        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_REMOVED);
     419        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "test0.txt");
     420
     421        /* and we now see the rest of the unlink calls on both
     422         * directory handles */
     423        notify.smb2.in.file.handle = h1;
     424        sleep(3);
     425        req = smb2_notify_send(tree1, &(notify.smb2));
     426        status = smb2_notify_recv(req, torture, &(notify.smb2));
     427        CHECK_STATUS(status, NT_STATUS_OK);
     428        CHECK_VAL(notify.smb2.out.num_changes, count-1);
     429        for (i=0;i<notify.smb2.out.num_changes;i++) {
     430                CHECK_VAL(notify.smb2.out.changes[i].action,
     431                          NOTIFY_ACTION_REMOVED);
     432        }
     433        notify.smb2.in.file.handle = h2;
     434        req = smb2_notify_send(tree1, &(notify.smb2));
     435        status = smb2_notify_recv(req, torture, &(notify.smb2));
     436        CHECK_STATUS(status, NT_STATUS_OK);
     437        CHECK_VAL(notify.smb2.out.num_changes, count-1);
     438        for (i=0;i<notify.smb2.out.num_changes;i++) {
     439                CHECK_VAL(notify.smb2.out.changes[i].action,
     440                          NOTIFY_ACTION_REMOVED);
     441        }
     442
     443        torture_comment(torture,
     444        "Testing if a close() on the dir handle triggers the notify reply\n");
     445
     446        notify.smb2.in.file.handle = h1;
     447        req = smb2_notify_send(tree1, &(notify.smb2));
     448
     449        ZERO_STRUCT(cl.smb2);
     450        cl.smb2.level = RAW_CLOSE_SMB2;
     451        cl.smb2.in.file.handle = h1;
     452        status = smb2_close(tree1, &(cl.smb2));
     453        CHECK_STATUS(status, NT_STATUS_OK);
     454
     455        status = smb2_notify_recv(req, torture, &(notify.smb2));
     456        CHECK_STATUS(status, STATUS_NOTIFY_CLEANUP);
     457        CHECK_VAL(notify.smb2.out.num_changes, 9);
     458
     459done:
     460        smb2_util_close(tree1, h1);
     461        smb2_util_close(tree1, h2);
     462        smb2_deltree(tree1, BASEDIR);
    211463        return ret;
    212464}
     465
     466static struct smb2_handle custom_smb2_create(struct smb2_tree *tree,
     467                                                struct torture_context *torture,
     468                                                struct smb2_create *smb2)
     469{
     470        struct smb2_handle h1;
     471        bool ret = true;
     472        NTSTATUS status;
     473        smb2_deltree(tree, smb2->in.fname);
     474        status = smb2_create(tree, torture, smb2);
     475        CHECK_STATUS(status, NT_STATUS_OK);
     476        h1 = smb2->out.file.handle;
     477done:
     478        return h1;
     479}
     480
     481/*
     482   testing of recursive change notify
     483*/
     484
     485static bool torture_smb2_notify_recursive(struct torture_context *torture,
     486                                struct smb2_tree *tree1,
     487                                struct smb2_tree *tree2)
     488{
     489        bool ret = true;
     490        NTSTATUS status;
     491        union smb_notify notify;
     492        union smb_open io, io1;
     493        union smb_setfileinfo sinfo;
     494        struct smb2_handle h1;
     495        struct smb2_request *req1, *req2;
     496
     497        smb2_deltree(tree1, BASEDIR);
     498        smb2_util_rmdir(tree1, BASEDIR);
     499
     500        torture_comment(torture, "TESTING CHANGE NOTIFY WITH RECURSION\n");
     501
     502        /*
     503          get a handle on the directory
     504        */
     505        ZERO_STRUCT(io.smb2);
     506        io.generic.level = RAW_OPEN_SMB2;
     507        io.smb2.in.create_flags = 0;
     508        io.smb2.in.desired_access = SEC_FILE_ALL;
     509        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     510        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     511        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     512                                NTCREATEX_SHARE_ACCESS_WRITE;
     513        io.smb2.in.alloc_size = 0;
     514        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     515        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     516        io.smb2.in.security_flags = 0;
     517        io.smb2.in.fname = BASEDIR;
     518
     519        status = smb2_create(tree1, torture, &(io.smb2));
     520        CHECK_STATUS(status, NT_STATUS_OK);
     521        h1 = io.smb2.out.file.handle;
     522
     523        /* ask for a change notify, on file or directory name
     524           changes. Setup both with and without recursion */
     525        ZERO_STRUCT(notify.smb2);
     526        notify.smb2.level = RAW_NOTIFY_SMB2;
     527        notify.smb2.in.buffer_size = 1000;
     528        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME |
     529                                FILE_NOTIFY_CHANGE_ATTRIBUTES |
     530                                FILE_NOTIFY_CHANGE_CREATION;
     531        notify.smb2.in.file.handle = h1;
     532
     533        notify.smb2.in.recursive = true;
     534        req1 = smb2_notify_send(tree1, &(notify.smb2));
     535        smb2_cancel(req1);
     536        status = smb2_notify_recv(req1, torture, &(notify.smb2));
     537        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     538
     539        notify.smb2.in.recursive = false;
     540        req2 = smb2_notify_send(tree1, &(notify.smb2));
     541        smb2_cancel(req2);
     542        status = smb2_notify_recv(req2, torture, &(notify.smb2));
     543        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     544
     545        ZERO_STRUCT(io1.smb2);
     546        io1.generic.level = RAW_OPEN_SMB2;
     547        io1.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     548        io1.smb2.in.desired_access = SEC_RIGHTS_FILE_READ |
     549                                SEC_RIGHTS_FILE_WRITE|
     550                                SEC_RIGHTS_FILE_ALL;
     551        io1.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     552        io1.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     553        io1.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     554                                NTCREATEX_SHARE_ACCESS_WRITE |
     555                                NTCREATEX_SHARE_ACCESS_DELETE;
     556        io1.smb2.in.alloc_size = 0;
     557        io1.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     558        io1.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     559        io1.smb2.in.security_flags = 0;
     560        io1.smb2.in.fname = BASEDIR "\\subdir-name";
     561        status = smb2_create(tree2, torture, &(io1.smb2));
     562        CHECK_STATUS(status, NT_STATUS_OK);
     563        smb2_util_close(tree2, io1.smb2.out.file.handle);
     564
     565        io1.smb2.in.fname = BASEDIR "\\subdir-name\\subname1";
     566        status = smb2_create(tree2, torture, &(io1.smb2));
     567        CHECK_STATUS(status, NT_STATUS_OK);
     568        ZERO_STRUCT(sinfo);
     569        sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     570        sinfo.rename_information.in.file.handle = io1.smb2.out.file.handle;
     571        sinfo.rename_information.in.overwrite = 0;
     572        sinfo.rename_information.in.root_fid = 0;
     573        sinfo.rename_information.in.new_name =
     574                                BASEDIR "\\subdir-name\\subname1-r";
     575        status = smb2_setinfo_file(tree2, &sinfo);
     576        CHECK_STATUS(status, NT_STATUS_OK);
     577
     578        io1.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     579        io1.smb2.in.fname = BASEDIR "\\subdir-name\\subname2";
     580        status = smb2_create(tree2, torture, &(io1.smb2));
     581        CHECK_STATUS(status, NT_STATUS_OK);
     582        ZERO_STRUCT(sinfo);
     583        sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     584        sinfo.rename_information.in.file.handle = io1.smb2.out.file.handle;
     585        sinfo.rename_information.in.overwrite = true;
     586        sinfo.rename_information.in.root_fid = 0;
     587        sinfo.rename_information.in.new_name = BASEDIR "\\subname2-r";
     588        status = smb2_setinfo_file(tree2, &sinfo);
     589        CHECK_STATUS(status, NT_STATUS_OK);
     590
     591        io1.smb2.in.fname = BASEDIR "\\subname2-r";
     592        io1.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     593        status = smb2_create(tree2, torture, &(io1.smb2));
     594        CHECK_STATUS(status, NT_STATUS_OK);
     595        ZERO_STRUCT(sinfo);
     596        sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     597        sinfo.rename_information.in.file.handle = io1.smb2.out.file.handle;
     598        sinfo.rename_information.in.overwrite = true;
     599        sinfo.rename_information.in.root_fid = 0;
     600        sinfo.rename_information.in.new_name = BASEDIR "\\subname3-r";
     601        status = smb2_setinfo_file(tree2, &sinfo);
     602        CHECK_STATUS(status, NT_STATUS_OK);
     603
     604        notify.smb2.in.completion_filter = 0;
     605        notify.smb2.in.recursive = true;
     606        smb_msleep(200);
     607        req1 = smb2_notify_send(tree1, &(notify.smb2));
     608
     609        status = smb2_util_rmdir(tree2, BASEDIR "\\subdir-name\\subname1-r");
     610        CHECK_STATUS(status, NT_STATUS_OK);
     611        status = smb2_util_rmdir(tree2, BASEDIR "\\subdir-name");
     612        CHECK_STATUS(status, NT_STATUS_OK);
     613        status = smb2_util_unlink(tree2, BASEDIR "\\subname3-r");
     614        CHECK_STATUS(status, NT_STATUS_OK);
     615
     616        notify.smb2.in.recursive = false;
     617        req2 = smb2_notify_send(tree1, &(notify.smb2));
     618
     619        status = smb2_notify_recv(req1, torture, &(notify.smb2));
     620        CHECK_STATUS(status, NT_STATUS_OK);
     621
     622        CHECK_VAL(notify.smb2.out.num_changes, 9);
     623        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_ADDED);
     624        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     625        CHECK_VAL(notify.smb2.out.changes[1].action, NOTIFY_ACTION_ADDED);
     626        CHECK_WIRE_STR(notify.smb2.out.changes[1].name, "subdir-name\\subname1");
     627        CHECK_VAL(notify.smb2.out.changes[2].action, NOTIFY_ACTION_OLD_NAME);
     628        CHECK_WIRE_STR(notify.smb2.out.changes[2].name, "subdir-name\\subname1");
     629        CHECK_VAL(notify.smb2.out.changes[3].action, NOTIFY_ACTION_NEW_NAME);
     630        CHECK_WIRE_STR(notify.smb2.out.changes[3].name, "subdir-name\\subname1-r");
     631        CHECK_VAL(notify.smb2.out.changes[4].action, NOTIFY_ACTION_ADDED);
     632        CHECK_WIRE_STR(notify.smb2.out.changes[4].name, "subdir-name\\subname2");
     633        CHECK_VAL(notify.smb2.out.changes[5].action, NOTIFY_ACTION_REMOVED);
     634        CHECK_WIRE_STR(notify.smb2.out.changes[5].name, "subdir-name\\subname2");
     635        CHECK_VAL(notify.smb2.out.changes[6].action, NOTIFY_ACTION_ADDED);
     636        CHECK_WIRE_STR(notify.smb2.out.changes[6].name, "subname2-r");
     637        CHECK_VAL(notify.smb2.out.changes[7].action, NOTIFY_ACTION_OLD_NAME);
     638        CHECK_WIRE_STR(notify.smb2.out.changes[7].name, "subname2-r");
     639        CHECK_VAL(notify.smb2.out.changes[8].action, NOTIFY_ACTION_NEW_NAME);
     640        CHECK_WIRE_STR(notify.smb2.out.changes[8].name, "subname3-r");
     641
     642done:
     643        smb2_deltree(tree1, BASEDIR);
     644        return ret;
     645}
     646
     647/*
     648   testing of change notify mask change
     649*/
     650
     651static bool torture_smb2_notify_mask_change(struct torture_context *torture,
     652                                            struct smb2_tree *tree1,
     653                                            struct smb2_tree *tree2)
     654{
     655        bool ret = true;
     656        NTSTATUS status;
     657        union smb_notify notify;
     658        union smb_open io, io1;
     659        struct smb2_handle h1;
     660        struct smb2_request *req1, *req2;
     661        union smb_setfileinfo sinfo;
     662
     663        smb2_deltree(tree1, BASEDIR);
     664        smb2_util_rmdir(tree1, BASEDIR);
     665
     666        torture_comment(torture, "TESTING CHANGE NOTIFY WITH MASK CHANGE\n");
     667
     668        /*
     669          get a handle on the directory
     670        */
     671        ZERO_STRUCT(io.smb2);
     672        io.generic.level = RAW_OPEN_SMB2;
     673        io.smb2.in.create_flags = 0;
     674        io.smb2.in.desired_access = SEC_FILE_ALL;
     675        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     676        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     677        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     678                                NTCREATEX_SHARE_ACCESS_WRITE;
     679        io.smb2.in.alloc_size = 0;
     680        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     681        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     682        io.smb2.in.security_flags = 0;
     683        io.smb2.in.fname = BASEDIR;
     684
     685        status = smb2_create(tree1, torture, &(io.smb2));
     686        CHECK_STATUS(status, NT_STATUS_OK);
     687        h1 = io.smb2.out.file.handle;
     688
     689        /* ask for a change notify, on file or directory name
     690           changes. Setup both with and without recursion */
     691        ZERO_STRUCT(notify.smb2);
     692        notify.smb2.level = RAW_NOTIFY_SMB2;
     693        notify.smb2.in.buffer_size = 1000;
     694        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_ATTRIBUTES;
     695        notify.smb2.in.file.handle = h1;
     696
     697        notify.smb2.in.recursive = true;
     698        req1 = smb2_notify_send(tree1, &(notify.smb2));
     699
     700        smb2_cancel(req1);
     701        status = smb2_notify_recv(req1, torture, &(notify.smb2));
     702        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     703
     704
     705        notify.smb2.in.recursive = false;
     706        req2 = smb2_notify_send(tree1, &(notify.smb2));
     707
     708        smb2_cancel(req2);
     709        status = smb2_notify_recv(req2, torture, &(notify.smb2));
     710        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     711
     712        notify.smb2.in.recursive = true;
     713        req1 = smb2_notify_send(tree1, &(notify.smb2));
     714
     715        /* Set to hidden then back again. */
     716        ZERO_STRUCT(io1.smb2);
     717        io1.generic.level = RAW_OPEN_SMB2;
     718        io1.smb2.in.create_flags = 0;
     719        io1.smb2.in.desired_access = SEC_RIGHTS_FILE_READ |
     720                                SEC_RIGHTS_FILE_WRITE|
     721                                SEC_RIGHTS_FILE_ALL;
     722        io1.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     723        io1.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     724                                NTCREATEX_SHARE_ACCESS_WRITE |
     725                                NTCREATEX_SHARE_ACCESS_DELETE;
     726        io1.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     727        io1.smb2.in.security_flags = 0;
     728        io1.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     729        io1.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     730        io1.smb2.in.fname = BASEDIR "\\tname1";
     731
     732        smb2_util_close(tree1,
     733                custom_smb2_create(tree1, torture, &(io1.smb2)));
     734        status = smb2_util_setatr(tree1, BASEDIR "\\tname1",
     735                                FILE_ATTRIBUTE_HIDDEN);
     736        CHECK_STATUS(status, NT_STATUS_OK);
     737        smb2_util_unlink(tree1, BASEDIR "\\tname1");
     738
     739        status = smb2_notify_recv(req1, torture, &(notify.smb2));
     740        CHECK_STATUS(status, NT_STATUS_OK);
     741
     742        CHECK_VAL(notify.smb2.out.num_changes, 1);
     743        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_MODIFIED);
     744        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "tname1");
     745
     746        /* Now try and change the mask to include other events.
     747         * This should not work - once the mask is set on a directory
     748         * h1 it seems to be fixed until the fnum is closed. */
     749
     750        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME |
     751                                        FILE_NOTIFY_CHANGE_ATTRIBUTES |
     752                                        FILE_NOTIFY_CHANGE_CREATION;
     753        notify.smb2.in.recursive = true;
     754        req1 = smb2_notify_send(tree1, &(notify.smb2));
     755
     756        notify.smb2.in.recursive = false;
     757        req2 = smb2_notify_send(tree1, &(notify.smb2));
     758
     759        io1.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     760        io1.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     761        io1.smb2.in.fname = BASEDIR "\\subdir-name";
     762        status = smb2_create(tree2, torture, &(io1.smb2));
     763        CHECK_STATUS(status, NT_STATUS_OK);
     764        smb2_util_close(tree2, io1.smb2.out.file.handle);
     765
     766        ZERO_STRUCT(sinfo);
     767        io1.smb2.in.fname = BASEDIR "\\subdir-name\\subname1";
     768        io1.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     769        io1.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     770        status = smb2_create(tree2, torture, &(io1.smb2));
     771        CHECK_STATUS(status, NT_STATUS_OK);
     772        sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     773        sinfo.rename_information.in.file.handle = io1.smb2.out.file.handle;
     774        sinfo.rename_information.in.overwrite = true;
     775        sinfo.rename_information.in.root_fid = 0;
     776        sinfo.rename_information.in.new_name =
     777                                BASEDIR "\\subdir-name\\subname1-r";
     778        status = smb2_setinfo_file(tree2, &sinfo);
     779        CHECK_STATUS(status, NT_STATUS_OK);
     780
     781        io1.smb2.in.fname = BASEDIR "\\subdir-name\\subname2";
     782        io1.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     783        io1.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     784        status = smb2_create(tree2, torture, &(io1.smb2));
     785        CHECK_STATUS(status, NT_STATUS_OK);
     786        sinfo.rename_information.in.file.handle = io1.smb2.out.file.handle;
     787        sinfo.rename_information.in.new_name = BASEDIR "\\subname2-r";
     788        status = smb2_setinfo_file(tree2, &sinfo);
     789        CHECK_STATUS(status, NT_STATUS_OK);
     790        smb2_util_close(tree2, io1.smb2.out.file.handle);
     791
     792        io1.smb2.in.fname = BASEDIR "\\subname2-r";
     793        io1.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     794        status = smb2_create(tree2, torture, &(io1.smb2));
     795        CHECK_STATUS(status, NT_STATUS_OK);
     796        sinfo.rename_information.in.file.handle = io1.smb2.out.file.handle;
     797        sinfo.rename_information.in.new_name = BASEDIR "\\subname3-r";
     798        status = smb2_setinfo_file(tree2, &sinfo);
     799        CHECK_STATUS(status, NT_STATUS_OK);
     800        smb2_util_close(tree2, io1.smb2.out.file.handle);
     801
     802        status = smb2_util_rmdir(tree2, BASEDIR "\\subdir-name\\subname1-r");
     803        CHECK_STATUS(status, NT_STATUS_OK);
     804        status = smb2_util_rmdir(tree2, BASEDIR "\\subdir-name");
     805        CHECK_STATUS(status, NT_STATUS_OK);
     806        status = smb2_util_unlink(tree2, BASEDIR "\\subname3-r");
     807        CHECK_STATUS(status, NT_STATUS_OK);
     808
     809        status = smb2_notify_recv(req1, torture, &(notify.smb2));
     810        CHECK_STATUS(status, NT_STATUS_OK);
     811
     812        CHECK_VAL(notify.smb2.out.num_changes, 1);
     813        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_MODIFIED);
     814        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subname2-r");
     815
     816        status = smb2_notify_recv(req2, torture, &(notify.smb2));
     817        CHECK_STATUS(status, NT_STATUS_OK);
     818
     819        CHECK_VAL(notify.smb2.out.num_changes, 1);
     820        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_MODIFIED);
     821        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subname3-r");
     822
     823        if (!ret) {
     824                goto done;
     825        }
     826
     827done:
     828        smb2_deltree(tree1, BASEDIR);
     829        return ret;
     830}
     831
     832/*
     833   testing of mask bits for change notify
     834*/
     835
     836static bool torture_smb2_notify_mask(struct torture_context *torture,
     837                                     struct smb2_tree *tree1,
     838                                     struct smb2_tree *tree2)
     839{
     840        bool ret = true;
     841        NTSTATUS status;
     842        union smb_notify notify;
     843        union smb_open io, io1;
     844        struct smb2_handle h1, h2;
     845        uint32_t mask;
     846        int i;
     847        char c = 1;
     848        struct timeval tv;
     849        NTTIME t;
     850        union smb_setfileinfo sinfo;
     851
     852        smb2_deltree(tree1, BASEDIR);
     853        smb2_util_rmdir(tree1, BASEDIR);
     854
     855        torture_comment(torture, "TESTING CHANGE NOTIFY COMPLETION FILTERS\n");
     856
     857        tv = timeval_current_ofs(1000, 0);
     858        t = timeval_to_nttime(&tv);
     859
     860        /*
     861          get a handle on the directory
     862        */
     863        ZERO_STRUCT(io.smb2);
     864        io.generic.level = RAW_OPEN_SMB2;
     865        io.smb2.in.create_flags = 0;
     866        io.smb2.in.desired_access = SEC_FILE_ALL;
     867        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     868        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     869        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     870                                NTCREATEX_SHARE_ACCESS_WRITE;
     871        io.smb2.in.alloc_size = 0;
     872        io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     873        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     874        io.smb2.in.security_flags = 0;
     875        io.smb2.in.fname = BASEDIR;
     876
     877        ZERO_STRUCT(notify.smb2);
     878        notify.smb2.level = RAW_NOTIFY_SMB2;
     879        notify.smb2.in.buffer_size = 1000;
     880        notify.smb2.in.recursive = true;
     881
     882#define NOTIFY_MASK_TEST(test_name, setup, op, cleanup, Action, \
     883                         expected, nchanges) \
     884        do { \
     885        do { for (mask=i=0;i<32;i++) { \
     886                struct smb2_request *req; \
     887                status = smb2_create(tree1, torture, &(io.smb2)); \
     888                CHECK_STATUS(status, NT_STATUS_OK); \
     889                h1 = io.smb2.out.file.handle; \
     890                setup \
     891                notify.smb2.in.file.handle = h1;        \
     892                notify.smb2.in.completion_filter = (1<<i); \
     893                /* cancel initial requests so the buffer is setup */    \
     894                req = smb2_notify_send(tree1, &(notify.smb2)); \
     895                smb2_cancel(req); \
     896                status = smb2_notify_recv(req, torture, &(notify.smb2)); \
     897                CHECK_STATUS(status, NT_STATUS_CANCELLED); \
     898                /* send the change notify request */ \
     899                req = smb2_notify_send(tree1, &(notify.smb2)); \
     900                op \
     901                smb_msleep(200); smb2_cancel(req); \
     902                status = smb2_notify_recv(req, torture, &(notify.smb2)); \
     903                cleanup \
     904                smb2_util_close(tree1, h1); \
     905                if (NT_STATUS_EQUAL(status, NT_STATUS_CANCELLED)) continue; \
     906                CHECK_STATUS(status, NT_STATUS_OK); \
     907                /* special case to cope with file rename behaviour */ \
     908                if (nchanges == 2 && notify.smb2.out.num_changes == 1 && \
     909                    notify.smb2.out.changes[0].action == \
     910                        NOTIFY_ACTION_MODIFIED && \
     911                    ((expected) & FILE_NOTIFY_CHANGE_ATTRIBUTES) && \
     912                    Action == NOTIFY_ACTION_OLD_NAME) { \
     913                        torture_comment(torture, \
     914                                "(rename file special handling OK)\n"); \
     915                } else if (nchanges != notify.smb2.out.num_changes) { \
     916                        torture_result(torture, TORTURE_FAIL, \
     917                               "ERROR: nchanges=%d expected=%d "\
     918                               "action=%d filter=0x%08x\n", \
     919                               notify.smb2.out.num_changes, \
     920                               nchanges, \
     921                               notify.smb2.out.changes[0].action, \
     922                               notify.smb2.in.completion_filter); \
     923                        ret = false; \
     924                } else if (notify.smb2.out.changes[0].action != Action) { \
     925                        torture_result(torture, TORTURE_FAIL, \
     926                               "ERROR: nchanges=%d action=%d " \
     927                               "expectedAction=%d filter=0x%08x\n", \
     928                               notify.smb2.out.num_changes, \
     929                               notify.smb2.out.changes[0].action, \
     930                               Action, \
     931                               notify.smb2.in.completion_filter); \
     932                        ret = false; \
     933                } else if (strcmp(notify.smb2.out.changes[0].name.s, \
     934                           "tname1") != 0) { \
     935                        torture_result(torture, TORTURE_FAIL, \
     936                               "ERROR: nchanges=%d action=%d " \
     937                               "filter=0x%08x name=%s\n", \
     938                               notify.smb2.out.num_changes, \
     939                               notify.smb2.out.changes[0].action, \
     940                               notify.smb2.in.completion_filter, \
     941                               notify.smb2.out.changes[0].name.s);      \
     942                        ret = false; \
     943                } \
     944                mask |= (1<<i); \
     945        } \
     946        } while (0); \
     947        } while (0);
     948
     949        torture_comment(torture, "Testing mkdir\n");
     950        NOTIFY_MASK_TEST("Testing mkdir",;,
     951                         smb2_util_mkdir(tree2, BASEDIR "\\tname1");,
     952                         smb2_util_rmdir(tree2, BASEDIR "\\tname1");,
     953                         NOTIFY_ACTION_ADDED,
     954                         FILE_NOTIFY_CHANGE_DIR_NAME, 1);
     955
     956        torture_comment(torture, "Testing create file\n");
     957        ZERO_STRUCT(io1.smb2);
     958        io1.generic.level = RAW_OPEN_SMB2;
     959        io1.smb2.in.create_flags = 0;
     960        io1.smb2.in.desired_access = SEC_FILE_ALL;
     961        io1.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     962        io1.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     963                                NTCREATEX_SHARE_ACCESS_WRITE;
     964        io1.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     965        io1.smb2.in.security_flags = 0;
     966        io1.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     967        io1.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     968        io1.smb2.in.fname = BASEDIR "\\tname1";
     969
     970        NOTIFY_MASK_TEST("Testing create file",;,
     971                         smb2_util_close(tree2, custom_smb2_create(tree2,
     972                                                torture, &(io1.smb2)));,
     973                         smb2_util_unlink(tree2, BASEDIR "\\tname1");,
     974                         NOTIFY_ACTION_ADDED,
     975                         FILE_NOTIFY_CHANGE_FILE_NAME, 1);
     976
     977        torture_comment(torture, "Testing unlink\n");
     978        NOTIFY_MASK_TEST("Testing unlink",
     979                         smb2_util_close(tree2, custom_smb2_create(tree2,
     980                                                torture, &(io1.smb2)));,
     981                         smb2_util_unlink(tree2, BASEDIR "\\tname1");,
     982                         ;,
     983                         NOTIFY_ACTION_REMOVED,
     984                         FILE_NOTIFY_CHANGE_FILE_NAME, 1);
     985
     986        torture_comment(torture, "Testing rmdir\n");
     987        NOTIFY_MASK_TEST("Testing rmdir",
     988                         smb2_util_mkdir(tree2, BASEDIR "\\tname1");,
     989                         smb2_util_rmdir(tree2, BASEDIR "\\tname1");,
     990                         ;,
     991                         NOTIFY_ACTION_REMOVED,
     992                         FILE_NOTIFY_CHANGE_DIR_NAME, 1);
     993
     994        torture_comment(torture, "Testing rename file\n");
     995        ZERO_STRUCT(sinfo);
     996        sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     997        sinfo.rename_information.in.file.handle = h1;
     998        sinfo.rename_information.in.overwrite = true;
     999        sinfo.rename_information.in.root_fid = 0;
     1000        sinfo.rename_information.in.new_name = BASEDIR "\\tname2";
     1001        NOTIFY_MASK_TEST("Testing rename file",
     1002                         smb2_util_close(tree2, custom_smb2_create(tree2,
     1003                                                torture, &(io1.smb2)));,
     1004                         smb2_setinfo_file(tree2, &sinfo);,
     1005                         smb2_util_unlink(tree2, BASEDIR "\\tname2");,
     1006                         NOTIFY_ACTION_OLD_NAME,
     1007                         FILE_NOTIFY_CHANGE_FILE_NAME, 2);
     1008
     1009        torture_comment(torture, "Testing rename dir\n");
     1010        ZERO_STRUCT(sinfo);
     1011        sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     1012        sinfo.rename_information.in.file.handle = h1;
     1013        sinfo.rename_information.in.overwrite = true;
     1014        sinfo.rename_information.in.root_fid = 0;
     1015        sinfo.rename_information.in.new_name = BASEDIR "\\tname2";
     1016        NOTIFY_MASK_TEST("Testing rename dir",
     1017                smb2_util_mkdir(tree2, BASEDIR "\\tname1");,
     1018                smb2_setinfo_file(tree2, &sinfo);,
     1019                smb2_util_rmdir(tree2, BASEDIR "\\tname2");,
     1020                NOTIFY_ACTION_OLD_NAME,
     1021                FILE_NOTIFY_CHANGE_DIR_NAME, 2);
     1022
     1023        torture_comment(torture, "Testing set path attribute\n");
     1024        NOTIFY_MASK_TEST("Testing set path attribute",
     1025                smb2_util_close(tree2, custom_smb2_create(tree2,
     1026                                       torture, &(io.smb2)));,
     1027                smb2_util_setatr(tree2, BASEDIR "\\tname1",
     1028                                 FILE_ATTRIBUTE_HIDDEN);,
     1029                smb2_util_unlink(tree2, BASEDIR "\\tname1");,
     1030                NOTIFY_ACTION_MODIFIED,
     1031                FILE_NOTIFY_CHANGE_ATTRIBUTES, 1);
     1032
     1033        torture_comment(torture, "Testing set path write time\n");
     1034        ZERO_STRUCT(sinfo);
     1035        sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
     1036        sinfo.generic.in.file.handle = h1;
     1037        sinfo.basic_info.in.write_time = 1000;
     1038        NOTIFY_MASK_TEST("Testing set path write time",
     1039                smb2_util_close(tree2, custom_smb2_create(tree2,
     1040                                       torture, &(io1.smb2)));,
     1041                smb2_setinfo_file(tree2, &sinfo);,
     1042                smb2_util_unlink(tree2, BASEDIR "\\tname1");,
     1043                NOTIFY_ACTION_MODIFIED,
     1044                FILE_NOTIFY_CHANGE_LAST_WRITE, 1);
     1045
     1046        if (torture_setting_bool(torture, "samba3", false)) {
     1047                torture_comment(torture,
     1048                       "Samba3 does not yet support create times "
     1049                       "everywhere\n");
     1050        }
     1051        else {
     1052                ZERO_STRUCT(sinfo);
     1053                sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
     1054                sinfo.generic.in.file.handle = h1;
     1055                sinfo.basic_info.in.create_time = 0;
     1056                torture_comment(torture, "Testing set file create time\n");
     1057                NOTIFY_MASK_TEST("Testing set file create time",
     1058                        smb2_create_complex_file(tree2,
     1059                        BASEDIR "\\tname1", &h2);,
     1060                        smb2_setinfo_file(tree2, &sinfo);,
     1061                        (smb2_util_close(tree2, h2),
     1062                         smb2_util_unlink(tree2, BASEDIR "\\tname1"));,
     1063                        NOTIFY_ACTION_MODIFIED,
     1064                        FILE_NOTIFY_CHANGE_CREATION, 1);
     1065        }
     1066
     1067        ZERO_STRUCT(sinfo);
     1068        sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
     1069        sinfo.generic.in.file.handle = h1;
     1070        sinfo.basic_info.in.access_time = 0;
     1071        torture_comment(torture, "Testing set file access time\n");
     1072        NOTIFY_MASK_TEST("Testing set file access time",
     1073                smb2_create_complex_file(tree2, BASEDIR "\\tname1", &h2);,
     1074                smb2_setinfo_file(tree2, &sinfo);,
     1075                (smb2_util_close(tree2, h2),
     1076                smb2_util_unlink(tree2, BASEDIR "\\tname1"));,
     1077                NOTIFY_ACTION_MODIFIED,
     1078                FILE_NOTIFY_CHANGE_LAST_ACCESS, 1);
     1079
     1080        ZERO_STRUCT(sinfo);
     1081        sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
     1082        sinfo.generic.in.file.handle = h1;
     1083        sinfo.basic_info.in.change_time = 0;
     1084        torture_comment(torture, "Testing set file change time\n");
     1085        NOTIFY_MASK_TEST("Testing set file change time",
     1086                smb2_create_complex_file(tree2, BASEDIR "\\tname1", &h2);,
     1087                smb2_setinfo_file(tree2, &sinfo);,
     1088                (smb2_util_close(tree2, h2),
     1089                smb2_util_unlink(tree2, BASEDIR "\\tname1"));,
     1090                NOTIFY_ACTION_MODIFIED,
     1091                0, 1);
     1092
     1093
     1094        torture_comment(torture, "Testing write\n");
     1095        NOTIFY_MASK_TEST("Testing write",
     1096                smb2_create_complex_file(tree2, BASEDIR "\\tname1", &h2);,
     1097                smb2_util_write(tree2, h2, &c, 10000, 1);,
     1098                (smb2_util_close(tree2, h2),
     1099                smb2_util_unlink(tree2, BASEDIR "\\tname1"));,
     1100                NOTIFY_ACTION_MODIFIED,
     1101                0, 1);
     1102
     1103done:
     1104        smb2_deltree(tree1, BASEDIR);
     1105        return ret;
     1106}
     1107
     1108/*
     1109  basic testing of change notify on files
     1110*/
     1111static bool torture_smb2_notify_file(struct torture_context *torture,
     1112                                struct smb2_tree *tree)
     1113{
     1114        NTSTATUS status;
     1115        bool ret = true;
     1116        union smb_open io;
     1117        union smb_close cl;
     1118        union smb_notify notify;
     1119        struct smb2_request *req;
     1120        struct smb2_handle h1;
     1121        const char *fname = BASEDIR "\\file.txt";
     1122
     1123        smb2_deltree(tree, BASEDIR);
     1124        smb2_util_rmdir(tree, BASEDIR);
     1125
     1126        torture_comment(torture, "TESTING CHANGE NOTIFY ON FILES\n");
     1127        status = torture_smb2_testdir(tree, BASEDIR, &h1);
     1128        CHECK_STATUS(status, NT_STATUS_OK);
     1129
     1130        ZERO_STRUCT(io.smb2);
     1131        io.generic.level = RAW_OPEN_SMB2;
     1132        io.smb2.in.create_flags = 0;
     1133        io.smb2.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     1134        io.smb2.in.create_options = 0;
     1135        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     1136        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1137                                NTCREATEX_SHARE_ACCESS_WRITE;
     1138        io.smb2.in.alloc_size = 0;
     1139        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     1140        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     1141        io.smb2.in.security_flags = 0;
     1142        io.smb2.in.fname = fname;
     1143        status = smb2_create(tree, torture, &(io.smb2));
     1144        CHECK_STATUS(status, NT_STATUS_OK);
     1145        h1 = io.smb2.out.file.handle;
     1146
     1147        /* ask for a change notify,
     1148           on file or directory name changes */
     1149        ZERO_STRUCT(notify.smb2);
     1150        notify.smb2.level = RAW_NOTIFY_SMB2;
     1151        notify.smb2.in.file.handle = h1;
     1152        notify.smb2.in.buffer_size = 1000;
     1153        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_STREAM_NAME;
     1154        notify.smb2.in.recursive = false;
     1155
     1156        torture_comment(torture,
     1157        "Testing if notifies on file handles are invalid (should be)\n");
     1158
     1159        req = smb2_notify_send(tree, &(notify.smb2));
     1160        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1161        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     1162
     1163        ZERO_STRUCT(cl.smb2);
     1164        cl.close.level = RAW_CLOSE_SMB2;
     1165        cl.close.in.file.handle = h1;
     1166        status = smb2_close(tree, &(cl.smb2));
     1167        CHECK_STATUS(status, NT_STATUS_OK);
     1168
     1169        status = smb2_util_unlink(tree, fname);
     1170        CHECK_STATUS(status, NT_STATUS_OK);
     1171
     1172done:
     1173        smb2_deltree(tree, BASEDIR);
     1174        return ret;
     1175}
     1176/*
     1177  basic testing of change notifies followed by a tdis
     1178*/
     1179
     1180static bool torture_smb2_notify_tree_disconnect(
     1181                struct torture_context *torture,
     1182                struct smb2_tree *tree)
     1183{
     1184        bool ret = true;
     1185        NTSTATUS status;
     1186        union smb_notify notify;
     1187        union smb_open io;
     1188        struct smb2_handle h1;
     1189        struct smb2_request *req;
     1190
     1191        smb2_deltree(tree, BASEDIR);
     1192        smb2_util_rmdir(tree, BASEDIR);
     1193
     1194        torture_comment(torture, "TESTING CHANGE NOTIFY FOLLOWED BY "
     1195                        "TREE-DISCONNECT\n");
     1196
     1197        /*
     1198          get a handle on the directory
     1199        */
     1200        ZERO_STRUCT(io.smb2);
     1201        io.generic.level = RAW_OPEN_SMB2;
     1202        io.smb2.in.create_flags = 0;
     1203        io.smb2.in.desired_access = SEC_FILE_ALL;
     1204        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     1205        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     1206        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1207                                NTCREATEX_SHARE_ACCESS_WRITE;
     1208        io.smb2.in.alloc_size = 0;
     1209        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     1210        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     1211        io.smb2.in.security_flags = 0;
     1212        io.smb2.in.fname = BASEDIR;
     1213
     1214        status = smb2_create(tree, torture, &(io.smb2));
     1215        CHECK_STATUS(status, NT_STATUS_OK);
     1216        h1 = io.smb2.out.file.handle;
     1217
     1218        /* ask for a change notify,
     1219           on file or directory name changes */
     1220        ZERO_STRUCT(notify.smb2);
     1221        notify.smb2.level = RAW_NOTIFY_SMB2;
     1222        notify.smb2.in.buffer_size = 1000;
     1223        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
     1224        notify.smb2.in.file.handle = h1;
     1225        notify.smb2.in.recursive = true;
     1226
     1227        req = smb2_notify_send(tree, &(notify.smb2));
     1228        smb2_cancel(req);
     1229        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1230
     1231        status = smb2_tdis(tree);
     1232        CHECK_STATUS(status, NT_STATUS_OK);
     1233
     1234        req = smb2_notify_send(tree, &(notify.smb2));
     1235
     1236        smb2_notify_recv(req, torture, &(notify.smb2));
     1237        CHECK_STATUS(status, NT_STATUS_OK);
     1238        CHECK_VAL(notify.smb2.out.num_changes, 0);
     1239
     1240done:
     1241        smb2_deltree(tree, BASEDIR);
     1242        return ret;
     1243}
     1244
     1245/*
     1246  basic testing of change notifies followed by a ulogoff
     1247*/
     1248
     1249static bool torture_smb2_notify_ulogoff(struct torture_context *torture,
     1250                                struct smb2_tree *tree1,
     1251                                struct smb2_tree *tree2)
     1252{
     1253        bool ret = true;
     1254        NTSTATUS status;
     1255        union smb_notify notify;
     1256        union smb_open io;
     1257        struct smb2_handle h1;
     1258        struct smb2_request *req;
     1259
     1260        smb2_deltree(tree1, BASEDIR);
     1261        smb2_util_rmdir(tree1, BASEDIR);
     1262
     1263        torture_comment(torture, "TESTING CHANGE NOTIFY FOLLOWED BY ULOGOFF\n");
     1264
     1265        /*
     1266          get a handle on the directory
     1267        */
     1268        ZERO_STRUCT(io.smb2);
     1269        io.generic.level = RAW_OPEN_SMB2;
     1270        io.smb2.in.create_flags = 0;
     1271        io.smb2.in.desired_access = SEC_FILE_ALL;
     1272        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     1273        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     1274        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1275                                NTCREATEX_SHARE_ACCESS_WRITE;
     1276        io.smb2.in.alloc_size = 0;
     1277        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     1278        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     1279        io.smb2.in.security_flags = 0;
     1280        io.smb2.in.fname = BASEDIR;
     1281
     1282        status = smb2_create(tree2, torture, &(io.smb2));
     1283        CHECK_STATUS(status, NT_STATUS_OK);
     1284
     1285        io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     1286        status = smb2_create(tree2, torture, &(io.smb2));
     1287        CHECK_STATUS(status, NT_STATUS_OK);
     1288        h1 = io.smb2.out.file.handle;
     1289
     1290        /* ask for a change notify,
     1291           on file or directory name changes */
     1292        ZERO_STRUCT(notify.smb2);
     1293        notify.smb2.level = RAW_NOTIFY_SMB2;
     1294        notify.smb2.in.buffer_size = 1000;
     1295        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
     1296        notify.smb2.in.file.handle = h1;
     1297        notify.smb2.in.recursive = true;
     1298
     1299        req = smb2_notify_send(tree1, &(notify.smb2));
     1300
     1301        status = smb2_logoff(tree2->session);
     1302        CHECK_STATUS(status, NT_STATUS_OK);
     1303
     1304        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1305        CHECK_VAL(notify.smb2.out.num_changes, 0);
     1306
     1307done:
     1308        smb2_deltree(tree1, BASEDIR);
     1309        return ret;
     1310}
     1311
     1312static void tcp_dis_handler(struct smb2_transport *t, void *p)
     1313{
     1314        struct smb2_tree *tree = (struct smb2_tree *)p;
     1315        smb2_transport_dead(tree->session->transport,
     1316                        NT_STATUS_LOCAL_DISCONNECT);
     1317        t = NULL;
     1318        tree = NULL;
     1319}
     1320
     1321/*
     1322  basic testing of change notifies followed by tcp disconnect
     1323*/
     1324
     1325static bool torture_smb2_notify_tcp_disconnect(
     1326                struct torture_context *torture,
     1327                struct smb2_tree *tree)
     1328{
     1329        bool ret = true;
     1330        NTSTATUS status;
     1331        union smb_notify notify;
     1332        union smb_open io;
     1333        struct smb2_handle h1;
     1334        struct smb2_request *req;
     1335
     1336        smb2_deltree(tree, BASEDIR);
     1337        smb2_util_rmdir(tree, BASEDIR);
     1338
     1339        torture_comment(torture,
     1340                "TESTING CHANGE NOTIFY FOLLOWED BY TCP DISCONNECT\n");
     1341
     1342        /*
     1343          get a handle on the directory
     1344        */
     1345        ZERO_STRUCT(io.smb2);
     1346        io.generic.level = RAW_OPEN_SMB2;
     1347        io.smb2.in.create_flags = 0;
     1348        io.smb2.in.desired_access = SEC_FILE_ALL;
     1349        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     1350        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     1351        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1352                                NTCREATEX_SHARE_ACCESS_WRITE;
     1353        io.smb2.in.alloc_size = 0;
     1354        io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     1355        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     1356        io.smb2.in.security_flags = 0;
     1357        io.smb2.in.fname = BASEDIR;
     1358
     1359        status = smb2_create(tree, torture, &(io.smb2));
     1360        CHECK_STATUS(status, NT_STATUS_OK);
     1361        h1 = io.smb2.out.file.handle;
     1362
     1363        /* ask for a change notify,
     1364           on file or directory name changes */
     1365        ZERO_STRUCT(notify.smb2);
     1366        notify.smb2.level = RAW_NOTIFY_SMB2;
     1367        notify.smb2.in.buffer_size = 1000;
     1368        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
     1369        notify.smb2.in.file.handle = h1;
     1370        notify.smb2.in.recursive = true;
     1371
     1372        req = smb2_notify_send(tree, &(notify.smb2));
     1373        smb2_cancel(req);
     1374        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1375        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     1376
     1377        notify.smb2.in.recursive = true;
     1378        req = smb2_notify_send(tree, &(notify.smb2));
     1379        smb2_transport_idle_handler(tree->session->transport,
     1380                                tcp_dis_handler, 250, tree);
     1381        tree = NULL;
     1382        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1383        CHECK_STATUS(status, NT_STATUS_LOCAL_DISCONNECT);
     1384
     1385done:
     1386        return ret;
     1387}
     1388
     1389/*
     1390   test setting up two change notify requests on one handle
     1391*/
     1392
     1393static bool torture_smb2_notify_double(struct torture_context *torture,
     1394                        struct smb2_tree *tree1,
     1395                        struct smb2_tree *tree2)
     1396{
     1397        bool ret = true;
     1398        NTSTATUS status;
     1399        union smb_notify notify;
     1400        union smb_open io;
     1401        struct smb2_handle h1;
     1402        struct smb2_request *req1, *req2;
     1403
     1404        smb2_deltree(tree1, BASEDIR);
     1405        smb2_util_rmdir(tree1, BASEDIR);
     1406
     1407        torture_comment(torture,
     1408                "TESTING CHANGE NOTIFY TWICE ON ONE DIRECTORY\n");
     1409
     1410        /*
     1411          get a handle on the directory
     1412        */
     1413        ZERO_STRUCT(io.smb2);
     1414        io.generic.level = RAW_OPEN_SMB2;
     1415        io.smb2.in.create_flags = 0;
     1416        io.smb2.in.desired_access = SEC_RIGHTS_FILE_READ|
     1417                                SEC_RIGHTS_FILE_WRITE|
     1418                                SEC_RIGHTS_FILE_ALL;
     1419        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     1420        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     1421        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1422                                NTCREATEX_SHARE_ACCESS_WRITE;
     1423        io.smb2.in.alloc_size = 0;
     1424        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     1425        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     1426        io.smb2.in.security_flags = 0;
     1427        io.smb2.in.fname = BASEDIR;
     1428
     1429        status = smb2_create(tree1, torture, &(io.smb2));
     1430        CHECK_STATUS(status, NT_STATUS_OK);
     1431        h1 = io.smb2.out.file.handle;
     1432
     1433        /* ask for a change notify,
     1434           on file or directory name changes */
     1435        ZERO_STRUCT(notify.smb2);
     1436        notify.smb2.level = RAW_NOTIFY_SMB2;
     1437        notify.smb2.in.buffer_size = 1000;
     1438        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
     1439        notify.smb2.in.file.handle = h1;
     1440        notify.smb2.in.recursive = true;
     1441
     1442        req1 = smb2_notify_send(tree1, &(notify.smb2));
     1443        smb2_cancel(req1);
     1444        status = smb2_notify_recv(req1, torture, &(notify.smb2));
     1445        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     1446
     1447        req2 = smb2_notify_send(tree1, &(notify.smb2));
     1448        smb2_cancel(req2);
     1449        status = smb2_notify_recv(req2, torture, &(notify.smb2));
     1450        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     1451
     1452        smb2_util_mkdir(tree2, BASEDIR "\\subdir-name");
     1453        req1 = smb2_notify_send(tree1, &(notify.smb2));
     1454        req2 = smb2_notify_send(tree1, &(notify.smb2));
     1455
     1456        status = smb2_notify_recv(req1, torture, &(notify.smb2));
     1457        CHECK_STATUS(status, NT_STATUS_OK);
     1458        CHECK_VAL(notify.smb2.out.num_changes, 1);
     1459        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     1460
     1461        smb2_util_mkdir(tree2, BASEDIR "\\subdir-name2");
     1462
     1463        status = smb2_notify_recv(req2, torture, &(notify.smb2));
     1464        CHECK_STATUS(status, NT_STATUS_OK);
     1465        CHECK_VAL(notify.smb2.out.num_changes, 1);
     1466        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name2");
     1467
     1468done:
     1469        smb2_deltree(tree1, BASEDIR);
     1470        return ret;
     1471}
     1472
     1473
     1474/*
     1475   test multiple change notifies at different depths and with/without recursion
     1476*/
     1477
     1478static bool torture_smb2_notify_tree(struct torture_context *torture,
     1479                             struct smb2_tree *tree)
     1480{
     1481        bool ret = true;
     1482        union smb_notify notify;
     1483        union smb_open io;
     1484        struct smb2_request *req;
     1485        struct timeval tv;
     1486        struct {
     1487                const char *path;
     1488                bool recursive;
     1489                uint32_t filter;
     1490                int expected;
     1491                struct smb2_handle h1;
     1492                int counted;
     1493        } dirs[] = {
     1494                {BASEDIR "\\abc",               true, FILE_NOTIFY_CHANGE_NAME, 30 },
     1495                {BASEDIR "\\zqy",               true, FILE_NOTIFY_CHANGE_NAME, 8 },
     1496                {BASEDIR "\\atsy",              true, FILE_NOTIFY_CHANGE_NAME, 4 },
     1497                {BASEDIR "\\abc\\foo",          true,  FILE_NOTIFY_CHANGE_NAME, 2 },
     1498                {BASEDIR "\\abc\\blah",         true,  FILE_NOTIFY_CHANGE_NAME, 13 },
     1499                {BASEDIR "\\abc\\blah",         false, FILE_NOTIFY_CHANGE_NAME, 7 },
     1500                {BASEDIR "\\abc\\blah\\a",      true, FILE_NOTIFY_CHANGE_NAME, 2 },
     1501                {BASEDIR "\\abc\\blah\\b",      true, FILE_NOTIFY_CHANGE_NAME, 2 },
     1502                {BASEDIR "\\abc\\blah\\c",      true, FILE_NOTIFY_CHANGE_NAME, 2 },
     1503                {BASEDIR "\\abc\\fooblah",      true, FILE_NOTIFY_CHANGE_NAME, 2 },
     1504                {BASEDIR "\\zqy\\xx",           true, FILE_NOTIFY_CHANGE_NAME, 2 },
     1505                {BASEDIR "\\zqy\\yyy",          true, FILE_NOTIFY_CHANGE_NAME, 2 },
     1506                {BASEDIR "\\zqy\\..",           true, FILE_NOTIFY_CHANGE_NAME, 40 },
     1507                {BASEDIR,                       true, FILE_NOTIFY_CHANGE_NAME, 40 },
     1508                {BASEDIR,                       false,FILE_NOTIFY_CHANGE_NAME, 6 },
     1509                {BASEDIR "\\atsy",              false,FILE_NOTIFY_CHANGE_NAME, 4 },
     1510                {BASEDIR "\\abc",               true, FILE_NOTIFY_CHANGE_NAME, 24 },
     1511                {BASEDIR "\\abc",               false,FILE_NOTIFY_CHANGE_FILE_NAME, 0 },
     1512                {BASEDIR "\\abc",               true, FILE_NOTIFY_CHANGE_FILE_NAME, 0 },
     1513                {BASEDIR "\\abc",               true, FILE_NOTIFY_CHANGE_NAME, 24 },
     1514        };
     1515        int i;
     1516        NTSTATUS status;
     1517        bool all_done = false;
     1518
     1519        smb2_deltree(tree, BASEDIR);
     1520        smb2_util_rmdir(tree, BASEDIR);
     1521
     1522        torture_comment(torture, "TESTING NOTIFY FOR DIFFERENT DEPTHS\n");
     1523
     1524        ZERO_STRUCT(io.smb2);
     1525        io.generic.level = RAW_OPEN_SMB2;
     1526        io.smb2.in.create_flags = 0;
     1527        io.smb2.in.desired_access = SEC_FILE_ALL;
     1528        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     1529        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     1530        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1531                                NTCREATEX_SHARE_ACCESS_WRITE;
     1532        io.smb2.in.alloc_size = 0;
     1533        io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     1534        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     1535        io.smb2.in.security_flags = 0;
     1536        io.smb2.in.fname = BASEDIR;
     1537        status = smb2_create(tree, torture, &(io.smb2));
     1538        CHECK_STATUS(status, NT_STATUS_OK);
     1539
     1540        ZERO_STRUCT(notify.smb2);
     1541        notify.smb2.level = RAW_NOTIFY_SMB2;
     1542        notify.smb2.in.buffer_size = 20000;
     1543
     1544        /*
     1545          setup the directory tree, and the notify buffer on each directory
     1546        */
     1547        for (i=0;i<ARRAY_SIZE(dirs);i++) {
     1548                io.smb2.in.fname = dirs[i].path;
     1549                status = smb2_create(tree, torture, &(io.smb2));
     1550                CHECK_STATUS(status, NT_STATUS_OK);
     1551                dirs[i].h1 = io.smb2.out.file.handle;
     1552
     1553                notify.smb2.in.completion_filter = dirs[i].filter;
     1554                notify.smb2.in.file.handle = dirs[i].h1;
     1555                notify.smb2.in.recursive = dirs[i].recursive;
     1556                req = smb2_notify_send(tree, &(notify.smb2));
     1557                smb2_cancel(req);
     1558                status = smb2_notify_recv(req, torture, &(notify.smb2));
     1559                CHECK_STATUS(status, NT_STATUS_CANCELLED);
     1560        }
     1561
     1562        /* trigger 2 events in each dir */
     1563        for (i=0;i<ARRAY_SIZE(dirs);i++) {
     1564                char *path = talloc_asprintf(torture, "%s\\test.dir",
     1565                                             dirs[i].path);
     1566                smb2_util_mkdir(tree, path);
     1567                smb2_util_rmdir(tree, path);
     1568                talloc_free(path);
     1569        }
     1570
     1571        /* give a bit of time for the events to propogate */
     1572        tv = timeval_current();
     1573
     1574        do {
     1575                /* count events that have happened in each dir */
     1576                for (i=0;i<ARRAY_SIZE(dirs);i++) {
     1577                        notify.smb2.in.file.handle = dirs[i].h1;
     1578                        req = smb2_notify_send(tree, &(notify.smb2));
     1579                        smb2_cancel(req);
     1580                        notify.smb2.out.num_changes = 0;
     1581                        status = smb2_notify_recv(req, torture,
     1582                                 &(notify.smb2));
     1583                        dirs[i].counted += notify.smb2.out.num_changes;
     1584                }
     1585
     1586                all_done = true;
     1587
     1588                for (i=0;i<ARRAY_SIZE(dirs);i++) {
     1589                        if (dirs[i].counted != dirs[i].expected) {
     1590                                all_done = false;
     1591                        }
     1592                }
     1593        } while (!all_done && timeval_elapsed(&tv) < 20);
     1594
     1595        torture_comment(torture, "took %.4f seconds to propogate all events\n",
     1596                        timeval_elapsed(&tv));
     1597
     1598        for (i=0;i<ARRAY_SIZE(dirs);i++) {
     1599                if (dirs[i].counted != dirs[i].expected) {
     1600                        torture_comment(torture,
     1601                                "ERROR: i=%d expected %d got %d for '%s'\n",
     1602                                i, dirs[i].expected, dirs[i].counted,
     1603                                dirs[i].path);
     1604                        ret = false;
     1605                }
     1606        }
     1607
     1608        /*
     1609          run from the back, closing and deleting
     1610        */
     1611        for (i=ARRAY_SIZE(dirs)-1;i>=0;i--) {
     1612                smb2_util_close(tree, dirs[i].h1);
     1613                smb2_util_rmdir(tree, dirs[i].path);
     1614        }
     1615
     1616done:
     1617        smb2_deltree(tree, BASEDIR);
     1618        smb2_util_rmdir(tree, BASEDIR);
     1619        return ret;
     1620}
     1621
     1622/*
     1623   Test response when cached server events exceed single NT NOTFIY response
     1624   packet size.
     1625*/
     1626
     1627static bool torture_smb2_notify_overflow(struct torture_context *torture,
     1628                                struct smb2_tree *tree)
     1629{
     1630        bool ret = true;
     1631        NTSTATUS status;
     1632        union smb_notify notify;
     1633        union smb_open io;
     1634        struct smb2_handle h1, h2;
     1635        int count = 100;
     1636        struct smb2_request *req1;
     1637        int i;
     1638
     1639        smb2_deltree(tree, BASEDIR);
     1640        smb2_util_rmdir(tree, BASEDIR);
     1641
     1642        torture_comment(torture, "TESTING CHANGE NOTIFY EVENT OVERFLOW\n");
     1643
     1644        /* get a handle on the directory */
     1645        ZERO_STRUCT(io.smb2);
     1646        io.generic.level = RAW_OPEN_SMB2;
     1647        io.smb2.in.create_flags = 0;
     1648        io.smb2.in.desired_access = SEC_FILE_ALL;
     1649        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     1650        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     1651        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1652                            NTCREATEX_SHARE_ACCESS_WRITE;
     1653        io.smb2.in.alloc_size = 0;
     1654        io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     1655        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     1656        io.smb2.in.security_flags = 0;
     1657        io.smb2.in.fname = BASEDIR;
     1658
     1659        status = smb2_create(tree, torture, &(io.smb2));
     1660        CHECK_STATUS(status, NT_STATUS_OK);
     1661        h1 = io.smb2.out.file.handle;
     1662
     1663        /* ask for a change notify, on name changes. */
     1664        ZERO_STRUCT(notify.smb2);
     1665        notify.smb2.level = RAW_NOTIFY_NTTRANS;
     1666        notify.smb2.in.buffer_size = 1000;
     1667        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
     1668        notify.smb2.in.file.handle = h1;
     1669
     1670        notify.smb2.in.recursive = true;
     1671        req1 = smb2_notify_send(tree, &(notify.smb2));
     1672
     1673        /* cancel initial requests so the buffer is setup */
     1674        smb2_cancel(req1);
     1675        status = smb2_notify_recv(req1, torture, &(notify.smb2));
     1676        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     1677
     1678        /* open a lot of files, filling up the server side notify buffer */
     1679        torture_comment(torture,
     1680                "Testing overflowed buffer notify on create of %d files\n",
     1681                count);
     1682
     1683        for (i=0;i<count;i++) {
     1684                char *fname = talloc_asprintf(torture,
     1685                              BASEDIR "\\test%d.txt", i);
     1686                union smb_open io1;
     1687                ZERO_STRUCT(io1.smb2);
     1688                io1.generic.level = RAW_OPEN_SMB2;
     1689                io1.smb2.in.create_flags = 0;
     1690                io1.smb2.in.desired_access = SEC_FILE_ALL;
     1691                io1.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     1692                io1.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     1693                io1.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1694                                    NTCREATEX_SHARE_ACCESS_WRITE;
     1695                io1.smb2.in.alloc_size = 0;
     1696                io1.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     1697                io1.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     1698                io1.smb2.in.security_flags = 0;
     1699                io1.smb2.in.fname = fname;
     1700
     1701                h2 = custom_smb2_create(tree, torture, &(io1.smb2));
     1702                talloc_free(fname);
     1703                smb2_util_close(tree, h2);
     1704        }
     1705
     1706        req1 = smb2_notify_send(tree, &(notify.smb2));
     1707        status = smb2_notify_recv(req1, torture, &(notify.smb2));
     1708        CHECK_STATUS(status, STATUS_NOTIFY_ENUM_DIR);
     1709        CHECK_VAL(notify.smb2.out.num_changes, 0);
     1710
     1711done:
     1712        smb2_deltree(tree, BASEDIR);
     1713        return ret;
     1714}
     1715
     1716/*
     1717   Test if notifications are returned for changes to the base directory.
     1718   They shouldn't be.
     1719*/
     1720
     1721static bool torture_smb2_notify_basedir(struct torture_context *torture,
     1722                                struct smb2_tree *tree1,
     1723                                struct smb2_tree *tree2)
     1724{
     1725        bool ret = true;
     1726        NTSTATUS status;
     1727        union smb_notify notify;
     1728        union smb_open io;
     1729        struct smb2_handle h1;
     1730        struct smb2_request *req1;
     1731
     1732        smb2_deltree(tree1, BASEDIR);
     1733        smb2_util_rmdir(tree1, BASEDIR);
     1734
     1735        torture_comment(torture, "TESTING CHANGE NOTIFY BASEDIR EVENTS\n");
     1736
     1737        /* get a handle on the directory */
     1738        ZERO_STRUCT(io.smb2);
     1739        io.generic.level = RAW_OPEN_SMB2;
     1740        io.smb2.in.create_flags = 0;
     1741        io.smb2.in.desired_access = SEC_FILE_ALL;
     1742        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     1743        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     1744        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1745            NTCREATEX_SHARE_ACCESS_WRITE;
     1746        io.smb2.in.alloc_size = 0;
     1747        io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     1748        io.smb2.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     1749        io.smb2.in.security_flags = 0;
     1750        io.smb2.in.fname = BASEDIR;
     1751
     1752        status = smb2_create(tree1, torture, &(io.smb2));
     1753        CHECK_STATUS(status, NT_STATUS_OK);
     1754        h1 = io.smb2.out.file.handle;
     1755
     1756        /* create a test file that will also be modified */
     1757        io.smb2.in.fname = BASEDIR "\\tname1";
     1758        io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     1759        status =  smb2_create(tree2, torture, &(io.smb2));
     1760        CHECK_STATUS(status,NT_STATUS_OK);
     1761        smb2_util_close(tree2, io.smb2.out.file.handle);
     1762
     1763        /* ask for a change notify, on attribute changes. */
     1764        ZERO_STRUCT(notify.smb2);
     1765        notify.smb2.level = RAW_NOTIFY_SMB2;
     1766        notify.smb2.in.buffer_size = 1000;
     1767        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_ATTRIBUTES;
     1768        notify.smb2.in.file.handle = h1;
     1769        notify.smb2.in.recursive = true;
     1770
     1771        req1 = smb2_notify_send(tree1, &(notify.smb2));
     1772
     1773        /* set attribute on the base dir */
     1774        smb2_util_setatr(tree2, BASEDIR, FILE_ATTRIBUTE_HIDDEN);
     1775
     1776        /* set attribute on a file to assure we receive a notification */
     1777        smb2_util_setatr(tree2, BASEDIR "\\tname1", FILE_ATTRIBUTE_HIDDEN);
     1778        smb_msleep(200);
     1779
     1780        /* check how many responses were given, expect only 1 for the file */
     1781        status = smb2_notify_recv(req1, torture, &(notify.smb2));
     1782        CHECK_STATUS(status, NT_STATUS_OK);
     1783        CHECK_VAL(notify.smb2.out.num_changes, 1);
     1784        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_MODIFIED);
     1785        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "tname1");
     1786
     1787done:
     1788        smb2_deltree(tree1, BASEDIR);
     1789        return ret;
     1790}
     1791
     1792
     1793/*
     1794  create a secondary tree connect - used to test for a bug in Samba3 messaging
     1795  with change notify
     1796*/
     1797static struct smb2_tree *secondary_tcon(struct smb2_tree *tree,
     1798                                        struct torture_context *tctx)
     1799{
     1800        NTSTATUS status;
     1801        const char *share, *host;
     1802        struct smb2_tree *tree1;
     1803        union smb_tcon tcon;
     1804
     1805        share = torture_setting_string(tctx, "share", NULL);
     1806        host  = torture_setting_string(tctx, "host", NULL);
     1807
     1808        torture_comment(tctx,
     1809                "create a second tree context on the same session\n");
     1810        tree1 = smb2_tree_init(tree->session, tctx, false);
     1811
     1812        ZERO_STRUCT(tcon.smb2);
     1813        tcon.generic.level = RAW_TCON_SMB2;
     1814        tcon.smb2.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
     1815        status = smb2_tree_connect(tree, &(tcon.smb2));
     1816        if (!NT_STATUS_IS_OK(status)) {
     1817                talloc_free(tree);
     1818                torture_comment(tctx,"Failed to create secondary tree\n");
     1819                return NULL;
     1820        }
     1821
     1822        tree1->tid = tcon.smb2.out.tid;
     1823        torture_comment(tctx,"tid1=%d tid2=%d\n", tree->tid, tree1->tid);
     1824
     1825        return tree1;
     1826}
     1827
     1828
     1829/*
     1830   very simple change notify test
     1831*/
     1832static bool torture_smb2_notify_tcon(struct torture_context *torture,
     1833                                  struct smb2_tree *tree)
     1834{
     1835        bool ret = true;
     1836        NTSTATUS status;
     1837        union smb_notify notify;
     1838        union smb_open io;
     1839        struct smb2_handle h1;
     1840        struct smb2_request *req = NULL;
     1841        struct smb2_tree *tree1 = NULL;
     1842        const char *fname = BASEDIR "\\subdir-name";
     1843
     1844        smb2_deltree(tree, BASEDIR);
     1845        smb2_util_rmdir(tree, BASEDIR);
     1846
     1847        torture_comment(torture, "TESTING SIMPLE CHANGE NOTIFY\n");
     1848
     1849        /*
     1850          get a handle on the directory
     1851        */
     1852
     1853        ZERO_STRUCT(io.smb2);
     1854        io.generic.level = RAW_OPEN_SMB2;
     1855        io.smb2.in.create_flags = 0;
     1856        io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
     1857        io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     1858        io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL |
     1859                                FILE_ATTRIBUTE_DIRECTORY;
     1860        io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     1861                                NTCREATEX_SHARE_ACCESS_WRITE;
     1862        io.smb2.in.alloc_size = 0;
     1863        io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     1864        io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     1865        io.smb2.in.security_flags = 0;
     1866        io.smb2.in.fname = BASEDIR;
     1867
     1868        status = smb2_create(tree, torture, &(io.smb2));
     1869        CHECK_STATUS(status, NT_STATUS_OK);
     1870        h1 = io.smb2.out.file.handle;
     1871
     1872        /* ask for a change notify,
     1873           on file or directory name changes */
     1874        ZERO_STRUCT(notify.smb2);
     1875        notify.smb2.level = RAW_NOTIFY_SMB2;
     1876        notify.smb2.in.buffer_size = 1000;
     1877        notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
     1878        notify.smb2.in.file.handle = h1;
     1879        notify.smb2.in.recursive = true;
     1880
     1881        torture_comment(torture, "Testing notify mkdir\n");
     1882        req = smb2_notify_send(tree, &(notify.smb2));
     1883        smb2_cancel(req);
     1884        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1885        CHECK_STATUS(status, NT_STATUS_CANCELLED);
     1886
     1887        notify.smb2.in.recursive = true;
     1888        req = smb2_notify_send(tree, &(notify.smb2));
     1889        status = smb2_util_mkdir(tree, fname);
     1890        CHECK_STATUS(status, NT_STATUS_OK);
     1891
     1892        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1893        CHECK_STATUS(status, NT_STATUS_OK);
     1894
     1895        CHECK_VAL(notify.smb2.out.num_changes, 1);
     1896        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_ADDED);
     1897        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     1898
     1899        torture_comment(torture, "Testing notify rmdir\n");
     1900        req = smb2_notify_send(tree, &(notify.smb2));
     1901        status = smb2_util_rmdir(tree, fname);
     1902        CHECK_STATUS(status, NT_STATUS_OK);
     1903
     1904        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1905        CHECK_STATUS(status, NT_STATUS_OK);
     1906        CHECK_VAL(notify.smb2.out.num_changes, 1);
     1907        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_REMOVED);
     1908        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     1909
     1910        torture_comment(torture, "SIMPLE CHANGE NOTIFY OK\n");
     1911
     1912        torture_comment(torture, "TESTING WITH SECONDARY TCON\n");
     1913        tree1 = secondary_tcon(tree, torture);
     1914
     1915        torture_comment(torture, "Testing notify mkdir\n");
     1916        req = smb2_notify_send(tree, &(notify.smb2));
     1917        smb2_util_mkdir(tree1, fname);
     1918
     1919        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1920        CHECK_STATUS(status, NT_STATUS_OK);
     1921
     1922        CHECK_VAL(notify.smb2.out.num_changes, 1);
     1923        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_ADDED);
     1924        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     1925
     1926        torture_comment(torture, "Testing notify rmdir\n");
     1927        req = smb2_notify_send(tree, &(notify.smb2));
     1928        smb2_util_rmdir(tree, fname);
     1929
     1930        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1931        CHECK_STATUS(status, NT_STATUS_OK);
     1932        CHECK_VAL(notify.smb2.out.num_changes, 1);
     1933        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_REMOVED);
     1934        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     1935
     1936        torture_comment(torture, "CHANGE NOTIFY WITH TCON OK\n");
     1937
     1938        torture_comment(torture, "Disconnecting secondary tree\n");
     1939        status = smb2_tdis(tree1);
     1940        CHECK_STATUS(status, NT_STATUS_OK);
     1941        talloc_free(tree1);
     1942
     1943        torture_comment(torture, "Testing notify mkdir\n");
     1944        req = smb2_notify_send(tree, &(notify.smb2));
     1945        smb2_util_mkdir(tree, fname);
     1946
     1947        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1948        CHECK_STATUS(status, NT_STATUS_OK);
     1949
     1950        CHECK_VAL(notify.smb2.out.num_changes, 1);
     1951        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_ADDED);
     1952        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     1953
     1954        torture_comment(torture, "Testing notify rmdir\n");
     1955        req = smb2_notify_send(tree, &(notify.smb2));
     1956        smb2_util_rmdir(tree, fname);
     1957
     1958        status = smb2_notify_recv(req, torture, &(notify.smb2));
     1959        CHECK_STATUS(status, NT_STATUS_OK);
     1960        CHECK_VAL(notify.smb2.out.num_changes, 1);
     1961        CHECK_VAL(notify.smb2.out.changes[0].action, NOTIFY_ACTION_REMOVED);
     1962        CHECK_WIRE_STR(notify.smb2.out.changes[0].name, "subdir-name");
     1963
     1964        torture_comment(torture, "CHANGE NOTIFY WITH TDIS OK\n");
     1965done:
     1966        smb2_util_close(tree, h1);
     1967        smb2_deltree(tree, BASEDIR);
     1968
     1969        return ret;
     1970}
     1971
     1972/*
     1973   basic testing of SMB2 change notify
     1974*/
     1975struct torture_suite *torture_smb2_notify_init(void)
     1976{
     1977        struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "notify");
     1978
     1979        torture_suite_add_1smb2_test(suite, "valid-req", test_valid_request);
     1980        torture_suite_add_1smb2_test(suite, "tcon", torture_smb2_notify_tcon);
     1981        torture_suite_add_2smb2_test(suite, "dir", torture_smb2_notify_dir);
     1982        torture_suite_add_2smb2_test(suite, "mask", torture_smb2_notify_mask);
     1983        torture_suite_add_1smb2_test(suite, "tdis", torture_smb2_notify_tree_disconnect);
     1984        torture_suite_add_2smb2_test(suite, "mask-change", torture_smb2_notify_mask_change);
     1985        torture_suite_add_2smb2_test(suite, "logoff", torture_smb2_notify_ulogoff);
     1986        torture_suite_add_1smb2_test(suite, "tree", torture_smb2_notify_tree);
     1987        torture_suite_add_2smb2_test(suite, "basedir", torture_smb2_notify_basedir);
     1988        torture_suite_add_2smb2_test(suite, "double", torture_smb2_notify_double);
     1989        torture_suite_add_1smb2_test(suite, "file", torture_smb2_notify_file);
     1990        torture_suite_add_1smb2_test(suite, "tcp", torture_smb2_notify_tcp_disconnect);
     1991        torture_suite_add_2smb2_test(suite, "rec", torture_smb2_notify_recursive);
     1992        torture_suite_add_1smb2_test(suite, "overflow", torture_smb2_notify_overflow);
     1993
     1994        suite->description = talloc_strdup(suite, "SMB2-NOTIFY tests");
     1995
     1996        return suite;
     1997}
     1998
  • trunk/server/source4/torture/smb2/read.c

    r414 r745  
    2727#include "torture/smb2/proto.h"
    2828
    29 #include "librpc/gen_ndr/ndr_security.h"
    3029
    3130#define CHECK_STATUS(status, correct) do { \
     
    233232struct torture_suite *torture_smb2_read_init(void)
    234233{
    235         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "READ");
    236 
    237         torture_suite_add_1smb2_test(suite, "EOF", test_read_eof);
    238         torture_suite_add_1smb2_test(suite, "POSITION", test_read_position);
    239         torture_suite_add_1smb2_test(suite, "DIR", test_read_dir);
     234        struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "read");
     235
     236        torture_suite_add_1smb2_test(suite, "eof", test_read_eof);
     237        torture_suite_add_1smb2_test(suite, "position", test_read_position);
     238        torture_suite_add_1smb2_test(suite, "dir", test_read_dir);
    240239
    241240        suite->description = talloc_strdup(suite, "SMB2-READ tests");
  • trunk/server/source4/torture/smb2/scan.c

    r414 r745  
    2424#include "libcli/smb2/smb2_calls.h"
    2525#include "lib/cmdline/popt_common.h"
    26 #include "lib/events/events.h"
    2726#include "torture/torture.h"
    2827#include "param/param.h"
     
    203202        struct smbcli_options options;
    204203
    205         lp_smbcli_options(torture->lp_ctx, &options);
     204        lpcfg_smbcli_options(torture->lp_ctx, &options);
    206205
    207206        status = smb2_connect(mem_ctx, host,
    208                                                   lp_smb_ports(torture->lp_ctx),
     207                                                  lpcfg_smb_ports(torture->lp_ctx),
    209208                                                  share,
    210                                                   lp_resolve_context(torture->lp_ctx),
     209                                                  lpcfg_resolve_context(torture->lp_ctx),
    211210                                                  credentials, &tree, torture->ev, &options,
    212                                                   lp_socket_options(torture->lp_ctx),
    213                                                   lp_gensec_settings(torture, torture->lp_ctx));
     211                                                  lpcfg_socket_options(torture->lp_ctx),
     212                                                  lpcfg_gensec_settings(torture, torture->lp_ctx));
    214213        if (!NT_STATUS_IS_OK(status)) {
    215214                printf("Connection failed - %s\n", nt_errstr(status));
     
    226225                        talloc_free(tree);
    227226                        status = smb2_connect(mem_ctx, host,
    228                                                                   lp_smb_ports(torture->lp_ctx),
     227                                                                  lpcfg_smb_ports(torture->lp_ctx),
    229228                                                                  share,
    230                                                                   lp_resolve_context(torture->lp_ctx),
     229                                                                  lpcfg_resolve_context(torture->lp_ctx),
    231230                                                                  credentials, &tree, torture->ev, &options,
    232                                                                   lp_socket_options(torture->lp_ctx),
    233                                                                   lp_gensec_settings(mem_ctx, torture->lp_ctx));
     231                                                                  lpcfg_socket_options(torture->lp_ctx),
     232                                                                  lpcfg_gensec_settings(mem_ctx, torture->lp_ctx));
    234233                        if (!NT_STATUS_IS_OK(status)) {
    235234                                printf("Connection failed - %s\n", nt_errstr(status));
  • trunk/server/source4/torture/smb2/setinfo.c

    r414 r745  
    3333#define BASEDIR ""
    3434
     35#define FAIL_UNLESS(__cond)                                     \
     36        do {                                                    \
     37                if (__cond) {} else {                           \
     38                        torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n",      \
     39                               __location__, #__cond);          \
     40                        ret = false; goto done;                 \
     41                }                                               \
     42        } while(0)
     43
    3544/* basic testing of all SMB2 setinfo calls
    3645   for each call we test that it succeeds, and where possible test
    3746   for consistency between the calls.
    3847*/
    39 bool torture_smb2_setinfo(struct torture_context *torture)
     48bool torture_smb2_setinfo(struct torture_context *tctx)
    4049{
    4150        struct smb2_tree *tree;
     
    5665        ZERO_STRUCT(handle);
    5766       
    58         fname = talloc_asprintf(torture, BASEDIR "fnum_test_%d.txt", n);
    59         fname_new = talloc_asprintf(torture, BASEDIR "fnum_test_new_%d.txt", n);
    60 
    61         if (!torture_smb2_connection(torture, &tree)) {
     67        fname = talloc_asprintf(tctx, BASEDIR "fnum_test_%d.txt", n);
     68        fname_new = talloc_asprintf(tctx, BASEDIR "fnum_test_new_%d.txt", n);
     69
     70        if (!torture_smb2_connection(tctx, &tree)) {
    6271                return false;
    6372        }
     
    6776        status = smb2_create_complex_file(tree, fname, &handle); \
    6877        if (!NT_STATUS_IS_OK(status)) { \
    69                 printf("(%s) ERROR: open of %s failed (%s)\n", \
     78                torture_result(tctx, TORTURE_ERROR, "(%s) ERROR: open of %s failed (%s)\n", \
    7079                       __location__, fname, nt_errstr(status)); \
    7180                ret = false; \
     
    8594        status = smb2_setinfo_file(tree, &sfinfo); \
    8695        if (!NT_STATUS_EQUAL(status, rightstatus)) { \
    87                 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
     96                torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s (should be %s)\n", __location__, #call, \
    8897                        nt_errstr(status), nt_errstr(rightstatus)); \
    8998                ret = false; \
     
    96105                finfo2.generic.level = RAW_FILEINFO_ ## call; \
    97106                finfo2.generic.in.file.handle = handle; \
    98                 status2 = smb2_getinfo_file(tree, torture, &finfo2); \
     107                status2 = smb2_getinfo_file(tree, tctx, &finfo2); \
    99108                if (!NT_STATUS_IS_OK(status2)) { \
    100                         printf("(%s) %s - %s\n", __location__, #call, nt_errstr(status2)); \
     109                        torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__, #call, nt_errstr(status2)); \
    101110                ret = false; \
    102111                goto done; \
     
    107116        CHECK1(call); \
    108117        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
    109                 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
     118                torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
    110119                       call_name, #stype, #field, \
    111                        (uint_t)value, (uint_t)finfo2.stype.out.field); \
     120                       (unsigned int)value, (unsigned int)finfo2.stype.out.field); \
    112121                torture_smb2_all_info(tree, handle); \
    113122                ret = false; \
     
    118127        CHECK1(call); \
    119128        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
    120                 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
     129                torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
    121130                        call_name, #stype, #field, \
    122                         (uint_t)value, \
    123                         (uint_t)nt_time_to_unix(finfo2.stype.out.field)); \
    124                 printf("\t%s", timestring(torture, value)); \
    125                 printf("\t%s\n", nt_time_string(torture, finfo2.stype.out.field)); \
     131                        (unsigned int)value, \
     132                        (unsigned int)nt_time_to_unix(finfo2.stype.out.field)); \
     133                torture_warning(tctx, "\t%s", timestring(tctx, value)); \
     134                torture_warning(tctx, "\t%s\n", nt_time_string(tctx, finfo2.stype.out.field)); \
    126135                torture_smb2_all_info(tree, handle); \
    127136                ret = false; \
     
    131140#define CHECK_STATUS(status, correct) do { \
    132141        if (!NT_STATUS_EQUAL(status, correct)) { \
    133                 printf("(%s) Incorrect status %s - should be %s\n", \
     142                torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
    134143                       __location__, nt_errstr(status), nt_errstr(correct)); \
    135144                ret = false; \
     
    139148        torture_smb2_all_info(tree, handle);
    140149       
    141         printf("test basic_information level\n");
     150        torture_comment(tctx, "Test basic_information level\n");
    142151        basetime += 86400;
    143152        unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
     
    153162        CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib,     FILE_ATTRIBUTE_READONLY);
    154163
    155         printf("a zero time means don't change\n");
     164        torture_comment(tctx, "a zero time means don't change\n");
    156165        unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
    157166        unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
     
    166175        CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib,     FILE_ATTRIBUTE_NORMAL);
    167176
    168         printf("change the attribute\n");
     177        torture_comment(tctx, "change the attribute\n");
    169178        sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    170179        CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
    171180        CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_HIDDEN);
    172181
    173         printf("zero attrib means don't change\n");
     182        torture_comment(tctx, "zero attrib means don't change\n");
    174183        sfinfo.basic_info.in.attrib = 0;
    175184        CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
    176185        CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_HIDDEN);
    177186
    178         printf("can't change a file to a directory\n");
     187        torture_comment(tctx, "can't change a file to a directory\n");
    179188        sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
    180189        CHECK_CALL(BASIC_INFORMATION, NT_STATUS_INVALID_PARAMETER);
    181190
    182         printf("restore attribute\n");
     191        torture_comment(tctx, "restore attribute\n");
    183192        sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
    184193        CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
    185194        CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_NORMAL);
    186195
    187         printf("test disposition_information level\n");
     196        torture_comment(tctx, "Test disposition_information level\n");
    188197        sfinfo.disposition_info.in.delete_on_close = 1;
    189198        CHECK_CALL(DISPOSITION_INFORMATION, NT_STATUS_OK);
     
    196205        CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, nlink, 1);
    197206
    198         printf("test allocation_information level\n");
     207        torture_comment(tctx, "Test allocation_information level\n");
    199208        sfinfo.allocation_info.in.alloc_size = 0;
    200209        CHECK_CALL(ALLOCATION_INFORMATION, NT_STATUS_OK);
     
    207216        CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 0);
    208217
    209         printf("test end_of_file_info level\n");
     218        torture_comment(tctx, "Test end_of_file_info level\n");
    210219        sfinfo.end_of_file_info.in.size = 37;
    211220        CHECK_CALL(END_OF_FILE_INFORMATION, NT_STATUS_OK);
     
    216225        CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 7);
    217226
    218         printf("test position_information level\n");
     227        torture_comment(tctx, "Test position_information level\n");
    219228        sfinfo.position_information.in.position = 123456;
    220229        CHECK_CALL(POSITION_INFORMATION, NT_STATUS_OK);
     
    222231        CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, position, 123456);
    223232
    224         printf("test mode_information level\n");
     233        torture_comment(tctx, "Test mode_information level\n");
    225234        sfinfo.mode_information.in.mode = 2;
    226235        CHECK_CALL(MODE_INFORMATION, NT_STATUS_OK);
     
    235244        CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
    236245
    237         printf("test sec_desc level\n");
     246        torture_comment(tctx, "Test sec_desc level\n");
    238247        ZERO_STRUCT(finfo2);
    239248        finfo2.query_secdesc.in.secinfo_flags =
     
    244253        sd = finfo2.query_secdesc.out.sd;
    245254
    246         test_sid = dom_sid_parse_talloc(torture, "S-1-5-32-1234-5432");
     255        test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
    247256        ZERO_STRUCT(ace);
    248257        ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
     
    253262        CHECK_STATUS(status, NT_STATUS_OK);
    254263
    255         printf("add a new ACE to the DACL\n");
     264        torture_comment(tctx, "add a new ACE to the DACL\n");
    256265
    257266        sfinfo.set_secdesc.in.secinfo_flags = finfo2.query_secdesc.in.secinfo_flags;
    258267        sfinfo.set_secdesc.in.sd = sd;
    259268        CHECK_CALL(SEC_DESC, NT_STATUS_OK);
    260         CHECK1(SEC_DESC);
    261 
    262         if (!security_acl_equal(finfo2.query_secdesc.out.sd->dacl, sd->dacl)) {
    263                 printf("%s: security descriptors don't match!\n", __location__);
    264                 printf("got:\n");
    265                 NDR_PRINT_DEBUG(security_descriptor, finfo2.query_secdesc.out.sd);
    266                 printf("expected:\n");
    267                 NDR_PRINT_DEBUG(security_descriptor, sd);
    268                 ret = false;
    269         }
    270 
    271         printf("remove it again\n");
     269        FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, handle, sd));
     270
     271        torture_comment(tctx, "remove it again\n");
    272272
    273273        status = security_descriptor_dacl_del(sd, test_sid);
     
    277277        sfinfo.set_secdesc.in.sd = sd;
    278278        CHECK_CALL(SEC_DESC, NT_STATUS_OK);
    279         CHECK1(SEC_DESC);
    280 
    281         if (!security_acl_equal(finfo2.query_secdesc.out.sd->dacl, sd->dacl)) {
    282                 printf("%s: security descriptors don't match!\n", __location__);
    283                 printf("got:\n");
    284                 NDR_PRINT_DEBUG(security_descriptor, finfo2.query_secdesc.out.sd);
    285                 printf("expected:\n");
    286                 NDR_PRINT_DEBUG(security_descriptor, sd);
    287                 ret = false;
    288         }
     279        FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, handle, sd));
    289280
    290281done:
    291282        status = smb2_util_close(tree, handle);
    292283        if (NT_STATUS_IS_ERR(status)) {
    293                 printf("Failed to delete %s - %s\n", fname, nt_errstr(status));
     284                torture_warning(tctx, "Failed to delete %s - %s\n", fname, nt_errstr(status));
    294285        }
    295286        smb2_util_unlink(tree, fname);
  • trunk/server/source4/torture/smb2/smb2.c

    r414 r745  
    2020#include "includes.h"
    2121#include "libcli/smb2/smb2.h"
    22 #include "libcli/smb2/smb2_calls.h"
    2322
    2423#include "torture/smbtorture.h"
     
    127126NTSTATUS torture_smb2_init(void)
    128127{
    129         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "SMB2");
    130         torture_suite_add_simple_test(suite, "CONNECT", torture_smb2_connect);
    131         torture_suite_add_simple_test(suite, "SCAN", torture_smb2_scan);
    132         torture_suite_add_simple_test(suite, "SCANGETINFO", torture_smb2_getinfo_scan);
    133         torture_suite_add_simple_test(suite, "SCANSETINFO", torture_smb2_setinfo_scan);
    134         torture_suite_add_simple_test(suite, "SCANFIND", torture_smb2_find_scan);
    135         torture_suite_add_simple_test(suite, "GETINFO", torture_smb2_getinfo);
    136         torture_suite_add_simple_test(suite, "SETINFO", torture_smb2_setinfo);
     128        struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "smb2");
     129        torture_suite_add_simple_test(suite, "connect", torture_smb2_connect);
     130        torture_suite_add_simple_test(suite, "scan", torture_smb2_scan);
     131        torture_suite_add_simple_test(suite, "scangetinfo", torture_smb2_getinfo_scan);
     132        torture_suite_add_simple_test(suite, "scansetinfo", torture_smb2_setinfo_scan);
     133        torture_suite_add_simple_test(suite, "scanfind", torture_smb2_find_scan);
     134        torture_suite_add_simple_test(suite, "getinfo", torture_smb2_getinfo);
     135        torture_suite_add_simple_test(suite, "setinfo", torture_smb2_setinfo);
    137136        torture_suite_add_suite(suite, torture_smb2_lock_init());
    138137        torture_suite_add_suite(suite, torture_smb2_read_init());
    139138        torture_suite_add_suite(suite, torture_smb2_create_init());
    140         torture_suite_add_simple_test(suite, "NOTIFY", torture_smb2_notify);
     139        torture_suite_add_suite(suite, torture_smb2_acls_init());
     140        torture_suite_add_suite(suite, torture_smb2_notify_init());
    141141        torture_suite_add_suite(suite, torture_smb2_durable_open_init());
    142         torture_suite_add_1smb2_test(suite, "OPLOCK-BATCH1", torture_smb2_oplock_batch1);
    143142        torture_suite_add_suite(suite, torture_smb2_dir_init());
    144143        torture_suite_add_suite(suite, torture_smb2_lease_init());
    145144        torture_suite_add_suite(suite, torture_smb2_compound_init());
     145        torture_suite_add_suite(suite, torture_smb2_oplocks_init());
     146        torture_suite_add_suite(suite, torture_smb2_streams_init());
     147        torture_suite_add_1smb2_test(suite, "bench-oplock", test_smb2_bench_oplock);
     148        torture_suite_add_1smb2_test(suite, "hold-oplock", test_smb2_hold_oplock);
    146149
    147150        suite->description = talloc_strdup(suite, "SMB2-specific tests");
  • trunk/server/source4/torture/smb2/util.c

    r414 r745  
    2121
    2222#include "includes.h"
     23#include "libcli/security/security_descriptor.h"
    2324#include "libcli/smb2/smb2.h"
    2425#include "libcli/smb2/smb2_calls.h"
    25 #include "libcli/smb_composite/smb_composite.h"
    2626#include "lib/cmdline/popt_common.h"
    27 #include "lib/events/events.h"
    2827#include "system/time.h"
    2928#include "librpc/gen_ndr/ndr_security.h"
     
    3231
    3332#include "torture/torture.h"
    34 #include "torture/smb2/proto.h"
    3533
    3634
     
    273271        struct smbcli_options options;
    274272
    275         lp_smbcli_options(tctx->lp_ctx, &options);
     273        lpcfg_smbcli_options(tctx->lp_ctx, &options);
    276274
    277275        status = smb2_connect(tctx, host,
    278                                                   lp_smb_ports(tctx->lp_ctx),
     276                                                  lpcfg_smb_ports(tctx->lp_ctx),
    279277                                                  share,
    280                               lp_resolve_context(tctx->lp_ctx),
     278                              lpcfg_resolve_context(tctx->lp_ctx),
    281279                              credentials, tree,
    282280                              tctx->ev, &options,
    283                                   lp_socket_options(tctx->lp_ctx),
    284                                   lp_gensec_settings(tctx, tctx->lp_ctx)
     281                                  lpcfg_socket_options(tctx->lp_ctx),
     282                                  lpcfg_gensec_settings(tctx, tctx->lp_ctx)
    285283                                  );
    286284        if (!NT_STATUS_IS_OK(status)) {
     
    325323        r.in.offset      = 0;
    326324
     325        // What is the purpose of this? Server returns EOF.
    327326        smb2_read(tree, tree, &r);
    328327
     
    358357
    359358/*
    360   create a complex file using the old SMB protocol, to make it easier to
     359  create a complex file using SMB2, to make it easier to
    361360  find fields in SMB2 getinfo levels
    362361*/
     
    371370
    372371/*
    373   create a complex dir using the old SMB protocol, to make it easier to
     372  create a complex dir using SMB2, to make it easier to
    374373  find fields in SMB2 getinfo levels
    375374*/
     
    407406        return NT_STATUS_OK;
    408407}
     408
     409/* Comparable to torture_setup_dir, but for SMB2. */
     410bool smb2_util_setup_dir(struct torture_context *tctx, struct smb2_tree *tree,
     411    const char *dname)
     412{
     413        NTSTATUS status;
     414
     415        /* XXX: smb_raw_exit equivalent?
     416        smb_raw_exit(cli->session); */
     417        if (smb2_deltree(tree, dname) == -1) {
     418                torture_result(tctx, TORTURE_ERROR, "Unable to deltree when setting up %s.\n", dname);
     419                return false;
     420        }
     421
     422        status = smb2_util_mkdir(tree, dname);
     423        if (NT_STATUS_IS_ERR(status)) {
     424                torture_result(tctx, TORTURE_ERROR, "Unable to mkdir when setting up %s - %s\n", dname,
     425                    nt_errstr(status));
     426                return false;
     427        }
     428
     429        return true;
     430}
     431
     432#define CHECK_STATUS(status, correct) do { \
     433        if (!NT_STATUS_EQUAL(status, correct)) { \
     434                torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
     435                       __location__, nt_errstr(status), nt_errstr(correct)); \
     436                ret = false; \
     437                goto done; \
     438        }} while (0)
     439
     440/*
     441 * Helper function to verify a security descriptor, by querying
     442 * and comparing against the passed in sd.
     443 */
     444bool smb2_util_verify_sd(TALLOC_CTX *tctx, struct smb2_tree *tree,
     445    struct smb2_handle handle, struct security_descriptor *sd)
     446{
     447        NTSTATUS status;
     448        bool ret = true;
     449        union smb_fileinfo q = {};
     450
     451        q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     452        q.query_secdesc.in.file.handle = handle;
     453        q.query_secdesc.in.secinfo_flags =
     454            SECINFO_OWNER |
     455            SECINFO_GROUP |
     456            SECINFO_DACL;
     457        status = smb2_getinfo_file(tree, tctx, &q);
     458        CHECK_STATUS(status, NT_STATUS_OK);
     459
     460        if (!security_acl_equal(
     461            q.query_secdesc.out.sd->dacl, sd->dacl)) {
     462                torture_warning(tctx, "%s: security descriptors don't match!\n",
     463                    __location__);
     464                torture_warning(tctx, "got:\n");
     465                NDR_PRINT_DEBUG(security_descriptor,
     466                    q.query_secdesc.out.sd);
     467                torture_warning(tctx, "expected:\n");
     468                NDR_PRINT_DEBUG(security_descriptor, sd);
     469                ret = false;
     470        }
     471
     472 done:
     473        return ret;
     474}
     475
     476/*
     477 * Helper function to verify attributes, by querying
     478 * and comparing against the passed in attrib.
     479 */
     480bool smb2_util_verify_attrib(TALLOC_CTX *tctx, struct smb2_tree *tree,
     481    struct smb2_handle handle, uint32_t attrib)
     482{
     483        NTSTATUS status;
     484        bool ret = true;
     485        union smb_fileinfo q = {};
     486
     487        q.standard.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     488        q.standard.in.file.handle = handle;
     489        status = smb2_getinfo_file(tree, tctx, &q);
     490        CHECK_STATUS(status, NT_STATUS_OK);
     491
     492        q.all_info2.out.attrib &= ~FILE_ATTRIBUTE_ARCHIVE;
     493
     494        if (q.all_info2.out.attrib != attrib) {
     495                torture_warning(tctx, "%s: attributes don't match! "
     496                    "got %x, expected %x\n", __location__,
     497                    (uint32_t)q.standard.out.attrib,
     498                    (uint32_t)attrib);
     499                ret = false;
     500        }
     501
     502 done:
     503        return ret;
     504}
     505
     506
Note: See TracChangeset for help on using the changeset viewer.