ReactOS 0.4.16-dev-336-gb667d82
acchksup.c File Reference
#include "fatprocs.h"
Include dependency graph for acchksup.c:

Go to the source code of this file.

Macros

#define Dbg   (DEBUG_TRACE_ACCHKSUP)
 

Functions

NTSTATUS FatCreateRestrictEveryoneToken (IN PACCESS_TOKEN Token, OUT PACCESS_TOKEN *RestrictedToken)
 
BOOLEAN FatCheckFileAccess (PIRP_CONTEXT IrpContext, IN UCHAR DirentAttributes, IN PACCESS_MASK DesiredAccess)
 
BOOLEAN FatCheckManageVolumeAccess (_In_ PIRP_CONTEXT IrpContext, _In_ PACCESS_STATE AccessState, _In_ KPROCESSOR_MODE ProcessorMode)
 
NTSTATUS FatExplicitDeviceAccessGranted (IN PIRP_CONTEXT IrpContext, IN PDEVICE_OBJECT DeviceObject, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE ProcessorMode)
 

Macro Definition Documentation

◆ Dbg

#define Dbg   (DEBUG_TRACE_ACCHKSUP)

Definition at line 22 of file acchksup.c.

Function Documentation

◆ FatCheckFileAccess()

BOOLEAN FatCheckFileAccess ( PIRP_CONTEXT  IrpContext,
IN UCHAR  DirentAttributes,
IN PACCESS_MASK  DesiredAccess 
)

Definition at line 39 of file acchksup.c.

64{
66
67 DebugTrace(+1, Dbg, "FatCheckFileAccess\n", 0);
68 DebugTrace( 0, Dbg, "DirentAttributes = %8lx\n", DirentAttributes);
69 DebugTrace( 0, Dbg, "DesiredAccess = %8lx\n", *DesiredAccess);
70
71 PAGED_CODE();
72
73 //
74 // This procedures is programmed like a string of filters each
75 // filter checks to see if some access is allowed, if it is not allowed
76 // the filter return FALSE to the user without further checks otherwise
77 // it moves on to the next filter. The filter check is to check for
78 // desired access flags that are not allowed for a particular dirent
79 //
80
81 Result = TRUE;
82
83 _SEH2_TRY {
84
85 //
86 // Check for Volume ID or Device Dirents, these are not allowed user
87 // access at all
88 //
89
90 if (FlagOn(DirentAttributes, FAT_DIRENT_ATTR_VOLUME_ID) ||
91 FlagOn(DirentAttributes, FAT_DIRENT_ATTR_DEVICE)) {
92
93 DebugTrace(0, Dbg, "Cannot access volume id or device\n", 0);
94
96 }
97
98 //
99 // Check the desired access for the object - we only blackball that
100 // we do not understand. The model of filesystems using ACLs is that
101 // they do not type the ACL to the object the ACL is on. Permissions
102 // are not checked for consistency vs. the object type - dir/file.
103 //
104
105 if (FlagOn(*DesiredAccess, ~(DELETE |
108 WRITE_DAC |
120 MAXIMUM_ALLOWED))) {
121
122 DebugTrace(0, Dbg, "Cannot open object\n", 0);
123
125 }
126
127 //
128 // Check for a read-only Dirent
129 //
130
131 if (FlagOn(DirentAttributes, FAT_DIRENT_ATTR_READ_ONLY)) {
132
133 //
134 // Check the desired access for a read-only dirent. AccessMask will contain
135 // the flags we're going to allow.
136 //
137
143
144 //
145 // If this is a subdirectory also allow add file/directory and delete.
146 //
147
148 if (FlagOn(DirentAttributes, FAT_DIRENT_ATTR_DIRECTORY)) {
149
151 }
152
154
155 DebugTrace(0, Dbg, "Cannot open readonly\n", 0);
156
158 }
159 }
160
161 try_exit: NOTHING;
162 } _SEH2_FINALLY {
163
165
166 DebugTrace(-1, Dbg, "FatCheckFileAccess -> %08lx\n", Result);
167 } _SEH2_END;
168
169 UNREFERENCED_PARAMETER( IrpContext );
170
171 return Result;
172}
#define PAGED_CODE()
unsigned char BOOLEAN
BOOLEAN FatCheckFileAccess(PIRP_CONTEXT IrpContext, IN UCHAR DirentAttributes, IN PACCESS_MASK DesiredAccess)
Definition: acchksup.c:39
#define Dbg
Definition: acchksup.c:22
#define try_return(S)
Definition: cdprocs.h:2179
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define FAT_DIRENT_ATTR_READ_ONLY
Definition: fat.h:368
#define FAT_DIRENT_ATTR_VOLUME_ID
Definition: fat.h:371
#define FAT_DIRENT_ATTR_DIRECTORY
Definition: fat.h:372
#define FAT_DIRENT_ATTR_DEVICE
Definition: fat.h:374
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define DebugUnwind(X)
Definition: fatdata.h:315
#define NOTHING
Definition: input_list.c:10
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define WRITE_DAC
Definition: nt_native.h:59
#define FILE_READ_DATA
Definition: nt_native.h:628
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define FILE_DELETE_CHILD
Definition: nt_native.h:645
#define FILE_READ_EA
Definition: nt_native.h:638
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_TRAVERSE
Definition: nt_native.h:643
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define DELETE
Definition: nt_native.h:57
#define READ_CONTROL
Definition: nt_native.h:58
#define WRITE_OWNER
Definition: nt_native.h:60
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define FILE_WRITE_EA
Definition: nt_native.h:640
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by FatCheckFileAccess().

◆ FatCheckManageVolumeAccess()

BOOLEAN FatCheckManageVolumeAccess ( _In_ PIRP_CONTEXT  IrpContext,
_In_ PACCESS_STATE  AccessState,
_In_ KPROCESSOR_MODE  ProcessorMode 
)

Definition at line 176 of file acchksup.c.

201{
202 PRIVILEGE_SET PrivilegeSet;
203
204 PAGED_CODE();
205
206 PrivilegeSet.PrivilegeCount = 1;
208 PrivilegeSet.Privilege[0].Luid = RtlConvertLongToLuid( SE_MANAGE_VOLUME_PRIVILEGE );
209 PrivilegeSet.Privilege[0].Attributes = 0;
210
211 if (SePrivilegeCheck( &PrivilegeSet,
212 &AccessState->SubjectSecurityContext,
213 ProcessorMode )) {
214
215 return TRUE;
216 }
217
218 UNREFERENCED_PARAMETER( IrpContext );
219
220 return FALSE;
221}
#define SE_MANAGE_VOLUME_PRIVILEGE
Definition: security.c:682
BOOLEAN NTAPI SePrivilegeCheck(_In_ PPRIVILEGE_SET Privileges, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a set of privileges exist and match within a security subject context.
Definition: priv.c:698
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88
$ULONG Control
Definition: setypes.h:87
$ULONG PrivilegeCount
Definition: setypes.h:86
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83

Referenced by FatExplicitDeviceAccessGranted().

◆ FatCreateRestrictEveryoneToken()

NTSTATUS FatCreateRestrictEveryoneToken ( IN PACCESS_TOKEN  Token,
OUT PACCESS_TOKEN RestrictedToken 
)

Definition at line 359 of file acchksup.c.

385{
386 //
387 // Array of sids to disable.
388 //
389
390 TOKEN_GROUPS SidsToDisable;
391
393
394 PAGED_CODE();
395
396 //
397 // Restricted token will contain the original sids with one change:
398 // If Everyone sid is present in the token, it will be marked for DenyOnly.
399 //
400
401 *RestrictedToken = NULL;
402
403 //
404 // Put Everyone sid in the array of sids to disable. This will mark it
405 // for SE_GROUP_USE_FOR_DENY_ONLY and it'll only be applicable for Deny aces.
406 //
407
408 SidsToDisable.GroupCount = 1;
409 SidsToDisable.Groups[0].Attributes = 0;
410 SidsToDisable.Groups[0].Sid = SeExports->SeWorldSid;
411
413 Token, // Token that needs to be restricted.
414 0, // No flags
415 &SidsToDisable, // Disable everyone sid
416 NULL, // Do not create any restricted sids
417 NULL, // Do not delete any privileges
418 RestrictedToken // Restricted token
419 );
420
421 return Status;
422}
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
Status
Definition: gdiplustypes.h:25
PSE_EXPORTS SeExports
Definition: semgr.c:21
#define STATUS_SUCCESS
Definition: shellext.h:65
PSID SeWorldSid
Definition: setypes.h:1219
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]
Definition: setypes.h:1018
$ULONG GroupCount
Definition: setypes.h:1014
NTSTATUS NTAPI SeFilterToken(_In_ PACCESS_TOKEN ExistingToken, _In_ ULONG Flags, _In_opt_ PTOKEN_GROUPS SidsToDisable, _In_opt_ PTOKEN_PRIVILEGES PrivilegesToDelete, _In_opt_ PTOKEN_GROUPS RestrictedSids, _Out_ PACCESS_TOKEN *FilteredToken)
Filters an access token from an existing token, making it more restricted than the previous one.
Definition: tokenlif.c:1438

Referenced by FatExplicitDeviceAccessGranted().

◆ FatExplicitDeviceAccessGranted()

NTSTATUS FatExplicitDeviceAccessGranted ( IN PIRP_CONTEXT  IrpContext,
IN PDEVICE_OBJECT  DeviceObject,
IN PACCESS_STATE  AccessState,
IN KPROCESSOR_MODE  ProcessorMode 
)

Definition at line 225 of file acchksup.c.

255{
257
258 PACCESS_TOKEN OriginalAccessToken;
259 PACCESS_TOKEN RestrictedAccessToken;
260
261 PACCESS_TOKEN *EffectiveToken;
262
264
265 PAGED_CODE();
266
267 UNREFERENCED_PARAMETER( IrpContext );
268
269 //
270 // If the access state indicates that specific access other
271 // than traverse was acquired, either Everyone does have such
272 // access or explicit access was granted. In both cases, we're
273 // happy to let this proceed.
274 //
275
276 if (AccessState->PreviouslyGrantedAccess & (SPECIFIC_RIGHTS_ALL ^
277 FILE_TRAVERSE)) {
278
279 return STATUS_SUCCESS;
280 }
281
282 //
283 // If the manage volume privilege is held, this also permits access.
284 //
285
286 if (FatCheckManageVolumeAccess( IrpContext,
288 ProcessorMode )) {
289
290 return STATUS_SUCCESS;
291 }
292
293 //
294 // Capture the subject context as a prelude to everything below.
295 //
296
297 SeLockSubjectContext( &AccessState->SubjectSecurityContext );
298
299 //
300 // Convert the token in the subject context into one which does not
301 // acquire access through the Everyone SID.
302 //
303 // The logic for deciding which token is effective comes from
304 // SeQuerySubjectContextToken; since there is no natural way
305 // of getting a pointer to it, do it by hand.
306 //
307
308 if (ARGUMENT_PRESENT( AccessState->SubjectSecurityContext.ClientToken )) {
309 EffectiveToken = &AccessState->SubjectSecurityContext.ClientToken;
310 } else {
311 EffectiveToken = &AccessState->SubjectSecurityContext.PrimaryToken;
312 }
313
314 OriginalAccessToken = *EffectiveToken;
315 Status = FatCreateRestrictEveryoneToken( OriginalAccessToken, &RestrictedAccessToken );
316
317 if (!NT_SUCCESS(Status)) {
318
319 SeReleaseSubjectContext( &AccessState->SubjectSecurityContext );
320 return Status;
321 }
322
323 //
324 // Now see if the resulting context has access to the device through
325 // its explicitly granted access. We swap in our restricted token
326 // for this check as the effective client token.
327 //
328
329 *EffectiveToken = RestrictedAccessToken;
330
331#ifdef _MSC_VER
332#pragma prefast( suppress: 28175, "we're a file system, this is ok to touch" )
333#endif
334 SeAccessCheck( DeviceObject->SecurityDescriptor,
335 &AccessState->SubjectSecurityContext,
336 FALSE,
337 AccessState->OriginalDesiredAccess,
338 0,
339 NULL,
341 ProcessorMode,
343 &Status );
344
345 *EffectiveToken = OriginalAccessToken;
346
347 //
348 // Cleanup and return.
349 //
350
351 SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );
352 ObDereferenceObject( RestrictedAccessToken );
353
354 return Status;
355}
BOOLEAN NTAPI SeAccessCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, _In_ BOOLEAN SubjectContextLocked, _In_ ACCESS_MASK DesiredAccess, _In_ ACCESS_MASK PreviouslyGrantedAccess, _Out_ PPRIVILEGE_SET *Privileges, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:1994
NTSTATUS FatCreateRestrictEveryoneToken(IN PACCESS_TOKEN Token, OUT PACCESS_TOKEN *RestrictedToken)
Definition: acchksup.c:359
BOOLEAN FatCheckManageVolumeAccess(_In_ PIRP_CONTEXT IrpContext, _In_ PACCESS_STATE AccessState, _In_ KPROCESSOR_MODE ProcessorMode)
Definition: acchksup.c:176
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define SPECIFIC_RIGHTS_ALL
Definition: nt_native.h:71
#define ARGUMENT_PRESENT(ArgumentPointer)
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3267
VOID NTAPI SeLockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Locks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:107
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: subject.c:171
VOID NTAPI SeUnlockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Unlocks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:138
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:20