*/
#include "includes.h"
+#include "system/filesys.h"
#include "libcli/raw/libcliraw.h"
extern BOOL torture_showall;
static const char *denystr(int denymode)
{
- struct {
+ const struct {
int v;
const char *name;
} deny_modes[] = {
static const char *openstr(int mode)
{
- struct {
+ const struct {
int v;
const char *name;
} open_modes[] = {
static const char *resultstr(enum deny_result res)
{
- struct {
+ const struct {
enum deny_result res;
const char *name;
} results[] = {
smbcli_close(cli1->tree, fnum1);
}
- printf("testing %d entries\n", ARRAY_SIZE(denytable1));
+ printf("testing %d entries\n", (int)ARRAY_SIZE(denytable1));
GetTimeOfDay(&tv_start);
} else if (fnum2 == -1) {
res = A_0;
} else {
- char x = 1;
+ uint8_t x = 1;
res = A_0;
- if (smbcli_read(cli1->tree, fnum2, (void *)&x, 0, 1) == 1) {
+ if (smbcli_read(cli1->tree, fnum2, &x, 0, 1) == 1) {
res += A_R;
}
- if (smbcli_write(cli1->tree, fnum2, 0, (void *)&x, 0, 1) == 1) {
+ if (smbcli_write(cli1->tree, fnum2, 0, &x, 0, 1) == 1) {
res += A_W;
}
}
tdif = usec_time_diff(&tv, &tv_start);
tdif /= 1000;
printf("%lld: %s %8s %10s %8s %10s %s (correct=%s)\n",
- tdif,
+ (long long)tdif,
fname,
denystr(denytable1[i].deny1),
openstr(denytable1[i].mode1),
} else if (fnum2 == -1) {
res = A_0;
} else {
- char x = 1;
+ uint8_t x = 1;
res = A_0;
- if (smbcli_read(cli2->tree, fnum2, (void *)&x, 0, 1) == 1) {
+ if (smbcli_read(cli2->tree, fnum2, &x, 0, 1) == 1) {
res += A_R;
}
- if (smbcli_write(cli2->tree, fnum2, 0, (void *)&x, 0, 1) == 1) {
+ if (smbcli_write(cli2->tree, fnum2, 0, &x, 0, 1) == 1) {
res += A_W;
}
}
tdif = usec_time_diff(&tv, &tv_start);
tdif /= 1000;
printf("%lld: %s %8s %10s %8s %10s %s (correct=%s)\n",
- tdif,
+ (long long)tdif,
fname,
denystr(denytable2[i].deny1),
openstr(denytable2[i].mode1),
}} while (0)
*res = A_0;
- if (am2 & SA_RIGHT_FILE_WRITE_APPEND) {
+ if (am2 & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) {
*res += A_W;
}
- if (am2 & SA_RIGHT_FILE_READ_DATA) {
+ if (am2 & SEC_FILE_READ_DATA) {
*res += A_R;
- } else if ((am2 & SA_RIGHT_FILE_EXECUTE) &&
+ } else if ((am2 & SEC_FILE_EXECUTE) &&
(flags2 & FLAGS2_READ_PERMIT_EXECUTE)) {
*res += A_R;
}
/* if either open involves no read.write or delete access then
it can't conflict */
- if (!(am1 & (SA_RIGHT_FILE_WRITE_APPEND |
- SA_RIGHT_FILE_READ_EXEC |
- STD_RIGHT_DELETE_ACCESS))) {
+ if (!(am1 & (SEC_FILE_WRITE_DATA |
+ SEC_FILE_APPEND_DATA |
+ SEC_FILE_READ_DATA |
+ SEC_FILE_EXECUTE |
+ SEC_STD_DELETE))) {
return NT_STATUS_OK;
}
- if (!(am2 & (SA_RIGHT_FILE_WRITE_APPEND |
- SA_RIGHT_FILE_READ_EXEC |
- STD_RIGHT_DELETE_ACCESS))) {
+ if (!(am2 & (SEC_FILE_WRITE_DATA |
+ SEC_FILE_APPEND_DATA |
+ SEC_FILE_READ_DATA |
+ SEC_FILE_EXECUTE |
+ SEC_STD_DELETE))) {
return NT_STATUS_OK;
}
/* check the basic share access */
CHECK_MASK(am1, sa2,
- SA_RIGHT_FILE_WRITE_APPEND,
+ SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA,
NTCREATEX_SHARE_ACCESS_WRITE);
CHECK_MASK(am2, sa1,
- SA_RIGHT_FILE_WRITE_APPEND,
+ SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA,
NTCREATEX_SHARE_ACCESS_WRITE);
CHECK_MASK(am1, sa2,
- SA_RIGHT_FILE_READ_EXEC,
+ SEC_FILE_READ_DATA | SEC_FILE_EXECUTE,
NTCREATEX_SHARE_ACCESS_READ);
CHECK_MASK(am2, sa1,
- SA_RIGHT_FILE_READ_EXEC,
+ SEC_FILE_READ_DATA | SEC_FILE_EXECUTE,
NTCREATEX_SHARE_ACCESS_READ);
CHECK_MASK(am1, sa2,
- STD_RIGHT_DELETE_ACCESS,
+ SEC_STD_DELETE,
NTCREATEX_SHARE_ACCESS_DELETE);
CHECK_MASK(am2, sa1,
- STD_RIGHT_DELETE_ACCESS,
+ SEC_STD_DELETE,
NTCREATEX_SHARE_ACCESS_DELETE);
return NT_STATUS_OK;
{ NTCREATEX_SHARE_ACCESS_DELETE, "S_D" }
};
const struct bit_value access_mask_bits[] = {
- { SA_RIGHT_FILE_READ_DATA, "R_DATA" },
- { SA_RIGHT_FILE_WRITE_DATA, "W_DATA" },
- { SA_RIGHT_FILE_READ_ATTRIBUTES, "R_ATTR" },
- { SA_RIGHT_FILE_WRITE_ATTRIBUTES, "W_ATTR" },
- { SA_RIGHT_FILE_READ_EA, "R_EAS " },
- { SA_RIGHT_FILE_WRITE_EA, "W_EAS " },
- { SA_RIGHT_FILE_APPEND_DATA, "A_DATA" },
- { SA_RIGHT_FILE_EXECUTE, "EXEC " }
+ { SEC_FILE_READ_DATA, "R_DATA" },
+ { SEC_FILE_WRITE_DATA, "W_DATA" },
+ { SEC_FILE_READ_ATTRIBUTE, "R_ATTR" },
+ { SEC_FILE_WRITE_ATTRIBUTE, "W_ATTR" },
+ { SEC_FILE_READ_EA, "R_EAS " },
+ { SEC_FILE_WRITE_EA, "W_EAS " },
+ { SEC_FILE_APPEND_DATA, "A_DATA" },
+ { SEC_FILE_EXECUTE, "EXEC " }
};
int fnum1;
int i;
union smb_open io1, io2;
extern int torture_numops;
int failures = 0;
- char buf[1];
+ uint8_t buf[1];
+
+ printf("format: server correct\n");
ZERO_STRUCT(buf);
for (i=0;i<torture_numops;i++) {
NTSTATUS status1, status2, status2_p;
int64_t tdif;
- TALLOC_CTX *mem_ctx = talloc(NULL, 0);
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
enum deny_result res, res2;
int b_sa1 = random() & ((1<<nbits1)-1);
int b_am1 = random() & ((1<<nbits2)-1);
} else {
res = A_0;
if (smbcli_read(cli2->tree,
- io2.ntcreatex.out.fnum, (void *)buf, 0, sizeof(buf)) >= 1) {
+ io2.ntcreatex.out.fnum, buf, 0, sizeof(buf)) >= 1) {
res += A_R;
}
if (smbcli_write(cli2->tree,
- io2.ntcreatex.out.fnum, 0, (void *)buf, 0, sizeof(buf)) >= 1) {
+ io2.ntcreatex.out.fnum, 0, buf, 0, sizeof(buf)) >= 1) {
res += A_W;
}
}
return ret;
}
+
+
+#define CHECK_STATUS(status, correct) do { \
+ if (!NT_STATUS_EQUAL(status, correct)) { \
+ printf("(%s) Incorrect status %s - should be %s\n", \
+ __location__, nt_errstr(status), nt_errstr(correct)); \
+ ret = False; \
+ goto done; \
+ }} while (0)
+
+#define CHECK_VAL(v, correct) do { \
+ if ((v) != (correct)) { \
+ printf("(%s) wrong value for %s 0x%x - should be 0x%x\n", \
+ __location__, #v, (int)(v), (int)correct); \
+ ret = False; \
+ }} while (0)
+
+/*
+ test sharing of handles with DENY_DOS on a single connection
+*/
+BOOL torture_denydos_sharing(void)
+{
+ struct smbcli_state *cli;
+ union smb_open io;
+ union smb_fileinfo finfo;
+ const char *fname = "\\torture_denydos.txt";
+ NTSTATUS status;
+ int fnum1 = -1, fnum2 = -1;
+ BOOL ret = True;
+ union smb_setfileinfo sfinfo;
+ TALLOC_CTX *mem_ctx;
+
+ if (!torture_open_connection(&cli)) {
+ return False;
+ }
+
+ mem_ctx = talloc_new(cli);
+
+ printf("Checking DENY_DOS shared handle semantics\n");
+ smbcli_unlink(cli->tree, fname);
+
+ io.openx.level = RAW_OPEN_OPENX;
+ io.openx.in.fname = fname;
+ io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
+ io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_DOS;
+ io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
+ io.openx.in.search_attrs = 0;
+ io.openx.in.file_attrs = 0;
+ io.openx.in.write_time = 0;
+ io.openx.in.size = 0;
+ io.openx.in.timeout = 0;
+
+ printf("openx twice with RDWR/DENY_DOS\n");
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum1 = io.openx.out.fnum;
+
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum2 = io.openx.out.fnum;
+
+ printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
+
+ sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
+ sfinfo.position_information.file.fnum = fnum1;
+ sfinfo.position_information.in.position = 1000;
+ status = smb_raw_setfileinfo(cli->tree, &sfinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ printf("two handles should be same file handle\n");
+ finfo.position_information.level = RAW_FILEINFO_POSITION_INFORMATION;
+ finfo.position_information.in.fnum = fnum1;
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_VAL(finfo.position_information.out.position, 1000);
+
+ finfo.position_information.in.fnum = fnum2;
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_VAL(finfo.position_information.out.position, 1000);
+
+
+ smbcli_close(cli->tree, fnum1);
+ smbcli_close(cli->tree, fnum2);
+
+ printf("openx twice with RDWR/DENY_NONE\n");
+ io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_NONE;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum1 = io.openx.out.fnum;
+
+ io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum2 = io.openx.out.fnum;
+
+ printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
+
+ printf("two handles should be separate\n");
+ sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
+ sfinfo.position_information.file.fnum = fnum1;
+ sfinfo.position_information.in.position = 1000;
+ status = smb_raw_setfileinfo(cli->tree, &sfinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ finfo.position_information.level = RAW_FILEINFO_POSITION_INFORMATION;
+ finfo.position_information.in.fnum = fnum1;
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_VAL(finfo.position_information.out.position, 1000);
+
+ finfo.position_information.in.fnum = fnum2;
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_VAL(finfo.position_information.out.position, 0);
+
+done:
+ smbcli_close(cli->tree, fnum1);
+ smbcli_close(cli->tree, fnum2);
+ smbcli_unlink(cli->tree, fname);
+
+ return ret;
+}
+
+