internal static void SetAccessControlInternal(string path, SafeHandle handle, ObjectSecurity objectSecurity, AccessControlSections includeSections, PathFormat pathFormat)
      {
         if (pathFormat == PathFormat.RelativePath)
            Path.CheckValidPath(path, true, true);

         if (objectSecurity == null)
            throw new ArgumentNullException("objectSecurity");

         byte[] managedDescriptor = objectSecurity.GetSecurityDescriptorBinaryForm();
         using (var safeBuffer = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length))
         {
            string pathLp = Path.GetExtendedLengthPathInternal(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars);

            safeBuffer.CopyFrom(managedDescriptor, 0, managedDescriptor.Length);

            SecurityDescriptorControl control;
            uint revision;
            if (!Security.NativeMethods.GetSecurityDescriptorControl(safeBuffer, out control, out revision))
               NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp);

            PrivilegeEnabler privilegeEnabler = null;
            try
            {
               var securityInfo = SecurityInformation.None;

               IntPtr pDacl = IntPtr.Zero;
               if ((includeSections & AccessControlSections.Access) != 0)
               {
                  bool daclDefaulted, daclPresent;
                  if (!Security.NativeMethods.GetSecurityDescriptorDacl(safeBuffer, out daclPresent, out pDacl, out daclDefaulted))
                     NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp);

                  if (daclPresent)
                  {
                     securityInfo |= SecurityInformation.Dacl;
                     securityInfo |= (control & SecurityDescriptorControl.DaclProtected) != 0
                        ? SecurityInformation.ProtectedDacl
                        : SecurityInformation.UnprotectedDacl;
                  }
               }

               IntPtr pSacl = IntPtr.Zero;
               if ((includeSections & AccessControlSections.Audit) != 0)
               {
                  bool saclDefaulted, saclPresent;
                  if (!Security.NativeMethods.GetSecurityDescriptorSacl(safeBuffer, out saclPresent, out pSacl, out saclDefaulted))
                     NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp);

                  if (saclPresent)
                  {
                     securityInfo |= SecurityInformation.Sacl;
                     securityInfo |= (control & SecurityDescriptorControl.SaclProtected) != 0
                        ? SecurityInformation.ProtectedSacl
                        : SecurityInformation.UnprotectedSacl;

                     privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
                  }
               }

               IntPtr pOwner = IntPtr.Zero;
               if ((includeSections & AccessControlSections.Owner) != 0)
               {
                  bool ownerDefaulted;
                  if (!Security.NativeMethods.GetSecurityDescriptorOwner(safeBuffer, out pOwner, out ownerDefaulted))
                     NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp);

                  if (pOwner != IntPtr.Zero)
                     securityInfo |= SecurityInformation.Owner;
               }

               IntPtr pGroup = IntPtr.Zero;
               if ((includeSections & AccessControlSections.Group) != 0)
               {
                  bool groupDefaulted;
                  if (!Security.NativeMethods.GetSecurityDescriptorGroup(safeBuffer, out pGroup, out groupDefaulted))
                     NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp);

                  if (pGroup != IntPtr.Zero)
                     securityInfo |= SecurityInformation.Group;
               }


               uint lastError;
               if (!Utils.IsNullOrWhiteSpace(pathLp))
               {
                  // SetNamedSecurityInfo()
                  // In the ANSI version of this function, the name is limited to MAX_PATH characters.
                  // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
                  // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.

                  lastError = Security.NativeMethods.SetNamedSecurityInfo(pathLp, ObjectType.FileObject, securityInfo, pOwner, pGroup, pDacl, pSacl);
                  if (lastError != Win32Errors.ERROR_SUCCESS)
                     NativeError.ThrowException(lastError, pathLp);
               }
               else if (NativeMethods.IsValidHandle(handle))
               {
                  lastError = Security.NativeMethods.SetSecurityInfo(handle, ObjectType.FileObject, securityInfo, pOwner, pGroup, pDacl, pSacl);
                  if (lastError != Win32Errors.ERROR_SUCCESS)
                     NativeError.ThrowException((int)lastError);
               }
            }
            finally
            {
               if (privilegeEnabler != null)
                  privilegeEnabler.Dispose();
            }
         }
      }
Exemple #2
0
        internal static void SetSecurityInfo(SafeHandle handle, NativeMethods.SE_OBJECT_TYPE objectType, NativeObjectSecurity fileSecurity)
        {
            byte[] managedDescriptor = fileSecurity.GetSecurityDescriptorBinaryForm();
            using (SafeGlobalMemoryBufferHandle hDescriptor = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length))
            {
                hDescriptor.CopyFrom(managedDescriptor, 0, managedDescriptor.Length);


                NativeMethods.SECURITY_DESCRIPTOR_CONTROL control;
                uint revision;
                if (!NativeMethods.GetSecurityDescriptorControl(hDescriptor, out control, out revision))
                {
                    NativeError.ThrowException();
                }

                IntPtr pDacl;
                bool   daclDefaulted, daclPresent;
                if (!NativeMethods.GetSecurityDescriptorDacl(hDescriptor, out daclPresent, out pDacl, out daclDefaulted))
                {
                    NativeError.ThrowException();
                }

                IntPtr pSacl;
                bool   saclDefaulted, saclPresent;
                if (!NativeMethods.GetSecurityDescriptorSacl(hDescriptor, out saclPresent, out pSacl, out saclDefaulted))
                {
                    NativeError.ThrowException();
                }

                IntPtr pOwner;
                bool   ownerDefaulted;
                if (!NativeMethods.GetSecurityDescriptorOwner(hDescriptor, out pOwner, out ownerDefaulted))
                {
                    NativeError.ThrowException();
                }

                IntPtr pGroup;
                bool   GroupDefaulted;
                if (!NativeMethods.GetSecurityDescriptorGroup(hDescriptor, out pGroup, out GroupDefaulted))
                {
                    NativeError.ThrowException();
                }

                PrivilegeEnabler privilegeEnabler = null;
                try
                {
                    NativeMethods.SECURITY_INFORMATION info = 0;

                    if (daclPresent)
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.DACL_SECURITY_INFORMATION;

                        if ((control & NativeMethods.SECURITY_DESCRIPTOR_CONTROL.SE_DACL_PROTECTED) != 0)
                        {
                            info |= NativeMethods.SECURITY_INFORMATION.PROTECTED_DACL_SECURITY_INFORMATION;
                        }
                        else
                        {
                            info |= NativeMethods.SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION;
                        }
                    }

                    if (saclPresent)
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.SACL_SECURITY_INFORMATION;
                        if ((control & NativeMethods.SECURITY_DESCRIPTOR_CONTROL.SE_SACL_PROTECTED) != 0)
                        {
                            info |= NativeMethods.SECURITY_INFORMATION.PROTECTED_SACL_SECURITY_INFORMATION;
                        }
                        else
                        {
                            info |= NativeMethods.SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION;
                        }

                        privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
                    }

                    if (pOwner != IntPtr.Zero)
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION;
                    }

                    if (pGroup != IntPtr.Zero)
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION;
                    }

                    uint errorCode = NativeMethods.SetSecurityInfo(handle, objectType, info, pOwner, pGroup, pDacl, pSacl);

                    if (errorCode != 0)
                    {
                        NativeError.ThrowException((int)errorCode);
                    }
                }
                finally
                {
                    if (privilegeEnabler != null)
                    {
                        privilegeEnabler.Dispose();
                    }
                }
            }
        }
Exemple #3
0
      internal static SafeFileHandle CreateFileInternal(KernelTransaction transaction, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, PathFormat pathFormat)
      {
         if (checkPath && pathFormat == PathFormat.RelativePath)
            Path.CheckValidPath(path, true, true);

         // When isFile == null, we're working with a device.
         // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive),
         // the path string should be the following form: "\\.\X:"
         // Do not use a trailing backslash (\), which indicates the root.

         string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);

         PrivilegeEnabler privilegeEnabler = null;
         try
         {
            if (fileSecurity != null)
               fileSystemRights |= (FileSystemRights)0x1000000;

            // AccessSystemSecurity = 0x1000000    AccessSystemAcl access type.
            // MaximumAllowed       = 0x2000000    MaximumAllowed access type.            
            if ((fileSystemRights & (FileSystemRights)0x1000000) != 0 ||
                (fileSystemRights & (FileSystemRights)0x2000000) != 0)
               privilegeEnabler = new PrivilegeEnabler(Privilege.Security);


            using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity))
            {
               SafeFileHandle handle = transaction == null || !NativeMethods.IsAtLeastWindowsVista

                  // CreateFile() / CreateFileTransacted()
                  // In the ANSI version of this function, the name is limited to MAX_PATH characters.
                  // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
                  // 2013-01-13: MSDN confirms LongPath usage.

                  ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero)
                  : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero);

               int lastError = Marshal.GetLastWin32Error();
               if (handle.IsInvalid)
               {
                  handle.Close();
                  NativeError.ThrowException(lastError, pathLp);
               }

               return handle;
            }
         }
         finally
         {
            if (privilegeEnabler != null)
               privilegeEnabler.Dispose();
         }
      }