sys,dll: backup/restore privilege support

This commit is contained in:
Bill Zissimopoulos 2016-10-21 19:13:05 -07:00
parent b194a33406
commit 3bf4140f91
5 changed files with 43 additions and 10 deletions

View File

@ -218,13 +218,16 @@ typedef struct
UINT64 AllocationSize; /* initial allocation size */ UINT64 AllocationSize; /* initial allocation size */
UINT64 AccessToken; /* request access token (HANDLE) */ UINT64 AccessToken; /* request access token (HANDLE) */
UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */ UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */
FSP_FSCTL_TRANSACT_BUF Ea; /* reserved; not currently implemented */ FSP_FSCTL_TRANSACT_BUF Ea; /* reserved; not currently implemented */
UINT32 UserMode:1; /* request originated in user mode */ UINT32 UserMode:1; /* request originated in user mode */
UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */ UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */
UINT32 HasBackupPrivilege:1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */
UINT32 HasRestorePrivilege:1; /* requestor has TOKEN_HAS_RESTORE_PRIVILEGE */
UINT32 OpenTargetDirectory:1; /* open target dir and report FILE_{EXISTS,DOES_NOT_EXIST} */ UINT32 OpenTargetDirectory:1; /* open target dir and report FILE_{EXISTS,DOES_NOT_EXIST} */
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */ UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
UINT32 ReservedFlags:28; UINT32 ReservedFlags:26;
UINT16 NamedStream; /* request targets named stream; colon offset in FileName */ UINT16 NamedStream; /* request targets named stream; colon offset in FileName */
} Create; } Create;
struct struct

View File

@ -299,12 +299,16 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
&Sddl, 0); &Sddl, 0);
FspDebugLog("%S[TID=%04lx]: %p: >>Create [%c%c%c%c] \"%S\", " FspDebugLog("%S[TID=%04lx]: %p: >>Create [%c%c%c%c%c%c] \"%S\", "
"%s, CreateOptions=%lx, FileAttributes=%lx, Security=%s%s%s, " "%s, CreateOptions=%lx, FileAttributes=%lx, Security=%s%s%s, "
"AllocationSize=%lx:%lx, AccessToken=%p, DesiredAccess=%lx, ShareAccess=%lx\n", "AllocationSize=%lx:%lx, "
"AccessToken=%p, DesiredAccess=%lx, GrantedAccess=%lx, "
"ShareAccess=%lx\n",
FspDiagIdent(), GetCurrentThreadId(), Request->Hint, FspDiagIdent(), GetCurrentThreadId(), Request->Hint,
Request->Req.Create.UserMode ? 'U' : 'K', Request->Req.Create.UserMode ? 'U' : 'K',
Request->Req.Create.HasTraversePrivilege ? 'T' : '-', Request->Req.Create.HasTraversePrivilege ? 'T' : '-',
Request->Req.Create.HasBackupPrivilege ? 'B' : '-',
Request->Req.Create.HasRestorePrivilege ? 'R' : '-',
Request->Req.Create.OpenTargetDirectory ? 'D' : '-', Request->Req.Create.OpenTargetDirectory ? 'D' : '-',
Request->Req.Create.CaseSensitive ? 'C' : '-', Request->Req.Create.CaseSensitive ? 'C' : '-',
(PWSTR)Request->Buffer, (PWSTR)Request->Buffer,
@ -317,6 +321,7 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
MAKE_UINT32_PAIR(Request->Req.Create.AllocationSize), MAKE_UINT32_PAIR(Request->Req.Create.AllocationSize),
(PVOID)Request->Req.Create.AccessToken, (PVOID)Request->Req.Create.AccessToken,
Request->Req.Create.DesiredAccess, Request->Req.Create.DesiredAccess,
Request->Req.Create.GrantedAccess,
Request->Req.Create.ShareAccess); Request->Req.Create.ShareAccess);
LocalFree(Sddl); LocalFree(Sddl);
break; break;

View File

@ -137,7 +137,7 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
PSECURITY_DESCRIPTOR *PSecurityDescriptor) PSECURITY_DESCRIPTOR *PSecurityDescriptor)
{ {
NTSTATUS Result; NTSTATUS Result;
UINT32 GrantedAccess; UINT32 ParentDesiredAccess, GrantedAccess;
/* /*
* CreateCheck does different checks depending on whether we are * CreateCheck does different checks depending on whether we are
@ -161,9 +161,14 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
if (!Request->Req.Create.NamedStream) if (!Request->Req.Create.NamedStream)
{ {
if (Request->Req.Create.HasRestorePrivilege)
ParentDesiredAccess = 0;
else if (Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE)
ParentDesiredAccess = FILE_ADD_SUBDIRECTORY;
else
ParentDesiredAccess = FILE_ADD_FILE;
Result = FspAccessCheckEx(FileSystem, Request, TRUE, AllowTraverseCheck, Result = FspAccessCheckEx(FileSystem, Request, TRUE, AllowTraverseCheck,
(Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE) ? ParentDesiredAccess,
FILE_ADD_SUBDIRECTORY : FILE_ADD_FILE,
&GrantedAccess, PSecurityDescriptor); &GrantedAccess, PSecurityDescriptor);
if (STATUS_REPARSE == Result) if (STATUS_REPARSE == Result)
Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess); Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess);
@ -171,6 +176,7 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
{ {
*PGrantedAccess = (MAXIMUM_ALLOWED & Request->Req.Create.DesiredAccess) ? *PGrantedAccess = (MAXIMUM_ALLOWED & Request->Req.Create.DesiredAccess) ?
FspGetFileGenericMapping()->GenericAll : Request->Req.Create.DesiredAccess; FspGetFileGenericMapping()->GenericAll : Request->Req.Create.DesiredAccess;
*PGrantedAccess |= Request->Req.Create.GrantedAccess;
} }
} }
else else
@ -190,6 +196,7 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED)) if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED))
*PGrantedAccess &= ~(DELETE | FILE_WRITE_DATA) | *PGrantedAccess &= ~(DELETE | FILE_WRITE_DATA) |
(Request->Req.Create.DesiredAccess & (DELETE | FILE_WRITE_DATA)); (Request->Req.Create.DesiredAccess & (DELETE | FILE_WRITE_DATA));
*PGrantedAccess |= Request->Req.Create.GrantedAccess;
} }
} }
@ -225,6 +232,7 @@ NTSTATUS FspFileSystemOpenCheck(FSP_FILE_SYSTEM *FileSystem,
*PGrantedAccess = GrantedAccess; *PGrantedAccess = GrantedAccess;
if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED)) if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED))
*PGrantedAccess &= ~DELETE | (Request->Req.Create.DesiredAccess & DELETE); *PGrantedAccess &= ~DELETE | (Request->Req.Create.DesiredAccess & DELETE);
*PGrantedAccess |= Request->Req.Create.GrantedAccess;
} }
return Result; return Result;
@ -263,6 +271,7 @@ NTSTATUS FspFileSystemOverwriteCheck(FSP_FILE_SYSTEM *FileSystem,
if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED)) if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED))
*PGrantedAccess &= ~(DELETE | FILE_WRITE_DATA) | *PGrantedAccess &= ~(DELETE | FILE_WRITE_DATA) |
(Request->Req.Create.DesiredAccess & (DELETE | FILE_WRITE_DATA)); (Request->Req.Create.DesiredAccess & (DELETE | FILE_WRITE_DATA));
*PGrantedAccess |= Request->Req.Create.GrantedAccess;
} }
return Result; return Result;
@ -286,7 +295,7 @@ NTSTATUS FspFileSystemOpenTargetDirectoryCheck(FSP_FILE_SYSTEM *FileSystem,
if (STATUS_REPARSE == Result) if (STATUS_REPARSE == Result)
Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess); Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess);
else if (NT_SUCCESS(Result)) else if (NT_SUCCESS(Result))
*PGrantedAccess = GrantedAccess; *PGrantedAccess = GrantedAccess | Request->Req.Create.GrantedAccess;
return Result; return Result;
} }

View File

@ -193,7 +193,9 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
if (Request->Req.Create.UserMode && 0 < SecurityDescriptorSize) if (Request->Req.Create.UserMode && 0 < SecurityDescriptorSize)
{ {
if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess, if (0 == DesiredAccess)
Result = STATUS_SUCCESS;
else if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess,
&FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, PGrantedAccess, &AccessStatus)) &FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, PGrantedAccess, &AccessStatus))
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED; Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
else else

View File

@ -163,7 +163,8 @@ static NTSTATUS FspFsvolCreateNoLock(
ULONG SecurityDescriptorSize = 0; ULONG SecurityDescriptorSize = 0;
UINT64 AllocationSize = Irp->Overlay.AllocationSize.QuadPart; UINT64 AllocationSize = Irp->Overlay.AllocationSize.QuadPart;
UINT64 AllocationUnit; UINT64 AllocationUnit;
ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; ACCESS_MASK DesiredAccess = AccessState->RemainingDesiredAccess;
ACCESS_MASK GrantedAccess = AccessState->PreviouslyGrantedAccess;
USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess;
PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer;
//ULONG EaLength = IrpSp->Parameters.Create.EaLength; //ULONG EaLength = IrpSp->Parameters.Create.EaLength;
@ -176,6 +177,10 @@ static NTSTATUS FspFsvolCreateNoLock(
CaseSensitiveRequested || FsvolDeviceExtension->VolumeParams.CaseSensitiveSearch; CaseSensitiveRequested || FsvolDeviceExtension->VolumeParams.CaseSensitiveSearch;
BOOLEAN HasTraversePrivilege = BOOLEAN HasTraversePrivilege =
BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE); BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE);
BOOLEAN HasBackupPrivilege =
BooleanFlagOn(AccessState->Flags, TOKEN_HAS_BACKUP_PRIVILEGE);
BOOLEAN HasRestorePrivilege =
BooleanFlagOn(AccessState->Flags, TOKEN_HAS_RESTORE_PRIVILEGE);
FSP_FILE_NODE *FileNode, *RelatedFileNode; FSP_FILE_NODE *FileNode, *RelatedFileNode;
FSP_FILE_DESC *FileDesc; FSP_FILE_DESC *FileDesc;
UNICODE_STRING MainFileName = { 0 }, StreamPart = { 0 }; UNICODE_STRING MainFileName = { 0 }, StreamPart = { 0 };
@ -453,6 +458,7 @@ static NTSTATUS FspFsvolCreateNoLock(
FileDesc->FileNode = FileNode; FileDesc->FileNode = FileNode;
FileDesc->CaseSensitive = CaseSensitive; FileDesc->CaseSensitive = CaseSensitive;
FileDesc->HasTraversePrivilege = HasTraversePrivilege; FileDesc->HasTraversePrivilege = HasTraversePrivilege;
if (!MainFileOpen) if (!MainFileOpen)
{ {
FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, Request); FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, Request);
@ -470,11 +476,14 @@ static NTSTATUS FspFsvolCreateNoLock(
Request->Req.Create.AllocationSize = AllocationSize; Request->Req.Create.AllocationSize = AllocationSize;
Request->Req.Create.AccessToken = 0; Request->Req.Create.AccessToken = 0;
Request->Req.Create.DesiredAccess = DesiredAccess; Request->Req.Create.DesiredAccess = DesiredAccess;
Request->Req.Create.GrantedAccess = GrantedAccess;
Request->Req.Create.ShareAccess = ShareAccess; Request->Req.Create.ShareAccess = ShareAccess;
Request->Req.Create.Ea.Offset = 0; Request->Req.Create.Ea.Offset = 0;
Request->Req.Create.Ea.Size = 0; Request->Req.Create.Ea.Size = 0;
Request->Req.Create.UserMode = UserMode == RequestorMode; Request->Req.Create.UserMode = UserMode == RequestorMode;
Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege; Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege;
Request->Req.Create.HasBackupPrivilege = HasBackupPrivilege;
Request->Req.Create.HasRestorePrivilege = HasRestorePrivilege;
Request->Req.Create.OpenTargetDirectory = BooleanFlagOn(Flags, SL_OPEN_TARGET_DIRECTORY); Request->Req.Create.OpenTargetDirectory = BooleanFlagOn(Flags, SL_OPEN_TARGET_DIRECTORY);
Request->Req.Create.CaseSensitive = CaseSensitiveRequested; Request->Req.Create.CaseSensitive = CaseSensitiveRequested;
Request->Req.Create.NamedStream = MainFileName.Length; Request->Req.Create.NamedStream = MainFileName.Length;
@ -600,6 +609,7 @@ NTSTATUS FspFsvolCreateComplete(
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject; PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState;
PFILE_OBJECT FileObject = IrpSp->FileObject; PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
FSP_FILE_DESC *FileDesc = FspIopRequestContext(Request, RequestFileDesc); FSP_FILE_DESC *FileDesc = FspIopRequestContext(Request, RequestFileDesc);
@ -817,6 +827,10 @@ NTSTATUS FspFsvolCreateComplete(
FileDesc->FileNode = FileNode = OpenedFileNode; FileDesc->FileNode = FileNode = OpenedFileNode;
} }
/* set up the AccessState */
AccessState->RemainingDesiredAccess = 0;
AccessState->PreviouslyGrantedAccess = Response->Rsp.Create.Opened.GrantedAccess;
/* set up the FileObject */ /* set up the FileObject */
if (0 != FsvolDeviceExtension->FsvrtDeviceObject) if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
#pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb") #pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb")
@ -1161,7 +1175,7 @@ NTSTATUS FspCreate(
"Ea=%p, EaLength=%ld", "Ea=%p, EaLength=%ld",
IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName, IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName,
IrpSp->Flags, IrpSp->Flags,
IrpSp->Parameters.Create.SecurityContext->DesiredAccess, IrpSp->Parameters.Create.SecurityContext->AccessState->OriginalDesiredAccess,
IrpSp->Parameters.Create.ShareAccess, IrpSp->Parameters.Create.ShareAccess,
IrpSp->Parameters.Create.Options, IrpSp->Parameters.Create.Options,
IrpSp->Parameters.Create.FileAttributes, IrpSp->Parameters.Create.FileAttributes,