changing getacl downcall
instead of passing sids for the owner and group, create a security descriptor and pass that back. this way we can add all the security information that was queried in the daemon and pass a fully formed security descriptor back to the kernel. notice: irp_mj_query_security provides a pointer to the buffer that suppose to hold the security descriptor. that memory is valid only in the context of the process doing the security irp. we can't use this pointer in then upcall entry and try to write the security descriptor directly there as we process the downcall. that leads to kernel oops. thus we have to first allocate memory to hold the security descriptor then copy bytes passed to us from the daemon. then do another copy with the context of the security irp.
This commit is contained in:
parent
c00085bfb4
commit
80b3d11609
3 changed files with 119 additions and 152 deletions
79
daemon/acl.c
79
daemon/acl.c
|
|
@ -150,6 +150,7 @@ static int handle_getacl(nfs41_upcall *upcall)
|
||||||
nfs41_file_info info;
|
nfs41_file_info info;
|
||||||
bitmap4 attr_request;
|
bitmap4 attr_request;
|
||||||
LPSTR domain = NULL;
|
LPSTR domain = NULL;
|
||||||
|
SECURITY_DESCRIPTOR sec_desc;
|
||||||
|
|
||||||
// need to cache owner/group information XX
|
// need to cache owner/group information XX
|
||||||
ZeroMemory(&info, sizeof(info));
|
ZeroMemory(&info, sizeof(info));
|
||||||
|
|
@ -168,6 +169,13 @@ static int handle_getacl(nfs41_upcall *upcall)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = InitializeSecurityDescriptor(&sec_desc, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
if (!status) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("handle_getacl: InitializeSecurityDescriptor failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
args->osid_len = args->gsid_len = 0;
|
args->osid_len = args->gsid_len = 0;
|
||||||
if (args->query & OWNER_SECURITY_INFORMATION) {
|
if (args->query & OWNER_SECURITY_INFORMATION) {
|
||||||
// parse user@domain. currently ignoring domain part XX
|
// parse user@domain. currently ignoring domain part XX
|
||||||
|
|
@ -177,6 +185,13 @@ static int handle_getacl(nfs41_upcall *upcall)
|
||||||
status = map_name_2_sid(&args->osid_len, &args->osid, (LPSTR)info.owner);
|
status = map_name_2_sid(&args->osid_len, &args->osid, (LPSTR)info.owner);
|
||||||
if (status)
|
if (status)
|
||||||
goto out;
|
goto out;
|
||||||
|
status = SetSecurityDescriptorOwner(&sec_desc, args->osid, TRUE);
|
||||||
|
free(args->osid);
|
||||||
|
if (!status) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("handle_getacl: SetSecurityDescriptorOwner failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (args->query & GROUP_SECURITY_INFORMATION) {
|
if (args->query & GROUP_SECURITY_INFORMATION) {
|
||||||
convert_nfs4name_2_user_domain((LPSTR)info.owner_group, &domain);
|
convert_nfs4name_2_user_domain((LPSTR)info.owner_group, &domain);
|
||||||
|
|
@ -185,12 +200,45 @@ static int handle_getacl(nfs41_upcall *upcall)
|
||||||
status = map_name_2_sid(&args->gsid_len, &args->gsid, (LPSTR)info.owner_group);
|
status = map_name_2_sid(&args->gsid_len, &args->gsid, (LPSTR)info.owner_group);
|
||||||
if (status)
|
if (status)
|
||||||
goto out;
|
goto out;
|
||||||
|
status = SetSecurityDescriptorGroup(&sec_desc, args->gsid, TRUE);
|
||||||
|
free(args->gsid);
|
||||||
|
if (!status) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("handle_getacl: SetSecurityDescriptorGroup failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (args->query & DACL_SECURITY_INFORMATION)
|
if (args->query & DACL_SECURITY_INFORMATION)
|
||||||
dprintf(1, "handle_getacl: DACL_SECURITY_INFORMATION\n");
|
dprintf(1, "handle_getacl: DACL_SECURITY_INFORMATION\n");
|
||||||
if (args->query & SACL_SECURITY_INFORMATION)
|
if (args->query & SACL_SECURITY_INFORMATION)
|
||||||
dprintf(1, "handle_getacl: SACL_SECURITY_INFORMATION\n");
|
dprintf(1, "handle_getacl: SACL_SECURITY_INFORMATION\n");
|
||||||
|
|
||||||
|
args->sec_desc_len = 0;
|
||||||
|
status = MakeSelfRelativeSD(&sec_desc, args->sec_desc, &args->sec_desc_len);
|
||||||
|
if (!status) {
|
||||||
|
status = GetLastError();
|
||||||
|
if (status == ERROR_INSUFFICIENT_BUFFER) {
|
||||||
|
args->sec_desc = malloc(args->sec_desc_len);
|
||||||
|
if (args->sec_desc == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
status = MakeSelfRelativeSD(&sec_desc, args->sec_desc, &args->sec_desc_len);
|
||||||
|
if (!status) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("handle_getacl: MakeSelfRelativeSD failes with %d\n", status);
|
||||||
|
free(args->sec_desc);
|
||||||
|
goto out;
|
||||||
|
} else status = 0;
|
||||||
|
} else {
|
||||||
|
eprintf("handle_getacl: MakeSelfRelativeSD failes with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else { // this shouldn't happen
|
||||||
|
status = ERROR_INTERNAL_ERROR;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (args->query & DACL_SECURITY_INFORMATION) {
|
if (args->query & DACL_SECURITY_INFORMATION) {
|
||||||
nfsacl41_free(info.acl);
|
nfsacl41_free(info.acl);
|
||||||
|
|
@ -199,41 +247,16 @@ out:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int marshall_acl(unsigned char **buffer, uint32_t *remaining, uint32_t sid_len, PSID sid)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
status = safe_write(buffer, remaining, &sid_len, sizeof(sid_len));
|
|
||||||
if (status) goto out;
|
|
||||||
if (*remaining < sid_len)
|
|
||||||
return ERROR_BUFFER_OVERFLOW;
|
|
||||||
status = CopySid(sid_len, *buffer, sid);
|
|
||||||
free(sid);
|
|
||||||
if (!status) {
|
|
||||||
status = GetLastError();
|
|
||||||
dprintf(1, "marshall_acl: CopySid failed %d\n", status);
|
|
||||||
goto out;
|
|
||||||
} else {
|
|
||||||
status = 0;
|
|
||||||
*buffer += sid_len;
|
|
||||||
*remaining -= sid_len;
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int marshall_getacl(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
static int marshall_getacl(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
{
|
{
|
||||||
int status = ERROR_NOT_SUPPORTED;
|
int status = ERROR_NOT_SUPPORTED;
|
||||||
getacl_upcall_args *args = &upcall->args.getacl;
|
getacl_upcall_args *args = &upcall->args.getacl;
|
||||||
|
|
||||||
if (args->query & OWNER_SECURITY_INFORMATION) {
|
status = safe_write(&buffer, length, &args->sec_desc_len, sizeof(DWORD));
|
||||||
status = marshall_acl(&buffer, length, args->osid_len, args->osid);
|
|
||||||
if (status) goto out;
|
if (status) goto out;
|
||||||
}
|
status = safe_write(&buffer, length, args->sec_desc, args->sec_desc_len);
|
||||||
if (args->query & GROUP_SECURITY_INFORMATION) {
|
free(args->sec_desc);
|
||||||
status = marshall_acl(&buffer, length, args->gsid_len, args->gsid);
|
|
||||||
if (status) goto out;
|
if (status) goto out;
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,8 @@ typedef struct __getacl_upcall_args {
|
||||||
DWORD osid_len;
|
DWORD osid_len;
|
||||||
PSID gsid;
|
PSID gsid;
|
||||||
DWORD gsid_len;
|
DWORD gsid_len;
|
||||||
|
PSECURITY_DESCRIPTOR sec_desc;
|
||||||
|
DWORD sec_desc_len;
|
||||||
} getacl_upcall_args;
|
} getacl_upcall_args;
|
||||||
|
|
||||||
typedef struct __setacl_upcall_args {
|
typedef struct __setacl_upcall_args {
|
||||||
|
|
|
||||||
|
|
@ -216,22 +216,13 @@ typedef struct _updowncall_entry {
|
||||||
PVOID buf;
|
PVOID buf;
|
||||||
LONG buf_len;
|
LONG buf_len;
|
||||||
} Volume;
|
} Volume;
|
||||||
struct {
|
|
||||||
HANDLE open_state;
|
|
||||||
HANDLE session;
|
|
||||||
SECURITY_INFORMATION query;
|
|
||||||
PVOID owner_buf;
|
|
||||||
LONG owner_buf_len;
|
|
||||||
PVOID owner_group_buf;
|
|
||||||
LONG owner_group_buf_len;
|
|
||||||
} QueryAcl;
|
|
||||||
struct {
|
struct {
|
||||||
HANDLE open_state;
|
HANDLE open_state;
|
||||||
HANDLE session;
|
HANDLE session;
|
||||||
SECURITY_INFORMATION query;
|
SECURITY_INFORMATION query;
|
||||||
PVOID buf;
|
PVOID buf;
|
||||||
LONG buf_len;
|
DWORD buf_len;
|
||||||
} SetAcl;
|
} Acl;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
} nfs41_updowncall_entry;
|
} nfs41_updowncall_entry;
|
||||||
|
|
@ -1131,15 +1122,15 @@ NTSTATUS marshal_nfs41_getacl(nfs41_updowncall_entry *entry,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlCopyMemory(tmp, &entry->u.QueryAcl.session, sizeof(HANDLE));
|
RtlCopyMemory(tmp, &entry->u.Acl.session, sizeof(HANDLE));
|
||||||
tmp += sizeof(HANDLE);
|
tmp += sizeof(HANDLE);
|
||||||
RtlCopyMemory(tmp, &entry->u.QueryAcl.open_state, sizeof(HANDLE));
|
RtlCopyMemory(tmp, &entry->u.Acl.open_state, sizeof(HANDLE));
|
||||||
tmp += sizeof(HANDLE);
|
tmp += sizeof(HANDLE);
|
||||||
RtlCopyMemory(tmp, &entry->u.QueryAcl.query, sizeof(SECURITY_INFORMATION));
|
RtlCopyMemory(tmp, &entry->u.Acl.query, sizeof(SECURITY_INFORMATION));
|
||||||
*len = header_len;
|
*len = header_len;
|
||||||
|
|
||||||
DbgP("session=0x%x open_state=0x%x query=%d\n", entry->u.QueryAcl.session,
|
DbgP("session=0x%x open_state=0x%x query=%d\n", entry->u.Acl.session,
|
||||||
entry->u.QueryAcl.open_state, entry->u.QueryAcl.query);
|
entry->u.Acl.open_state, entry->u.Acl.query);
|
||||||
out:
|
out:
|
||||||
DbgEx();
|
DbgEx();
|
||||||
return status;
|
return status;
|
||||||
|
|
@ -1161,26 +1152,26 @@ NTSTATUS marshal_nfs41_setacl(nfs41_updowncall_entry *entry,
|
||||||
else
|
else
|
||||||
tmp += *len;
|
tmp += *len;
|
||||||
header_len = *len + 2 * sizeof(HANDLE) + sizeof(SECURITY_INFORMATION) +
|
header_len = *len + 2 * sizeof(HANDLE) + sizeof(SECURITY_INFORMATION) +
|
||||||
sizeof(ULONG) + entry->u.SetAcl.buf_len;
|
sizeof(ULONG) + entry->u.Acl.buf_len;
|
||||||
if (header_len > buf_len) {
|
if (header_len > buf_len) {
|
||||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlCopyMemory(tmp, &entry->u.SetAcl.session, sizeof(HANDLE));
|
RtlCopyMemory(tmp, &entry->u.Acl.session, sizeof(HANDLE));
|
||||||
tmp += sizeof(HANDLE);
|
tmp += sizeof(HANDLE);
|
||||||
RtlCopyMemory(tmp, &entry->u.SetAcl.open_state, sizeof(HANDLE));
|
RtlCopyMemory(tmp, &entry->u.Acl.open_state, sizeof(HANDLE));
|
||||||
tmp += sizeof(HANDLE);
|
tmp += sizeof(HANDLE);
|
||||||
RtlCopyMemory(tmp, &entry->u.SetAcl.query, sizeof(SECURITY_INFORMATION));
|
RtlCopyMemory(tmp, &entry->u.Acl.query, sizeof(SECURITY_INFORMATION));
|
||||||
tmp += sizeof(SECURITY_INFORMATION);
|
tmp += sizeof(SECURITY_INFORMATION);
|
||||||
RtlCopyMemory(tmp, &entry->u.SetAcl.buf_len, sizeof(ULONG));
|
RtlCopyMemory(tmp, &entry->u.Acl.buf_len, sizeof(DWORD));
|
||||||
tmp += sizeof(ULONG);
|
tmp += sizeof(DWORD);
|
||||||
RtlCopyMemory(tmp, entry->u.SetAcl.buf, entry->u.SetAcl.buf_len);
|
RtlCopyMemory(tmp, entry->u.Acl.buf, entry->u.Acl.buf_len);
|
||||||
*len = header_len;
|
*len = header_len;
|
||||||
|
|
||||||
DbgP("session=0x%x open_state=0x%x query=%d sec_desc_len=%d\n",
|
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.Acl.session, entry->u.Acl.open_state,
|
||||||
entry->u.SetAcl.query, entry->u.SetAcl.buf_len);
|
entry->u.Acl.query, entry->u.Acl.buf_len);
|
||||||
out:
|
out:
|
||||||
DbgEx();
|
DbgEx();
|
||||||
return status;
|
return status;
|
||||||
|
|
@ -1622,29 +1613,21 @@ nfs41_downcall (
|
||||||
RtlCopyMemory(cur->u.Volume.buf, buf, tmp->u.Volume.buf_len);
|
RtlCopyMemory(cur->u.Volume.buf, buf, tmp->u.Volume.buf_len);
|
||||||
break;
|
break;
|
||||||
case NFS41_ACL_QUERY:
|
case NFS41_ACL_QUERY:
|
||||||
if (cur->u.QueryAcl.query & OWNER_SECURITY_INFORMATION) {
|
RtlCopyMemory(&tmp->u.Acl.buf_len, buf, sizeof(DWORD));
|
||||||
RtlCopyMemory(&tmp->u.QueryAcl.owner_buf_len, buf, sizeof(LONG));
|
buf += sizeof(DWORD);
|
||||||
buf += sizeof(LONG);
|
if (tmp->u.Acl.buf_len > cur->u.Acl.buf_len) {
|
||||||
if (tmp->u.QueryAcl.owner_buf_len > cur->u.QueryAcl.owner_buf_len) {
|
|
||||||
cur->status = STATUS_BUFFER_TOO_SMALL;
|
cur->status = STATUS_BUFFER_TOO_SMALL;
|
||||||
cur->u.QueryAcl.owner_buf_len = tmp->u.QueryAcl.owner_buf_len;
|
cur->u.Acl.buf_len = tmp->u.Acl.buf_len;
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
cur->u.Acl.buf = RxAllocatePoolWithTag(NonPagedPool,
|
||||||
|
tmp->u.Acl.buf_len, NFS41_MM_POOLTAG);
|
||||||
|
if (cur->u.Acl.buf == NULL) {
|
||||||
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto out_free;
|
||||||
}
|
}
|
||||||
cur->u.QueryAcl.owner_buf_len = tmp->u.QueryAcl.owner_buf_len;
|
RtlCopyMemory(cur->u.Acl.buf, buf, tmp->u.Acl.buf_len);
|
||||||
RtlCopySid(cur->u.QueryAcl.owner_buf_len, cur->u.QueryAcl.owner_buf, buf);
|
cur->u.Acl.buf_len = tmp->u.Acl.buf_len;
|
||||||
buf += tmp->u.QueryAcl.owner_buf_len;
|
|
||||||
}
|
|
||||||
if (cur->u.QueryAcl.query & GROUP_SECURITY_INFORMATION) {
|
|
||||||
RtlCopyMemory(&tmp->u.QueryAcl.owner_group_buf_len, buf, sizeof(LONG));
|
|
||||||
buf += sizeof(LONG);
|
|
||||||
if (tmp->u.QueryAcl.owner_group_buf_len > cur->u.QueryAcl.owner_group_buf_len) {
|
|
||||||
cur->status = STATUS_BUFFER_TOO_SMALL;
|
|
||||||
cur->u.QueryAcl.owner_group_buf_len = tmp->u.QueryAcl.owner_group_buf_len;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cur->u.QueryAcl.owner_group_buf_len = tmp->u.QueryAcl.owner_group_buf_len;
|
|
||||||
RtlCopySid(cur->u.QueryAcl.owner_group_buf_len, cur->u.QueryAcl.owner_group_buf, buf);
|
|
||||||
buf += tmp->u.QueryAcl.owner_group_buf_len;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -3778,7 +3761,6 @@ NTSTATUS nfs41_QuerySecurityInformation (
|
||||||
NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
|
NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
|
||||||
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];
|
|
||||||
SECURITY_INFORMATION info_class =
|
SECURITY_INFORMATION info_class =
|
||||||
RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
|
RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
|
||||||
|
|
||||||
|
|
@ -3793,14 +3775,15 @@ NTSTATUS nfs41_QuerySecurityInformation (
|
||||||
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.Acl.open_state = nfs41_fobx->nfs41_open_state;
|
||||||
entry->u.QueryAcl.session = pVNetRootContext->session;
|
entry->u.Acl.session = pVNetRootContext->session;
|
||||||
entry->u.QueryAcl.query = info_class;
|
entry->u.Acl.query = info_class;
|
||||||
entry->u.QueryAcl.owner_buf = owner_buf;
|
|
||||||
entry->u.QueryAcl.owner_buf_len = SECURITY_MAX_SID_SIZE;
|
|
||||||
entry->u.QueryAcl.owner_group_buf = group_buf;
|
|
||||||
entry->u.QueryAcl.owner_group_buf_len = SECURITY_MAX_SID_SIZE;
|
|
||||||
entry->version = pNetRootContext->nfs41d_version;
|
entry->version = pNetRootContext->nfs41d_version;
|
||||||
|
/* we can't provide RxContext->CurrentIrp->UserBuffer to the upcall thread
|
||||||
|
* because it becomes an invalid pointer with that execution context
|
||||||
|
*/
|
||||||
|
entry->u.Acl.buf_len = RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length;
|
||||||
|
DbgP("security buffer len %d\n", entry->u.Acl.buf_len);
|
||||||
|
|
||||||
if (nfs41_UpcallWaitForReply(entry) != STATUS_SUCCESS) {
|
if (nfs41_UpcallWaitForReply(entry) != STATUS_SUCCESS) {
|
||||||
status = STATUS_INTERNAL_ERROR;
|
status = STATUS_INTERNAL_ERROR;
|
||||||
|
|
@ -3808,76 +3791,35 @@ NTSTATUS nfs41_QuerySecurityInformation (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->status == STATUS_BUFFER_TOO_SMALL) {
|
if (entry->status == STATUS_BUFFER_TOO_SMALL) {
|
||||||
DbgP("nfs41_QuerySecurityInformation: our SID buffers are %d but we need %d\n",
|
DbgP("nfs41_QuerySecurityInformation: provided buffer size=%d but we need %d\n",
|
||||||
SECURITY_MAX_SID_SIZE, entry->u.QueryFile.buf_len);
|
RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length,
|
||||||
status = STATUS_INTERNAL_ERROR;
|
entry->u.Acl.buf_len);
|
||||||
|
status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
RxContext->InformationToReturn = entry->u.Acl.buf_len;
|
||||||
} else if (entry->status == STATUS_SUCCESS) {
|
} else if (entry->status == STATUS_SUCCESS) {
|
||||||
|
if (RtlValidSecurityDescriptor(entry->u.Acl.buf)) {
|
||||||
|
DbgP("Received a valid security descriptor\n");
|
||||||
|
if (MmIsAddressValid(RxContext->CurrentIrp->UserBuffer)) {
|
||||||
PSECURITY_DESCRIPTOR sec_desc = (PSECURITY_DESCRIPTOR)
|
PSECURITY_DESCRIPTOR sec_desc = (PSECURITY_DESCRIPTOR)
|
||||||
RxContext->CurrentIrp->UserBuffer;
|
RxContext->CurrentIrp->UserBuffer;
|
||||||
SECURITY_DESCRIPTOR tmp_sec_desc;
|
DbgP("Received a valid user pointer\n");
|
||||||
ULONG tmpLength = RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length;
|
RtlCopyMemory(sec_desc, entry->u.Acl.buf, entry->u.Acl.buf_len);
|
||||||
status = RtlCreateSecurityDescriptor(&tmp_sec_desc, SECURITY_DESCRIPTOR_REVISION);
|
|
||||||
if (status) {
|
|
||||||
DbgP("RtlCreateSecurityDescriptor failed %x\n", status);
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
if (entry->u.QueryAcl.query & OWNER_SECURITY_INFORMATION) {
|
|
||||||
PSID osid = (PSID)owner_buf;
|
|
||||||
if (RtlValidSid(osid)) {
|
|
||||||
status = RtlSetOwnerSecurityDescriptor(&tmp_sec_desc, osid, TRUE);
|
|
||||||
if (status) {
|
|
||||||
DbgP("RtlSetOwnerSecurityDescriptor returned %x\n", status);
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
DbgP("added owner sid\n");
|
|
||||||
} else {
|
} else {
|
||||||
DbgP("INVALID OWNER SID: adding NULL sid\n");
|
DbgP("Received invalid user pointer\n");
|
||||||
status = RtlSetOwnerSecurityDescriptor(&tmp_sec_desc, NULL, TRUE);
|
status = STATUS_INTERNAL_ERROR;
|
||||||
if (status) {
|
|
||||||
DbgP("RtlSetOwnerSecurityDescriptor returned %x\n", status);
|
|
||||||
goto out_free;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if (entry->u.QueryAcl.query & GROUP_SECURITY_INFORMATION) {
|
|
||||||
PSID gsid = (PSID)group_buf;
|
|
||||||
if (RtlValidSid(gsid)) {
|
|
||||||
status = RtlSetGroupSecurityDescriptor(&tmp_sec_desc, gsid, TRUE);
|
|
||||||
if (status) {
|
|
||||||
DbgP("RtlSetOwnerSecurityDescriptor returned %x\n", status);
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
DbgP("adder group sid\n");
|
|
||||||
} else {
|
} else {
|
||||||
DbgP("INVAID GROUP SID: adding NULL sid\n");
|
DbgP("Received invalid security descriptor\n");
|
||||||
status = RtlSetGroupSecurityDescriptor(&tmp_sec_desc, NULL, TRUE);
|
status = STATUS_INTERNAL_ERROR;
|
||||||
if (status) {
|
|
||||||
DbgP("RtlSetOwnerSecurityDescriptor returned %x\n", status);
|
|
||||||
goto out_free;
|
|
||||||
}
|
}
|
||||||
}
|
RxFreePool(entry->u.Acl.buf);
|
||||||
}
|
|
||||||
if (entry->u.QueryAcl.query & DACL_SECURITY_INFORMATION)
|
|
||||||
DbgP("handle_getacl: DACL_SECURITY_INFORMATION\n");
|
|
||||||
if (entry->u.QueryAcl.query & SACL_SECURITY_INFORMATION)
|
|
||||||
DbgP("handle_getacl: SACL_SECURITY_INFORMATION\n");
|
|
||||||
|
|
||||||
status = RtlAbsoluteToSelfRelativeSD(&tmp_sec_desc, sec_desc, &tmpLength);
|
|
||||||
if (status) {
|
|
||||||
DbgP("RtlAbsoluteToSelfRelativeSD failed %x have %dbytes need %dbytes\n",
|
|
||||||
status, RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length, tmpLength);
|
|
||||||
if (status == STATUS_BUFFER_TOO_SMALL)
|
|
||||||
RxContext->InformationToReturn = tmpLength;
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
RxContext->IoStatusBlock.Information = RxContext->InformationToReturn =
|
RxContext->IoStatusBlock.Information = RxContext->InformationToReturn =
|
||||||
RtlLengthSecurityDescriptor(sec_desc);
|
entry->u.Acl.buf_len;
|
||||||
|
if (!status)
|
||||||
RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
|
RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
status = map_query_acl_error(entry->status);
|
status = map_query_acl_error(entry->status);
|
||||||
}
|
}
|
||||||
out_free:
|
|
||||||
RxFreePool(entry);
|
RxFreePool(entry);
|
||||||
out:
|
out:
|
||||||
DbgEx();
|
DbgEx();
|
||||||
|
|
@ -3924,11 +3866,11 @@ NTSTATUS nfs41_SetSecurityInformation (
|
||||||
status = nfs41_UpcallCreate(NFS41_ACL_SET, &nfs41_fobx->sec_ctx, &entry);
|
status = nfs41_UpcallCreate(NFS41_ACL_SET, &nfs41_fobx->sec_ctx, &entry);
|
||||||
if (status)
|
if (status)
|
||||||
goto out;
|
goto out;
|
||||||
entry->u.SetAcl.open_state = nfs41_fobx->nfs41_open_state;
|
entry->u.Acl.open_state = nfs41_fobx->nfs41_open_state;
|
||||||
entry->u.SetAcl.session = pVNetRootContext->session;
|
entry->u.Acl.session = pVNetRootContext->session;
|
||||||
entry->u.SetAcl.query = info_class;
|
entry->u.Acl.query = info_class;
|
||||||
entry->u.SetAcl.buf = sec_desc;
|
entry->u.Acl.buf = sec_desc;
|
||||||
entry->u.SetAcl.buf_len = RtlLengthSecurityDescriptor(sec_desc);
|
entry->u.Acl.buf_len = RtlLengthSecurityDescriptor(sec_desc);
|
||||||
entry->version = pNetRootContext->nfs41d_version;
|
entry->version = pNetRootContext->nfs41d_version;
|
||||||
|
|
||||||
if (nfs41_UpcallWaitForReply(entry) != STATUS_SUCCESS) {
|
if (nfs41_UpcallWaitForReply(entry) != STATUS_SUCCESS) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue