This fixes a regression introduced by commit
f98d10af2a05f0261611f4cabdfe274cd9fe91c0
(smbd: Always use UCF_PREP_CREATEFILE for filename_convert calls to resolve a path for open)
The main problem was that Windows client seem to verify
the access to user.V2\ntuser.ini is rejected with NT_STATUS_ACCESS_DENIED,
using the machine credentials.
Passing UCF_PREP_CREATEFILE to filename_convert() triggers a code path
that implements a dropbox behaviour. A dropbox is a directory with only -wx permissions,
so get_real_filename fails with EACCESS, it needs to list the directory.
EACCESS is ignored with UCF_PREP_CREATEFILE.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=10297
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Tue Oct 25 05:33:36 CEST 2016 on sn-devel-144
#include "smbd/smbd.h"
#include "smbd/globals.h"
+uint32_t filename_create_ucf_flags(struct smb_request *req, uint32_t create_disposition)
+{
+ uint32_t ucf_flags = 0;
+
+ if (req != NULL && req->posix_pathnames) {
+ ucf_flags |= UCF_POSIX_PATHNAMES;
+ }
+
+ switch (create_disposition) {
+ case FILE_OPEN:
+ case FILE_OVERWRITE:
+ break;
+ case FILE_SUPERSEDE:
+ case FILE_CREATE:
+ case FILE_OPEN_IF:
+ case FILE_OVERWRITE_IF:
+ ucf_flags |= UCF_PREP_CREATEFILE;
+ break;
+ }
+
+ return ucf_flags;
+}
+
static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
connection_struct *conn,
struct smb_filename *smb_fname);
int oplock_request;
uint8_t oplock_granted = NO_OPLOCK_RETURN;
struct case_semantics_state *case_state = NULL;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBntcreateX);
}
}
+ ucf_flags = filename_create_ucf_flags(req, create_disposition);
status = filename_convert(ctx,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
int oplock_request;
uint8_t oplock_granted;
struct case_semantics_state *case_state = NULL;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
DEBUG(5,("call_nt_transact_create\n"));
}
}
+ ucf_flags = filename_create_ucf_flags(req, create_disposition);
status = filename_convert(ctx,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
/* The following definitions come from smbd/filename.c */
+uint32_t filename_create_ucf_flags(struct smb_request *req, uint32_t create_disposition);
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
uint32_t create_options = 0;
uint32_t private_flags = 0;
NTSTATUS status;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBopen);
goto out;
}
+ ucf_flags = filename_create_ucf_flags(req, create_disposition);
+
status = filename_convert(ctx,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
uint32_t create_disposition;
uint32_t create_options = 0;
uint32_t private_flags = 0;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBopenX);
goto out;
}
+ ucf_flags = filename_create_ucf_flags(req, create_disposition);
+
status = filename_convert(ctx,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
uint32_t share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
uint32_t create_disposition;
uint32_t create_options = 0;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBcreate);
fattr = SVAL(req->vwv+0, 0);
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
+ if (req->cmd == SMBmknew) {
+ /* We should fail if file exists. */
+ create_disposition = FILE_CREATE;
+ } else {
+ /* Create if file doesn't exist, truncate if it does. */
+ create_disposition = FILE_OVERWRITE_IF;
+ }
+
/* mtime. */
ft.mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1));
goto out;
}
+ ucf_flags = filename_create_ucf_flags(req, create_disposition);
status = filename_convert(ctx,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
smb_fname_str_dbg(smb_fname)));
}
- if(req->cmd == SMBmknew) {
- /* We should fail if file exists. */
- create_disposition = FILE_CREATE;
- } else {
- /* Create if file doesn't exist, truncate if it does. */
- create_disposition = FILE_OVERWRITE_IF;
- }
-
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
char *s;
NTSTATUS status;
int i;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBctemp);
goto out;
}
+ ucf_flags = filename_create_ucf_flags(req, FILE_CREATE);
status = filename_convert(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
struct smb_filename *smb_dname = NULL;
char *directory = NULL;
NTSTATUS status;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBmkdir);
goto out;
}
+ ucf_flags = filename_create_ucf_flags(req, FILE_CREATE);
status = filename_convert(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
return ((key->data[0] != 0) || (key->data[1] != 0));
}
-static NTSTATUS smbd_smb2_create_durable_lease_check(
+static NTSTATUS smbd_smb2_create_durable_lease_check(struct smb_request *smb1req,
const char *requested_filename, const struct files_struct *fsp,
const struct smb2_lease *lease_ptr)
{
struct smb_filename *smb_fname = NULL;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE;
+ uint32_t ucf_flags;
NTSTATUS status;
if (lease_ptr == NULL) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
+ ucf_flags = filename_create_ucf_flags(smb1req, FILE_OPEN);
status = filename_convert(talloc_tos(), fsp->conn, false,
requested_filename, ucf_flags,
NULL, &smb_fname);
(unsigned)result->oplock_type, lease_ptr));
status = smbd_smb2_create_durable_lease_check(
- fname, result, lease_ptr);
+ smb1req, fname, result, lease_ptr);
if (!NT_STATUS_IS_OK(status)) {
close_file(smb1req, result, SHUTDOWN_CLOSE);
tevent_req_nterror(req, status);
info = FILE_WAS_OPENED;
} else {
struct smb_filename *smb_fname = NULL;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE;
+ uint32_t ucf_flags;
if (requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
if (lease_ptr == NULL) {
}
}
+ ucf_flags = filename_create_ucf_flags(smb1req, in_create_disposition);
status = filename_convert(req,
smb1req->conn,
smb1req->flags2 & FLAGS2_DFS_PATHNAMES,