20
20
#include "includes.h"
21
#include "torture/torture.h"
22
21
#include "system/filesys.h"
23
#include "libcli/raw/libcliraw.h"
24
22
#include "libcli/libcli.h"
25
23
#include "libcli/security/security.h"
26
24
#include "torture/util.h"
27
#include "torture/smbtorture.h"
28
#include "libcli/util/clilsa.h"
29
25
#include "cxd_known.h"
31
27
extern int torture_failures;
1406
static void progress_bar(struct torture_context *tctx, uint_t i, uint_t total)
1402
static void progress_bar(struct torture_context *tctx, unsigned int i, unsigned int total)
1408
1404
if (torture_setting_bool(tctx, "progress", true)) {
1409
1405
torture_comment(tctx, "%5d/%5d\r", i, total);
1433
1429
smbcli_close(cli1->tree, fnum1);
1436
torture_comment(tctx, "testing %d entries\n", (int)ARRAY_SIZE(denytable1));
1432
torture_comment(tctx, "Testing %d entries\n", (int)ARRAY_SIZE(denytable1));
1438
GetTimeOfDay(&tv_start);
1434
clock_gettime_mono(&tv_start);
1440
1436
for (i=0; i<ARRAY_SIZE(denytable1); i++) {
1441
1437
enum deny_result res;
1444
1440
progress_bar(tctx, i, ARRAY_SIZE(denytable1));
1442
if (!torture_setting_bool(tctx, "deny_fcb_support", true) &&
1443
(denytable1[i].deny1 == DENY_FCB ||
1444
denytable1[i].deny2 == DENY_FCB))
1447
if (!torture_setting_bool(tctx, "deny_dos_support", true) &&
1448
(denytable1[i].deny1 == DENY_DOS ||
1449
denytable1[i].deny2 == DENY_DOS))
1446
1452
fnum1 = smbcli_open(cli1->tree, fname,
1447
1453
denytable1[i].mode1,
1448
1454
denytable1[i].deny1);
1468
1474
if (torture_setting_bool(tctx, "showall", false) ||
1469
1475
res != denytable1[i].result) {
1472
tdif = usec_time_diff(&tv, &tv_start);
1477
clock_gettime_mono(&tv);
1478
tdif = nsec_time_diff(&tv, &tv_start);
1474
1480
torture_comment(tctx, "%lld: %s %8s %10s %8s %10s %s (correct=%s)\n",
1475
1481
(long long)tdif,
1531
1537
progress_bar(tctx, i, ARRAY_SIZE(denytable1));
1539
if (!torture_setting_bool(tctx, "deny_fcb_support", true) &&
1540
(denytable1[i].deny1 == DENY_FCB ||
1541
denytable1[i].deny2 == DENY_FCB))
1544
if (!torture_setting_bool(tctx, "deny_dos_support", true) &&
1545
(denytable1[i].deny1 == DENY_DOS ||
1546
denytable1[i].deny2 == DENY_DOS))
1533
1549
fnum1 = smbcli_open(cli1->tree, fname,
1534
1550
denytable2[i].mode1,
1535
1551
denytable2[i].deny1);
1555
1571
if (torture_setting_bool(tctx, "showall", false) ||
1556
1572
res != denytable2[i].result) {
1559
tdif = usec_time_diff(&tv, &tv_start);
1574
clock_gettime_mono(&tv);
1575
tdif = nsec_time_diff(&tv, &tv_start);
1561
1577
torture_comment(tctx, "%lld: %s %8s %10s %8s %10s %s (correct=%s)\n",
1562
1578
(long long)tdif,
1726
1742
a denytest for ntcreatex
1728
1744
static bool torture_ntdenytest(struct torture_context *tctx,
1729
struct smbcli_state *cli1, struct smbcli_state *cli2, int client)
1745
struct smbcli_state *cli1,
1746
struct smbcli_state *cli2, int client)
1731
1748
const struct bit_value share_access_bits[] = {
1732
1749
{ NTCREATEX_SHARE_ACCESS_READ, "S_R" },
1766
1783
smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf));
1767
1784
smbcli_close(cli1->tree, fnum1);
1769
GetTimeOfDay(&tv_start);
1786
clock_gettime_mono(&tv_start);
1771
1788
io1.ntcreatex.level = RAW_OPEN_NTCREATEX;
1772
io1.ntcreatex.in.root_fid = 0;
1789
io1.ntcreatex.in.root_fid.fnum = 0;
1773
1790
io1.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1774
1791
io1.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
1775
1792
io1.ntcreatex.in.file_attr = 0;
1780
1797
io1.ntcreatex.in.fname = fname;
1783
torture_comment(tctx, "testing %d entries on %s\n", torture_numops, fname);
1800
torture_comment(tctx, "Testing %d entries on %s\n", torture_numops, fname);
1785
1802
for (i=0;i<torture_numops;i++) {
1786
1803
NTSTATUS status1, status2, status2_p;
1854
1871
read_for_execute,
1858
tdif = usec_time_diff(&tv, &tv_start);
1874
clock_gettime_mono(&tv);
1875
tdif = nsec_time_diff(&tv, &tv_start);
1860
1877
if (torture_setting_bool(tctx, "showall", false) ||
1861
1878
!NT_STATUS_EQUAL(status2, status2_p) ||
2081
#define FILL_NTCREATEX(_struct, _init...) \
2083
(_struct)->generic.level = RAW_OPEN_NTCREATEX; \
2084
(_struct)->ntcreatex.in \
2085
= (typeof((_struct)->ntcreatex.in)) {_init};\
2088
2098
#define CREATEX_NAME "\\createx_dir"
2090
2100
static bool createx_make_dir(struct torture_context *tctx,
2107
2117
bool ret = true;
2108
2118
NTSTATUS status;
2110
FILL_NTCREATEX(&open_parms,
2112
.access_mask = SEC_RIGHTS_FILE_ALL,
2113
.file_attr = FILE_ATTRIBUTE_NORMAL,
2115
.open_disposition = NTCREATEX_DISP_CREATE,
2116
.create_options = 0,
2120
ZERO_STRUCT(open_parms);
2121
open_parms.generic.level = RAW_OPEN_NTCREATEX;
2122
open_parms.ntcreatex.in.flags = 0;
2123
open_parms.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2124
open_parms.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2125
open_parms.ntcreatex.in.share_access = 0;
2126
open_parms.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2127
open_parms.ntcreatex.in.create_options = 0;
2128
open_parms.ntcreatex.in.fname = fname;
2119
2130
status = smb_raw_open(tree, mem_ctx, &open_parms);
2120
2131
CHECK_STATUS(status, NT_STATUS_OK);
2129
2140
static void createx_fill_dir(union smb_open *open_parms, int accessmode,
2130
2141
int sharemode, const char *fname)
2132
FILL_NTCREATEX(open_parms,
2134
.access_mask = accessmode,
2135
.file_attr = FILE_ATTRIBUTE_DIRECTORY,
2136
.share_access = sharemode,
2137
.open_disposition = NTCREATEX_DISP_OPEN_IF,
2138
.create_options = NTCREATEX_OPTIONS_DIRECTORY,
2143
ZERO_STRUCTP(open_parms);
2144
open_parms->generic.level = RAW_OPEN_NTCREATEX;
2145
open_parms->ntcreatex.in.flags = 0;
2146
open_parms->ntcreatex.in.access_mask = accessmode;
2147
open_parms->ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
2148
open_parms->ntcreatex.in.share_access = sharemode;
2149
open_parms->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2150
open_parms->ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2151
open_parms->ntcreatex.in.fname = fname;
2143
2154
static void createx_fill_file(union smb_open *open_parms, int accessmode,
2144
2155
int sharemode, const char *fname)
2146
FILL_NTCREATEX(open_parms,
2148
.access_mask = accessmode,
2149
.file_attr = FILE_ATTRIBUTE_NORMAL,
2150
.share_access = sharemode,
2151
.open_disposition = NTCREATEX_DISP_OPEN_IF,
2152
.create_options = 0,
2157
ZERO_STRUCTP(open_parms);
2158
open_parms->generic.level = RAW_OPEN_NTCREATEX;
2159
open_parms->ntcreatex.in.flags = 0;
2160
open_parms->ntcreatex.in.access_mask = accessmode;
2161
open_parms->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2162
open_parms->ntcreatex.in.share_access = sharemode;
2163
open_parms->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2164
open_parms->ntcreatex.in.create_options = 0;
2165
open_parms->ntcreatex.in.fname = fname;
2166
open_parms->ntcreatex.in.root_fid.fnum = 0;
2157
2169
static int data_file_fd = -1;
2166
2178
union smb_open open_parms;
2168
2180
/* bypass original handle to guarantee creation */
2169
FILL_NTCREATEX(&open_parms,
2171
.access_mask = SEC_RIGHTS_FILE_ALL,
2172
.file_attr = FILE_ATTRIBUTE_NORMAL,
2174
.open_disposition = NTCREATEX_DISP_CREATE,
2175
.create_options = 0,
2176
.fname = CREATEX_NAME "\\" KNOWN,
2181
ZERO_STRUCT(open_parms);
2182
open_parms.generic.level = RAW_OPEN_NTCREATEX;
2183
open_parms.ntcreatex.in.flags = 0;
2184
open_parms.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2185
open_parms.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2186
open_parms.ntcreatex.in.share_access = 0;
2187
open_parms.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2188
open_parms.ntcreatex.in.create_options = 0;
2189
open_parms.ntcreatex.in.fname = CREATEX_NAME "\\" KNOWN;
2178
2191
status = smb_raw_open(tree, mem_ctx, &open_parms);
2179
2192
CHECK_STATUS(status, NT_STATUS_OK);
2180
2193
smbcli_close(tree, open_parms.ntcreatex.out.file.fnum);
2182
2195
result[CXD_DIR_ENUMERATE] = NT_STATUS_OK;
2184
2197
/* try to create a child */
2185
FILL_NTCREATEX(&open_parms,
2187
.access_mask = SEC_RIGHTS_FILE_ALL,
2188
.file_attr = FILE_ATTRIBUTE_NORMAL,
2190
.open_disposition = NTCREATEX_DISP_CREATE,
2191
.create_options = 0,
2198
ZERO_STRUCT(open_parms);
2199
open_parms.generic.level = RAW_OPEN_NTCREATEX;
2200
open_parms.ntcreatex.in.flags = 0;
2201
open_parms.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2202
open_parms.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2203
open_parms.ntcreatex.in.share_access = 0;
2204
open_parms.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2205
open_parms.ntcreatex.in.create_options = 0;
2206
open_parms.ntcreatex.in.fname = CHILD;
2207
open_parms.ntcreatex.in.root_fid.fnum = fnum;
2196
2209
result[CXD_DIR_CREATE_CHILD] =
2197
2210
smb_raw_open(tree, mem_ctx, &open_parms);
2198
2211
smbcli_close(tree, open_parms.ntcreatex.out.file.fnum);
2200
2213
/* try to traverse dir to known good file */
2201
FILL_NTCREATEX(&open_parms,
2203
.access_mask = SEC_RIGHTS_FILE_ALL,
2204
.file_attr = FILE_ATTRIBUTE_NORMAL,
2206
.open_disposition = NTCREATEX_DISP_OPEN,
2207
.create_options = 0,
2214
ZERO_STRUCT(open_parms);
2215
open_parms.generic.level = RAW_OPEN_NTCREATEX;
2216
open_parms.ntcreatex.in.flags = 0;
2217
open_parms.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2218
open_parms.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2219
open_parms.ntcreatex.in.share_access = 0;
2220
open_parms.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2221
open_parms.ntcreatex.in.create_options = 0;
2222
open_parms.ntcreatex.in.fname = KNOWN;
2223
open_parms.ntcreatex.in.root_fid.fnum = fnum;
2212
2225
result[CXD_DIR_TRAVERSE] =
2213
2226
smb_raw_open(tree, mem_ctx, &open_parms);
2224
2237
static bool createx_test_file(struct torture_context *tctx,
2225
2238
struct smbcli_tree *tree, int fnum, TALLOC_CTX *mem_ctx, NTSTATUS *result)
2227
union smb_read rd = {};
2228
union smb_write wr = {};
2229
2242
char buf[256] = "";
2244
memset(&rd, 0, sizeof(rd));
2231
2245
rd.readx.level = RAW_READ_READX;
2232
2246
rd.readx.in.file.fnum = fnum;
2233
2247
rd.readx.in.mincnt = sizeof(buf);
2234
2248
rd.readx.in.maxcnt = sizeof(buf);
2235
rd.readx.out.data = buf;
2249
rd.readx.out.data = (uint8_t *)buf;
2237
2251
result[CXD_FILE_READ] = smb_raw_read(tree, &rd);
2253
memset(&wr, 0, sizeof(wr));
2239
2254
wr.writex.level = RAW_WRITE_WRITEX;
2240
2255
wr.writex.in.file.fnum = fnum;
2241
2256
wr.writex.in.count = sizeof(buf);
2242
wr.writex.in.data = buf;
2257
wr.writex.in.data = (uint8_t *)buf;
2244
2259
result[CXD_FILE_WRITE] = smb_raw_write(tree, &wr);
2249
2264
rd.readx.in.mincnt = sizeof(buf);
2250
2265
rd.readx.in.maxcnt = sizeof(buf);
2251
2266
rd.readx.in.read_for_execute = 1;
2252
rd.readx.out.data = buf;
2267
rd.readx.out.data = (uint8_t *)buf;
2254
2269
result[CXD_FILE_EXECUTE] = smb_raw_read(tree, &rd);
2259
2274
/* TODO When redirecting stdout to a file, the progress bar really screws up
2260
2275
* the output. Could use a switch "--noprogress", or direct the progress bar to
2261
2276
* stderr? No other solution? */
2262
static void createx_progress_bar(struct torture_context *tctx, uint_t i,
2263
uint_t total, uint_t skipped)
2277
static void createx_progress_bar(struct torture_context *tctx, unsigned int i,
2278
unsigned int total, unsigned int skipped)
2265
2280
if (torture_setting_bool(tctx, "progress", true)) {
2266
2281
torture_comment(tctx, "%5d/%5d (%d skipped)\r", i, total,
2581
2596
torture_createx_specific(tctx, cli, NULL, mem_ctx,
2585
2599
for (i = 0; i < num_access_bits; i++) {
2586
2600
/* And now run through the single access bits. */
2587
2601
cxd.cxd_access1 = 1 << i;
2690
2704
smbcli_unlink(cli->tree, MAXIMUM_ALLOWED_FILE);
2692
2706
/* create initial file with restrictive SD */
2707
memset(&io, 0, sizeof(io));
2693
2708
io.generic.level = RAW_OPEN_NTTRANS_CREATE;
2694
2709
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2695
2710
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2716
2731
owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
2718
status = smblsa_sid_check_privilege(cli,
2720
sec_privilege_name(SEC_PRIV_RESTORE));
2733
status = torture_check_privilege(cli,
2735
sec_privilege_name(SEC_PRIV_RESTORE));
2721
2736
has_restore_privilege = NT_STATUS_IS_OK(status);
2722
torture_comment(tctx, "Checked SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
2737
torture_comment(tctx, "Checked SEC_PRIV_RESTORE for %s - %s\n",
2739
has_restore_privilege?"Yes":"No");
2724
status = smblsa_sid_check_privilege(cli,
2726
sec_privilege_name(SEC_PRIV_BACKUP));
2741
status = torture_check_privilege(cli,
2743
sec_privilege_name(SEC_PRIV_BACKUP));
2727
2744
has_backup_privilege = NT_STATUS_IS_OK(status);
2728
torture_comment(tctx, "Checked SEC_PRIV_BACKUP - %s\n", has_backup_privilege?"Yes":"No");
2745
torture_comment(tctx, "Checked SEC_PRIV_BACKUP for %s - %s\n",
2747
has_backup_privilege?"Yes":"No");
2730
2749
smbcli_close(cli->tree, fnum);