~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/raw/composite.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
   libcli composite function testing
 
5
 
 
6
   Copyright (C) Andrew Tridgell 2005
 
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 "torture/torture.h"
 
24
#include "lib/events/events.h"
 
25
#include "libcli/raw/libcliraw.h"
 
26
#include "libcli/libcli.h"
 
27
#include "libcli/security/security.h"
 
28
#include "libcli/composite/composite.h"
 
29
#include "libcli/smb_composite/smb_composite.h"
 
30
#include "librpc/gen_ndr/ndr_misc.h"
 
31
#include "lib/cmdline/popt_common.h"
 
32
#include "torture/util.h"
 
33
#include "param/param.h"
 
34
#include "libcli/resolve/resolve.h"
 
35
 
 
36
#define BASEDIR "\\composite"
 
37
 
 
38
static void loadfile_complete(struct composite_context *c)
 
39
{
 
40
        int *count = talloc_get_type(c->async.private_data, int);
 
41
        (*count)++;
 
42
}
 
43
 
 
44
/*
 
45
  test a simple savefile/loadfile combination
 
46
*/
 
47
static bool test_loadfile(struct smbcli_state *cli, struct torture_context *tctx)
 
48
{
 
49
        const char *fname = BASEDIR "\\test.txt";
 
50
        NTSTATUS status;
 
51
        struct smb_composite_savefile io1;
 
52
        struct smb_composite_loadfile io2;
 
53
        struct composite_context **c;
 
54
        uint8_t *data;
 
55
        size_t len = random() % 100000;
 
56
        const int num_ops = 50;
 
57
        int i;
 
58
        int *count = talloc_zero(tctx, int);
 
59
 
 
60
        data = talloc_array(tctx, uint8_t, len);
 
61
 
 
62
        generate_random_buffer(data, len);
 
63
 
 
64
        io1.in.fname = fname;
 
65
        io1.in.data  = data;
 
66
        io1.in.size  = len;
 
67
 
 
68
        printf("testing savefile\n");
 
69
 
 
70
        status = smb_composite_savefile(cli->tree, &io1);
 
71
        if (!NT_STATUS_IS_OK(status)) {
 
72
                printf("(%s) savefile failed: %s\n", __location__,nt_errstr(status));
 
73
                return false;
 
74
        }
 
75
 
 
76
        io2.in.fname = fname;
 
77
 
 
78
        printf("testing parallel loadfile with %d ops\n", num_ops);
 
79
 
 
80
        c = talloc_array(tctx, struct composite_context *, num_ops);
 
81
 
 
82
        for (i=0;i<num_ops;i++) {
 
83
                c[i] = smb_composite_loadfile_send(cli->tree, &io2);
 
84
                c[i]->async.fn = loadfile_complete;
 
85
                c[i]->async.private_data = count;
 
86
        }
 
87
 
 
88
        printf("waiting for completion\n");
 
89
        while (*count != num_ops) {
 
90
                event_loop_once(cli->transport->socket->event.ctx);
 
91
                if (torture_setting_bool(tctx, "progress", true)) {
 
92
                        printf("(%s) count=%d\r", __location__, *count);
 
93
                        fflush(stdout);
 
94
                }
 
95
        }
 
96
        printf("count=%d\n", *count);
 
97
        
 
98
        for (i=0;i<num_ops;i++) {
 
99
                status = smb_composite_loadfile_recv(c[i], tctx);
 
100
                if (!NT_STATUS_IS_OK(status)) {
 
101
                        printf("(%s) loadfile[%d] failed - %s\n", __location__, i, nt_errstr(status));
 
102
                        return false;
 
103
                }
 
104
 
 
105
                if (io2.out.size != len) {
 
106
                        printf("(%s) wrong length in returned data - %d should be %d\n",__location__,
 
107
                               io2.out.size, (int)len);
 
108
                        return false;
 
109
                }
 
110
                
 
111
                if (memcmp(io2.out.data, data, len) != 0) {
 
112
                        printf("(%s) wrong data in loadfile!\n",__location__);
 
113
                        return false;
 
114
                }
 
115
        }
 
116
 
 
117
        talloc_free(data);
 
118
 
 
119
        return true;
 
120
}
 
121
 
 
122
/*
 
123
  test a simple savefile/loadfile combination
 
124
*/
 
125
static bool test_fetchfile(struct smbcli_state *cli, struct torture_context *tctx)
 
126
{
 
127
        const char *fname = BASEDIR "\\test.txt";
 
128
        NTSTATUS status;
 
129
        struct smb_composite_savefile io1;
 
130
        struct smb_composite_fetchfile io2;
 
131
        struct composite_context **c;
 
132
        uint8_t *data;
 
133
        int i;
 
134
        size_t len = random() % 10000;
 
135
        extern int torture_numops;
 
136
        struct tevent_context *event_ctx;
 
137
        int *count = talloc_zero(tctx, int);
 
138
        bool ret = true;
 
139
 
 
140
        data = talloc_array(tctx, uint8_t, len);
 
141
 
 
142
        generate_random_buffer(data, len);
 
143
 
 
144
        io1.in.fname = fname;
 
145
        io1.in.data  = data;
 
146
        io1.in.size  = len;
 
147
 
 
148
        printf("testing savefile\n");
 
149
 
 
150
        status = smb_composite_savefile(cli->tree, &io1);
 
151
        if (!NT_STATUS_IS_OK(status)) {
 
152
                printf("(%s) savefile failed: %s\n",__location__, nt_errstr(status));
 
153
                return false;
 
154
        }
 
155
 
 
156
        io2.in.dest_host = torture_setting_string(tctx, "host", NULL);
 
157
        io2.in.ports = lp_smb_ports(tctx->lp_ctx);
 
158
        io2.in.called_name = torture_setting_string(tctx, "host", NULL);
 
159
        io2.in.service = torture_setting_string(tctx, "share", NULL);
 
160
        io2.in.service_type = "A:";
 
161
 
 
162
        io2.in.credentials = cmdline_credentials;
 
163
        io2.in.workgroup  = lp_workgroup(tctx->lp_ctx);
 
164
        io2.in.filename = fname;
 
165
        io2.in.resolve_ctx = lp_resolve_context(tctx->lp_ctx);
 
166
        io2.in.iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);
 
167
        io2.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
 
168
        lp_smbcli_options(tctx->lp_ctx, &io2.in.options);
 
169
        lp_smbcli_session_options(tctx->lp_ctx, &io2.in.session_options);
 
170
 
 
171
        printf("testing parallel fetchfile with %d ops\n", torture_numops);
 
172
 
 
173
        event_ctx = cli->transport->socket->event.ctx;
 
174
        c = talloc_array(tctx, struct composite_context *, torture_numops);
 
175
 
 
176
        for (i=0; i<torture_numops; i++) {
 
177
                c[i] = smb_composite_fetchfile_send(&io2, event_ctx);
 
178
                c[i]->async.fn = loadfile_complete;
 
179
                c[i]->async.private_data = count;
 
180
        }
 
181
 
 
182
        printf("waiting for completion\n");
 
183
 
 
184
        while (*count != torture_numops) {
 
185
                event_loop_once(event_ctx);
 
186
                if (torture_setting_bool(tctx, "progress", true)) {
 
187
                        printf("(%s) count=%d\r", __location__, *count);
 
188
                        fflush(stdout);
 
189
                }
 
190
        }
 
191
        printf("count=%d\n", *count);
 
192
 
 
193
        for (i=0;i<torture_numops;i++) {
 
194
                status = smb_composite_fetchfile_recv(c[i], tctx);
 
195
                if (!NT_STATUS_IS_OK(status)) {
 
196
                        printf("(%s) loadfile[%d] failed - %s\n", __location__, i,
 
197
                               nt_errstr(status));
 
198
                        ret = false;
 
199
                        continue;
 
200
                }
 
201
 
 
202
                if (io2.out.size != len) {
 
203
                        printf("(%s) wrong length in returned data - %d "
 
204
                               "should be %d\n", __location__,
 
205
                               io2.out.size, (int)len);
 
206
                        ret = false;
 
207
                        continue;
 
208
                }
 
209
                
 
210
                if (memcmp(io2.out.data, data, len) != 0) {
 
211
                        printf("(%s) wrong data in loadfile!\n", __location__);
 
212
                        ret = false;
 
213
                        continue;
 
214
                }
 
215
        }
 
216
 
 
217
        return ret;
 
218
}
 
219
 
 
220
/*
 
221
  test setfileacl
 
222
*/
 
223
static bool test_appendacl(struct smbcli_state *cli, struct torture_context *tctx)
 
224
{
 
225
        struct smb_composite_appendacl **io;
 
226
        struct smb_composite_appendacl **io_orig;
 
227
        struct composite_context **c;
 
228
        struct tevent_context *event_ctx;
 
229
 
 
230
        struct security_descriptor *test_sd;
 
231
        struct security_ace *ace;
 
232
        struct dom_sid *test_sid;
 
233
 
 
234
        const int num_ops = 50;
 
235
        int *count = talloc_zero(tctx, int);
 
236
        struct smb_composite_savefile io1;
 
237
 
 
238
        NTSTATUS status;
 
239
        int i;
 
240
 
 
241
        io_orig = talloc_array(tctx, struct smb_composite_appendacl *, num_ops);
 
242
 
 
243
        printf ("creating %d empty files and getting their acls with appendacl\n", num_ops);
 
244
 
 
245
        for (i = 0; i < num_ops; i++) {
 
246
                io1.in.fname = talloc_asprintf(io_orig, BASEDIR "\\test%d.txt", i);
 
247
                io1.in.data  = NULL;
 
248
                io1.in.size  = 0;
 
249
          
 
250
                status = smb_composite_savefile(cli->tree, &io1);
 
251
                if (!NT_STATUS_IS_OK(status)) {
 
252
                        printf("(%s) savefile failed: %s\n", __location__, nt_errstr(status));
 
253
                        return false;
 
254
                }
 
255
 
 
256
                io_orig[i] = talloc (io_orig, struct smb_composite_appendacl);
 
257
                io_orig[i]->in.fname = talloc_steal(io_orig[i], io1.in.fname);
 
258
                io_orig[i]->in.sd = security_descriptor_initialise(io_orig[i]);
 
259
                status = smb_composite_appendacl(cli->tree, io_orig[i], io_orig[i]);
 
260
                if (!NT_STATUS_IS_OK(status)) {
 
261
                        printf("(%s) appendacl failed: %s\n", __location__, nt_errstr(status));
 
262
                        return false;
 
263
                }
 
264
        }
 
265
        
 
266
 
 
267
        /* fill Security Descriptor with aces to be added */
 
268
 
 
269
        test_sd = security_descriptor_initialise(tctx);
 
270
        test_sid = dom_sid_parse_talloc (tctx, "S-1-5-32-1234-5432");
 
271
 
 
272
        ace = talloc_zero(tctx, struct security_ace);
 
273
 
 
274
        ace->type = SEC_ACE_TYPE_ACCESS_ALLOWED;
 
275
        ace->flags = 0;
 
276
        ace->access_mask = SEC_STD_ALL;
 
277
        ace->trustee = *test_sid;
 
278
 
 
279
        status = security_descriptor_dacl_add(test_sd, ace);
 
280
        if (!NT_STATUS_IS_OK(status)) {
 
281
                printf("(%s) appendacl failed: %s\n", __location__, nt_errstr(status));
 
282
                return false;
 
283
        }
 
284
 
 
285
        /* set parameters for appendacl async call */
 
286
 
 
287
        printf("testing parallel appendacl with %d ops\n", num_ops);
 
288
 
 
289
        c = talloc_array(tctx, struct composite_context *, num_ops);
 
290
        io = talloc_array(tctx, struct  smb_composite_appendacl *, num_ops);
 
291
 
 
292
        for (i=0; i < num_ops; i++) {
 
293
                io[i] = talloc (io, struct smb_composite_appendacl);
 
294
                io[i]->in.sd = test_sd;
 
295
                io[i]->in.fname = talloc_asprintf(io[i], BASEDIR "\\test%d.txt", i);
 
296
 
 
297
                c[i] = smb_composite_appendacl_send(cli->tree, io[i]);
 
298
                c[i]->async.fn = loadfile_complete;
 
299
                c[i]->async.private_data = count;
 
300
        }
 
301
 
 
302
        event_ctx = tctx->ev;
 
303
        printf("waiting for completion\n");
 
304
        while (*count != num_ops) {
 
305
                event_loop_once(event_ctx);
 
306
                if (torture_setting_bool(tctx, "progress", true)) {
 
307
                        printf("(%s) count=%d\r", __location__, *count);
 
308
                        fflush(stdout);
 
309
                }
 
310
        }
 
311
        printf("count=%d\n", *count);
 
312
 
 
313
        for (i=0; i < num_ops; i++) {
 
314
                status = smb_composite_appendacl_recv(c[i], io[i]);
 
315
                if (!NT_STATUS_IS_OK(status)) {
 
316
                        printf("(%s) appendacl[%d] failed - %s\n", __location__, i, nt_errstr(status));
 
317
                        return false;
 
318
                }
 
319
                
 
320
                security_descriptor_dacl_add(io_orig[i]->out.sd, ace);
 
321
                if (!security_acl_equal(io_orig[i]->out.sd->dacl, io[i]->out.sd->dacl)) {
 
322
                        printf("(%s) appendacl[%d] failed - needed acl isn't set\n", __location__, i);
 
323
                        return false;
 
324
                }
 
325
        }
 
326
        
 
327
 
 
328
        talloc_free (ace);
 
329
        talloc_free (test_sid);
 
330
        talloc_free (test_sd);
 
331
                
 
332
        return true;
 
333
}
 
334
 
 
335
/* test a query FS info by asking for share's GUID */
 
336
static bool test_fsinfo(struct smbcli_state *cli, struct torture_context *tctx)
 
337
{
 
338
        char *guid = NULL;
 
339
        NTSTATUS status;
 
340
        struct smb_composite_fsinfo io1;
 
341
        struct composite_context **c;
 
342
 
 
343
        int i;
 
344
        extern int torture_numops;
 
345
        struct tevent_context *event_ctx;
 
346
        int *count = talloc_zero(tctx, int);
 
347
        bool ret = true;
 
348
 
 
349
        io1.in.dest_host = torture_setting_string(tctx, "host", NULL);
 
350
        io1.in.dest_ports = lp_smb_ports(tctx->lp_ctx);
 
351
        io1.in.socket_options = lp_socket_options(tctx->lp_ctx);
 
352
        io1.in.called_name = torture_setting_string(tctx, "host", NULL);
 
353
        io1.in.service = torture_setting_string(tctx, "share", NULL);
 
354
        io1.in.service_type = "A:";
 
355
        io1.in.credentials = cmdline_credentials;
 
356
        io1.in.workgroup = lp_workgroup(tctx->lp_ctx);
 
357
        io1.in.level = RAW_QFS_OBJECTID_INFORMATION;
 
358
        io1.in.iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);
 
359
        io1.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
 
360
 
 
361
        printf("testing parallel queryfsinfo [Object ID] with %d ops\n", torture_numops);
 
362
 
 
363
        event_ctx = tctx->ev;
 
364
        c = talloc_array(tctx, struct composite_context *, torture_numops);
 
365
 
 
366
        for (i=0; i<torture_numops; i++) {
 
367
                c[i] = smb_composite_fsinfo_send(cli->tree, &io1, lp_resolve_context(tctx->lp_ctx));
 
368
                c[i]->async.fn = loadfile_complete;
 
369
                c[i]->async.private_data = count;
 
370
        }
 
371
 
 
372
        printf("waiting for completion\n");
 
373
 
 
374
        while (*count < torture_numops) {
 
375
                event_loop_once(event_ctx);
 
376
                if (torture_setting_bool(tctx, "progress", true)) {
 
377
                        printf("(%s) count=%d\r", __location__, *count);
 
378
                        fflush(stdout);
 
379
                }
 
380
        }
 
381
        printf("count=%d\n", *count);
 
382
 
 
383
        for (i=0;i<torture_numops;i++) {
 
384
                status = smb_composite_fsinfo_recv(c[i], tctx);
 
385
                if (!NT_STATUS_IS_OK(status)) {
 
386
                        printf("(%s) fsinfo[%d] failed - %s\n", __location__, i, nt_errstr(status));
 
387
                        ret = false;
 
388
                        continue;
 
389
                }
 
390
 
 
391
                if (io1.out.fsinfo->generic.level != RAW_QFS_OBJECTID_INFORMATION) {
 
392
                        printf("(%s) wrong level in returned info - %d "
 
393
                               "should be %d\n", __location__,
 
394
                               io1.out.fsinfo->generic.level, RAW_QFS_OBJECTID_INFORMATION);
 
395
                        ret = false;
 
396
                        continue;
 
397
                }
 
398
 
 
399
                guid=GUID_string(tctx, &io1.out.fsinfo->objectid_information.out.guid);
 
400
                printf("[%d] GUID: %s\n", i, guid);
 
401
 
 
402
                
 
403
        }
 
404
 
 
405
        return ret;
 
406
}
 
407
 
 
408
 
 
409
/* 
 
410
   basic testing of libcli composite calls
 
411
*/
 
412
bool torture_raw_composite(struct torture_context *tctx, 
 
413
                           struct smbcli_state *cli)
 
414
{
 
415
        bool ret = true;
 
416
 
 
417
        if (!torture_setup_dir(cli, BASEDIR)) {
 
418
                return false;
 
419
        }
 
420
 
 
421
        ret &= test_fetchfile(cli, tctx);
 
422
        ret &= test_loadfile(cli, tctx);
 
423
        ret &= test_appendacl(cli, tctx);
 
424
        ret &= test_fsinfo(cli, tctx);
 
425
 
 
426
        smb_raw_exit(cli->session);
 
427
        smbcli_deltree(cli->tree, BASEDIR);
 
428
 
 
429
        return ret;
 
430
}