ea: QueryEaInfo accepts a null EaList

check_nfs41_queryea_args() will now accept EaList == NULL, unless EAs are unsupported

moved handling of cygwin EAs to new function QueryCygwinEA()

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2012-04-16 12:44:16 -04:00 committed by unknown
parent b2e6a60710
commit 7b8715ce8e
2 changed files with 71 additions and 53 deletions

View file

@ -217,7 +217,7 @@ static int parse_getexattr(unsigned char *buffer, uint32_t length, nfs41_upcall
if (status) goto out; if (status) goto out;
status = safe_read(&buffer, &length, &args->ealist_len, sizeof(args->ealist_len)); status = safe_read(&buffer, &length, &args->ealist_len, sizeof(args->ealist_len));
if (status) goto out; if (status) goto out;
args->ealist = buffer; args->ealist = args->ealist_len ? buffer : NULL;
dprintf(1, "parsing NFS41_EA_GET: buf_len=%d Initial %d Restart %d " dprintf(1, "parsing NFS41_EA_GET: buf_len=%d Initial %d Restart %d "
"Single %d\n", args->buf_len,args->eaindex, args->restart, args->single); "Single %d\n", args->buf_len,args->eaindex, args->restart, args->single);

View file

@ -1147,7 +1147,9 @@ NTSTATUS marshal_nfs41_eaget(
tmp += sizeof(BOOLEAN); tmp += sizeof(BOOLEAN);
RtlCopyMemory(tmp, &entry->u.QueryEa.EaListLength, sizeof(ULONG)); RtlCopyMemory(tmp, &entry->u.QueryEa.EaListLength, sizeof(ULONG));
tmp += sizeof(ULONG); tmp += sizeof(ULONG);
RtlCopyMemory(tmp, entry->u.QueryEa.EaList, entry->u.QueryEa.EaListLength); if (entry->u.QueryEa.EaList && entry->u.QueryEa.EaListLength)
RtlCopyMemory(tmp, entry->u.QueryEa.EaList,
entry->u.QueryEa.EaListLength);
*len = header_len; *len = header_len;
@ -4678,18 +4680,18 @@ NTSTATUS check_nfs41_queryea_args(
status = check_nfs41_dirquery_args(RxContext); status = check_nfs41_dirquery_args(RxContext);
if (status) goto out; if (status) goto out;
/* XXX windows can query for all eas in which case the list can be empty */ if (!(FsAttrs->FileSystemAttributes & FILE_SUPPORTS_EXTENDED_ATTRIBUTES)) {
if (ea == NULL) { if (ea == NULL) {
status = STATUS_INVALID_PARAMETER; status = STATUS_EAS_NOT_SUPPORTED;
goto out; goto out;
} }
/* ignore cygwin EAs when checking support */ /* ignore cygwin EAs when checking support */
if (!(FsAttrs->FileSystemAttributes & FILE_SUPPORTS_EXTENDED_ATTRIBUTES) if (!AnsiStrEq(&NfsV3Attributes, ea->EaName, ea->EaNameLength) &&
&& !AnsiStrEq(&NfsV3Attributes, ea->EaName, ea->EaNameLength) !AnsiStrEq(&NfsActOnLink, ea->EaName, ea->EaNameLength) &&
&& !AnsiStrEq(&NfsActOnLink, ea->EaName, ea->EaNameLength) !AnsiStrEq(&NfsSymlinkTargetName, ea->EaName, ea->EaNameLength)) {
&& !AnsiStrEq(&NfsSymlinkTargetName, ea->EaName, ea->EaNameLength)) { status = STATUS_EAS_NOT_SUPPORTED;
status = STATUS_EAS_NOT_SUPPORTED; goto out;
goto out; }
} }
if ((RxContext->pRelevantSrvOpen->DesiredAccess & FILE_READ_EA) == 0) { if ((RxContext->pRelevantSrvOpen->DesiredAccess & FILE_READ_EA) == 0) {
status = STATUS_ACCESS_DENIED; status = STATUS_ACCESS_DENIED;
@ -4699,36 +4701,15 @@ out:
return status; return status;
} }
NTSTATUS nfs41_QueryEaInformation( static NTSTATUS QueryCygwinEA(
IN OUT PRX_CONTEXT RxContext) IN OUT PRX_CONTEXT RxContext,
IN PFILE_GET_EA_INFORMATION query,
OUT PFILE_FULL_EA_INFORMATION info)
{ {
NTSTATUS status = STATUS_EAS_NOT_SUPPORTED; NTSTATUS status = STATUS_NONEXISTENT_EA_ENTRY;
nfs41_updowncall_entry *entry;
PFILE_GET_EA_INFORMATION query = (PFILE_GET_EA_INFORMATION)
RxContext->CurrentIrpSp->Parameters.QueryEa.EaList;
__notnull PFILE_FULL_EA_INFORMATION info =
(PFILE_FULL_EA_INFORMATION)RxContext->Info.Buffer;
PUNICODE_STRING FileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
ULONG buflen = RxContext->CurrentIrpSp->Parameters.QueryEa.Length;
__notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
__notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
__notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
__notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
__notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
#ifdef ENABLE_TIMINGS
LARGE_INTEGER t1, t2;
t1 = KeQueryPerformanceCounter(NULL);
#endif
#ifdef DEBUG_EA_QUERY if (query == NULL)
DbgEn(); goto out;
print_debug_header(RxContext);
print_get_ea(1, query);
#endif
status = check_nfs41_queryea_args(RxContext);
if (status) goto out;
if (AnsiStrEq(&NfsV3Attributes, query->EaName, query->EaNameLength)) { if (AnsiStrEq(&NfsV3Attributes, query->EaName, query->EaNameLength)) {
nfs3_attrs attrs; nfs3_attrs attrs;
@ -4741,7 +4722,7 @@ NTSTATUS nfs41_QueryEaInformation(
goto out; goto out;
} }
create_nfs3_attrs(&attrs, nfs41_fcb); create_nfs3_attrs(&attrs, NFS41GetFcbExtension(RxContext->pFcb));
#ifdef DEBUG_EA_QUERY #ifdef DEBUG_EA_QUERY
print_nfs3_attrs(&attrs); print_nfs3_attrs(&attrs);
#endif #endif
@ -4757,11 +4738,10 @@ NTSTATUS nfs41_QueryEaInformation(
RxContext->Info.LengthRemaining = LengthRequired; RxContext->Info.LengthRemaining = LengthRequired;
status = STATUS_SUCCESS; status = STATUS_SUCCESS;
goto out; goto out;
} }
if (AnsiStrEq(&NfsActOnLink, query->EaName, query->EaNameLength) || if (AnsiStrEq(&NfsActOnLink, query->EaName, query->EaNameLength) ||
AnsiStrEq(&NfsSymlinkTargetName, query->EaName, AnsiStrEq(&NfsSymlinkTargetName, query->EaName, query->EaNameLength)) {
query->EaNameLength)) {
const LONG LengthRequired = sizeof(FILE_FULL_EA_INFORMATION) + const LONG LengthRequired = sizeof(FILE_FULL_EA_INFORMATION) +
query->EaNameLength - sizeof(CHAR); query->EaNameLength - sizeof(CHAR);
@ -4780,17 +4760,55 @@ NTSTATUS nfs41_QueryEaInformation(
status = STATUS_SUCCESS; status = STATUS_SUCCESS;
goto out; goto out;
} }
out:
return status;
}
NTSTATUS nfs41_QueryEaInformation(
IN OUT PRX_CONTEXT RxContext)
{
NTSTATUS status = STATUS_EAS_NOT_SUPPORTED;
nfs41_updowncall_entry *entry;
PFILE_GET_EA_INFORMATION query = (PFILE_GET_EA_INFORMATION)
RxContext->CurrentIrpSp->Parameters.QueryEa.EaList;
PUNICODE_STRING FileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
ULONG buflen = RxContext->CurrentIrpSp->Parameters.QueryEa.Length;
__notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
__notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
__notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
__notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
#ifdef ENABLE_TIMINGS
LARGE_INTEGER t1, t2;
t1 = KeQueryPerformanceCounter(NULL);
#endif
#ifdef DEBUG_EA_QUERY
DbgEn();
print_debug_header(RxContext);
print_get_ea(1, query);
#endif
status = check_nfs41_queryea_args(RxContext);
if (status) goto out;
/* handle queries for cygwin EAs */
status = QueryCygwinEA(RxContext, query,
(PFILE_FULL_EA_INFORMATION)RxContext->Info.Buffer);
if (status != STATUS_NONEXISTENT_EA_ENTRY)
goto out;
status = nfs41_UpcallCreate(NFS41_EA_GET, &nfs41_fobx->sec_ctx, status = nfs41_UpcallCreate(NFS41_EA_GET, &nfs41_fobx->sec_ctx,
pVNetRootContext->session, nfs41_fobx->nfs41_open_state, pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry); pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
if (status) goto out; if (status) goto out;
entry->u.QueryEa.filename = FileName; entry->u.QueryEa.filename = FileName;
entry->u.QueryEa.buf_len = buflen; entry->u.QueryEa.buf_len = buflen;
entry->u.QueryEa.buf = RxContext->Info.Buffer; entry->u.QueryEa.buf = RxContext->Info.Buffer;
entry->u.QueryEa.EaList = query; entry->u.QueryEa.EaList = query;
entry->u.QueryEa.EaListLength = RxContext->QueryEa.UserEaListLength; entry->u.QueryEa.EaListLength = query == NULL ? 0 :
RxContext->QueryEa.UserEaListLength;
entry->u.QueryEa.EaIndex = RxContext->QueryEa.UserEaIndex; entry->u.QueryEa.EaIndex = RxContext->QueryEa.UserEaIndex;
entry->u.QueryEa.RestartScan = RxContext->QueryEa.RestartScan; entry->u.QueryEa.RestartScan = RxContext->QueryEa.RestartScan;
entry->u.QueryEa.ReturnSingleEntry = RxContext->QueryEa.ReturnSingleEntry; entry->u.QueryEa.ReturnSingleEntry = RxContext->QueryEa.ReturnSingleEntry;
@ -4811,7 +4829,7 @@ NTSTATUS nfs41_QueryEaInformation(
} else { } else {
status = map_setea_error(entry->status); status = map_setea_error(entry->status);
} }
RxFreePool(entry); RxFreePool(entry);
out: out:
#ifdef ENABLE_TIMINGS #ifdef ENABLE_TIMINGS
t2 = KeQueryPerformanceCounter(NULL); t2 = KeQueryPerformanceCounter(NULL);