From aef8aad638b916026651d900b91e963897b31c1a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 9 Jul 2013 11:02:39 -0700 Subject: smbd: Fix a profile problem When trying to read a profile, under certain circumstances Windows tries to read with its machine account first. The profile previously written was stored with an ACL that only allows access for the user and not the machine. Windows should get an NT_STATUS_ACCESS_DENIED when using the machine account, making it retry with the user account (which would then succeed). Samba under these circumstances erroneously gives NT_STATUS_OBJECT_PATH_NOT_FOUND, which makes Windows give up and not retry. The reasons is the "dropbox" patch in unix_convert, turning EACCESS on the last path component to OBJECT_PATH_NOT_FOUND. This patch makes the dropbox behaviour only kick in when we are creating a file. I think this is an abstraction violation. unix_convert() should not have to know about the create_disposition, but given that we have pathname resolution separated from the core open code right now this is the best we can do. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- source3/smbd/reply.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 07b144e68b..2ae3ff4b1e 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1906,11 +1906,20 @@ void reply_open(struct smb_request *req) goto out; } + if (!map_open_params_to_ntcreate(fname, deny_mode, + OPENX_FILE_EXISTS_OPEN, &access_mask, + &share_mode, &create_disposition, + &create_options, &private_flags)) { + reply_force_doserror(req, ERRDOS, ERRbadaccess); + goto out; + } + status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - 0, + (create_disposition == FILE_CREATE) + ? UCF_CREATING_FILE : 0, NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -1924,14 +1933,6 @@ void reply_open(struct smb_request *req) goto out; } - if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode, - OPENX_FILE_EXISTS_OPEN, &access_mask, - &share_mode, &create_disposition, - &create_options, &private_flags)) { - reply_force_doserror(req, ERRDOS, ERRbadaccess); - goto out; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -2081,11 +2082,22 @@ void reply_open_and_X(struct smb_request *req) goto out; } + if (!map_open_params_to_ntcreate(fname, deny_mode, + smb_ofun, + &access_mask, &share_mode, + &create_disposition, + &create_options, + &private_flags)) { + reply_force_doserror(req, ERRDOS, ERRbadaccess); + goto out; + } + status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - 0, + (create_disposition == FILE_CREATE) + ? UCF_CREATING_FILE : 0, NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -2099,16 +2111,6 @@ void reply_open_and_X(struct smb_request *req) goto out; } - if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode, - smb_ofun, - &access_mask, &share_mode, - &create_disposition, - &create_options, - &private_flags)) { - reply_force_doserror(req, ERRDOS, ERRbadaccess); - goto out; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -2328,7 +2330,7 @@ void reply_mknew(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - 0, + UCF_CREATING_FILE, NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -2469,7 +2471,7 @@ void reply_ctemp(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, - 0, + UCF_CREATING_FILE, NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -5828,7 +5830,7 @@ void reply_mkdir(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, - 0, + UCF_CREATING_FILE, NULL, &smb_dname); if (!NT_STATUS_IS_OK(status)) { -- cgit