1c2c66affSColin Finck ////////////////////////////////////////////////////////////////////
2c2c66affSColin Finck // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3c2c66affSColin Finck // All rights reserved
4c2c66affSColin Finck // This file was released under the GPLv2 on June 2015.
5c2c66affSColin Finck ////////////////////////////////////////////////////////////////////
6c2c66affSColin Finck /*************************************************************************
7c2c66affSColin Finck *
8c2c66affSColin Finck * File: SecurSup.cpp
9c2c66affSColin Finck *
10c2c66affSColin Finck * Module: UDF File System Driver (Kernel mode execution only)
11c2c66affSColin Finck *
12c2c66affSColin Finck * Description:
13c2c66affSColin Finck *   Contains code to handle the "Get/Set Security" dispatch entry points.
14c2c66affSColin Finck *
15c2c66affSColin Finck *************************************************************************/
16c2c66affSColin Finck 
17c2c66affSColin Finck #include            "udffs.h"
18c2c66affSColin Finck 
19c2c66affSColin Finck // define the file specific bug-check id
20c2c66affSColin Finck #define         UDF_BUG_CHECK_ID                UDF_FILE_SECURITY
21c2c66affSColin Finck 
22c2c66affSColin Finck #ifdef UDF_ENABLE_SECURITY
23c2c66affSColin Finck 
24c2c66affSColin Finck NTSTATUS UDFConvertToSelfRelative(
25c2c66affSColin Finck     IN OUT PSECURITY_DESCRIPTOR* SecurityDesc);
26c2c66affSColin Finck 
27c2c66affSColin Finck /*UCHAR FullControlSD[] = {
28c2c66affSColin Finck 0x01, 0x00, 0x04, 0x80, 0x4c, 0x00, 0x00, 0x00,
29c2c66affSColin Finck 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30c2c66affSColin Finck 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x38, 0x00,
31c2c66affSColin Finck 0x02, 0x00, 0x00, 0x00, 0x00, 0x09, 0x18, 0x00,
32c2c66affSColin Finck 0x00, 0x00, 0x00, 0x10, 0x01, 0x01, 0x00, 0x00,
33c2c66affSColin Finck 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
34c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00,
35c2c66affSColin Finck 0xff, 0x01, 0x1f, 0x00, 0x01, 0x01, 0x00, 0x00,
36c2c66affSColin Finck 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
37c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
38c2c66affSColin Finck 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
39c2c66affSColin Finck 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
40c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00
41c2c66affSColin Finck };*/
42c2c66affSColin Finck 
43c2c66affSColin Finck /*************************************************************************
44c2c66affSColin Finck *
45c2c66affSColin Finck * Function: UDFGetSecurity()
46c2c66affSColin Finck *
47c2c66affSColin Finck * Description:
48c2c66affSColin Finck *
49c2c66affSColin Finck * Expected Interrupt Level (for execution) :
50c2c66affSColin Finck *
51c2c66affSColin Finck *  IRQL_PASSIVE_LEVEL
52c2c66affSColin Finck *
53c2c66affSColin Finck * Return Value: Irrelevant.
54c2c66affSColin Finck *
55c2c66affSColin Finck *************************************************************************/
56c2c66affSColin Finck NTSTATUS
UDFGetSecurity(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)57c2c66affSColin Finck UDFGetSecurity(
58c2c66affSColin Finck     IN PDEVICE_OBJECT DeviceObject,       // the logical volume device object
59c2c66affSColin Finck     IN PIRP           Irp)                // I/O Request Packet
60c2c66affSColin Finck {
61c2c66affSColin Finck     NTSTATUS            RC = STATUS_SUCCESS;
62c2c66affSColin Finck     PtrUDFIrpContext    PtrIrpContext = NULL;
63c2c66affSColin Finck     BOOLEAN             AreWeTopLevel = FALSE;
64c2c66affSColin Finck 
65c2c66affSColin Finck     UDFPrint(("UDFGetSecurity\n"));
66c2c66affSColin Finck //    BrutePoint();
67c2c66affSColin Finck 
68c2c66affSColin Finck     FsRtlEnterFileSystem();
69c2c66affSColin Finck     ASSERT(DeviceObject);
70c2c66affSColin Finck     ASSERT(Irp);
71c2c66affSColin Finck 
72c2c66affSColin Finck     // set the top level context
73c2c66affSColin Finck     AreWeTopLevel = UDFIsIrpTopLevel(Irp);
74c2c66affSColin Finck     ASSERT(!UDFIsFSDevObj(DeviceObject));
75c2c66affSColin Finck     //  Call the common Lock Control routine, with blocking allowed if
76c2c66affSColin Finck     //  synchronous
77c2c66affSColin Finck     _SEH2_TRY {
78c2c66affSColin Finck 
79c2c66affSColin Finck         // get an IRP context structure and issue the request
80c2c66affSColin Finck         PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
81c2c66affSColin Finck         if(PtrIrpContext) {
82c2c66affSColin Finck             RC = UDFCommonGetSecurity(PtrIrpContext, Irp);
83c2c66affSColin Finck         } else {
84c2c66affSColin Finck             RC = STATUS_INSUFFICIENT_RESOURCES;
85c2c66affSColin Finck             Irp->IoStatus.Status = RC;
86c2c66affSColin Finck             Irp->IoStatus.Information = 0;
87c2c66affSColin Finck             // complete the IRP
88c2c66affSColin Finck             IoCompleteRequest(Irp, IO_DISK_INCREMENT);
89c2c66affSColin Finck         }
90c2c66affSColin Finck 
91c2c66affSColin Finck     } __except (UDFExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
92c2c66affSColin Finck 
93c2c66affSColin Finck         RC = UDFExceptionHandler(PtrIrpContext, Irp);
94c2c66affSColin Finck 
95c2c66affSColin Finck         UDFLogEvent(UDF_ERROR_INTERNAL_ERROR, RC);
96c2c66affSColin Finck     }
97c2c66affSColin Finck 
98c2c66affSColin Finck     if (AreWeTopLevel) {
99c2c66affSColin Finck         IoSetTopLevelIrp(NULL);
100c2c66affSColin Finck     }
101c2c66affSColin Finck 
102c2c66affSColin Finck     FsRtlExitFileSystem();
103c2c66affSColin Finck 
104c2c66affSColin Finck     return(RC);
105c2c66affSColin Finck } // end UDFGetSecurity()
106c2c66affSColin Finck 
107c2c66affSColin Finck 
108c2c66affSColin Finck /*************************************************************************
109c2c66affSColin Finck *
110c2c66affSColin Finck * Function: UDFCommonGetSecurity()
111c2c66affSColin Finck *
112c2c66affSColin Finck * Description:
113c2c66affSColin Finck *  This is the common routine for getting Security (ACL) called
114c2c66affSColin Finck *  by both the fsd and fsp threads
115c2c66affSColin Finck *
116c2c66affSColin Finck * Expected Interrupt Level (for execution) :
117c2c66affSColin Finck *
118c2c66affSColin Finck *  IRQL_PASSIVE_LEVEL
119c2c66affSColin Finck *
120c2c66affSColin Finck * Return Value: Irrelevant
121c2c66affSColin Finck *
122c2c66affSColin Finck *************************************************************************/
123c2c66affSColin Finck NTSTATUS
UDFCommonGetSecurity(IN PtrUDFIrpContext PtrIrpContext,IN PIRP Irp)124c2c66affSColin Finck UDFCommonGetSecurity(
125c2c66affSColin Finck     IN PtrUDFIrpContext PtrIrpContext,
126c2c66affSColin Finck     IN PIRP             Irp)
127c2c66affSColin Finck {
128c2c66affSColin Finck     NTSTATUS            RC = STATUS_SUCCESS;
129c2c66affSColin Finck     PIO_STACK_LOCATION  IrpSp = NULL;
130c2c66affSColin Finck     BOOLEAN             PostRequest = FALSE;
131c2c66affSColin Finck     BOOLEAN             CanWait = FALSE;
132c2c66affSColin Finck     PtrUDFNTRequiredFCB NtReqFcb = NULL;
133c2c66affSColin Finck     BOOLEAN             AcquiredFCB = FALSE;
134c2c66affSColin Finck     PFILE_OBJECT        FileObject = NULL;
135c2c66affSColin Finck     PtrUDFFCB           Fcb = NULL;
136c2c66affSColin Finck     PtrUDFCCB           Ccb = NULL;
137c2c66affSColin Finck     PVOID               PtrSystemBuffer = NULL;
138c2c66affSColin Finck     ULONG               BufferLength = 0;
139c2c66affSColin Finck 
140c2c66affSColin Finck     UDFPrint(("UDFCommonGetSecurity\n"));
141c2c66affSColin Finck 
142c2c66affSColin Finck     _SEH2_TRY {
143c2c66affSColin Finck 
144c2c66affSColin Finck         // First, get a pointer to the current I/O stack location.
145c2c66affSColin Finck         IrpSp = IoGetCurrentIrpStackLocation(Irp);
146c2c66affSColin Finck         ASSERT(IrpSp);
147c2c66affSColin Finck 
148c2c66affSColin Finck         FileObject = IrpSp->FileObject;
149c2c66affSColin Finck         ASSERT(FileObject);
150c2c66affSColin Finck 
151c2c66affSColin Finck         // Get the FCB and CCB pointers.
152c2c66affSColin Finck         Ccb = (PtrUDFCCB)(FileObject->FsContext2);
153c2c66affSColin Finck         ASSERT(Ccb);
154c2c66affSColin Finck         Fcb = Ccb->Fcb;
155c2c66affSColin Finck         ASSERT(Fcb);
156c2c66affSColin Finck 
157c2c66affSColin Finck /*        if(!Fcb->Vcb->ReadSecurity)
158c2c66affSColin Finck             try_return(RC = STATUS_NOT_IMPLEMENTED);*/
159c2c66affSColin Finck 
160c2c66affSColin Finck         NtReqFcb = Fcb->NTRequiredFCB;
161c2c66affSColin Finck         CanWait = ((PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE);
162c2c66affSColin Finck 
163c2c66affSColin Finck         // Acquire the FCB resource shared
164c2c66affSColin Finck         UDF_CHECK_PAGING_IO_RESOURCE(NtReqFcb);
165c2c66affSColin Finck         if (!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
166c2c66affSColin Finck //        if (!UDFAcquireResourceShared(&(NtReqFcb->MainResource), CanWait)) {
167c2c66affSColin Finck             PostRequest = TRUE;
168c2c66affSColin Finck             try_return(RC = STATUS_PENDING);
169c2c66affSColin Finck         }
170c2c66affSColin Finck         AcquiredFCB = TRUE;
171c2c66affSColin Finck 
172c2c66affSColin Finck         PtrSystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
173c2c66affSColin Finck         if(!PtrSystemBuffer)
174c2c66affSColin Finck             try_return(RC = STATUS_INVALID_USER_BUFFER);
175c2c66affSColin Finck         BufferLength = IrpSp->Parameters.QuerySecurity.Length;
176c2c66affSColin Finck 
177c2c66affSColin Finck         if(!NtReqFcb->SecurityDesc) {
178c2c66affSColin Finck             RC = UDFAssignAcl(Fcb->Vcb, FileObject, Fcb, NtReqFcb);
179c2c66affSColin Finck             if(!NT_SUCCESS(RC))
180c2c66affSColin Finck                 try_return(RC);
181c2c66affSColin Finck         }
182c2c66affSColin Finck 
183c2c66affSColin Finck         _SEH2_TRY {
184c2c66affSColin Finck             RC = SeQuerySecurityDescriptorInfo(&(IrpSp->Parameters.QuerySecurity.SecurityInformation),
185c2c66affSColin Finck                                           (PSECURITY_DESCRIPTOR)PtrSystemBuffer,
186c2c66affSColin Finck                                           &BufferLength,
187c2c66affSColin Finck                                           &(NtReqFcb->SecurityDesc) );
188c2c66affSColin Finck         } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
189c2c66affSColin Finck             RC = STATUS_BUFFER_TOO_SMALL;
190c2c66affSColin Finck         }
191c2c66affSColin Finck 
192c2c66affSColin Finck try_exit: NOTHING;
193c2c66affSColin Finck 
194c2c66affSColin Finck     } _SEH2_FINALLY {
195c2c66affSColin Finck 
196c2c66affSColin Finck         // Release the FCB resources if acquired.
197c2c66affSColin Finck         if (AcquiredFCB) {
198c2c66affSColin Finck             UDF_CHECK_PAGING_IO_RESOURCE(NtReqFcb);
199c2c66affSColin Finck             UDFReleaseResource(&(NtReqFcb->MainResource));
200c2c66affSColin Finck             AcquiredFCB = FALSE;
201c2c66affSColin Finck         }
202c2c66affSColin Finck 
203c2c66affSColin Finck         if (PostRequest) {
204c2c66affSColin Finck             // Perform appropriate post related processing here
205c2c66affSColin Finck             RC = UDFPostRequest(PtrIrpContext, Irp);
206c2c66affSColin Finck         } else
207c2c66affSColin Finck         if(!AbnormalTermination()) {
208c2c66affSColin Finck             Irp->IoStatus.Status = RC;
209c2c66affSColin Finck             Irp->IoStatus.Information = BufferLength;
210c2c66affSColin Finck             // Free up the Irp Context
211c2c66affSColin Finck             UDFReleaseIrpContext(PtrIrpContext);
212c2c66affSColin Finck             // complete the IRP
213c2c66affSColin Finck             IoCompleteRequest(Irp, IO_DISK_INCREMENT);
214c2c66affSColin Finck         }
215c2c66affSColin Finck 
216c2c66affSColin Finck     } // end of "__finally" processing
217c2c66affSColin Finck 
218c2c66affSColin Finck     return(RC);
219c2c66affSColin Finck }
220c2c66affSColin Finck 
221c2c66affSColin Finck #ifndef UDF_READ_ONLY_BUILD
222c2c66affSColin Finck /*************************************************************************
223c2c66affSColin Finck *
224c2c66affSColin Finck * Function: UDFSetSecurity()
225c2c66affSColin Finck *
226c2c66affSColin Finck * Description:
227c2c66affSColin Finck *
228c2c66affSColin Finck * Expected Interrupt Level (for execution) :
229c2c66affSColin Finck *
230c2c66affSColin Finck *  IRQL_PASSIVE_LEVEL
231c2c66affSColin Finck *
232c2c66affSColin Finck * Return Value: Irrelevant.
233c2c66affSColin Finck *
234c2c66affSColin Finck *************************************************************************/
235c2c66affSColin Finck NTSTATUS
UDFSetSecurity(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)236c2c66affSColin Finck UDFSetSecurity(
237c2c66affSColin Finck     IN PDEVICE_OBJECT DeviceObject,       // the logical volume device object
238c2c66affSColin Finck     IN PIRP           Irp)                // I/O Request Packet
239c2c66affSColin Finck {
240c2c66affSColin Finck     NTSTATUS            RC = STATUS_SUCCESS;
241c2c66affSColin Finck     PtrUDFIrpContext    PtrIrpContext = NULL;
242c2c66affSColin Finck     BOOLEAN             AreWeTopLevel = FALSE;
243c2c66affSColin Finck 
244c2c66affSColin Finck     UDFPrint(("UDFSetSecurity\n"));
245c2c66affSColin Finck //    BrutePoint();
246c2c66affSColin Finck 
247c2c66affSColin Finck     FsRtlEnterFileSystem();
248c2c66affSColin Finck     ASSERT(DeviceObject);
249c2c66affSColin Finck     ASSERT(Irp);
250c2c66affSColin Finck 
251c2c66affSColin Finck     // set the top level context
252c2c66affSColin Finck     AreWeTopLevel = UDFIsIrpTopLevel(Irp);
253c2c66affSColin Finck     //  Call the common Lock Control routine, with blocking allowed if
254c2c66affSColin Finck     //  synchronous
255c2c66affSColin Finck     _SEH2_TRY {
256c2c66affSColin Finck 
257c2c66affSColin Finck         // get an IRP context structure and issue the request
258c2c66affSColin Finck         PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
259c2c66affSColin Finck         if(PtrIrpContext) {
260c2c66affSColin Finck             RC = UDFCommonSetSecurity(PtrIrpContext, Irp);
261c2c66affSColin Finck         } else {
262c2c66affSColin Finck             RC = STATUS_INSUFFICIENT_RESOURCES;
263c2c66affSColin Finck             Irp->IoStatus.Status = RC;
264c2c66affSColin Finck             Irp->IoStatus.Information = 0;
265c2c66affSColin Finck             // complete the IRP
266c2c66affSColin Finck             IoCompleteRequest(Irp, IO_DISK_INCREMENT);
267c2c66affSColin Finck         }
268c2c66affSColin Finck 
269c2c66affSColin Finck     } __except (UDFExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
270c2c66affSColin Finck 
271c2c66affSColin Finck         RC = UDFExceptionHandler(PtrIrpContext, Irp);
272c2c66affSColin Finck 
273c2c66affSColin Finck         UDFLogEvent(UDF_ERROR_INTERNAL_ERROR, RC);
274c2c66affSColin Finck     }
275c2c66affSColin Finck 
276c2c66affSColin Finck     if (AreWeTopLevel) {
277c2c66affSColin Finck         IoSetTopLevelIrp(NULL);
278c2c66affSColin Finck     }
279c2c66affSColin Finck 
280c2c66affSColin Finck     FsRtlExitFileSystem();
281c2c66affSColin Finck 
282c2c66affSColin Finck     return(RC);
283c2c66affSColin Finck } // end UDFSetSecurity()
284c2c66affSColin Finck 
285c2c66affSColin Finck 
286c2c66affSColin Finck /*************************************************************************
287c2c66affSColin Finck *
288c2c66affSColin Finck * Function: UDFCommonSetSecurity()
289c2c66affSColin Finck *
290c2c66affSColin Finck * Description:
291c2c66affSColin Finck *  This is the common routine for getting Security (ACL) called
292c2c66affSColin Finck *  by both the fsd and fsp threads
293c2c66affSColin Finck *
294c2c66affSColin Finck * Expected Interrupt Level (for execution) :
295c2c66affSColin Finck *
296c2c66affSColin Finck *  IRQL_PASSIVE_LEVEL
297c2c66affSColin Finck *
298c2c66affSColin Finck * Return Value: Irrelevant
299c2c66affSColin Finck *
300c2c66affSColin Finck *************************************************************************/
301c2c66affSColin Finck NTSTATUS
UDFCommonSetSecurity(IN PtrUDFIrpContext PtrIrpContext,IN PIRP Irp)302c2c66affSColin Finck UDFCommonSetSecurity(
303c2c66affSColin Finck     IN PtrUDFIrpContext PtrIrpContext,
304c2c66affSColin Finck     IN PIRP             Irp)
305c2c66affSColin Finck {
306c2c66affSColin Finck     NTSTATUS            RC = STATUS_SUCCESS;
307c2c66affSColin Finck     PIO_STACK_LOCATION  IrpSp = NULL;
308c2c66affSColin Finck     BOOLEAN             PostRequest = FALSE;
309c2c66affSColin Finck     BOOLEAN             CanWait = FALSE;
310c2c66affSColin Finck     PtrUDFNTRequiredFCB NtReqFcb = NULL;
311c2c66affSColin Finck     BOOLEAN             AcquiredFCB = FALSE;
312c2c66affSColin Finck     PFILE_OBJECT        FileObject = NULL;
313c2c66affSColin Finck     PtrUDFFCB           Fcb = NULL;
314c2c66affSColin Finck     PtrUDFCCB           Ccb = NULL;
315c2c66affSColin Finck     ACCESS_MASK         DesiredAccess = 0;
316c2c66affSColin Finck 
317c2c66affSColin Finck     UDFPrint(("UDFCommonSetSecurity\n"));
318c2c66affSColin Finck 
319c2c66affSColin Finck     _SEH2_TRY {
320c2c66affSColin Finck 
321c2c66affSColin Finck         // First, get a pointer to the current I/O stack location.
322c2c66affSColin Finck         IrpSp = IoGetCurrentIrpStackLocation(Irp);
323c2c66affSColin Finck         ASSERT(IrpSp);
324c2c66affSColin Finck 
325c2c66affSColin Finck         FileObject = IrpSp->FileObject;
326c2c66affSColin Finck         ASSERT(FileObject);
327c2c66affSColin Finck 
328c2c66affSColin Finck         // Get the FCB and CCB pointers.
329c2c66affSColin Finck         Ccb = (PtrUDFCCB)(FileObject->FsContext2);
330c2c66affSColin Finck         ASSERT(Ccb);
331c2c66affSColin Finck         Fcb = Ccb->Fcb;
332c2c66affSColin Finck         ASSERT(Fcb);
333c2c66affSColin Finck 
334c2c66affSColin Finck         if(!Fcb->Vcb->WriteSecurity)
335c2c66affSColin Finck             try_return(RC = STATUS_NOT_IMPLEMENTED);
336c2c66affSColin Finck 
337c2c66affSColin Finck         NtReqFcb = Fcb->NTRequiredFCB;
338c2c66affSColin Finck         CanWait = ((PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE);
339c2c66affSColin Finck 
340c2c66affSColin Finck         // Acquire the FCB resource exclusive
341c2c66affSColin Finck         UDF_CHECK_PAGING_IO_RESOURCE(NtReqFcb);
342c2c66affSColin Finck         if (!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
343c2c66affSColin Finck             PostRequest = TRUE;
344c2c66affSColin Finck             try_return(RC = STATUS_PENDING);
345c2c66affSColin Finck         }
346c2c66affSColin Finck         AcquiredFCB = TRUE;
347c2c66affSColin Finck 
348c2c66affSColin Finck //OWNER_SECURITY_INFORMATION
349c2c66affSColin Finck         if(IrpSp->Parameters.SetSecurity.SecurityInformation & OWNER_SECURITY_INFORMATION)
350c2c66affSColin Finck             DesiredAccess |= WRITE_OWNER;
351c2c66affSColin Finck //GROUP_SECURITY_INFORMATION
352c2c66affSColin Finck         if(IrpSp->Parameters.SetSecurity.SecurityInformation & GROUP_SECURITY_INFORMATION)
353c2c66affSColin Finck             DesiredAccess |= WRITE_OWNER;
354c2c66affSColin Finck //DACL_SECURITY_INFORMATION
355c2c66affSColin Finck         if(IrpSp->Parameters.SetSecurity.SecurityInformation & DACL_SECURITY_INFORMATION)
356c2c66affSColin Finck             DesiredAccess |= WRITE_DAC;
357c2c66affSColin Finck //SACL_SECURITY_INFORMATION
358c2c66affSColin Finck         if(IrpSp->Parameters.SetSecurity.SecurityInformation & SACL_SECURITY_INFORMATION)
359c2c66affSColin Finck             DesiredAccess |= ACCESS_SYSTEM_SECURITY;
360c2c66affSColin Finck 
361c2c66affSColin Finck         _SEH2_TRY {
362c2c66affSColin Finck             UDFConvertToSelfRelative(&(NtReqFcb->SecurityDesc));
363c2c66affSColin Finck 
364c2c66affSColin Finck             KdDump(NtReqFcb->SecurityDesc, RtlLengthSecurityDescriptor(NtReqFcb->SecurityDesc));
365c2c66affSColin Finck             UDFPrint(("\n"));
366c2c66affSColin Finck 
367c2c66affSColin Finck             RC = SeSetSecurityDescriptorInfo(/*FileObject*/ NULL,
368c2c66affSColin Finck                                           &(IrpSp->Parameters.SetSecurity.SecurityInformation),
369c2c66affSColin Finck                                           IrpSp->Parameters.SetSecurity.SecurityDescriptor,
370c2c66affSColin Finck                                           &(NtReqFcb->SecurityDesc),
371c2c66affSColin Finck                                           NonPagedPool,
372c2c66affSColin Finck                                           IoGetFileObjectGenericMapping() );
373c2c66affSColin Finck 
374c2c66affSColin Finck             KdDump(NtReqFcb->SecurityDesc, RtlLengthSecurityDescriptor(NtReqFcb->SecurityDesc));
375c2c66affSColin Finck 
376c2c66affSColin Finck         } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
377c2c66affSColin Finck             RC = STATUS_INVALID_PARAMETER;
378c2c66affSColin Finck         }
379c2c66affSColin Finck         if(NT_SUCCESS(RC)) {
380c2c66affSColin Finck             NtReqFcb->NtReqFCBFlags |= UDF_NTREQ_FCB_SD_MODIFIED;
381c2c66affSColin Finck 
382c2c66affSColin Finck             UDFNotifyFullReportChange( Fcb->Vcb, Fcb->FileInfo,
383c2c66affSColin Finck                                        FILE_NOTIFY_CHANGE_SECURITY,
384c2c66affSColin Finck                                        FILE_ACTION_MODIFIED);
385c2c66affSColin Finck         }
386c2c66affSColin Finck 
387c2c66affSColin Finck try_exit: NOTHING;
388c2c66affSColin Finck 
389c2c66affSColin Finck     } _SEH2_FINALLY {
390c2c66affSColin Finck 
391c2c66affSColin Finck         // Release the FCB resources if acquired.
392c2c66affSColin Finck         if (AcquiredFCB) {
393c2c66affSColin Finck             UDF_CHECK_PAGING_IO_RESOURCE(NtReqFcb);
394c2c66affSColin Finck             UDFReleaseResource(&(NtReqFcb->MainResource));
395c2c66affSColin Finck             AcquiredFCB = FALSE;
396c2c66affSColin Finck         }
397c2c66affSColin Finck 
398c2c66affSColin Finck         if (PostRequest) {
399c2c66affSColin Finck             // Perform appropriate post related processing here
400c2c66affSColin Finck             RC = UDFPostRequest(PtrIrpContext, Irp);
401c2c66affSColin Finck         } else
402c2c66affSColin Finck         if(!AbnormalTermination()) {
403c2c66affSColin Finck             Irp->IoStatus.Status = RC;
404c2c66affSColin Finck             Irp->IoStatus.Information = 0;
405c2c66affSColin Finck             // Free up the Irp Context
406c2c66affSColin Finck             UDFReleaseIrpContext(PtrIrpContext);
407c2c66affSColin Finck             // complete the IRP
408c2c66affSColin Finck             IoCompleteRequest(Irp, IO_DISK_INCREMENT);
409c2c66affSColin Finck         }
410c2c66affSColin Finck 
411c2c66affSColin Finck     } // end of "__finally" processing
412c2c66affSColin Finck 
413c2c66affSColin Finck     return(RC);
414c2c66affSColin Finck } // ens UDFCommonSetSecurity()
415c2c66affSColin Finck 
416c2c66affSColin Finck #endif //UDF_READ_ONLY_BUILD
417c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
418c2c66affSColin Finck 
419c2c66affSColin Finck NTSTATUS
UDFReadSecurity(IN PVCB Vcb,IN PtrUDFFCB Fcb,IN PSECURITY_DESCRIPTOR * SecurityDesc)420c2c66affSColin Finck UDFReadSecurity(
421c2c66affSColin Finck     IN PVCB Vcb,
422c2c66affSColin Finck     IN PtrUDFFCB Fcb,
423c2c66affSColin Finck     IN PSECURITY_DESCRIPTOR* SecurityDesc
424c2c66affSColin Finck     )
425c2c66affSColin Finck {
426c2c66affSColin Finck #ifdef UDF_ENABLE_SECURITY
427c2c66affSColin Finck     PUDF_FILE_INFO FileInfo = NULL;
428c2c66affSColin Finck     PUDF_FILE_INFO SDirInfo = NULL;
429c2c66affSColin Finck     PUDF_FILE_INFO AclInfo = NULL;
430c2c66affSColin Finck     NTSTATUS RC;
431c2c66affSColin Finck     ULONG NumberBytesRead;
432c2c66affSColin Finck     PERESOURCE Res1 = NULL;
433c2c66affSColin Finck 
434c2c66affSColin Finck     UDFPrint(("UDFReadSecurity\n"));
435c2c66affSColin Finck 
436c2c66affSColin Finck     _SEH2_TRY {
437c2c66affSColin Finck 
438c2c66affSColin Finck         FileInfo = Fcb->FileInfo;
439c2c66affSColin Finck         ASSERT(FileInfo);
440c2c66affSColin Finck         if(!FileInfo) {
441c2c66affSColin Finck             UDFPrint(("  Volume Security\n"));
442c2c66affSColin Finck             try_return(RC = STATUS_NO_SECURITY_ON_OBJECT);
443c2c66affSColin Finck         }
444c2c66affSColin Finck         if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
445c2c66affSColin Finck             UDFPrint(("  No Security on blank volume\n"));
446c2c66affSColin Finck             try_return(RC = STATUS_NO_SECURITY_ON_OBJECT);
447c2c66affSColin Finck         }
448c2c66affSColin Finck 
449c2c66affSColin Finck         // Open Stream Directory
450c2c66affSColin Finck         RC = UDFOpenStreamDir__(Vcb, FileInfo, &SDirInfo);
451c2c66affSColin Finck 
452c2c66affSColin Finck         if(RC == STATUS_NOT_FOUND)
453c2c66affSColin Finck             try_return(RC = STATUS_NO_SECURITY_ON_OBJECT);
454c2c66affSColin Finck         if(!NT_SUCCESS(RC)) {
455c2c66affSColin Finck             if(UDFCleanUpFile__(Vcb, SDirInfo)) {
456c2c66affSColin Finck                 if(SDirInfo) MyFreePool__(SDirInfo);
457c2c66affSColin Finck             }
458c2c66affSColin Finck             SDirInfo = NULL;
459c2c66affSColin Finck             try_return(RC);
460c2c66affSColin Finck         }
461c2c66affSColin Finck         // Acquire SDir exclusively if Fcb present
462c2c66affSColin Finck         if(SDirInfo->Fcb) {
463c2c66affSColin Finck             BrutePoint();
464c2c66affSColin Finck             UDF_CHECK_PAGING_IO_RESOURCE(SDirInfo->Fcb->NTRequiredFCB);
465c2c66affSColin Finck             UDFAcquireResourceExclusive(Res1 = &(SDirInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
466c2c66affSColin Finck         }
467c2c66affSColin Finck 
468c2c66affSColin Finck         // Open Acl Stream
469c2c66affSColin Finck         RC = UDFOpenFile__(Vcb,
470c2c66affSColin Finck                            FALSE,TRUE,&(UDFGlobalData.AclName),
471c2c66affSColin Finck                            SDirInfo,&AclInfo,NULL);
472c2c66affSColin Finck         if(RC == STATUS_OBJECT_NAME_NOT_FOUND)
473c2c66affSColin Finck             try_return(RC = STATUS_NO_SECURITY_ON_OBJECT);
474c2c66affSColin Finck         if(!NT_SUCCESS(RC)) {
475c2c66affSColin Finck             if(UDFCleanUpFile__(Vcb, AclInfo)) {
476c2c66affSColin Finck                 if(AclInfo) MyFreePool__(AclInfo);
477c2c66affSColin Finck             }
478c2c66affSColin Finck             AclInfo = NULL;
479c2c66affSColin Finck             try_return(RC);
480c2c66affSColin Finck         }
481c2c66affSColin Finck 
482c2c66affSColin Finck         NumberBytesRead = (ULONG)UDFGetFileSize(AclInfo);
483c2c66affSColin Finck         (*SecurityDesc) = DbgAllocatePool(NonPagedPool, NumberBytesRead);
484c2c66affSColin Finck         if(!(*SecurityDesc))
485c2c66affSColin Finck             try_return(RC = STATUS_INSUFFICIENT_RESOURCES);
486c2c66affSColin Finck         RC = UDFReadFile__(Vcb, AclInfo, 0, NumberBytesRead,
487c2c66affSColin Finck                        FALSE, (PCHAR)(*SecurityDesc), &NumberBytesRead);
488c2c66affSColin Finck         if(!NT_SUCCESS(RC))
489c2c66affSColin Finck             try_return(RC);
490c2c66affSColin Finck 
491c2c66affSColin Finck         RC = RtlValidSecurityDescriptor(*SecurityDesc);
492c2c66affSColin Finck 
493c2c66affSColin Finck try_exit: NOTHING;
494c2c66affSColin Finck 
495c2c66affSColin Finck     } _SEH2_FINALLY {
496c2c66affSColin Finck 
497c2c66affSColin Finck         if(AclInfo) {
498c2c66affSColin Finck             UDFCloseFile__(Vcb, AclInfo);
499c2c66affSColin Finck             if(UDFCleanUpFile__(Vcb, AclInfo))
500c2c66affSColin Finck                 MyFreePool__(AclInfo);
501c2c66affSColin Finck         }
502c2c66affSColin Finck 
503c2c66affSColin Finck         if(SDirInfo) {
504c2c66affSColin Finck             UDFCloseFile__(Vcb, SDirInfo);
505c2c66affSColin Finck             if(UDFCleanUpFile__(Vcb, SDirInfo))
506c2c66affSColin Finck                 MyFreePool__(SDirInfo);
507c2c66affSColin Finck         }
508c2c66affSColin Finck 
509c2c66affSColin Finck         if(!NT_SUCCESS(RC) && (*SecurityDesc)) {
510c2c66affSColin Finck             DbgFreePool(*SecurityDesc);
511c2c66affSColin Finck             (*SecurityDesc) = NULL;
512c2c66affSColin Finck         }
513c2c66affSColin Finck         if(Res1)
514c2c66affSColin Finck             UDFReleaseResource(Res1);
515c2c66affSColin Finck     }
516c2c66affSColin Finck 
517c2c66affSColin Finck     return RC;
518c2c66affSColin Finck #else
519c2c66affSColin Finck     return STATUS_NO_SECURITY_ON_OBJECT;
520c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
521c2c66affSColin Finck 
522c2c66affSColin Finck } // end UDFReadSecurity()
523c2c66affSColin Finck 
524c2c66affSColin Finck #ifdef UDF_ENABLE_SECURITY
525c2c66affSColin Finck NTSTATUS
UDFConvertToSelfRelative(IN OUT PSECURITY_DESCRIPTOR * SecurityDesc)526c2c66affSColin Finck UDFConvertToSelfRelative(
527c2c66affSColin Finck     IN OUT PSECURITY_DESCRIPTOR* SecurityDesc
528c2c66affSColin Finck     )
529c2c66affSColin Finck {
530c2c66affSColin Finck     NTSTATUS RC;
531c2c66affSColin Finck     SECURITY_INFORMATION SecurityInformation;
532c2c66affSColin Finck     PSECURITY_DESCRIPTOR NewSD;
533c2c66affSColin Finck     ULONG Len;
534c2c66affSColin Finck 
535c2c66affSColin Finck     UDFPrint(("  UDFConvertToSelfRelative\n"));
536c2c66affSColin Finck 
537c2c66affSColin Finck     if(!(*SecurityDesc))
538c2c66affSColin Finck         return STATUS_NO_SECURITY_ON_OBJECT;
539c2c66affSColin Finck 
540c2c66affSColin Finck     SecurityInformation = FULL_SECURITY_INFORMATION;
541c2c66affSColin Finck     Len = RtlLengthSecurityDescriptor(*SecurityDesc);
542c2c66affSColin Finck     ASSERT(Len <= 1024);
543c2c66affSColin Finck     NewSD = (PSECURITY_DESCRIPTOR)DbgAllocatePool(NonPagedPool, Len);
544c2c66affSColin Finck     if(!NewSD)
545c2c66affSColin Finck         return STATUS_INSUFFICIENT_RESOURCES;
546c2c66affSColin Finck     _SEH2_TRY {
547c2c66affSColin Finck         RC = SeQuerySecurityDescriptorInfo(&SecurityInformation, NewSD, &Len, SecurityDesc);
548c2c66affSColin Finck     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
549c2c66affSColin Finck         RC = STATUS_INSUFFICIENT_RESOURCES;
550c2c66affSColin Finck     }
551c2c66affSColin Finck 
552c2c66affSColin Finck     if(NT_SUCCESS(RC)) {
553c2c66affSColin Finck         DbgFreePool(*SecurityDesc);
554c2c66affSColin Finck         *SecurityDesc = NewSD;
555c2c66affSColin Finck     } else {
556c2c66affSColin Finck         DbgFreePool(NewSD);
557c2c66affSColin Finck     }
558c2c66affSColin Finck     return RC;
559c2c66affSColin Finck } // end UDFConvertToSelfRelative()
560c2c66affSColin Finck 
561c2c66affSColin Finck NTSTATUS
UDFInheritAcl(IN PVCB Vcb,IN PSECURITY_DESCRIPTOR * ParentSecurityDesc,IN OUT PSECURITY_DESCRIPTOR * SecurityDesc)562c2c66affSColin Finck UDFInheritAcl(
563c2c66affSColin Finck     IN PVCB Vcb,
564c2c66affSColin Finck     IN PSECURITY_DESCRIPTOR* ParentSecurityDesc,
565c2c66affSColin Finck     IN OUT PSECURITY_DESCRIPTOR* SecurityDesc
566c2c66affSColin Finck     )
567c2c66affSColin Finck {
568c2c66affSColin Finck     NTSTATUS RC;
569c2c66affSColin Finck     SECURITY_INFORMATION SecurityInformation;
570c2c66affSColin Finck     ULONG Len;
571c2c66affSColin Finck 
572c2c66affSColin Finck     UDFPrint(("  UDFInheritAcl\n"));
573c2c66affSColin Finck 
574c2c66affSColin Finck     if(!(*ParentSecurityDesc)) {
575c2c66affSColin Finck         *SecurityDesc = NULL;
576c2c66affSColin Finck         return STATUS_SUCCESS;
577c2c66affSColin Finck     }
578c2c66affSColin Finck 
579c2c66affSColin Finck     SecurityInformation = FULL_SECURITY_INFORMATION;
580c2c66affSColin Finck     Len = RtlLengthSecurityDescriptor(*ParentSecurityDesc);
581c2c66affSColin Finck     *SecurityDesc = (PSECURITY_DESCRIPTOR)DbgAllocatePool(NonPagedPool, Len);
582c2c66affSColin Finck     if(!(*SecurityDesc))
583c2c66affSColin Finck         return STATUS_INSUFFICIENT_RESOURCES;
584c2c66affSColin Finck     _SEH2_TRY {
585c2c66affSColin Finck         RC = SeQuerySecurityDescriptorInfo(&SecurityInformation, *SecurityDesc, &Len, ParentSecurityDesc);
586c2c66affSColin Finck     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
587c2c66affSColin Finck         RC = STATUS_INSUFFICIENT_RESOURCES;
588c2c66affSColin Finck     }
589c2c66affSColin Finck 
590c2c66affSColin Finck     if(!NT_SUCCESS(RC)) {
591c2c66affSColin Finck         DbgFreePool(*SecurityDesc);
592c2c66affSColin Finck         *SecurityDesc = NULL;
593c2c66affSColin Finck     }
594c2c66affSColin Finck     return RC;
595c2c66affSColin Finck } // end UDFInheritAcl()
596c2c66affSColin Finck 
597c2c66affSColin Finck NTSTATUS
UDFBuildEmptyAcl(IN PVCB Vcb,IN PSECURITY_DESCRIPTOR * SecurityDesc)598c2c66affSColin Finck UDFBuildEmptyAcl(
599c2c66affSColin Finck     IN PVCB Vcb,
600c2c66affSColin Finck     IN PSECURITY_DESCRIPTOR* SecurityDesc
601c2c66affSColin Finck     )
602c2c66affSColin Finck {
603c2c66affSColin Finck     NTSTATUS RC;
604c2c66affSColin Finck     ULONG Len = 2 * (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(ULONG)*4 /*RtlLengthSid(SeExports->SeWorldSid)*/);
605c2c66affSColin Finck 
606c2c66affSColin Finck     UDFPrint(("  UDFBuildEmptyAcl\n"));
607c2c66affSColin Finck     // Create Security Descriptor
608c2c66affSColin Finck     (*SecurityDesc) = (PSECURITY_DESCRIPTOR)DbgAllocatePool(NonPagedPool,
609c2c66affSColin Finck            sizeof(SECURITY_DESCRIPTOR) + Len);
610c2c66affSColin Finck     if(!(*SecurityDesc))
611c2c66affSColin Finck         return STATUS_INSUFFICIENT_RESOURCES;
612c2c66affSColin Finck 
613c2c66affSColin Finck     RC = RtlCreateSecurityDescriptor(*SecurityDesc, SECURITY_DESCRIPTOR_REVISION);
614c2c66affSColin Finck 
615c2c66affSColin Finck     if(!NT_SUCCESS(RC)) {
616c2c66affSColin Finck         DbgFreePool(*SecurityDesc);
617c2c66affSColin Finck         *((PULONG)SecurityDesc) = NULL;
618c2c66affSColin Finck     }
619c2c66affSColin Finck     return RC;
620c2c66affSColin Finck } // end UDFBuildEmptyAcl()
621c2c66affSColin Finck 
622c2c66affSColin Finck NTSTATUS
UDFBuildFullControlAcl(IN PVCB Vcb,IN PSECURITY_DESCRIPTOR * SecurityDesc)623c2c66affSColin Finck UDFBuildFullControlAcl(
624c2c66affSColin Finck     IN PVCB Vcb,
625c2c66affSColin Finck     IN PSECURITY_DESCRIPTOR* SecurityDesc
626c2c66affSColin Finck     )
627c2c66affSColin Finck {
628c2c66affSColin Finck     NTSTATUS RC;
629c2c66affSColin Finck     PACL Acl;
630c2c66affSColin Finck     ULONG Len = sizeof(ACL) + 2*(sizeof(ACCESS_ALLOWED_ACE) + sizeof(ULONG)*4 /*- sizeof(ULONG)*/ /*+ RtlLengthSid(SeExports->SeWorldSid)*/);
631c2c66affSColin Finck 
632c2c66affSColin Finck     UDFPrint(("  UDFBuildFullControlAcl\n"));
633c2c66affSColin Finck     // Create Security Descriptor
634c2c66affSColin Finck     RC = UDFBuildEmptyAcl(Vcb, SecurityDesc);
635c2c66affSColin Finck     if(!NT_SUCCESS(RC))
636c2c66affSColin Finck         return RC;
637c2c66affSColin Finck 
638c2c66affSColin Finck     // Set Owner
639c2c66affSColin Finck     RC = RtlSetOwnerSecurityDescriptor(*SecurityDesc, SeExports->SeWorldSid, FALSE);
640c2c66affSColin Finck     if(!NT_SUCCESS(RC)) {
641c2c66affSColin Finck         DbgFreePool(*SecurityDesc);
642c2c66affSColin Finck         *((PULONG)SecurityDesc) = NULL;
643c2c66affSColin Finck         return RC;
644c2c66affSColin Finck     }
645c2c66affSColin Finck 
646c2c66affSColin Finck     // Set Group
647c2c66affSColin Finck     RC = RtlSetGroupSecurityDescriptor(*SecurityDesc, SeExports->SeWorldSid, FALSE);
648c2c66affSColin Finck     if(!NT_SUCCESS(RC)) {
649c2c66affSColin Finck         DbgFreePool(*SecurityDesc);
650c2c66affSColin Finck         *((PULONG)SecurityDesc) = NULL;
651c2c66affSColin Finck         return RC;
652c2c66affSColin Finck     }
653c2c66affSColin Finck 
654c2c66affSColin Finck     // Create empty Acl
655c2c66affSColin Finck     Acl = (PACL)DbgAllocatePool(NonPagedPool, Len);
656c2c66affSColin Finck     if(!Acl) {
657c2c66affSColin Finck         DbgFreePool(*SecurityDesc);
658c2c66affSColin Finck         *((PULONG)SecurityDesc) = NULL;
659c2c66affSColin Finck         return RC;
660c2c66affSColin Finck     }
661c2c66affSColin Finck     RtlZeroMemory(Acl, Len);
662c2c66affSColin Finck 
663c2c66affSColin Finck     RC = RtlCreateAcl(Acl, Len, ACL_REVISION);
664c2c66affSColin Finck     if(!NT_SUCCESS(RC)) {
665c2c66affSColin Finck         DbgFreePool(Acl);
666c2c66affSColin Finck         DbgFreePool(*SecurityDesc);
667c2c66affSColin Finck         *((PULONG)SecurityDesc) = NULL;
668c2c66affSColin Finck         return RC;
669c2c66affSColin Finck     }
670c2c66affSColin Finck 
671c2c66affSColin Finck     // Add (All)(All) access for Everyone
672c2c66affSColin Finck /*    RC = RtlAddAccessAllowedAce(Acl, ACL_REVISION,
673c2c66affSColin Finck                                 GENERIC_ALL,
674c2c66affSColin Finck                                 SeExports->SeWorldSid);*/
675c2c66affSColin Finck 
676c2c66affSColin Finck     RC = RtlAddAccessAllowedAce(Acl, ACL_REVISION,
677c2c66affSColin Finck                                 FILE_ALL_ACCESS,
678c2c66affSColin Finck                                 SeExports->SeWorldSid);
679c2c66affSColin Finck 
680c2c66affSColin Finck     if(!NT_SUCCESS(RC)) {
681c2c66affSColin Finck         DbgFreePool(Acl);
682c2c66affSColin Finck         DbgFreePool(*SecurityDesc);
683c2c66affSColin Finck         *((PULONG)SecurityDesc) = NULL;
684c2c66affSColin Finck         return RC;
685c2c66affSColin Finck     }
686c2c66affSColin Finck 
687c2c66affSColin Finck     // Add Acl to Security Descriptor
688c2c66affSColin Finck     RC = RtlSetDaclSecurityDescriptor(*SecurityDesc, TRUE, Acl, FALSE);
689c2c66affSColin Finck     if(!NT_SUCCESS(RC)) {
690c2c66affSColin Finck         DbgFreePool(Acl);
691c2c66affSColin Finck         DbgFreePool(*SecurityDesc);
692c2c66affSColin Finck         *((PULONG)SecurityDesc) = NULL;
693c2c66affSColin Finck         return RC;
694c2c66affSColin Finck     }
695c2c66affSColin Finck 
696c2c66affSColin Finck     RC = UDFConvertToSelfRelative(SecurityDesc);
697c2c66affSColin Finck 
698c2c66affSColin Finck     DbgFreePool(Acl);
699c2c66affSColin Finck 
700c2c66affSColin Finck     return RC;
701c2c66affSColin Finck } // end UDFBuildFullControlAcl()
702c2c66affSColin Finck 
703c2c66affSColin Finck #endif // UDF_ENABLE_SECURITY
704c2c66affSColin Finck 
705c2c66affSColin Finck NTSTATUS
UDFAssignAcl(IN PVCB Vcb,IN PFILE_OBJECT FileObject,IN PtrUDFFCB Fcb,IN PtrUDFNTRequiredFCB NtReqFcb)706c2c66affSColin Finck UDFAssignAcl(
707c2c66affSColin Finck     IN PVCB Vcb,
708c2c66affSColin Finck     IN PFILE_OBJECT FileObject, // OPTIONAL
709c2c66affSColin Finck     IN PtrUDFFCB Fcb,
710c2c66affSColin Finck     IN PtrUDFNTRequiredFCB NtReqFcb
711c2c66affSColin Finck     )
712c2c66affSColin Finck {
713c2c66affSColin Finck     NTSTATUS RC = STATUS_SUCCESS;
714c2c66affSColin Finck #ifdef UDF_ENABLE_SECURITY
715c2c66affSColin Finck //    SECURITY_INFORMATION SecurityInformation;
716c2c66affSColin Finck 
717c2c66affSColin Finck //    UDFPrint(("  UDFAssignAcl\n"));
718c2c66affSColin Finck     if(!NtReqFcb->SecurityDesc) {
719c2c66affSColin Finck 
720c2c66affSColin Finck         PSECURITY_DESCRIPTOR ExplicitSecurity = NULL;
721c2c66affSColin Finck 
722c2c66affSColin Finck         if(UDFIsAStreamDir(Fcb->FileInfo) || UDFIsAStream(Fcb->FileInfo)) {
723c2c66affSColin Finck             // Stream/SDir security
724c2c66affSColin Finck             NtReqFcb->SecurityDesc = Fcb->FileInfo->ParentFile->Dloc->CommonFcb->SecurityDesc;
725c2c66affSColin Finck             return STATUS_SUCCESS;
726c2c66affSColin Finck         } else
727c2c66affSColin Finck         if(!Fcb->FileInfo) {
728c2c66affSColin Finck             // Volume security
729c2c66affSColin Finck             if(Vcb->RootDirFCB &&
730c2c66affSColin Finck                Vcb->RootDirFCB->FileInfo &&
731c2c66affSColin Finck                Vcb->RootDirFCB->FileInfo->Dloc &&
732c2c66affSColin Finck                Vcb->RootDirFCB->FileInfo->Dloc->CommonFcb) {
733c2c66affSColin Finck                 RC = UDFInheritAcl(Vcb, &(Vcb->RootDirFCB->FileInfo->Dloc->CommonFcb->SecurityDesc), &ExplicitSecurity);
734c2c66affSColin Finck             } else {
735c2c66affSColin Finck                 NtReqFcb->SecurityDesc = NULL;
736c2c66affSColin Finck                 RC = STATUS_NO_SECURITY_ON_OBJECT;
737c2c66affSColin Finck             }
738c2c66affSColin Finck             return RC;
739c2c66affSColin Finck         }
740c2c66affSColin Finck 
741c2c66affSColin Finck         RC = UDFReadSecurity(Vcb, Fcb, &ExplicitSecurity);
742c2c66affSColin Finck         if(RC == STATUS_NO_SECURITY_ON_OBJECT) {
743c2c66affSColin Finck             if(!Fcb->FileInfo->ParentFile) {
744c2c66affSColin Finck                 RC = UDFBuildFullControlAcl(Vcb, &ExplicitSecurity);
745c2c66affSColin Finck             } else {
746c2c66affSColin Finck                 RC = UDFInheritAcl(Vcb, &(Fcb->FileInfo->ParentFile->Dloc->CommonFcb->SecurityDesc), &ExplicitSecurity);
747c2c66affSColin Finck             }
748c2c66affSColin Finck /*            if(NT_SUCCESS(RC)) {
749c2c66affSColin Finck                 NtReqFcb->NtReqFCBFlags |= UDF_NTREQ_FCB_SD_MODIFIED;
750c2c66affSColin Finck             }*/
751c2c66affSColin Finck         }
752c2c66affSColin Finck         if(NT_SUCCESS(RC)) {
753c2c66affSColin Finck 
754c2c66affSColin Finck //            SecurityInformation = FULL_SECURITY_INFORMATION;
755c2c66affSColin Finck             NtReqFcb->SecurityDesc = ExplicitSecurity;
756c2c66affSColin Finck 
757c2c66affSColin Finck /*            RC = SeSetSecurityDescriptorInfo(FileObject,
758c2c66affSColin Finck                                           &SecurityInformation,
759c2c66affSColin Finck                                           ExplicitSecurity,
760c2c66affSColin Finck                                           &(NtReqFcb->SecurityDesc),
761c2c66affSColin Finck                                           NonPagedPool,
762c2c66affSColin Finck                                           IoGetFileObjectGenericMapping() );*/
763c2c66affSColin Finck 
764c2c66affSColin Finck         }
765c2c66affSColin Finck     }
766c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
767c2c66affSColin Finck     return RC;
768c2c66affSColin Finck } // end UDFAssignAcl()
769c2c66affSColin Finck 
770c2c66affSColin Finck 
771c2c66affSColin Finck VOID
UDFDeassignAcl(IN PtrUDFNTRequiredFCB NtReqFcb,IN BOOLEAN AutoInherited)772c2c66affSColin Finck UDFDeassignAcl(
773c2c66affSColin Finck     IN PtrUDFNTRequiredFCB NtReqFcb,
774c2c66affSColin Finck     IN BOOLEAN AutoInherited
775c2c66affSColin Finck     )
776c2c66affSColin Finck {
777c2c66affSColin Finck #ifdef UDF_ENABLE_SECURITY
778c2c66affSColin Finck //    NTSTATUS RC = STATUS_SUCCESS;
779c2c66affSColin Finck 
780c2c66affSColin Finck //    UDFPrint(("  UDFDeassignAcl\n"));
781c2c66affSColin Finck     if(!NtReqFcb->SecurityDesc)
782c2c66affSColin Finck         return;
783c2c66affSColin Finck 
784c2c66affSColin Finck     if(AutoInherited) {
785c2c66affSColin Finck         NtReqFcb->SecurityDesc = NULL;
786c2c66affSColin Finck         return;
787c2c66affSColin Finck     }
788c2c66affSColin Finck 
789c2c66affSColin Finck     SeDeassignSecurity(&(NtReqFcb->SecurityDesc));
790c2c66affSColin Finck     NtReqFcb->SecurityDesc = NULL; // HA BCRK CLU4
791c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
792c2c66affSColin Finck     return;
793c2c66affSColin Finck } // end UDFDeassignAcl()
794c2c66affSColin Finck 
795c2c66affSColin Finck NTSTATUS
UDFWriteSecurity(IN PVCB Vcb,IN PtrUDFFCB Fcb,IN PSECURITY_DESCRIPTOR * SecurityDesc)796c2c66affSColin Finck UDFWriteSecurity(
797c2c66affSColin Finck     IN PVCB Vcb,
798c2c66affSColin Finck     IN PtrUDFFCB Fcb,
799c2c66affSColin Finck     IN PSECURITY_DESCRIPTOR* SecurityDesc
800c2c66affSColin Finck     )
801c2c66affSColin Finck {
802c2c66affSColin Finck #ifdef UDF_ENABLE_SECURITY
803c2c66affSColin Finck     PUDF_FILE_INFO FileInfo = NULL;
804c2c66affSColin Finck     PUDF_FILE_INFO SDirInfo = NULL;
805c2c66affSColin Finck     PUDF_FILE_INFO AclInfo = NULL;
806c2c66affSColin Finck     PERESOURCE Res1 = NULL;
807c2c66affSColin Finck     NTSTATUS RC;
808c2c66affSColin Finck     ULONG NumberBytesRead;
809c2c66affSColin Finck 
810c2c66affSColin Finck //    UDFPrint(("UDFWriteSecurity\n"));
811c2c66affSColin Finck 
812c2c66affSColin Finck #if !defined(UDF_READ_ONLY_BUILD)
813c2c66affSColin Finck 
814c2c66affSColin Finck     if(!Vcb->WriteSecurity ||
815c2c66affSColin Finck        (Vcb->VCBFlags & (UDF_VCB_FLAGS_VOLUME_READ_ONLY |
816c2c66affSColin Finck                          UDF_VCB_FLAGS_MEDIA_READ_ONLY)))
817c2c66affSColin Finck 
818c2c66affSColin Finck #endif //!defined(UDF_READ_ONLY_BUILD)
819c2c66affSColin Finck 
820c2c66affSColin Finck         return STATUS_SUCCESS;
821c2c66affSColin Finck 
822c2c66affSColin Finck #if !defined(UDF_READ_ONLY_BUILD)
823c2c66affSColin Finck 
824c2c66affSColin Finck     _SEH2_TRY {
825c2c66affSColin Finck 
826c2c66affSColin Finck         FileInfo = Fcb->FileInfo;
827c2c66affSColin Finck         ASSERT(FileInfo);
828c2c66affSColin Finck         if(!FileInfo) {
829c2c66affSColin Finck             UDFPrint(("  Volume Security\n"));
830c2c66affSColin Finck             try_return(RC = STATUS_SUCCESS);
831c2c66affSColin Finck         }
832c2c66affSColin Finck 
833c2c66affSColin Finck         if(!(Fcb->NTRequiredFCB->NtReqFCBFlags & UDF_NTREQ_FCB_SD_MODIFIED))
834c2c66affSColin Finck             try_return(RC = STATUS_SUCCESS);
835c2c66affSColin Finck 
836c2c66affSColin Finck         // Open Stream Directory
837c2c66affSColin Finck         RC = UDFOpenStreamDir__(Vcb, FileInfo, &SDirInfo);
838c2c66affSColin Finck 
839c2c66affSColin Finck         if(RC == STATUS_NOT_FOUND) {
840c2c66affSColin Finck             RC = UDFCreateStreamDir__(Vcb, FileInfo, &SDirInfo);
841c2c66affSColin Finck         }
842c2c66affSColin Finck         if(!NT_SUCCESS(RC)) {
843c2c66affSColin Finck             if(UDFCleanUpFile__(Vcb, SDirInfo)) {
844c2c66affSColin Finck                 if(SDirInfo) MyFreePool__(SDirInfo);
845c2c66affSColin Finck             }
846c2c66affSColin Finck             SDirInfo = NULL;
847c2c66affSColin Finck             try_return(RC);
848c2c66affSColin Finck         }
849c2c66affSColin Finck         // Acquire SDir exclusively if Fcb present
850c2c66affSColin Finck         if(SDirInfo->Fcb) {
851c2c66affSColin Finck             BrutePoint();
852c2c66affSColin Finck             UDF_CHECK_PAGING_IO_RESOURCE(SDirInfo->Fcb->NTRequiredFCB);
853c2c66affSColin Finck             UDFAcquireResourceExclusive(Res1 = &(SDirInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
854c2c66affSColin Finck         }
855c2c66affSColin Finck 
856c2c66affSColin Finck         // Open Acl Stream
857c2c66affSColin Finck         RC = UDFOpenFile__(Vcb,
858c2c66affSColin Finck                            FALSE,TRUE,&(UDFGlobalData.AclName),
859c2c66affSColin Finck                            SDirInfo,&AclInfo,NULL);
860c2c66affSColin Finck         if(RC == STATUS_OBJECT_NAME_NOT_FOUND) {
861c2c66affSColin Finck             RC = UDFCreateFile__(Vcb, FALSE, &(UDFGlobalData.AclName),
862c2c66affSColin Finck                                0, 0, FALSE, FALSE, SDirInfo, &AclInfo);
863c2c66affSColin Finck         }
864c2c66affSColin Finck         if(!NT_SUCCESS(RC)) {
865c2c66affSColin Finck             if(UDFCleanUpFile__(Vcb, AclInfo)) {
866c2c66affSColin Finck                 if(AclInfo) MyFreePool__(AclInfo);
867c2c66affSColin Finck             }
868c2c66affSColin Finck             AclInfo = NULL;
869c2c66affSColin Finck             try_return(RC);
870c2c66affSColin Finck         }
871c2c66affSColin Finck 
872c2c66affSColin Finck         if(!(*SecurityDesc)) {
873c2c66affSColin Finck             UDFFlushFile__(Vcb, AclInfo);
874c2c66affSColin Finck             RC = UDFUnlinkFile__(Vcb, AclInfo, TRUE);
875c2c66affSColin Finck             try_return(RC);
876c2c66affSColin Finck         }
877c2c66affSColin Finck         NumberBytesRead = RtlLengthSecurityDescriptor(*SecurityDesc);
878c2c66affSColin Finck 
879c2c66affSColin Finck         RC = UDFWriteFile__(Vcb, AclInfo, 0, NumberBytesRead,
880c2c66affSColin Finck                        FALSE, (PCHAR)(*SecurityDesc), &NumberBytesRead);
881c2c66affSColin Finck         if(!NT_SUCCESS(RC))
882c2c66affSColin Finck             try_return(RC);
883c2c66affSColin Finck 
884c2c66affSColin Finck         Fcb->NTRequiredFCB->NtReqFCBFlags &= ~UDF_NTREQ_FCB_SD_MODIFIED;
885c2c66affSColin Finck 
886c2c66affSColin Finck try_exit: NOTHING;
887c2c66affSColin Finck 
888c2c66affSColin Finck     } _SEH2_FINALLY {
889c2c66affSColin Finck 
890c2c66affSColin Finck         if(AclInfo) {
891c2c66affSColin Finck             UDFCloseFile__(Vcb, AclInfo);
892c2c66affSColin Finck             if(UDFCleanUpFile__(Vcb, AclInfo))
893c2c66affSColin Finck                 MyFreePool__(AclInfo);
894c2c66affSColin Finck         }
895c2c66affSColin Finck 
896c2c66affSColin Finck         if(SDirInfo) {
897c2c66affSColin Finck             UDFCloseFile__(Vcb, SDirInfo);
898c2c66affSColin Finck             if(UDFCleanUpFile__(Vcb, SDirInfo))
899c2c66affSColin Finck                 MyFreePool__(SDirInfo);
900c2c66affSColin Finck         }
901c2c66affSColin Finck         if(Res1)
902c2c66affSColin Finck             UDFReleaseResource(Res1);
903c2c66affSColin Finck     }
904c2c66affSColin Finck 
905c2c66affSColin Finck     return RC;
906c2c66affSColin Finck 
907c2c66affSColin Finck #endif //!defined(UDF_READ_ONLY_BUILD)
908c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
909c2c66affSColin Finck 
910c2c66affSColin Finck     return STATUS_SUCCESS;
911c2c66affSColin Finck 
912c2c66affSColin Finck } // end UDFWriteSecurity()
913c2c66affSColin Finck 
914c2c66affSColin Finck PSECURITY_DESCRIPTOR
UDFLookUpAcl(IN PVCB Vcb,PFILE_OBJECT FileObject,IN PtrUDFFCB Fcb)915c2c66affSColin Finck UDFLookUpAcl(
916c2c66affSColin Finck     IN PVCB      Vcb,
917c2c66affSColin Finck     PFILE_OBJECT FileObject, // OPTIONAL
918c2c66affSColin Finck     IN PtrUDFFCB Fcb
919c2c66affSColin Finck     )
920c2c66affSColin Finck {
921c2c66affSColin Finck     UDFAssignAcl(Vcb, FileObject, Fcb, Fcb->NTRequiredFCB);
922c2c66affSColin Finck     return (Fcb->NTRequiredFCB->SecurityDesc);
923c2c66affSColin Finck } // end UDFLookUpAcl()
924c2c66affSColin Finck 
925c2c66affSColin Finck 
926c2c66affSColin Finck NTSTATUS
UDFCheckAccessRights(PFILE_OBJECT FileObject,PACCESS_STATE AccessState,PtrUDFFCB Fcb,PtrUDFCCB Ccb,ACCESS_MASK DesiredAccess,USHORT ShareAccess)927c2c66affSColin Finck UDFCheckAccessRights(
928c2c66affSColin Finck     PFILE_OBJECT FileObject, // OPTIONAL
929c2c66affSColin Finck     PACCESS_STATE AccessState,
930c2c66affSColin Finck     PtrUDFFCB    Fcb,
931c2c66affSColin Finck     PtrUDFCCB    Ccb,        // OPTIONAL
932c2c66affSColin Finck     ACCESS_MASK  DesiredAccess,
933c2c66affSColin Finck     USHORT       ShareAccess
934c2c66affSColin Finck     )
935c2c66affSColin Finck {
936c2c66affSColin Finck     NTSTATUS RC;
937c2c66affSColin Finck     BOOLEAN ROCheck = FALSE;
938c2c66affSColin Finck #ifdef UDF_ENABLE_SECURITY
939*38db0744SSerge Gautherie     BOOLEAN SecurityCheck;
940c2c66affSColin Finck     PSECURITY_DESCRIPTOR SecDesc;
941c2c66affSColin Finck     SECURITY_SUBJECT_CONTEXT SubjectContext;
942c2c66affSColin Finck     ACCESS_MASK LocalAccessMask;
943c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
944c2c66affSColin Finck 
945c2c66affSColin Finck     // Check attr compatibility
946c2c66affSColin Finck     ASSERT(Fcb);
947c2c66affSColin Finck     ASSERT(Fcb->Vcb);
948c2c66affSColin Finck #ifdef UDF_READ_ONLY_BUILD
949c2c66affSColin Finck     goto treat_as_ro;
950c2c66affSColin Finck #endif //UDF_READ_ONLY_BUILD
951c2c66affSColin Finck 
952c2c66affSColin Finck     if(Fcb->FCBFlags & UDF_FCB_READ_ONLY) {
953c2c66affSColin Finck         ROCheck = TRUE;
954c2c66affSColin Finck     } else
955c2c66affSColin Finck     if((Fcb->Vcb->origIntegrityType == INTEGRITY_TYPE_OPEN) &&
956c2c66affSColin Finck         Ccb && !(Ccb->CCBFlags & UDF_CCB_VOLUME_OPEN) &&
957c2c66affSColin Finck        (Fcb->Vcb->CompatFlags & UDF_VCB_IC_DIRTY_RO)) {
958c2c66affSColin Finck         AdPrint(("force R/O on dirty\n"));
959c2c66affSColin Finck         ROCheck = TRUE;
960c2c66affSColin Finck     }
961c2c66affSColin Finck     if(ROCheck) {
962c2c66affSColin Finck #ifdef UDF_READ_ONLY_BUILD
963c2c66affSColin Finck treat_as_ro:
964c2c66affSColin Finck #endif //UDF_READ_ONLY_BUILD
965c2c66affSColin Finck         ACCESS_MASK  DesiredAccessMask = 0;
966c2c66affSColin Finck 
967c2c66affSColin Finck         if(Fcb->Vcb->CompatFlags & UDF_VCB_IC_WRITE_IN_RO_DIR) {
968c2c66affSColin Finck             if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
969c2c66affSColin Finck                 DesiredAccessMask = (FILE_WRITE_EA |
970c2c66affSColin Finck                                      DELETE);
971c2c66affSColin Finck             } else {
972c2c66affSColin Finck                 DesiredAccessMask = (FILE_WRITE_DATA |
973c2c66affSColin Finck                                      FILE_APPEND_DATA |
974c2c66affSColin Finck                                      FILE_WRITE_EA |
975c2c66affSColin Finck                                      DELETE);
976c2c66affSColin Finck             }
977c2c66affSColin Finck         } else {
978c2c66affSColin Finck                 DesiredAccessMask = (FILE_WRITE_DATA |
979c2c66affSColin Finck                                      FILE_APPEND_DATA |
980c2c66affSColin Finck                                      FILE_WRITE_EA |
981c2c66affSColin Finck                                      FILE_DELETE_CHILD |
982c2c66affSColin Finck                                      FILE_ADD_SUBDIRECTORY |
983c2c66affSColin Finck                                      FILE_ADD_FILE |
984c2c66affSColin Finck                                      DELETE);
985c2c66affSColin Finck         }
986c2c66affSColin Finck         if(DesiredAccess & DesiredAccessMask)
987c2c66affSColin Finck             return STATUS_ACCESS_DENIED;
988c2c66affSColin Finck     }
989c2c66affSColin Finck #ifdef UDF_ENABLE_SECURITY
990c2c66affSColin Finck     // Check Security
991c2c66affSColin Finck     // NOTE: we should not perform security check if an empty DesiredAccess
992c2c66affSColin Finck     // was specified. AFAIU, SeAccessCheck() will return FALSE in this case.
993c2c66affSColin Finck     SecDesc = UDFLookUpAcl(Fcb->Vcb, FileObject, Fcb);
994c2c66affSColin Finck     if(SecDesc && DesiredAccess) {
995c2c66affSColin Finck         SeCaptureSubjectContext(&SubjectContext);
996c2c66affSColin Finck         SecurityCheck =
997c2c66affSColin Finck             SeAccessCheck(SecDesc,
998c2c66affSColin Finck                           &SubjectContext,
999c2c66affSColin Finck                           FALSE,
1000c2c66affSColin Finck                           DesiredAccess,
1001c2c66affSColin Finck                           Ccb ? Ccb->PreviouslyGrantedAccess : 0,
1002c2c66affSColin Finck                           NULL,
1003c2c66affSColin Finck                           IoGetFileObjectGenericMapping(),
1004c2c66affSColin Finck                           UserMode,
1005c2c66affSColin Finck                           Ccb ? &(Ccb->PreviouslyGrantedAccess) : &LocalAccessMask,
1006c2c66affSColin Finck                           &RC);
1007c2c66affSColin Finck         SeReleaseSubjectContext(&SubjectContext);
1008c2c66affSColin Finck 
1009c2c66affSColin Finck         if(!SecurityCheck) {
1010c2c66affSColin Finck             return RC;
1011c2c66affSColin Finck         } else
1012c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
1013c2c66affSColin Finck         if(DesiredAccess & ACCESS_SYSTEM_SECURITY) {
1014*38db0744SSerge Gautherie             if (!SeSinglePrivilegeCheck(SeExports->SeSecurityPrivilege, UserMode))
1015c2c66affSColin Finck                 return STATUS_ACCESS_DENIED;
1016c2c66affSColin Finck             Ccb->PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY;
1017c2c66affSColin Finck         }
1018c2c66affSColin Finck #ifdef UDF_ENABLE_SECURITY
1019c2c66affSColin Finck     }
1020c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
1021c2c66affSColin Finck     if(FileObject) {
1022c2c66affSColin Finck         if (Fcb->OpenHandleCount) {
1023c2c66affSColin Finck             // The FCB is currently in use by some thread.
1024c2c66affSColin Finck             // We must check whether the requested access/share access
1025c2c66affSColin Finck             // conflicts with the existing open operations.
1026c2c66affSColin Finck             RC = IoCheckShareAccess(DesiredAccess, ShareAccess, FileObject,
1027c2c66affSColin Finck                                             &(Fcb->NTRequiredFCB->FCBShareAccess), TRUE);
1028c2c66affSColin Finck #ifndef UDF_ENABLE_SECURITY
1029c2c66affSColin Finck             if(Ccb)
1030c2c66affSColin Finck                 Ccb->PreviouslyGrantedAccess |= DesiredAccess;
1031c2c66affSColin Finck             IoUpdateShareAccess(FileObject, &(Fcb->NTRequiredFCB->FCBShareAccess));
1032c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
1033c2c66affSColin Finck         } else {
1034c2c66affSColin Finck             IoSetShareAccess(DesiredAccess, ShareAccess, FileObject, &(Fcb->NTRequiredFCB->FCBShareAccess));
1035c2c66affSColin Finck #ifndef UDF_ENABLE_SECURITY
1036c2c66affSColin Finck             if(Ccb)
1037c2c66affSColin Finck                 Ccb->PreviouslyGrantedAccess = DesiredAccess;
1038c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
1039c2c66affSColin Finck             RC = STATUS_SUCCESS;
1040c2c66affSColin Finck         }
1041c2c66affSColin Finck     } else {
1042c2c66affSColin Finck         // we get here if given file was opened for internal purposes
1043c2c66affSColin Finck         RC = STATUS_SUCCESS;
1044c2c66affSColin Finck     }
1045c2c66affSColin Finck     return RC;
1046c2c66affSColin Finck } // end UDFCheckAccessRights()
1047c2c66affSColin Finck 
1048c2c66affSColin Finck NTSTATUS
UDFSetAccessRights(PFILE_OBJECT FileObject,PACCESS_STATE AccessState,PtrUDFFCB Fcb,PtrUDFCCB Ccb,ACCESS_MASK DesiredAccess,USHORT ShareAccess)1049c2c66affSColin Finck UDFSetAccessRights(
1050c2c66affSColin Finck     PFILE_OBJECT FileObject,
1051c2c66affSColin Finck     PACCESS_STATE AccessState,
1052c2c66affSColin Finck     PtrUDFFCB    Fcb,
1053c2c66affSColin Finck     PtrUDFCCB    Ccb,
1054c2c66affSColin Finck     ACCESS_MASK  DesiredAccess,
1055c2c66affSColin Finck     USHORT       ShareAccess
1056c2c66affSColin Finck     )
1057c2c66affSColin Finck {
1058c2c66affSColin Finck #ifndef UDF_ENABLE_SECURITY
1059c2c66affSColin Finck     ASSERT(Ccb);
1060c2c66affSColin Finck     ASSERT(Fcb->FileInfo);
1061c2c66affSColin Finck 
1062c2c66affSColin Finck     return UDFCheckAccessRights(FileObject, AccessState, Fcb, Ccb, DesiredAccess, ShareAccess);
1063c2c66affSColin Finck 
1064c2c66affSColin Finck #else //UDF_ENABLE_SECURITY
1065c2c66affSColin Finck 
1066c2c66affSColin Finck     NTSTATUS RC;
1067c2c66affSColin Finck     // Set Security on Object
1068c2c66affSColin Finck     PSECURITY_DESCRIPTOR SecDesc;
1069c2c66affSColin Finck     SECURITY_SUBJECT_CONTEXT SubjectContext;
1070c2c66affSColin Finck     BOOLEAN AutoInherit;
1071c2c66affSColin Finck 
1072c2c66affSColin Finck     ASSERT(Ccb);
1073c2c66affSColin Finck     ASSERT(Fcb->FileInfo);
1074c2c66affSColin Finck 
1075c2c66affSColin Finck     SecDesc = UDFLookUpAcl(Fcb->Vcb, FileObject, Fcb);
1076c2c66affSColin Finck     AutoInherit = UDFIsAStreamDir(Fcb->FileInfo) || UDFIsAStream(Fcb->FileInfo);
1077c2c66affSColin Finck 
1078c2c66affSColin Finck     if(SecDesc && !AutoInherit) {
1079c2c66affSColin Finck         // Get caller's User/Primary Group info
1080c2c66affSColin Finck         SeCaptureSubjectContext(&SubjectContext);
1081c2c66affSColin Finck         RC = SeAssignSecurity(
1082c2c66affSColin Finck                          Fcb->FileInfo->ParentFile->Dloc->CommonFcb->SecurityDesc,
1083c2c66affSColin Finck //                         NULL,
1084c2c66affSColin Finck                          AccessState->SecurityDescriptor,
1085c2c66affSColin Finck                          &(Fcb->NTRequiredFCB->SecurityDesc),
1086c2c66affSColin Finck                          UDFIsADirectory(Fcb->FileInfo),
1087c2c66affSColin Finck                          &SubjectContext,
1088c2c66affSColin Finck                          IoGetFileObjectGenericMapping(),
1089c2c66affSColin Finck                          NonPagedPool);
1090c2c66affSColin Finck         SeReleaseSubjectContext(&SubjectContext);
1091c2c66affSColin Finck         UDFConvertToSelfRelative(&(Fcb->NTRequiredFCB->SecurityDesc));
1092c2c66affSColin Finck 
1093c2c66affSColin Finck         if(!NT_SUCCESS(RC)) {
1094c2c66affSColin Finck Clean_Up_SD:
1095c2c66affSColin Finck             UDFDeassignAcl(Fcb->NTRequiredFCB, AutoInherit);
1096c2c66affSColin Finck             return RC;
1097c2c66affSColin Finck         }
1098c2c66affSColin Finck     }
1099c2c66affSColin Finck 
1100c2c66affSColin Finck     RC = UDFCheckAccessRights(FileObject, AccessState, Fcb, Ccb, DesiredAccess, ShareAccess);
1101c2c66affSColin Finck     if(!NT_SUCCESS(RC))
1102c2c66affSColin Finck         goto Clean_Up_SD;
1103c2c66affSColin Finck     return RC;
1104c2c66affSColin Finck 
1105c2c66affSColin Finck #endif //UDF_ENABLE_SECURITY
1106c2c66affSColin Finck 
1107c2c66affSColin Finck } // end UDFSetAccessRights()
1108c2c66affSColin Finck 
1109