handling creating new file for no access
windows can send a create irp with dispostion representing creation of the file and specify DesiredAccess of 0. we were treating no data access as lookup but in this case, we still need to create a file. so send an open with a read access and request no delegation to be returned.
This commit is contained in:
parent
1ea2fb7891
commit
4017b235db
2 changed files with 38 additions and 4 deletions
|
|
@ -303,7 +303,11 @@ static BOOLEAN open_for_attributes(uint32_t type, ULONG access_mask,
|
||||||
if ((access_mask & FILE_READ_DATA) ||
|
if ((access_mask & FILE_READ_DATA) ||
|
||||||
(access_mask & FILE_WRITE_DATA) ||
|
(access_mask & FILE_WRITE_DATA) ||
|
||||||
(access_mask & FILE_APPEND_DATA) ||
|
(access_mask & FILE_APPEND_DATA) ||
|
||||||
(access_mask & FILE_EXECUTE))
|
(access_mask & FILE_EXECUTE) ||
|
||||||
|
disposition == FILE_CREATE ||
|
||||||
|
disposition == FILE_OVERWRITE_IF ||
|
||||||
|
disposition == FILE_SUPERSEDE ||
|
||||||
|
disposition == FILE_OPEN_IF)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else {
|
else {
|
||||||
dprintf(1, "Open call that wants to manage attributes\n");
|
dprintf(1, "Open call that wants to manage attributes\n");
|
||||||
|
|
@ -363,7 +367,7 @@ static int map_disposition_2_nfsopen(ULONG disposition, int in_status, bool_t pe
|
||||||
}
|
}
|
||||||
|
|
||||||
static void map_access_2_allowdeny(ULONG access_mask, ULONG access_mode,
|
static void map_access_2_allowdeny(ULONG access_mask, ULONG access_mode,
|
||||||
uint32_t *allow, uint32_t *deny)
|
ULONG disposition, uint32_t *allow, uint32_t *deny)
|
||||||
{
|
{
|
||||||
if ((access_mask &
|
if ((access_mask &
|
||||||
(FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES)) &&
|
(FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES)) &&
|
||||||
|
|
@ -374,6 +378,16 @@ static void map_access_2_allowdeny(ULONG access_mask, ULONG access_mode,
|
||||||
else if (access_mask &
|
else if (access_mask &
|
||||||
(FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES))
|
(FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES))
|
||||||
*allow = OPEN4_SHARE_ACCESS_WRITE;
|
*allow = OPEN4_SHARE_ACCESS_WRITE;
|
||||||
|
/* if we are creating a file and no data access is specified, then
|
||||||
|
* do an open and request no delegations. example open with share access 0
|
||||||
|
* and share deny 0 (ie deny_both).
|
||||||
|
*/
|
||||||
|
if ((disposition == FILE_CREATE || disposition == FILE_OPEN_IF ||
|
||||||
|
disposition == FILE_OVERWRITE_IF || disposition == FILE_SUPERSEDE) &&
|
||||||
|
!(access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA |
|
||||||
|
FILE_WRITE_ATTRIBUTES | FILE_READ_DATA | FILE_EXECUTE)))
|
||||||
|
*allow = OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_NO_DELEG;
|
||||||
|
|
||||||
#define FIX_ALLOW_DENY_WIN2NFS_CONVERSION
|
#define FIX_ALLOW_DENY_WIN2NFS_CONVERSION
|
||||||
#ifdef FIX_ALLOW_DENY_WIN2NFS_CONVERSION
|
#ifdef FIX_ALLOW_DENY_WIN2NFS_CONVERSION
|
||||||
if ((access_mode & FILE_SHARE_READ) &&
|
if ((access_mode & FILE_SHARE_READ) &&
|
||||||
|
|
@ -570,7 +584,7 @@ static int handle_open(nfs41_upcall *upcall)
|
||||||
uint32_t create = 0, createhowmode = 0;
|
uint32_t create = 0, createhowmode = 0;
|
||||||
|
|
||||||
map_access_2_allowdeny(args->access_mask, args->access_mode,
|
map_access_2_allowdeny(args->access_mask, args->access_mode,
|
||||||
&state->share_access, &state->share_deny);
|
args->disposition, &state->share_access, &state->share_deny);
|
||||||
status = map_disposition_2_nfsopen(args->disposition, status,
|
status = map_disposition_2_nfsopen(args->disposition, status,
|
||||||
state->session->flags & CREATE_SESSION4_FLAG_PERSIST,
|
state->session->flags & CREATE_SESSION4_FLAG_PERSIST,
|
||||||
&create, &createhowmode, &upcall->last_error);
|
&create, &createhowmode, &upcall->last_error);
|
||||||
|
|
|
||||||
|
|
@ -3247,6 +3247,15 @@ BOOLEAN isDataAccess(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN isOpen2Create(
|
||||||
|
ULONG disposition)
|
||||||
|
{
|
||||||
|
if (disposition == FILE_CREATE || disposition == FILE_OPEN_IF ||
|
||||||
|
disposition == FILE_OVERWRITE_IF || disposition == FILE_SUPERSEDE)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS map_open_errors(
|
NTSTATUS map_open_errors(
|
||||||
DWORD status,
|
DWORD status,
|
||||||
USHORT len)
|
USHORT len)
|
||||||
|
|
@ -3357,6 +3366,17 @@ NTSTATUS nfs41_Create(
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
|
||||||
|
* If FILE_SHARE_DELETE flag is not specified, but the file or device has been
|
||||||
|
* opened for delete access, the function fails.
|
||||||
|
*/
|
||||||
|
if (Fcb->OpenCount && nfs41_fcb->StandardInfo.DeletePending &&
|
||||||
|
!(params.ShareAccess & FILE_SHARE_DELETE)) {
|
||||||
|
DbgP("File opened already and marked for deletion\n");
|
||||||
|
status = STATUS_DELETE_PENDING;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(STORE_MOUNT_SEC_CONTEXT) && defined (USE_MOUNT_SEC_CONTEXT)
|
#if defined(STORE_MOUNT_SEC_CONTEXT) && defined (USE_MOUNT_SEC_CONTEXT)
|
||||||
status = nfs41_UpcallCreate(NFS41_OPEN, &pVNetRootContext->mount_sec_ctx,
|
status = nfs41_UpcallCreate(NFS41_OPEN, &pVNetRootContext->mount_sec_ctx,
|
||||||
#else
|
#else
|
||||||
|
|
@ -3374,7 +3394,7 @@ NTSTATUS nfs41_Create(
|
||||||
entry->u.Open.disp = params.Disposition;
|
entry->u.Open.disp = params.Disposition;
|
||||||
entry->u.Open.copts = params.CreateOptions;
|
entry->u.Open.copts = params.CreateOptions;
|
||||||
entry->u.Open.srv_open = SrvOpen;
|
entry->u.Open.srv_open = SrvOpen;
|
||||||
if (isDataAccess(params.DesiredAccess))
|
if (isDataAccess(params.DesiredAccess) || isOpen2Create(params.Disposition)) {
|
||||||
entry->u.Open.open_owner_id = InterlockedIncrement(&open_owner_id);
|
entry->u.Open.open_owner_id = InterlockedIncrement(&open_owner_id);
|
||||||
// if we are creating a file check if nfsv3attributes were passed in
|
// if we are creating a file check if nfsv3attributes were passed in
|
||||||
if (params.Disposition != FILE_OPEN && params.Disposition != FILE_OVERWRITE) {
|
if (params.Disposition != FILE_OPEN && params.Disposition != FILE_OVERWRITE) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue