[acls] driver portion of setacl upcall

This commit is contained in:
Olga Kornievskaia 2011-04-12 15:56:20 -04:00
parent 72c675f03b
commit 2b5e3fd64f
2 changed files with 125 additions and 2 deletions

View file

@ -614,6 +614,7 @@ const char *opcode2string(int opcode)
case NFS41_SYMLINK: return "NFS41_SYMLINK"; case NFS41_SYMLINK: return "NFS41_SYMLINK";
case NFS41_VOLUME_QUERY: return "NFS41_VOLUME_QUERY"; case NFS41_VOLUME_QUERY: return "NFS41_VOLUME_QUERY";
case NFS41_ACL_QUERY: return "NFS41_ACL_QUERY"; case NFS41_ACL_QUERY: return "NFS41_ACL_QUERY";
case NFS41_ACL_SET: return "NFS41_ACL_SET";
default: return "UNKNOWN"; default: return "UNKNOWN";
} }
} }

View file

@ -225,6 +225,13 @@ typedef struct _updowncall_entry {
PVOID owner_group_buf; PVOID owner_group_buf;
LONG owner_group_buf_len; LONG owner_group_buf_len;
} QueryAcl; } QueryAcl;
struct {
HANDLE open_state;
HANDLE session;
SECURITY_INFORMATION query;
PVOID buf;
LONG buf_len;
} SetAcl;
} u; } u;
} nfs41_updowncall_entry; } nfs41_updowncall_entry;
@ -1138,6 +1145,47 @@ out:
return status; return status;
} }
NTSTATUS marshal_nfs41_setacl(nfs41_updowncall_entry *entry,
unsigned char *buf,
ULONG buf_len,
ULONG *len)
{
NTSTATUS status = STATUS_SUCCESS;
ULONG header_len = 0;
unsigned char *tmp = buf;
DbgEn();
status = marshal_nfs41_header(entry, tmp, buf_len, len);
if (status == STATUS_INSUFFICIENT_RESOURCES)
goto out;
else
tmp += *len;
header_len = *len + 2 * sizeof(HANDLE) + sizeof(SECURITY_INFORMATION) +
sizeof(ULONG) + entry->u.SetAcl.buf_len;
if (header_len > buf_len) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto out;
}
RtlCopyMemory(tmp, &entry->u.SetAcl.session, sizeof(HANDLE));
tmp += sizeof(HANDLE);
RtlCopyMemory(tmp, &entry->u.SetAcl.open_state, sizeof(HANDLE));
tmp += sizeof(HANDLE);
RtlCopyMemory(tmp, &entry->u.SetAcl.query, sizeof(SECURITY_INFORMATION));
tmp += sizeof(SECURITY_INFORMATION);
RtlCopyMemory(tmp, &entry->u.SetAcl.buf_len, sizeof(ULONG));
tmp += sizeof(ULONG);
RtlCopyMemory(tmp, entry->u.SetAcl.buf, entry->u.SetAcl.buf_len);
*len = header_len;
DbgP("session=0x%x open_state=0x%x query=%d sec_desc_len=%d\n",
entry->u.SetAcl.session, entry->u.SetAcl.open_state,
entry->u.SetAcl.query, entry->u.SetAcl.buf_len);
out:
DbgEx();
return status;
}
NTSTATUS marshal_nfs41_shutdown(nfs41_updowncall_entry *entry, NTSTATUS marshal_nfs41_shutdown(nfs41_updowncall_entry *entry,
unsigned char *buf, unsigned char *buf,
ULONG buf_len, ULONG buf_len,
@ -1233,6 +1281,9 @@ handle_upcall(
case NFS41_ACL_QUERY: case NFS41_ACL_QUERY:
status = marshal_nfs41_getacl(entry, pbOut, cbOut, len); status = marshal_nfs41_getacl(entry, pbOut, cbOut, len);
break; break;
case NFS41_ACL_SET:
status = marshal_nfs41_setacl(entry, pbOut, cbOut, len);
break;
default: default:
status = STATUS_INVALID_PARAMETER; status = STATUS_INVALID_PARAMETER;
print_error("Unknown nfs41 ops %d\n", entry->opcode); print_error("Unknown nfs41 ops %d\n", entry->opcode);
@ -3688,9 +3739,23 @@ out:
DbgEx(); DbgEx();
return status; return status;
} }
static void print_acl_args(SECURITY_INFORMATION info)
{
if (info & OWNER_SECURITY_INFORMATION)
DbgP("OWNER_SECURITY_INFORMATION\n");
if (info & GROUP_SECURITY_INFORMATION)
DbgP("GROUP_SECURITY_INFORMATION\n");
if (info & DACL_SECURITY_INFORMATION)
DbgP("DACL_SECURITY_INFORMATION\n");
if (info & SACL_SECURITY_INFORMATION)
DbgP("SACL_SECURITY_INFORMATION\n");
}
static NTSTATUS map_query_acl_error(DWORD error) static NTSTATUS map_query_acl_error(DWORD error)
{ {
switch (error) { switch (error) {
case NO_ERROR: return STATUS_SUCCESS;
case ERROR_NOT_SUPPORTED: return STATUS_NOT_SUPPORTED; case ERROR_NOT_SUPPORTED: return STATUS_NOT_SUPPORTED;
case ERROR_ACCESS_DENIED: return STATUS_ACCESS_DENIED; case ERROR_ACCESS_DENIED: return STATUS_ACCESS_DENIED;
case ERROR_FILE_NOT_FOUND: return STATUS_OBJECT_NAME_NOT_FOUND; case ERROR_FILE_NOT_FOUND: return STATUS_OBJECT_NAME_NOT_FOUND;
@ -3701,6 +3766,7 @@ static NTSTATUS map_query_acl_error(DWORD error)
case ERROR_BAD_NET_RESP: return STATUS_INVALID_NETWORK_RESPONSE; case ERROR_BAD_NET_RESP: return STATUS_INVALID_NETWORK_RESPONSE;
} }
} }
NTSTATUS nfs41_QuerySecurityInformation ( NTSTATUS nfs41_QuerySecurityInformation (
IN OUT PRX_CONTEXT RxContext) IN OUT PRX_CONTEXT RxContext)
{ {
@ -3713,16 +3779,23 @@ NTSTATUS nfs41_QuerySecurityInformation (
PNFS41_NETROOT_EXTENSION pNetRootContext = PNFS41_NETROOT_EXTENSION pNetRootContext =
NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot); NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
BYTE owner_buf[SECURITY_MAX_SID_SIZE], group_buf[SECURITY_MAX_SID_SIZE]; BYTE owner_buf[SECURITY_MAX_SID_SIZE], group_buf[SECURITY_MAX_SID_SIZE];
SECURITY_INFORMATION info_class =
RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
DbgEn(); DbgEn();
print_debug_header(RxContext); print_debug_header(RxContext);
print_acl_args(info_class);
/* we don't support sacls */
if (info_class == SACL_SECURITY_INFORMATION)
goto out;
status = nfs41_UpcallCreate(NFS41_ACL_QUERY, &nfs41_fobx->sec_ctx, &entry); status = nfs41_UpcallCreate(NFS41_ACL_QUERY, &nfs41_fobx->sec_ctx, &entry);
if (status) if (status)
goto out; goto out;
entry->u.QueryAcl.open_state = nfs41_fobx->nfs41_open_state; entry->u.QueryAcl.open_state = nfs41_fobx->nfs41_open_state;
entry->u.QueryAcl.session = pVNetRootContext->session; entry->u.QueryAcl.session = pVNetRootContext->session;
entry->u.QueryAcl.query = RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation; entry->u.QueryAcl.query = info_class;
entry->u.QueryAcl.owner_buf = owner_buf; entry->u.QueryAcl.owner_buf = owner_buf;
entry->u.QueryAcl.owner_buf_len = SECURITY_MAX_SID_SIZE; entry->u.QueryAcl.owner_buf_len = SECURITY_MAX_SID_SIZE;
entry->u.QueryAcl.owner_group_buf = group_buf; entry->u.QueryAcl.owner_group_buf = group_buf;
@ -3815,7 +3888,56 @@ NTSTATUS nfs41_SetSecurityInformation (
IN OUT struct _RX_CONTEXT *RxContext) IN OUT struct _RX_CONTEXT *RxContext)
{ {
NTSTATUS status = STATUS_NOT_SUPPORTED; //STATUS_SUCCESS; NTSTATUS status = STATUS_NOT_SUPPORTED; //STATUS_SUCCESS;
nfs41_updowncall_entry *entry;
PNFS41_FOBX nfs41_fobx = (PNFS41_FOBX)(RxContext->pFobx)->Context;
__notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
PNFS41_NETROOT_EXTENSION pNetRootContext =
NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
PSECURITY_DESCRIPTOR sec_desc = RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityDescriptor;
SECURITY_INFORMATION info_class =
RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityInformation;
DbgEn(); DbgEn();
print_debug_header(RxContext);
print_acl_args(info_class);
/* check that ACL is present */
if (info_class & DACL_SECURITY_INFORMATION) {
PACL acl;
BOOLEAN present, dacl_default;
status = RtlGetDaclSecurityDescriptor(sec_desc, &present, &acl, &dacl_default);
if (status) {
DbgP("RtlGetDaclSecurityDescriptor failed %x\n", status);
goto out;
}
if (present == FALSE) {
DbgP("NO ACL present\n");
goto out;
}
}
/* we don't support sacls */
if (info_class == SACL_SECURITY_INFORMATION)
goto out;
status = nfs41_UpcallCreate(NFS41_ACL_SET, &nfs41_fobx->sec_ctx, &entry);
if (status)
goto out;
entry->u.SetAcl.open_state = nfs41_fobx->nfs41_open_state;
entry->u.SetAcl.session = pVNetRootContext->session;
entry->u.SetAcl.query = info_class;
entry->u.SetAcl.buf = sec_desc;
entry->u.SetAcl.buf_len = RtlLengthSecurityDescriptor(sec_desc);
entry->version = pNetRootContext->nfs41d_version;
if (nfs41_UpcallWaitForReply(entry) != STATUS_SUCCESS) {
status = STATUS_INTERNAL_ERROR;
goto out;
}
status = map_query_acl_error(entry->status);
RxFreePool(entry);
out:
DbgEx(); DbgEx();
return status; return status;
} }