[acls] driver portion of setacl upcall
This commit is contained in:
parent
72c675f03b
commit
2b5e3fd64f
2 changed files with 125 additions and 2 deletions
|
|
@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue