diff --git a/daemon/open.c b/daemon/open.c index b058613..da1d834 100644 --- a/daemon/open.c +++ b/daemon/open.c @@ -250,6 +250,40 @@ static int map_disposition_2_nfsopen(ULONG disposition, int in_status, bool_t pe return status; } +static void map_access_2_allowdeny(ULONG access_mask, ULONG access_mode, + uint32_t *allow, uint32_t *deny) +{ + if ((access_mask & FILE_WRITE_DATA) && + ((access_mask & FILE_READ_DATA) || + (access_mask & FILE_EXECUTE))) + *allow = OPEN4_SHARE_ACCESS_BOTH; + else if ((access_mask & FILE_READ_DATA) || + (access_mask & FILE_EXECUTE)) + *allow = OPEN4_SHARE_ACCESS_READ; + else if (access_mask & FILE_WRITE_DATA || + (access_mask & FILE_APPEND_DATA) || + (access_mask & FILE_WRITE_ATTRIBUTES)) + *allow = OPEN4_SHARE_ACCESS_WRITE; +#define FIX_ALLOW_DENY_WIN2NFS_CONVERSION +#ifdef FIX_ALLOW_DENY_WIN2NFS_CONVERSION + if ((access_mode & FILE_SHARE_READ) && + (access_mode & FILE_SHARE_WRITE)) + *deny = OPEN4_SHARE_DENY_NONE; + else if (access_mode & FILE_SHARE_READ) + *deny = OPEN4_SHARE_DENY_WRITE; + else if (access_mode & FILE_SHARE_WRITE) + *deny = OPEN4_SHARE_DENY_READ; + else + *deny = OPEN4_SHARE_DENY_BOTH; +#else + // AGLO: 11/13/2009. + // readonly file that is being opened for reading with a + // share read mode given above logic translates into deny + // write and linux server does not allow it. + *deny = OPEN4_SHARE_DENY_NONE; +#endif +} + static int check_execute_access(nfs41_open_state *state) { uint32_t supported, access; diff --git a/daemon/setattr.c b/daemon/setattr.c index 724b618..65d633c 100644 --- a/daemon/setattr.c +++ b/daemon/setattr.c @@ -52,19 +52,11 @@ static int parse_setattr(unsigned char *buffer, uint32_t length, nfs41_upcall *u } status = safe_read(&buffer, &length, args->buf, args->buf_len); if (status) goto out_free; - status = safe_read(&buffer, &length, &args->open_owner_id, sizeof(ULONG)); - if (status) goto out_free; - status = safe_read(&buffer, &length, &args->access_mask, sizeof(ULONG)); - if (status) goto out_free; - status = safe_read(&buffer, &length, &args->access_mode, sizeof(ULONG)); - if (status) goto out_free; args->root = upcall->root_ref; args->state = upcall->state_ref; dprintf(1, "parsing NFS41_FILE_SET: filename='%s' info_class=%d " - "buf_len=%d\nopen_owner_id=%d access_mask=%x access_mode=%x\n", - args->path, args->set_class, args->buf_len, args->open_owner_id, - args->access_mask, args->access_mode); + "buf_len=%d\n", args->path, args->set_class, args->buf_len); out: return status; out_free: @@ -467,29 +459,6 @@ static int handle_setattr(nfs41_upcall *upcall) nfs41_open_state *state = upcall->state_ref; int status; - switch (args->set_class) { - case FileAllocationInformation: - case FileEndOfFileInformation: - if (!state->do_close) { - // get a stateid - StringCchPrintfA((LPSTR)state->owner.owner, NFS4_OPAQUE_LIMIT, - "%u", args->open_owner_id); - state->owner.owner_len = (uint32_t)strlen( - (const char*)state->owner.owner); - map_access_2_allowdeny(args->access_mask, args->access_mode, - &state->share_access, &state->share_deny); - status = nfs41_open(state->session, state->share_access, - state->share_deny, OPEN4_NOCREATE, 0, 0, TRUE, state, NULL); - if (status) { - dprintf(1, "nfs41_open() failed with %s\n", nfs_error_string(status)); - status = nfs_to_windows_error(status, ERROR_FILE_NOT_FOUND); - goto out; - } else - client_state_add(state); - state->do_close = 1; - } - } - switch (args->set_class) { case FileBasicInformation: status = handle_nfs41_setattr(args); @@ -513,7 +482,7 @@ static int handle_setattr(nfs41_upcall *upcall) status = ERROR_NOT_SUPPORTED; break; } -out: + free(args->buf); return status; } diff --git a/daemon/upcall.h b/daemon/upcall.h index 6289d74..cbf5384 100644 --- a/daemon/upcall.h +++ b/daemon/upcall.h @@ -96,9 +96,6 @@ typedef struct __setattr_upcall_args { unsigned char *buf; uint32_t buf_len; int set_class; - ULONG open_owner_id; - ULONG access_mask; - ULONG access_mode; } setattr_upcall_args; typedef struct __setexattr_upcall_args { diff --git a/daemon/util.c b/daemon/util.c index ddd125e..a5a2d49 100644 --- a/daemon/util.c +++ b/daemon/util.c @@ -222,41 +222,6 @@ void get_nfs_time( file_time_to_nfs_time(&file_time, nfs_time); } -void map_access_2_allowdeny(ULONG access_mask, ULONG access_mode, - uint32_t *allow, uint32_t *deny) -{ - if ((access_mask & FILE_WRITE_DATA) && - ((access_mask & FILE_READ_DATA) || - (access_mask & FILE_EXECUTE))) - *allow = OPEN4_SHARE_ACCESS_BOTH; - else if ((access_mask & FILE_READ_DATA) || - (access_mask & FILE_EXECUTE)) - *allow = OPEN4_SHARE_ACCESS_READ; - else if (access_mask & FILE_WRITE_DATA || - (access_mask & FILE_APPEND_DATA) || - (access_mask & FILE_WRITE_ATTRIBUTES)) - *allow = OPEN4_SHARE_ACCESS_WRITE; -#define FIX_ALLOW_DENY_WIN2NFS_CONVERSION -#ifdef FIX_ALLOW_DENY_WIN2NFS_CONVERSION - if ((access_mode & FILE_SHARE_READ) && - (access_mode & FILE_SHARE_WRITE)) - *deny = OPEN4_SHARE_DENY_NONE; - else if (access_mode & FILE_SHARE_READ) - *deny = OPEN4_SHARE_DENY_WRITE; - else if (access_mode & FILE_SHARE_WRITE) - *deny = OPEN4_SHARE_DENY_READ; - else - *deny = OPEN4_SHARE_DENY_BOTH; -#else - // AGLO: 11/13/2009. - // readonly file that is being opened for reading with a - // share read mode given above logic translates into deny - // write and linux server does not allow it. - *deny = OPEN4_SHARE_DENY_NONE; -#endif - -} - bool_t multi_addr_find( IN const multi_addr4 *addrs, IN const netaddr4 *addr, diff --git a/daemon/util.h b/daemon/util.h index ae05007..87bdd6a 100644 --- a/daemon/util.h +++ b/daemon/util.h @@ -139,12 +139,6 @@ int create_silly_rename( IN const nfs41_fh *fh, OUT nfs41_component *silly); -void map_access_2_allowdeny( - IN ULONG access_mask, - IN ULONG access_mode, - OUT uint32_t *allow, - OUT uint32_t *deny); - bool_t multi_addr_find( IN const multi_addr4 *addrs, IN const netaddr4 *addr, diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c index d036989..4f14610 100644 --- a/sys/nfs41_driver.c +++ b/sys/nfs41_driver.c @@ -179,9 +179,6 @@ typedef struct _updowncall_entry { PVOID buf; ULONG buf_len; FILE_INFORMATION_CLASS InfoClass; - ULONG open_owner_id; - ULONG access_mask; - ULONG access_mode; } SetFile; struct { DWORD mode; @@ -900,19 +897,12 @@ NTSTATUS marshal_nfs41_fileset(nfs41_updowncall_entry *entry, tmp += sizeof(ULONG); RtlCopyMemory(tmp, entry->u.SetFile.buf, entry->u.SetFile.buf_len); tmp += entry->u.SetFile.buf_len; - RtlCopyMemory(tmp, &entry->u.SetFile.open_owner_id, sizeof(ULONG)); - tmp += sizeof(ULONG); - RtlCopyMemory(tmp, &entry->u.SetFile.access_mask, sizeof(ULONG)); - tmp += sizeof(ULONG); - RtlCopyMemory(tmp, &entry->u.SetFile.access_mode, sizeof(ULONG)); *len = header_len; - DbgP("marshal_nfs41_fileset: filename='%wZ' class=%d open_owner_id=0x%x " - "access_mask=0x%x access_mode=0x%x\n", entry->u.SetFile.filename, - entry->u.SetFile.InfoClass, entry->u.SetFile.open_owner_id, - entry->u.SetFile.access_mask, entry->u.SetFile.access_mode); - print_hexbuf(0, (unsigned char *)"setfile buffer", entry->u.SetFile.buf, + DbgP("marshal_nfs41_fileset: filename='%wZ' class=%d\n", + entry->u.SetFile.filename, entry->u.SetFile.InfoClass); + print_hexbuf(0, (unsigned char *)"setfile buffer", entry->u.SetFile.buf, entry->u.SetFile.buf_len); out: DbgEx(); @@ -4012,12 +4002,24 @@ NTSTATUS nfs41_SetFileInformation ( NFS41GetVNetRootExtension(SrvOpen->pVNetRoot); PNFS41_FCB nfs41_fcb = (PNFS41_FCB)(RxContext->pFcb)->Context; FILE_RENAME_INFORMATION rinfo; - PFILE_OBJECT fo = RxContext->CurrentIrpSp->FileObject; PNFS41_NETROOT_EXTENSION pNetRootContext = NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot); DbgEn(); print_setfile_args(RxContext); + /* http://msdn.microsoft.com/en-us/library/ff469355(v=PROT.10).aspx + * http://msdn.microsoft.com/en-us/library/ff469424(v=PROT.10).aspx + * If Open.GrantedAccess does not contain FILE_WRITE_DATA, the operation + * MUST be failed with STATUS_ACCESS_DENIED. + */ + if (InfoClass == FileAllocationInformation || + InfoClass == FileEndOfFileInformation) { + if (!(SrvOpen->DesiredAccess & FILE_WRITE_DATA)) { + status = STATUS_ACCESS_DENIED; + goto out; + } + } + switch (InfoClass) { case FileRenameInformation: { @@ -4096,19 +4098,7 @@ NTSTATUS nfs41_SetFileInformation ( goto out; entry->u.SetFile.filename = FileName; entry->u.SetFile.InfoClass = InfoClass; - switch(InfoClass) { - case FileAllocationInformation: - case FileEndOfFileInformation: - entry->u.SetFile.open_owner_id = get_next_open_owner(); - if (fo->ReadAccess) - entry->u.SetFile.access_mask = FILE_READ_DATA; - if (fo->WriteAccess) - entry->u.SetFile.access_mask |= FILE_WRITE_DATA; - if (fo->SharedRead) - entry->u.SetFile.access_mode = FILE_SHARE_READ; - if (fo->SharedWrite) - entry->u.SetFile.access_mode |= FILE_SHARE_WRITE; - } + if (RxContext->Info.FileInformationClass == FileDispositionInformation && InfoClass == FileRenameInformation) { entry->u.SetFile.buf = &rinfo;