root/source4/torture/raw/composite.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. loadfile_complete
  2. test_loadfile
  3. test_fetchfile
  4. test_appendacl
  5. test_fsinfo
  6. torture_raw_composite

   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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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, 
     /* [<][>][^][v][top][bottom][index][help] */
 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 }

/* [<][>][^][v][top][bottom][index][help] */