~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/smb2/oplocks.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Unix SMB/CIFS implementation.
 
3
 
 
4
   test suite for SMB2 oplocks
 
5
 
 
6
   Copyright (C) Stefan Metzmacher 2008
 
7
 
 
8
   This program is free software; you can redistribute it and/or modify
 
9
   it under the terms of the GNU General Public License as published by
 
10
   the Free Software Foundation; either version 3 of the License, or
 
11
   (at your option) any later version.
 
12
 
 
13
   This program is distributed in the hope that it will be useful,
 
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
 
 
18
   You should have received a copy of the GNU General Public License
 
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
*/
 
21
 
 
22
#include "includes.h"
 
23
#include "librpc/gen_ndr/security.h"
 
24
#include "libcli/smb2/smb2.h"
 
25
#include "libcli/smb2/smb2_calls.h"
 
26
#include "torture/torture.h"
 
27
#include "torture/smb2/proto.h"
 
28
 
 
29
#define CHECK_VAL(v, correct) do { \
 
30
        if ((v) != (correct)) { \
 
31
                torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
 
32
                                __location__, #v, (int)v, (int)correct); \
 
33
                ret = false; \
 
34
        }} while (0)
 
35
 
 
36
#define CHECK_STATUS(status, correct) do { \
 
37
        if (!NT_STATUS_EQUAL(status, correct)) { \
 
38
                torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
 
39
                       nt_errstr(status), nt_errstr(correct)); \
 
40
                ret = false; \
 
41
                goto done; \
 
42
        }} while (0)
 
43
 
 
44
static struct {
 
45
        struct smb2_handle handle;
 
46
        uint8_t level;
 
47
        struct smb2_break br;
 
48
        int count;
 
49
        int failures;
 
50
} break_info;
 
51
 
 
52
static void torture_oplock_break_callback(struct smb2_request *req)
 
53
{
 
54
        NTSTATUS status;
 
55
        struct smb2_break br;
 
56
 
 
57
        ZERO_STRUCT(br);
 
58
        status = smb2_break_recv(req, &break_info.br);
 
59
        if (!NT_STATUS_IS_OK(status)) {
 
60
                break_info.failures++;
 
61
        }
 
62
 
 
63
        return;
 
64
}
 
65
 
 
66
/* a oplock break request handler */
 
67
static bool torture_oplock_handler(struct smb2_transport *transport,
 
68
                                   const struct smb2_handle *handle,
 
69
                                   uint8_t level, void *private_data)
 
70
{
 
71
        struct smb2_tree *tree = private_data;
 
72
        const char *name;
 
73
        struct smb2_request *req;
 
74
 
 
75
        break_info.handle       = *handle;
 
76
        break_info.level        = level;
 
77
        break_info.count++;
 
78
 
 
79
        switch (level) {
 
80
        case SMB2_OPLOCK_LEVEL_II:
 
81
                name = "level II";
 
82
                break;
 
83
        case SMB2_OPLOCK_LEVEL_NONE:
 
84
                name = "none";
 
85
                break;
 
86
        default:
 
87
                name = "unknown";
 
88
                break_info.failures++;
 
89
        }
 
90
        printf("Acking to %s [0x%02X] in oplock handler\n",
 
91
                name, level);
 
92
 
 
93
        ZERO_STRUCT(break_info.br);
 
94
        break_info.br.in.file.handle    = *handle;
 
95
        break_info.br.in.oplock_level   = level;
 
96
        break_info.br.in.reserved       = 0;
 
97
        break_info.br.in.reserved2      = 0;
 
98
 
 
99
        req = smb2_break_send(tree, &break_info.br);
 
100
        req->async.fn = torture_oplock_break_callback;
 
101
        req->async.private_data = NULL;
 
102
 
 
103
        return true;
 
104
}
 
105
 
 
106
bool torture_smb2_oplock_batch1(struct torture_context *tctx,
 
107
                                struct smb2_tree *tree)
 
108
{
 
109
        TALLOC_CTX *mem_ctx = talloc_new(tctx);
 
110
        struct smb2_handle h1, h2;
 
111
        struct smb2_create io;
 
112
        NTSTATUS status;
 
113
        const char *fname = "oplock.dat";
 
114
        bool ret = true;
 
115
 
 
116
        tree->session->transport->oplock.handler        = torture_oplock_handler;
 
117
        tree->session->transport->oplock.private_data   = tree;
 
118
 
 
119
        smb2_util_unlink(tree, fname);
 
120
 
 
121
        ZERO_STRUCT(break_info);
 
122
 
 
123
        ZERO_STRUCT(io);
 
124
        io.in.security_flags            = 0x00;
 
125
        io.in.oplock_level              = SMB2_OPLOCK_LEVEL_BATCH;
 
126
        io.in.impersonation_level       = NTCREATEX_IMPERSONATION_IMPERSONATION;
 
127
        io.in.create_flags              = 0x00000000;
 
128
        io.in.reserved                  = 0x00000000;
 
129
        io.in.desired_access            = SEC_RIGHTS_FILE_ALL;
 
130
        io.in.file_attributes           = FILE_ATTRIBUTE_NORMAL;
 
131
        io.in.share_access              = NTCREATEX_SHARE_ACCESS_READ |
 
132
                                          NTCREATEX_SHARE_ACCESS_WRITE |
 
133
                                          NTCREATEX_SHARE_ACCESS_DELETE;
 
134
        io.in.create_disposition        = NTCREATEX_DISP_OPEN_IF;
 
135
        io.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
 
136
                                          NTCREATEX_OPTIONS_ASYNC_ALERT |
 
137
                                          NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
 
138
                                          0x00200000;
 
139
        io.in.fname                     = fname;
 
140
 
 
141
        status = smb2_create(tree, mem_ctx, &io);
 
142
        CHECK_STATUS(status, NT_STATUS_OK);
 
143
        CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
 
144
        /*CHECK_VAL(io.out.reserved, 0);*/
 
145
        CHECK_VAL(io.out.create_action, NTCREATEX_ACTION_CREATED);
 
146
        CHECK_VAL(io.out.alloc_size, 0);
 
147
        CHECK_VAL(io.out.size, 0);
 
148
        CHECK_VAL(io.out.file_attr, FILE_ATTRIBUTE_ARCHIVE);
 
149
        CHECK_VAL(io.out.reserved2, 0);
 
150
        CHECK_VAL(break_info.count, 0);
 
151
 
 
152
        h1 = io.out.file.handle;
 
153
 
 
154
        ZERO_STRUCT(io.in.blobs);
 
155
        status = smb2_create(tree, mem_ctx, &io);
 
156
        CHECK_VAL(break_info.count, 1);
 
157
        CHECK_VAL(break_info.failures, 0);
 
158
        CHECK_VAL(break_info.level, SMB2_OPLOCK_LEVEL_II);
 
159
        CHECK_STATUS(status, NT_STATUS_OK);
 
160
        CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_II);
 
161
        /*CHECK_VAL(io.out.reserved, 0);*/
 
162
        CHECK_VAL(io.out.create_action, NTCREATEX_ACTION_EXISTED);
 
163
        CHECK_VAL(io.out.alloc_size, 0);
 
164
        CHECK_VAL(io.out.size, 0);
 
165
        CHECK_VAL(io.out.file_attr, FILE_ATTRIBUTE_ARCHIVE);
 
166
        CHECK_VAL(io.out.reserved2, 0);
 
167
 
 
168
        h2 = io.out.file.handle;
 
169
 
 
170
done:
 
171
        talloc_free(mem_ctx);
 
172
 
 
173
        smb2_util_close(tree, h1);
 
174
        smb2_util_close(tree, h2);
 
175
        smb2_util_unlink(tree, fname);
 
176
        return ret;
 
177
}