示例#1
0
        public void AclInheritance()
        {
            NtfsFileSystem ntfs = FileSystemSource.NtfsFileSystem();

            RawSecurityDescriptor sd = new RawSecurityDescriptor("O:BAG:BAD:(A;OICINP;GA;;;BA)");

            ntfs.CreateDirectory("dir");
            ntfs.SetSecurity("dir", sd);

            ntfs.CreateDirectory(@"dir\subdir");
            RawSecurityDescriptor inheritedSd = ntfs.GetSecurity(@"dir\subdir");

            Assert.NotNull(inheritedSd);
            Assert.Equal("O:BAG:BAD:(A;ID;GA;;;BA)", inheritedSd.GetSddlForm(AccessControlSections.All));

            using (ntfs.OpenFile(@"dir\subdir\file", FileMode.Create, FileAccess.ReadWrite)) { }
            inheritedSd = ntfs.GetSecurity(@"dir\subdir\file");
            Assert.NotNull(inheritedSd);
            Assert.Equal("O:BAG:BAD:", inheritedSd.GetSddlForm(AccessControlSections.All));
        }
示例#2
0
        private void CopyFile(NtfsFileSystem sourceNtfs, NtfsFileSystem destNtfs, string path)
        {
            if (IsExcluded(path))
            {
                return;
            }

            using (Stream s = sourceNtfs.OpenFile(path, FileMode.Open, FileAccess.Read))
                using (Stream d = destNtfs.OpenFile(path, FileMode.Create, FileAccess.ReadWrite))
                {
                    d.SetLength(s.Length);
                    int numRead = s.Read(_copyBuffer, 0, _copyBuffer.Length);
                    while (numRead > 0)
                    {
                        d.Write(_copyBuffer, 0, numRead);
                        numRead = s.Read(_copyBuffer, 0, _copyBuffer.Length);
                    }
                }

            destNtfs.SetSecurity(path, sourceNtfs.GetSecurity(path));
            destNtfs.SetFileStandardInformation(path, sourceNtfs.GetFileStandardInformation(path));
        }
示例#3
0
        private static void DoNtfsSecurityComparison(int partition,
                                                     NtfsFileSystem leftFileSystem, DiscFileInfo left,
                                                     NtfsFileSystem rightFileSystem, DiscFileInfo right)
        {
            var leftEntry = leftFileSystem.GetDirectoryEntry(left.FullName);
            var leftRef   = leftFileSystem.GetFile(leftEntry.Reference);

            var rightEntry = rightFileSystem.GetDirectoryEntry(right.FullName);
            var rightRef   = rightFileSystem.GetFile(rightEntry.Reference);

            Info("Partition{0}:{1}: Comparing NTFS meta data", partition, left.FullName);

            // Disable these checks there are problems with the short names DiscUtils assigns

            /* // hard links
             * DoingCheck();
             * var leftRefHardLinkCount = leftRef.HardLinkCount;
             * if (leftRef.HasWin32OrDosName)
             *  leftRefHardLinkCount--; // remove the legacy short name
             *
             * var rightRefHardLinkCount = rightRef.HardLinkCount;
             * if (rightRef.HasWin32OrDosName)
             *  rightRefHardLinkCount--; // remove the legacy short name
             *
             * if (leftRefHardLinkCount != rightRefHardLinkCount)
             * {
             *  Error("Partition{0}:{1}: Non-matching hard link count" +
             *      "(Left: {2}, Right: {3})",
             *      partition, left.FullName, leftRefHardLinkCount, rightRefHardLinkCount);
             * }
             *
             * // file names
             * DoingCheck();
             * var leftRefNamesCount = leftRef.Names.Count;
             * if (leftRef.HasWin32OrDosName)
             *  leftRefNamesCount--; // remove the legacy short name
             *
             * var rightRefNamesCount = rightRef.Names.Count;
             * if (rightRef.HasWin32OrDosName)
             *  rightRefNamesCount--; // remove the legacy short name
             *
             * if (leftRefNamesCount != rightRefNamesCount)
             * {
             *  Error("Partition{0}:{1}: Non-matching file names count" +
             *      "(Left: {2}, Right: {3})",
             *      partition, left.FullName, leftRefNamesCount, rightRefNamesCount);
             * } */

            // security
            var leftSecurity  = leftFileSystem.GetSecurity(left.FullName);
            var rightSecurity = rightFileSystem.GetSecurity(right.FullName);

            DoingCheck();
            if (leftSecurity.BinaryLength != rightSecurity.BinaryLength)
            {
                Error("Partition{0}:{1}: Non-matching security binary length" +
                      "(Left: 0x{2:X}, Right: 0x{3:X})",
                      partition, left.FullName,
                      leftSecurity.BinaryLength, rightSecurity.BinaryLength);
            }

            DoingCheck();
            if (leftSecurity.ControlFlags != rightSecurity.ControlFlags)
            {
                Error("Partition{0}:{1}: Non-matching security control flags" +
                      "(Left: 0x{2:X}, Right: 0x{3:X})",
                      partition, left.FullName,
                      leftSecurity.ControlFlags, rightSecurity.ControlFlags);
            }

            DoingCheck();
            if (leftSecurity.Group != null && rightSecurity.Group != null)
            {
                if (leftSecurity.Group.Value != rightSecurity.Group.Value)
                {
                    Error("Partition{0}:{1}: Non-matching security group name" +
                          "(Left: {2}, Right: {3})",
                          partition, left.FullName,
                          leftSecurity.Group.Value, rightSecurity.Group.Value);
                }
            }
            else if ((leftSecurity.Group == null && rightSecurity.Group != null) ||
                     (leftSecurity.Group != null && rightSecurity.Owner == null))
            {
                Warning("Partition{0}:{1}: No valid NTFS security group found",
                        partition, left.FullName);
            }

            DoingCheck();
            if (leftSecurity.Owner != null && rightSecurity.Owner != null)
            {
                if (leftSecurity.Owner.Value != rightSecurity.Owner.Value)
                {
                    Error("Partition{0}:{1}: Non-matching security owner name" +
                          "(Left: {2}, Right: {3})",
                          partition, left.FullName,
                          leftSecurity.Group.Value, rightSecurity.Group.Value);
                }
            }
            else if ((leftSecurity.Owner == null && rightSecurity.Owner != null) ||
                     (leftSecurity.Owner != null && rightSecurity.Owner == null))
            {
                Warning("Partition{0}:{1}: No valid NTFS security owner found",
                        partition, left.FullName);
            }

            DoingCheck();
            if (leftSecurity.DiscretionaryAcl != null && rightSecurity.DiscretionaryAcl != null)
            {
                if (leftSecurity.DiscretionaryAcl.Count != rightSecurity.DiscretionaryAcl.Count)
                {
                    Error("Partition{0}:{1}: Non-matching count of Discretionary ACL entries" +
                          "(Left: {2}, Right: {3})",
                          partition, left.FullName,
                          leftSecurity.DiscretionaryAcl.Count, rightSecurity.DiscretionaryAcl.Count);
                }
            }
            else if ((leftSecurity.DiscretionaryAcl == null && rightSecurity.DiscretionaryAcl != null) ||
                     (leftSecurity.DiscretionaryAcl != null && rightSecurity.DiscretionaryAcl == null))
            {
                Warning("Partition{0}:{1}: No valid NTFS security Discretionary ACL found",
                        partition, left.FullName);
            }

            DoingCheck();
            if (leftSecurity.SystemAcl != null && rightSecurity.SystemAcl != null)
            {
                if (leftSecurity.SystemAcl.Count != rightSecurity.SystemAcl.Count)
                {
                    Error("Partition{0}:{1}: Non-matching count of System ACL entries" +
                          "(Left: {2}, Right: {3})",
                          partition, left.FullName,
                          leftSecurity.DiscretionaryAcl.Count, rightSecurity.DiscretionaryAcl.Count);
                }
            }
            else if ((leftSecurity.SystemAcl == null && rightSecurity.SystemAcl != null) ||
                     (leftSecurity.SystemAcl != null && rightSecurity.SystemAcl == null))
            {
                Warning("Partition{0}:{1}: No valid NTFS security System ACL found",
                        partition, left.FullName);
            }
        }
示例#4
0
        protected override void DoRun()
        {
            if (DiskSize <= 0)
            {
                DisplayHelp();
                return;
            }

            using (VirtualDisk sourceDisk = VirtualDisk.OpenDisk(_sourceFile.Value, FileAccess.Read, UserName, Password))
                using (VirtualDisk destDisk = VirtualDisk.CreateDisk(OutputDiskType, OutputDiskVariant, _destFile.Value, DiskParameters, UserName, Password))
                {
                    if (destDisk is DiscUtils.Vhd.Disk)
                    {
                        ((DiscUtils.Vhd.Disk)destDisk).AutoCommitFooter = false;
                    }

                    // Copy the MBR from the source disk, and invent a new signature for this new disk
                    destDisk.SetMasterBootRecord(sourceDisk.GetMasterBootRecord());
                    destDisk.Signature = new Random().Next();

                    SparseStream   sourcePartStream = SparseStream.FromStream(sourceDisk.Partitions[0].Open(), Ownership.None);
                    NtfsFileSystem sourceNtfs       = new NtfsFileSystem(sourcePartStream);

                    // Copy the OS boot code into memory, so we can apply it when formatting the new disk
                    byte[] bootCode;
                    using (Stream bootStream = sourceNtfs.OpenFile("$Boot", FileMode.Open, FileAccess.Read))
                    {
                        bootCode = new byte[bootStream.Length];
                        int totalRead = 0;
                        while (totalRead < bootCode.Length)
                        {
                            totalRead += bootStream.Read(bootCode, totalRead, bootCode.Length - totalRead);
                        }
                    }

                    // Partition the new disk with a single NTFS partition
                    BiosPartitionTable.Initialize(destDisk, WellKnownPartitionType.WindowsNtfs);
                    VolumeManager volMgr = new VolumeManager(destDisk);

                    string label = _labelSwitch.IsPresent ? _labelSwitch.Value : sourceNtfs.VolumeLabel;
                    using (NtfsFileSystem destNtfs = NtfsFileSystem.Format(volMgr.GetLogicalVolumes()[0], label, bootCode))
                    {
                        destNtfs.SetSecurity(@"\", sourceNtfs.GetSecurity(@"\"));
                        destNtfs.NtfsOptions.ShortNameCreation = ShortFileNameOption.Disabled;

                        sourceNtfs.NtfsOptions.HideHiddenFiles = false;
                        sourceNtfs.NtfsOptions.HideSystemFiles = false;
                        CopyFiles(sourceNtfs, destNtfs, @"\", true);

                        if (destNtfs.FileExists(@"\boot\BCD"))
                        {
                            // Force all boot entries in the BCD to point to the newly created NTFS partition - does _not_ cope with
                            // complex multi-volume / multi-boot scenarios at all.
                            using (Stream bcdStream = destNtfs.OpenFile(@"\boot\BCD", FileMode.Open, FileAccess.ReadWrite))
                            {
                                using (RegistryHive hive = new RegistryHive(bcdStream))
                                {
                                    Store store = new Store(hive.Root);
                                    foreach (var obj in store.Objects)
                                    {
                                        foreach (var elem in obj.Elements)
                                        {
                                            if (elem.Format == DiscUtils.BootConfig.ElementFormat.Device)
                                            {
                                                elem.Value = DiscUtils.BootConfig.ElementValue.ForDevice(elem.Value.ParentObject, volMgr.GetPhysicalVolumes()[0]);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }
示例#5
0
        private void CopyFiles(NtfsFileSystem sourceNtfs, NtfsFileSystem destNtfs, string path, bool subs)
        {
            if (subs)
            {
                foreach (var dir in sourceNtfs.GetDirectories(path))
                {
                    if (!IsExcluded(dir))
                    {
                        int  hardLinksRemaining = sourceNtfs.GetHardLinkCount(dir) - 1;
                        bool newDir             = false;

                        long   sourceFileId = sourceNtfs.GetFileId(dir);
                        string refPath;
                        if (_uniqueFiles.TryGetValue(sourceFileId, out refPath))
                        {
                            // If this is another name for a known dir, recreate the hard link
                            destNtfs.CreateHardLink(refPath, dir);
                        }
                        else
                        {
                            destNtfs.CreateDirectory(dir);
                            newDir = true;

                            FileAttributes fileAttrs = sourceNtfs.GetAttributes(dir);
                            if ((fileAttrs & FileAttributes.ReparsePoint) != 0)
                            {
                                destNtfs.SetReparsePoint(dir, sourceNtfs.GetReparsePoint(dir));
                            }

                            destNtfs.SetAttributes(dir, fileAttrs);

                            destNtfs.SetSecurity(dir, sourceNtfs.GetSecurity(dir));
                        }

                        // File may have a short name
                        string shortName = sourceNtfs.GetShortName(dir);
                        if (!string.IsNullOrEmpty(shortName) && shortName != dir)
                        {
                            destNtfs.SetShortName(dir, shortName);
                            --hardLinksRemaining;
                        }


                        if (newDir)
                        {
                            if (hardLinksRemaining > 0)
                            {
                                _uniqueFiles[sourceFileId] = dir;
                            }
                            CopyFiles(sourceNtfs, destNtfs, dir, subs);
                        }

                        // Set standard information last (includes modification timestamps)
                        destNtfs.SetFileStandardInformation(dir, sourceNtfs.GetFileStandardInformation(dir));
                    }
                }
            }

            foreach (var file in sourceNtfs.GetFiles(path))
            {
                Console.WriteLine(file);

                int hardLinksRemaining = sourceNtfs.GetHardLinkCount(file) - 1;

                long sourceFileId = sourceNtfs.GetFileId(file);

                string refPath;
                if (_uniqueFiles.TryGetValue(sourceFileId, out refPath))
                {
                    // If this is another name for a known file, recreate the hard link
                    destNtfs.CreateHardLink(refPath, file);
                }
                else
                {
                    CopyFile(sourceNtfs, destNtfs, file);

                    if (hardLinksRemaining > 0)
                    {
                        _uniqueFiles[sourceFileId] = file;
                    }
                }

                // File may have a short name
                string shortName = sourceNtfs.GetShortName(file);
                if (!string.IsNullOrEmpty(shortName) && shortName != file)
                {
                    destNtfs.SetShortName(file, shortName);
                }
            }
        }