Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

392 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. SeInfo.c
  5. Abstract:
  6. This module implements the Security Info routines for NTFS called by the
  7. dispatch driver.
  8. Author:
  9. Gary Kimura [GaryKi] 26-Dec-1991
  10. Revision History:
  11. --*/
  12. #include "NtfsProc.h"
  13. //
  14. // The debug trace level
  15. //
  16. #define Dbg (DEBUG_TRACE_SEINFO)
  17. #ifdef ALLOC_PRAGMA
  18. #pragma alloc_text(PAGE, NtfsCommonQuerySecurityInfo)
  19. #pragma alloc_text(PAGE, NtfsCommonSetSecurityInfo)
  20. #endif
  21. NTSTATUS
  22. NtfsCommonQuerySecurityInfo (
  23. IN PIRP_CONTEXT IrpContext,
  24. IN PIRP Irp
  25. )
  26. /*++
  27. Routine Description:
  28. This is the common routine for querying security information called by
  29. both the fsd and fsp threads.
  30. Arguments:
  31. Irp - Supplies the Irp to process
  32. Return Value:
  33. NTSTATUS - the return status for the operation
  34. --*/
  35. {
  36. NTSTATUS Status;
  37. PIO_STACK_LOCATION IrpSp;
  38. PFILE_OBJECT FileObject;
  39. TYPE_OF_OPEN TypeOfOpen;
  40. PVCB Vcb;
  41. PFCB Fcb;
  42. PSCB Scb;
  43. PCCB Ccb;
  44. BOOLEAN AcquiredFcb = TRUE;
  45. ASSERT_IRP_CONTEXT( IrpContext );
  46. ASSERT_IRP( Irp );
  47. ASSERT( FlagOn( IrpContext->TopLevelIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL ));
  48. PAGED_CODE();
  49. //
  50. // Get the current Irp stack location
  51. //
  52. IrpSp = IoGetCurrentIrpStackLocation( Irp );
  53. DebugTrace( +1, Dbg, ("NtfsCommonQuerySecurityInfo") );
  54. DebugTrace( 0, Dbg, ("IrpContext = %08lx\n", IrpContext) );
  55. DebugTrace( 0, Dbg, ("Irp = %08lx\n", Irp) );
  56. //
  57. // Extract and decode the file object
  58. //
  59. FileObject = IrpSp->FileObject;
  60. TypeOfOpen = NtfsDecodeFileObject( IrpContext, FileObject, &Vcb, &Fcb, &Scb, &Ccb, TRUE );
  61. //
  62. // The only type of opens we accept are user file and directory opens
  63. //
  64. if ((TypeOfOpen != UserFileOpen)
  65. && (TypeOfOpen != UserDirectoryOpen)
  66. && (TypeOfOpen != UserViewIndexOpen)) {
  67. Status = STATUS_INVALID_PARAMETER;
  68. } else {
  69. //
  70. // Our operation is to acquire the fcb, do the operation and then
  71. // release the fcb. If the security descriptor for this file is
  72. // not already loaded we will release the Fcb and then acquire both
  73. // the Vcb and Fcb. We must have the Vcb to examine our parent's
  74. // security descriptor.
  75. //
  76. NtfsAcquireSharedFcb( IrpContext, Fcb, NULL, 0 );
  77. try {
  78. if (Fcb->SharedSecurity == NULL) {
  79. NtfsReleaseFcb( IrpContext, Fcb );
  80. AcquiredFcb = FALSE;
  81. NtfsAcquireExclusiveFcb( IrpContext, Fcb, NULL, 0 );
  82. AcquiredFcb = TRUE;
  83. }
  84. //
  85. // Make sure the volume is still mounted.
  86. //
  87. if (FlagOn( Scb->ScbState, SCB_STATE_VOLUME_DISMOUNTED )) {
  88. Status = STATUS_VOLUME_DISMOUNTED;
  89. leave;
  90. }
  91. Status = NtfsQuerySecurity( IrpContext,
  92. Fcb,
  93. &IrpSp->Parameters.QuerySecurity.SecurityInformation,
  94. (PSECURITY_DESCRIPTOR)Irp->UserBuffer,
  95. &IrpSp->Parameters.QuerySecurity.Length );
  96. if (NT_SUCCESS( Status )) {
  97. Irp->IoStatus.Information = IrpSp->Parameters.QuerySecurity.Length;
  98. } else if (Status == STATUS_BUFFER_TOO_SMALL) {
  99. Irp->IoStatus.Information = IrpSp->Parameters.QuerySecurity.Length;
  100. Status = STATUS_BUFFER_OVERFLOW;
  101. }
  102. //
  103. // Abort transaction on error by raising.
  104. //
  105. NtfsCleanupTransaction( IrpContext, Status, FALSE );
  106. } finally {
  107. DebugUnwind( NtfsCommonQuerySecurityInfo );
  108. if (AcquiredFcb) {
  109. NtfsReleaseFcb( IrpContext, Fcb );
  110. }
  111. }
  112. }
  113. //
  114. // Now complete the request and return to our caller
  115. //
  116. NtfsCompleteRequest( IrpContext, Irp, Status );
  117. DebugTrace( -1, Dbg, ("NtfsCommonQuerySecurityInfo -> %08lx", Status) );
  118. return Status;
  119. }
  120. NTSTATUS
  121. NtfsCommonSetSecurityInfo (
  122. IN PIRP_CONTEXT IrpContext,
  123. IN PIRP Irp
  124. )
  125. /*++
  126. Routine Description:
  127. This is the common routine for Setting security information called by
  128. both the fsd and fsp threads.
  129. Arguments:
  130. Irp - Supplies the Irp to process
  131. Return Value:
  132. NTSTATUS - the return status for the operation
  133. --*/
  134. {
  135. NTSTATUS Status;
  136. PIO_STACK_LOCATION IrpSp;
  137. PFILE_OBJECT FileObject;
  138. PQUOTA_CONTROL_BLOCK OldQuotaControl = NULL;
  139. ULONG OldOwnerId;
  140. ULONG LargeStdInfo;
  141. TYPE_OF_OPEN TypeOfOpen;
  142. PVCB Vcb;
  143. PFCB Fcb;
  144. PSCB Scb;
  145. PCCB Ccb;
  146. ASSERT_IRP_CONTEXT( IrpContext );
  147. ASSERT_IRP( Irp );
  148. ASSERT( FlagOn( IrpContext->TopLevelIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL ));
  149. PAGED_CODE();
  150. //
  151. // Get the current Irp stack location
  152. //
  153. IrpSp = IoGetCurrentIrpStackLocation( Irp );
  154. DebugTrace( +1, Dbg, ("NtfsCommonSetSecurityInfo") );
  155. DebugTrace( 0, Dbg, ("IrpContext = %08lx\n", IrpContext) );
  156. DebugTrace( 0, Dbg, ("Irp = %08lx\n", Irp) );
  157. //
  158. // Extract and decode the file object
  159. //
  160. FileObject = IrpSp->FileObject;
  161. TypeOfOpen = NtfsDecodeFileObject( IrpContext, FileObject, &Vcb, &Fcb, &Scb, &Ccb, TRUE );
  162. //
  163. // The only type of opens we accept are user file and directory opens
  164. //
  165. if ((TypeOfOpen != UserFileOpen)
  166. && (TypeOfOpen != UserDirectoryOpen)
  167. && (TypeOfOpen != UserViewIndexOpen)) {
  168. Status = STATUS_INVALID_PARAMETER;
  169. } else if (NtfsIsVolumeReadOnly( Vcb )) {
  170. Status = STATUS_MEDIA_WRITE_PROTECTED;
  171. } else {
  172. //
  173. // Capture the source information.
  174. //
  175. IrpContext->SourceInfo = Ccb->UsnSourceInfo;
  176. //
  177. // Our operation is to acquire the fcb, do the operation and then
  178. // release the fcb
  179. //
  180. NtfsAcquireExclusiveFcb( IrpContext, Fcb, NULL, 0 );
  181. try {
  182. //
  183. // Make sure the volume is still mounted.
  184. //
  185. if (FlagOn( Scb->ScbState, SCB_STATE_VOLUME_DISMOUNTED )) {
  186. Status = STATUS_VOLUME_DISMOUNTED;
  187. leave;
  188. }
  189. //
  190. // Post the change to the Usn Journal.
  191. //
  192. NtfsPostUsnChange( IrpContext, Scb, USN_REASON_SECURITY_CHANGE );
  193. //
  194. // Capture the current OwnerId, Qutoa Control Block and
  195. // size of standard information.
  196. //
  197. OldQuotaControl = Fcb->QuotaControl;
  198. OldOwnerId = Fcb->OwnerId;
  199. LargeStdInfo = Fcb->FcbState & FCB_STATE_LARGE_STD_INFO;
  200. Status = NtfsModifySecurity( IrpContext,
  201. Fcb,
  202. &IrpSp->Parameters.SetSecurity.SecurityInformation,
  203. IrpSp->Parameters.SetSecurity.SecurityDescriptor );
  204. if (NT_SUCCESS( Status )) {
  205. //
  206. // Make sure the new security descriptor Id is written out.
  207. //
  208. NtfsUpdateStandardInformation( IrpContext, Fcb );
  209. }
  210. //
  211. // Abort transaction on error by raising.
  212. //
  213. NtfsCleanupTransaction( IrpContext, Status, FALSE );
  214. //
  215. // Set the flag in the Ccb to indicate this change occurred.
  216. //
  217. if (!IsDirectory( &Fcb->Info )) {
  218. SetFlag( Ccb->Flags, CCB_FLAG_UPDATE_LAST_CHANGE | CCB_FLAG_SET_ARCHIVE );
  219. }
  220. } finally {
  221. DebugUnwind( NtfsCommonSetSecurityInfo );
  222. if (AbnormalTermination()) {
  223. //
  224. // The request failed. Restore the owner and
  225. // QuotaControl are restored.
  226. //
  227. if ((Fcb->QuotaControl != OldQuotaControl) &&
  228. (Fcb->QuotaControl != NULL)) {
  229. //
  230. // A new quota control block was assigned.
  231. // Dereference it.
  232. //
  233. NtfsDereferenceQuotaControlBlock( Fcb->Vcb,
  234. &Fcb->QuotaControl );
  235. }
  236. Fcb->QuotaControl = OldQuotaControl;
  237. Fcb->OwnerId = OldOwnerId;
  238. if (LargeStdInfo == 0) {
  239. //
  240. // The standard information has be returned to
  241. // its orginal size.
  242. //
  243. ClearFlag( Fcb->FcbState, FCB_STATE_LARGE_STD_INFO );
  244. }
  245. } else {
  246. //
  247. // The request succeed. If the quota control block was
  248. // changed then derefence the old block.
  249. //
  250. if ((Fcb->QuotaControl != OldQuotaControl) &&
  251. (OldQuotaControl != NULL)) {
  252. NtfsDereferenceQuotaControlBlock( Fcb->Vcb,
  253. &OldQuotaControl);
  254. }
  255. }
  256. }
  257. }
  258. //
  259. // Now complete the request and return to our caller
  260. //
  261. NtfsCompleteRequest( IrpContext, Irp, Status );
  262. DebugTrace( -1, Dbg, ("NtfsCommonSetSecurityInfo -> %08lx", Status) );
  263. return Status;
  264. }