LCOV - code coverage report
Current view: top level - source4/torture/raw - composite.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 198 242 81.8 %
Date: 2024-04-21 15:09:00 Functions: 10 10 100.0 %

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

Generated by: LCOV version 1.14