ReactOS 0.4.15-dev-8207-gd73a838
acchksup.c
Go to the documentation of this file.
1/*++
2
3Copyright (c) 1989-2000 Microsoft Corporation
4
5Module Name:
6
7 AcChkSup.c
8
9Abstract:
10
11 This module implements the FAT access checking routine
12
13
14--*/
15
16#include "fatprocs.h"
17
18//
19// Our debug trace level
20//
21
22#define Dbg (DEBUG_TRACE_ACCHKSUP)
23
27 OUT PACCESS_TOKEN *RestrictedToken
28 );
29
30#ifdef ALLOC_PRAGMA
31#pragma alloc_text(PAGE, FatCheckFileAccess)
32#pragma alloc_text(PAGE, FatCheckManageVolumeAccess)
33#pragma alloc_text(PAGE, FatCreateRestrictEveryoneToken)
34#pragma alloc_text(PAGE, FatExplicitDeviceAccessGranted)
35#endif
36
37
40 PIRP_CONTEXT IrpContext,
41 IN UCHAR DirentAttributes,
43 )
44
45/*++
46
47Routine Description:
48
49 This routine checks if a desired access is allowed to a file represented
50 by the specified DirentAttriubutes.
51
52Arguments:
53
54 DirentAttributes - Supplies the Dirent attributes to check access for
55
56 DesiredAccess - Supplies the desired access mask that we are checking for
57
58Return Value:
59
60 BOOLEAN - TRUE if access is allowed and FALSE otherwise
61
62--*/
63
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}
173
174
177 _In_ PIRP_CONTEXT IrpContext,
179 _In_ KPROCESSOR_MODE ProcessorMode
180 )
181
182/*++
183
184Routine Description:
185
186 This function checks whether the SID described in the input access state has
187 manage volume privilege.
188
189Arguments:
190
191 AccessState - the access state describing the security context to be checked
192
193 ProcessorMode - the mode this check should occur against
194
195Return Value:
196
197 BOOLEAN - TRUE if privilege is held and FALSE otherwise
198
199--*/
200
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}
222
223
226 IN PIRP_CONTEXT IrpContext,
229 IN KPROCESSOR_MODE ProcessorMode
230 )
231
232/*++
233
234Routine Description:
235
236 This function asks whether the SID described in the input access state has
237 been granted any explicit access to the given device object. It does this
238 by acquiring a token stripped of its ability to acquire access via the
239 Everyone SID and re-doing the access check.
240
241Arguments:
242
243 DeviceObject - the device whose ACL will be checked
244
245 AccessState - the access state describing the security context to be checked
246
247 ProcessorMode - the mode this check should occur against
248
249Return Value:
250
251 NTSTATUS - Indicating whether explicit access was granted.
252
253--*/
254
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}
356
357
361 OUT PACCESS_TOKEN *RestrictedToken
362 )
363
364/*++
365
366Routine Description:
367
368 This function takes a token as the input and returns a new restricted token
369 from which Everyone sid has been disabled. The resulting token may be used
370 to find out if access is available to a user-sid by explicit means.
371
372Arguments:
373
374 Token - Input token from which Everyone sid needs to be deactivated.
375
376 RestrictedToken - Receives the the new restricted token.
377 This must be released using ObDereferenceObject(*RestrictedToken);
378
379Return Value:
380
381 NTSTATUS - Returned by SeFilterToken.
382
383--*/
384
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}
423
#define PAGED_CODE()
unsigned char BOOLEAN
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 FatCheckFileAccess(PIRP_CONTEXT IrpContext, IN UCHAR DirentAttributes, IN PACCESS_MASK DesiredAccess)
Definition: acchksup.c:39
NTSTATUS FatExplicitDeviceAccessGranted(IN PIRP_CONTEXT IrpContext, IN PDEVICE_OBJECT DeviceObject, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE ProcessorMode)
Definition: acchksup.c:225
#define Dbg
Definition: acchksup.c:22
BOOLEAN FatCheckManageVolumeAccess(_In_ PIRP_CONTEXT IrpContext, _In_ PACCESS_STATE AccessState, _In_ KPROCESSOR_MODE ProcessorMode)
Definition: acchksup.c:176
LONG NTSTATUS
Definition: precomp.h:26
#define try_return(S)
Definition: cdprocs.h:2179
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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 _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
#define NOTHING
Definition: input_list.c:10
#define SE_MANAGE_VOLUME_PRIVILEGE
Definition: security.c:682
#define _In_
Definition: ms_sal.h:308
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
#define SPECIFIC_RIGHTS_ALL
Definition: nt_native.h:71
#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
ACCESS_MASK * PACCESS_MASK
Definition: nt_native.h:41
#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:317
#define ARGUMENT_PRESENT(ArgumentPointer)
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3267
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
PSE_EXPORTS SeExports
Definition: semgr.c:21
#define STATUS_SUCCESS
Definition: shellext.h:65
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88
$ULONG Control
Definition: setypes.h:87
$ULONG PrivilegeCount
Definition: setypes.h:86
PSID SeWorldSid
Definition: setypes.h:1219
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]
Definition: setypes.h:1018
$ULONG GroupCount
Definition: setypes.h:1014
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
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
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_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
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417
_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
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
unsigned char UCHAR
Definition: xmlstorage.h:181