dll: dsctl: default security descriptor overhaul

This commit is contained in:
Bill Zissimopoulos 2015-12-01 12:02:02 -08:00
parent 6cf0f2d34f
commit 8201c4972b

View File

@ -17,21 +17,23 @@ static inline VOID GlobalDevicePath(PWCHAR DevicePathBuf, SIZE_T DevicePathSize,
L'\\' == DevicePath[0] ? GLOBALROOT "%s" : GLOBALROOT "\\Device\\%s", DevicePath); L'\\' == DevicePath[0] ? GLOBALROOT "%s" : GLOBALROOT "\\Device\\%s", DevicePath);
} }
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, static NTSTATUS CreateSelfRelativeSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
const FSP_FSCTL_VOLUME_PARAMS *Params, PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR *PSelfRelativeSecurityDescriptor, PDWORD PSelfRelativeSecurityDescriptorSize)
PWCHAR VolumePathBuf, SIZE_T VolumePathSize)
{ {
NTSTATUS Result = STATUS_SUCCESS; NTSTATUS Result;
FSP_FSCTL_VOLUME_PARAMS *ParamsBuf = 0; PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor = 0;
HANDLE Token = 0; DWORD SelfRelativeSecurityDescriptorSize;
PTOKEN_DEFAULT_DACL DefaultDacl = 0;
SECURITY_DESCRIPTOR SecurityDescriptorStruct; SECURITY_DESCRIPTOR SecurityDescriptorStruct;
PSECURITY_DESCRIPTOR SecurityDescriptorBuf; PTOKEN_OWNER Owner = 0;
DWORD SecurityDescriptorSize, Bytes; PTOKEN_PRIMARY_GROUP PrimaryGroup = 0;
WCHAR DevicePathBuf[MAX_PATH]; PTOKEN_DEFAULT_DACL DefaultDacl = 0;
HANDLE DeviceHandle = INVALID_HANDLE_VALUE; DWORD OwnerSize = 0;
DWORD PrimaryGroupSize = 0;
DWORD DefaultDaclSize = 0;
HANDLE Token = 0;
VolumePathBuf[0] = L'\0'; *PSelfRelativeSecurityDescriptor = 0;
*PSelfRelativeSecurityDescriptorSize = 0;
if (0 == SecurityDescriptor) if (0 == SecurityDescriptor)
{ {
@ -40,63 +42,123 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());
goto exit; goto exit;
} }
Bytes = 0; if ((!GetTokenInformation(Token, TokenOwner, 0, 0, &OwnerSize) &&
if (!GetTokenInformation(Token, TokenDefaultDacl, 0, 0, &Bytes) && ERROR_INSUFFICIENT_BUFFER != GetLastError()) ||
ERROR_INSUFFICIENT_BUFFER != GetLastError()) (!GetTokenInformation(Token, TokenPrimaryGroup, 0, 0, &PrimaryGroupSize) &&
ERROR_INSUFFICIENT_BUFFER != GetLastError()) ||
(!GetTokenInformation(Token, TokenDefaultDacl, 0, 0, &DefaultDaclSize) &&
ERROR_INSUFFICIENT_BUFFER != GetLastError()))
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());
goto exit; goto exit;
} }
DefaultDacl = malloc(Bytes); Owner = malloc(OwnerSize);
if (0 == DefaultDacl) PrimaryGroup = malloc(PrimaryGroupSize);
DefaultDacl = malloc(DefaultDaclSize);
if (0 == Owner || 0 == PrimaryGroup || 0 == DefaultDacl)
{ {
Result = STATUS_INSUFFICIENT_RESOURCES; Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit; goto exit;
} }
if (!GetTokenInformation(Token, TokenDefaultDacl, DefaultDacl, Bytes, &Bytes) || if (!GetTokenInformation(Token, TokenOwner, Owner, OwnerSize, &OwnerSize) ||
!InitializeSecurityDescriptor(&SecurityDescriptorStruct, SECURITY_DESCRIPTOR_REVISION) || !GetTokenInformation(Token, TokenPrimaryGroup, PrimaryGroup, PrimaryGroupSize, &PrimaryGroupSize) ||
!SetSecurityDescriptorDacl(&SecurityDescriptorStruct, TRUE, DefaultDacl->DefaultDacl, FALSE)) !GetTokenInformation(Token, TokenDefaultDacl, DefaultDacl, DefaultDaclSize, &DefaultDaclSize))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
if (!InitializeSecurityDescriptor(&SecurityDescriptorStruct, SECURITY_DESCRIPTOR_REVISION) ||
!SetSecurityDescriptorOwner(&SecurityDescriptorStruct, Owner->Owner, FALSE) ||
!SetSecurityDescriptorGroup(&SecurityDescriptorStruct, PrimaryGroup->PrimaryGroup, FALSE) ||
!SetSecurityDescriptorDacl(&SecurityDescriptorStruct, TRUE, DefaultDacl->DefaultDacl, FALSE) ||
!SetSecurityDescriptorControl(&SecurityDescriptorStruct, SE_DACL_PROTECTED, SE_DACL_PROTECTED))
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());
goto exit; goto exit;
} }
SecurityDescriptor = &SecurityDescriptorStruct; SecurityDescriptor = &SecurityDescriptorStruct;
CloseHandle(Token);
Token = 0;
} }
SecurityDescriptorSize = 0; SelfRelativeSecurityDescriptorSize = 0;
if (!MakeSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize) && if (!MakeSelfRelativeSD(SecurityDescriptor, 0, &SelfRelativeSecurityDescriptorSize) &&
ERROR_INSUFFICIENT_BUFFER != GetLastError()) ERROR_INSUFFICIENT_BUFFER != GetLastError())
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());
goto exit; goto exit;
} }
ParamsBuf = malloc(FSP_FSCTL_VOLUME_PARAMS_SIZE + SecurityDescriptorSize); SelfRelativeSecurityDescriptor = malloc(SelfRelativeSecurityDescriptorSize);
if (0 == SelfRelativeSecurityDescriptor)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
if (!MakeSelfRelativeSD(SecurityDescriptor, SelfRelativeSecurityDescriptor, &SelfRelativeSecurityDescriptorSize))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
*PSelfRelativeSecurityDescriptor = SelfRelativeSecurityDescriptor;
*PSelfRelativeSecurityDescriptorSize = SelfRelativeSecurityDescriptorSize;
Result = STATUS_SUCCESS;
exit:
if (0 != Token)
CloseHandle(Token);
free(DefaultDacl);
free(PrimaryGroup);
free(Owner);
if (STATUS_SUCCESS != Result)
free(SelfRelativeSecurityDescriptor);
return Result;
}
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
const FSP_FSCTL_VOLUME_PARAMS *Params, PSECURITY_DESCRIPTOR SecurityDescriptor,
PWCHAR VolumePathBuf, SIZE_T VolumePathSize)
{
NTSTATUS Result = STATUS_SUCCESS;
PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor = 0;
DWORD SelfRelativeSecurityDescriptorSize;
FSP_FSCTL_VOLUME_PARAMS *ParamsBuf = 0;
WCHAR DevicePathBuf[MAX_PATH];
HANDLE DeviceHandle = INVALID_HANDLE_VALUE;
DWORD Bytes;
if (sizeof(WCHAR) <= VolumePathSize)
VolumePathBuf[0] = L'\0';
Result = CreateSelfRelativeSecurityDescriptor(SecurityDescriptor,
&SelfRelativeSecurityDescriptor, &SelfRelativeSecurityDescriptorSize);
if (!NT_SUCCESS(Result))
goto exit;
ParamsBuf = malloc(FSP_FSCTL_VOLUME_PARAMS_SIZE + SelfRelativeSecurityDescriptorSize);
if (0 == ParamsBuf) if (0 == ParamsBuf)
{ {
Result = STATUS_INSUFFICIENT_RESOURCES; Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit; goto exit;
} }
memset(ParamsBuf, 0, FSP_FSCTL_VOLUME_PARAMS_SIZE); memset(ParamsBuf, 0, FSP_FSCTL_VOLUME_PARAMS_SIZE);
SecurityDescriptorBuf = (PVOID)((PUINT8)ParamsBuf + FSP_FSCTL_VOLUME_PARAMS_SIZE);
if (!MakeSelfRelativeSD(SecurityDescriptor, SecurityDescriptorBuf, &SecurityDescriptorSize))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
*ParamsBuf = *Params; *ParamsBuf = *Params;
memcpy((PUINT8)ParamsBuf + FSP_FSCTL_VOLUME_PARAMS_SIZE,
SelfRelativeSecurityDescriptor, SelfRelativeSecurityDescriptorSize);
GlobalDevicePath(DevicePathBuf, sizeof DevicePathBuf, DevicePath); GlobalDevicePath(DevicePathBuf, sizeof DevicePathBuf, DevicePath);
#if !defined(NDEBUG) #if !defined(NDEBUG)
{ {
PSTR Sddl; PSTR Sddl;
if (ConvertSecurityDescriptorToStringSecurityDescriptorA(SecurityDescriptorBuf, if (ConvertSecurityDescriptorToStringSecurityDescriptorA(SelfRelativeSecurityDescriptor,
SDDL_REVISION_1, DACL_SECURITY_INFORMATION, &Sddl, 0)) SDDL_REVISION_1,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
&Sddl, 0))
{ {
DEBUGLOG("Device=\"%S\", Sddl=\"%s\", SdSize=%lu", DEBUGLOG("Device=\"%S\", Sddl=\"%s\", SdSize=%lu",
DevicePathBuf, Sddl, SecurityDescriptorSize); DevicePathBuf, Sddl, SelfRelativeSecurityDescriptorSize);
LocalFree(Sddl); LocalFree(Sddl);
} }
} }
@ -113,7 +175,7 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
} }
if (!DeviceIoControl(DeviceHandle, FSP_FSCTL_CREATE, if (!DeviceIoControl(DeviceHandle, FSP_FSCTL_CREATE,
ParamsBuf, FSP_FSCTL_VOLUME_PARAMS_SIZE + SecurityDescriptorSize, ParamsBuf, FSP_FSCTL_VOLUME_PARAMS_SIZE + SelfRelativeSecurityDescriptorSize,
VolumePathBuf, (DWORD)VolumePathSize, VolumePathBuf, (DWORD)VolumePathSize,
&Bytes, 0)) &Bytes, 0))
{ {
@ -125,11 +187,9 @@ exit:
if (INVALID_HANDLE_VALUE != DeviceHandle) if (INVALID_HANDLE_VALUE != DeviceHandle)
CloseHandle(DeviceHandle); CloseHandle(DeviceHandle);
if (0 != Token)
CloseHandle(Token);
free(DefaultDacl);
free(ParamsBuf); free(ParamsBuf);
free(SelfRelativeSecurityDescriptor);
return Result; return Result;
} }