From 80a37beb53519fdbb907a01f29ef150bafdd74e7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Mar 2010 14:57:50 +1100 Subject: [PATCH] s4-pvfs: move the private ntcreatex flags to private_flags Re-using two of the create_options bits was bound to eventually cause problems, and indeed, Windows7 now uses one of those bits when opening text files. Fixes bug 7189 --- source4/libcli/raw/interfaces.h | 3 +++ source4/libcli/raw/smb.h | 12 ++++-------- source4/ntvfs/ntvfs_generic.c | 6 ++++-- source4/ntvfs/posix/pvfs_open.c | 10 ++++++---- source4/ntvfs/posix/vfs_posix.h | 2 ++ source4/smb_server/smb/nttrans.c | 1 + source4/smb_server/smb/reply.c | 7 +------ 7 files changed, 21 insertions(+), 20 deletions(-) diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index f1590747833..f6d090539c4 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1439,6 +1439,9 @@ union smb_open { /* some optional parameters from the SMB2 varient */ bool query_maximal_access; + + /* private flags for internal use only */ + uint8_t private_flags; } in; struct { union smb_handle file; diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h index 349705d2dfa..7291821faea 100644 --- a/source4/libcli/raw/smb.h +++ b/source4/libcli/raw/smb.h @@ -178,19 +178,15 @@ #define NTCREATEX_OPTIONS_INVALID_PARAM_MASK (NTCREATEX_OPTIONS_OPFILTER | \ NTCREATEX_OPTIONS_SYNC_ALERT | \ NTCREATEX_OPTIONS_ASYNC_ALERT | \ - NTCREATEX_OPTIONS_OPFILTER | \ 0xFF000000) /* - * We reuse some ignored flags for private use. + * private_flags field in ntcreatex * This values have different meaning for some ntvfs backends. - * - * TODO: use values that are ignore for sure... */ -#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x00010000 -#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x00020000 -#define NTCREATEX_OPTIONS_PRIVATE_MASK (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | \ - NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) +#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x0001 +#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x0002 + /* ntcreatex impersonation field */ #define NTCREATEX_IMPERSONATION_ANONYMOUS 0 diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 547d038738f..8e1eb0bc668 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -284,6 +284,7 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, union smb_open *io2) { io2->generic.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE; + io2->generic.in.private_flags = 0; if (flags & OPENX_FLAGS_REQUEST_OPLOCK) { io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK; @@ -327,7 +328,7 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, break; case OPENX_MODE_DENY_DOS: /* DENY_DOS is quite strange - it depends on the filename! */ - io2->generic.in.create_options |= + io2->generic.in.private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS; if (is_exe_filename(fname)) { io2->generic.in.share_access = @@ -342,7 +343,7 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, } break; case OPENX_MODE_DENY_FCB: - io2->generic.in.create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB; + io2->generic.in.private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB; io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; default: @@ -528,6 +529,7 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, io2->generic.in.sec_desc = io->smb2.in.sec_desc; io2->generic.in.ea_list = &io->smb2.in.eas; io2->generic.in.query_maximal_access = io->smb2.in.query_maximal_access; + io2->generic.in.private_flags = 0; /* we don't support timewarp yet */ if (io->smb2.in.timewarp != 0) { diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index aa66ad782d1..7901ef577b9 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -276,6 +276,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->fd = -1; f->handle->odb_locking_key = data_blob(NULL, 0); f->handle->create_options = io->generic.in.create_options; + f->handle->private_flags = io->generic.in.private_flags; f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; @@ -776,6 +777,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->name = talloc_steal(f->handle, name); f->handle->fd = fd; f->handle->create_options = io->generic.in.create_options; + f->handle->private_flags = io->generic.in.private_flags; f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; @@ -1061,7 +1063,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, if (f2 != f && f2->ntvfs->session_info == req->session_info && f2->ntvfs->smbpid == req->smbpid && - (f2->handle->create_options & + (f2->handle->private_flags & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) && (f2->access_mask & SEC_FILE_WRITE_DATA) && @@ -1077,7 +1079,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, /* quite an insane set of semantics ... */ if (is_exe_filename(io->generic.in.fname) && - (f2->handle->create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) { + (f2->handle->private_flags & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) { return NT_STATUS_SHARING_VIOLATION; } @@ -1129,7 +1131,7 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, struct timeval end_time; struct timeval *final_timeout = NULL; - if (io->generic.in.create_options & + if (io->generic.in.private_flags & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) { /* see if we can satisfy the request using the special DENY_DOS code */ @@ -1219,7 +1221,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, * but we reuse some of them as private values for the generic mapping */ create_options_must_ignore_mask = NTCREATEX_OPTIONS_MUST_IGNORE_MASK; - create_options_must_ignore_mask &= ~NTCREATEX_OPTIONS_PRIVATE_MASK; create_options &= ~create_options_must_ignore_mask; if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) { @@ -1438,6 +1439,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->fd = -1; f->handle->name = talloc_steal(f->handle, name); f->handle->create_options = io->generic.in.create_options; + f->handle->private_flags = io->generic.in.private_flags; f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 6354f7558fa..86e95327c1b 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -182,6 +182,8 @@ struct pvfs_file_handle { /* the open went through to completion */ bool open_completed; + + uint8_t private_flags; }; /* open file state */ diff --git a/source4/smb_server/smb/nttrans.c b/source4/smb_server/smb/nttrans.c index 74c98ea738b..5fba041e1eb 100644 --- a/source4/smb_server/smb/nttrans.c +++ b/source4/smb_server/smb/nttrans.c @@ -134,6 +134,7 @@ static NTSTATUS nttrans_create(struct smbsrv_request *req, io->ntcreatex.in.sec_desc = NULL; io->ntcreatex.in.ea_list = NULL; io->ntcreatex.in.query_maximal_access = false; + io->ntcreatex.in.private_flags = 0; req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname, params + 53, diff --git a/source4/smb_server/smb/reply.c b/source4/smb_server/smb/reply.c index ef7cbbf936b..7d33a37b4d1 100644 --- a/source4/smb_server/smb/reply.c +++ b/source4/smb_server/smb/reply.c @@ -2228,12 +2228,7 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req) io->ntcreatex.in.ea_list = NULL; io->ntcreatex.in.sec_desc = NULL; io->ntcreatex.in.query_maximal_access = false; - - /* we use a couple of bits of the create options internally */ - if (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) { - smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER); - return; - } + io->ntcreatex.in.private_flags = 0; /* we need a neater way to handle this alignment */ if ((req->flags2 & FLAGS2_UNICODE_STRINGS) && -- 2.11.4.GIT