summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/raw/smb.h46
-rw-r--r--source4/ntvfs/posix/pvfs_open.c23
-rw-r--r--source4/torture/raw/open.c56
3 files changed, 66 insertions, 59 deletions
diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h
index f54e979de2..8663792f78 100644
--- a/source4/libcli/raw/smb.h
+++ b/source4/libcli/raw/smb.h
@@ -144,32 +144,38 @@
#define NTCREATEX_DISP_OVERWRITE_IF 5 /* if exists overwrite, else create */
/* ntcreatex create_options field */
-#define NTCREATEX_OPTIONS_DIRECTORY 0x0001
-#define NTCREATEX_OPTIONS_WRITE_THROUGH 0x0002
-#define NTCREATEX_OPTIONS_SEQUENTIAL_ONLY 0x0004
-#define NTCREATEX_OPTIONS_SYNC_ALERT 0x0010
-#define NTCREATEX_OPTIONS_ASYNC_ALERT 0x0020
-#define NTCREATEX_OPTIONS_NON_DIRECTORY_FILE 0x0040
-#define NTCREATEX_OPTIONS_NO_EA_KNOWLEDGE 0x0200
-#define NTCREATEX_OPTIONS_EIGHT_DOT_THREE_ONLY 0x0400
-#define NTCREATEX_OPTIONS_RANDOM_ACCESS 0x0800
-#define NTCREATEX_OPTIONS_DELETE_ON_CLOSE 0x1000
-#define NTCREATEX_OPTIONS_OPEN_BY_FILE_ID 0x2000
-#define NTCREATEX_OPTIONS_BACKUP_INTENT 0x4000
+#define NTCREATEX_OPTIONS_DIRECTORY 0x0001
+#define NTCREATEX_OPTIONS_WRITE_THROUGH 0x0002
+#define NTCREATEX_OPTIONS_SEQUENTIAL_ONLY 0x0004
+#define NTCREATEX_OPTIONS_NO_INTERMEDIATE_BUFFERING 0x0008
+#define NTCREATEX_OPTIONS_SYNC_ALERT 0x0010
+#define NTCREATEX_OPTIONS_ASYNC_ALERT 0x0020
+#define NTCREATEX_OPTIONS_NON_DIRECTORY_FILE 0x0040
+#define NTCREATEX_OPTIONS_TREE_CONNECTION 0x0080
+#define NTCREATEX_OPTIONS_COMPLETE_IF_OPLOCKED 0x0100
+#define NTCREATEX_OPTIONS_NO_EA_KNOWLEDGE 0x0200
+#define NTCREATEX_OPTIONS_OPEN_FOR_RECOVERY 0x0400
+#define NTCREATEX_OPTIONS_RANDOM_ACCESS 0x0800
+#define NTCREATEX_OPTIONS_DELETE_ON_CLOSE 0x1000
+#define NTCREATEX_OPTIONS_OPEN_BY_FILE_ID 0x2000
+#define NTCREATEX_OPTIONS_BACKUP_INTENT 0x4000
+#define NTCREATEX_OPTIONS_NO_COMPRESSION 0x8000
/* Must be ignored by the server, per MS-SMB 2.2.8 */
-#define NTCREATEX_OPTIONS_OPFILTER 0x00100000
-#define NTCREATEX_OPTIONS_REPARSE_POINT 0x00200000
+#define NTCREATEX_OPTIONS_OPFILTER 0x00100000
+#define NTCREATEX_OPTIONS_REPARSE_POINT 0x00200000
/* Don't pull this file off tape in a HSM system */
-#define NTCREATEX_OPTIONS_NO_RECALL 0x00400000
+#define NTCREATEX_OPTIONS_NO_RECALL 0x00400000
/* Must be ignored by the server, per MS-SMB 2.2.8 */
-#define NTCREATEX_OPTIONS_FREE_SPACE_QUERY 0x00800000
+#define NTCREATEX_OPTIONS_FREE_SPACE_QUERY 0x00800000
/* create options these bits are for private use by backends, they are
not valid on the wire */
-#define NTCREATEX_OPTIONS_PRIVATE_MASK 0xFF000000
-#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000
-#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000
+#define NTCREATEX_OPTIONS_PRIVATE_MASK 0xFF000000
+#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000
+#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000
-#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK 0x000FA188
+#define NTCREATEX_OPTIONS_MUST_IGNORE_MASK ( NTCREATEX_OPTIONS_TREE_CONNECTION | NTCREATEX_OPTIONS_COMPLETE_IF_OPLOCKED | NTCREATEX_OPTIONS_OPEN_FOR_RECOVERY | NTCREATEX_OPTIONS_FREE_SPACE_QUERY | NTCREATEX_OPTIONS_OPFILTER )
+
+#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK (0x000F0000 | NTCREATEX_OPTIONS_OPEN_BY_FILE_ID)
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 5302fc3f50..01a249ceb7 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -1173,7 +1173,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req, union smb_open *io)
{
struct pvfs_state *pvfs = ntvfs->private_data;
- int flags;
+ int flags = 0;
struct pvfs_filename *name;
struct pvfs_file *f;
struct ntvfs_handle *h;
@@ -1206,6 +1206,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INVALID_PARAMETER;
}
+ /* These options are ignored */
+ create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
+
if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) {
return NT_STATUS_NOT_SUPPORTED;
}
@@ -1217,11 +1220,23 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
/* no-op */
}
- /* These options are ignored */
- if (create_options & (NTCREATEX_OPTIONS_FREE_SPACE_QUERY | NTCREATEX_OPTIONS_OPFILTER)) {
+ /* TODO: If (unlikely) Linux does a good compressed
+ * filesystem, we might need an ioctl call for this */
+ if (create_options & NTCREATEX_OPTIONS_NO_COMPRESSION) {
/* no-op */
}
+ if (create_options & NTCREATEX_OPTIONS_NO_INTERMEDIATE_BUFFERING) {
+ create_options |= NTCREATEX_OPTIONS_WRITE_THROUGH;
+ }
+
+ /* Open the file with sync, if they asked for it, but
+ 'strict sync = no' turns this client request into a no-op */
+ if (create_options & (NTCREATEX_OPTIONS_WRITE_THROUGH) && !(pvfs->flags | PVFS_FLAG_STRICT_SYNC)) {
+ flags |= O_SYNC;
+ }
+
+
/* other create options are not allowed */
if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
!(access_mask & SEC_STD_DELETE)) {
@@ -1282,8 +1297,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
open doesn't match */
io->generic.in.file_attr &= ~FILE_ATTRIBUTE_DIRECTORY;
- flags = 0;
-
switch (io->generic.in.open_disposition) {
case NTCREATEX_DISP_SUPERSEDE:
case NTCREATEX_DISP_OVERWRITE_IF:
diff --git a/source4/torture/raw/open.c b/source4/torture/raw/open.c
index 3e310ebe0b..1901338e21 100644
--- a/source4/torture/raw/open.c
+++ b/source4/torture/raw/open.c
@@ -975,40 +975,28 @@ static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context
smbcli_close(cli->tree, fnum);
/* Check some create options (these all should be ignored) */
- io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_OPFILTER;
- status = smb_raw_open(cli->tree, tctx, &io);
- CHECK_STATUS(status, NT_STATUS_OK);
-
- CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
- CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
- CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
- CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
- CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
- CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
- CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
- CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
- CHECK_ALL_INFO(io.ntcreatex.out.size, size);
- CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
- CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
- smbcli_close(cli->tree, fnum);
-
- io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_FREE_SPACE_QUERY;
- status = smb_raw_open(cli->tree, tctx, &io);
- CHECK_STATUS(status, NT_STATUS_OK);
- fnum = io.ntcreatex.out.file.fnum;
-
- CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
- CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
- CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
- CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
- CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
- CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
- CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
- CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
- CHECK_ALL_INFO(io.ntcreatex.out.size, size);
- CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
- CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
- smbcli_close(cli->tree, fnum);
+ for (i=0; i < 32; i++) {
+ uint32_t create_option = (1 << i) & NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
+ if (create_option == 0) {
+ continue;
+ }
+ io.ntcreatex.in.create_options = create_option;
+ status = smb_raw_open(cli->tree, tctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
+ CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
+ CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
+ CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
+ CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
+ CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
+ CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
+ CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
+ CHECK_ALL_INFO(io.ntcreatex.out.size, size);
+ CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
+ CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
+ smbcli_close(cli->tree, fnum);
+ }
smbcli_unlink(cli->tree, fname);