diff options
-rw-r--r-- | source4/libcli/raw/smb.h | 46 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 23 | ||||
-rw-r--r-- | source4/torture/raw/open.c | 56 |
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); |