Пример #1
0
        public void ProblemsWithLocation_FolderReadOnly_Fails()
        {
            using (var tempFolder = new TemporaryFolder(MethodBase.GetCurrentMethod().Name))
            {
                if (SIL.PlatformUtilities.Platform.IsWindows)
                {
                    var di = new DirectoryInfo(tempFolder.FolderPath);
                    var directorySecurity   = di.GetAccessControl();
                    var currentUserIdentity = WindowsIdentity.GetCurrent();
                    var fileSystemRule      = new FileSystemAccessRule(currentUserIdentity.Name,
                                                                       FileSystemRights.Write,
                                                                       InheritanceFlags.ObjectInherit |
                                                                       InheritanceFlags.ContainerInherit,
                                                                       PropagationFlags.None,
                                                                       AccessControlType.Deny);

                    directorySecurity.AddAccessRule(fileSystemRule);
                    di.SetAccessControl(directorySecurity);
                    Assert.That(_api.ProblemsWithLocation(tempFolder.FolderPath),
                                Contains.Substring("Bloom does not have permission to write to the selected folder"));
                    directorySecurity.RemoveAccessRule(fileSystemRule);
                    di.SetAccessControl(directorySecurity);
                }
                else
                {
                    var udi         = new Mono.Unix.UnixDirectoryInfo(tempFolder.FolderPath);
                    var permissions = udi.FileAccessPermissions;
                    udi.FileAccessPermissions =
                        Mono.Unix.FileAccessPermissions.UserRead | Mono.Unix.FileAccessPermissions.GroupRead | Mono.Unix.FileAccessPermissions.OtherRead;
                    Assert.That(_api.ProblemsWithLocation(tempFolder.FolderPath),
                                Contains.Substring("Bloom does not have permission to write to the selected folder"));
                    udi.FileAccessPermissions = permissions;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Gets the sysfs partitions.
        /// </summary>
        /// <returns>
        /// The sysfs partitions.
        /// </returns>
        /// <param name='diskPath'>
        /// Disk path. (eg /sys/devices/virtual/block/loop0)
        /// </param>
        /// <param name='diskName'>
        /// Disk name. (eg loop0)
        /// </param>
        internal List <Partition> GetSysfsPartitions(string diskPath, string diskName)
        {
            List <Partition> parts = new List <Partition>();

            Mono.Unix.UnixDirectoryInfo diskDir = new Mono.Unix.UnixDirectoryInfo(diskPath);
            foreach (Mono.Unix.Native.Dirent part in diskDir.GetEntries(diskName + ".*"))
            {
                Partition p = new Partition();
                p.Path   = "/dev/" + part.d_name;
                p.Offset = ulong.Parse(File.ReadAllText(diskPath + "/" + part.d_name + "/start"));
                p.Size   = long.Parse(File.ReadAllText(diskPath + "/" + part.d_name + "/size"));
                parts.Add(p);
            }
            return(parts);
        }
Пример #3
0
 /// <summary>
 /// returns the partition name (sdX format) from any by-xxxx value (by-path, by-uuid...)
 /// </summary>
 /// <param name='partitionName'>
 /// Partition name.
 /// </param>/
 private string GetPartitionFromPathOrUuid(string partitionName)
 {
     string[] disksBy = new string[] { "by-uuid", "by-path", "by-label", "by-id" };
     foreach (string byType in disksBy)
     {
         Mono.Unix.UnixDirectoryInfo byUuidParts = new Mono.Unix.UnixDirectoryInfo("/dev/disk/" + byType);
         foreach (Mono.Unix.Native.Dirent d in byUuidParts.GetEntries())
         {
             //Console.WriteLine ("______GetPartitionFromPathOrUuid looking cur entry="+d.d_name+", type="+d.d_type);
             if (d.d_type == 10 /*Mono.Unix.FileTypes.SymbolicLink*/)
             {
                 string partOnlyName = "";
                 if (partitionName.LastIndexOf("/") >= 0)
                 {
                     partOnlyName = partitionName.Substring(partitionName.LastIndexOf("/") + 1);
                 }
                 else if (partitionName.IndexOf("UUID=") == 0)
                 {
                     partOnlyName = partitionName.Replace("UUID=", "");
                 }
                 else
                 {
                     partOnlyName = partitionName;
                 }
                 //Console.WriteLine ("______GetPartitionFromPathOrUuid :d_name="+d.d_name+", partonlyname="+partOnlyName);
                 if (d.d_name == partOnlyName)
                 {
                     Mono.Unix.UnixSymbolicLinkInfo devLink = new Mono.Unix.UnixSymbolicLinkInfo(byUuidParts + "/" + d.d_name);
                     //Console.WriteLine ("______GetPartitionFromPathOrUuid : "+partitionName+" --> /dev/"+devLink.ContentsPath.Substring(devLink.ContentsPath.LastIndexOf('/')+1));
                     return("/dev/" + devLink.ContentsPath.Substring(devLink.ContentsPath.LastIndexOf('/') + 1));
                 }
             }
         }
     }
     // partition was probably referenced by its devics (/dev/sdXX) path, nothing to do
     return(partitionName);
 }
Пример #4
0
        public static string GetPathDetails(FileSystemInfo fs, string name)
        {
            string pathname = fs.FullName;

#if !__MonoCS__
            bool isDir = Directory.Exists(pathname);
#else
            bool isDir = (fs.Attributes & System.IO.FileAttributes.Directory) != 0;
#endif

            char   d    = isDir ? 'd' : '-';
            string last = fs.LastWriteTime.ToString("MMM dd yyyy HH:mm");

            string user        = string.Empty;
            string group       = string.Empty;
            string links       = null;
            string permissions = "rwx";
            long   size        = 0;


#if __MonoCS__
            Mono.Unix.UnixFileSystemInfo info;
            if (isDir)
            {
                info = new Mono.Unix.UnixDirectoryInfo(pathname);
            }
            else
            {
                info = new Mono.Unix.UnixFileInfo(pathname);
            }

            char ur = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.UserRead) != 0 ? 'r' : '-';
            char uw = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.UserWrite) != 0 ? 'w' : '-';
            char ux = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.UserExecute) != 0 ? 'x' : '-';
            char gr = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.GroupRead) != 0 ? 'r' : '-';
            char gw = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.GroupWrite) != 0 ? 'w' : '-';
            char gx = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.GroupExecute) != 0 ? 'x' : '-';
            char or = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.OtherRead) != 0 ? 'r' : '-';
            char ow = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.OtherWrite) != 0 ? 'w' : '-';
            char ox = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.OtherExecute) != 0 ? 'x' : '-';

            permissions = string.Format("{0}{1}{2}{3}{4}{5}{6}{7}{8}",
                                        ur, uw, ux, gr, gw, gx, or, ow, ox);

            user  = info.OwnerUser.UserName;
            group = info.OwnerGroup.GroupName;
            links = info.LinkCount.ToString();

            size = info.Length;

            if (info.IsSymbolicLink)
            {
                d = 's';
            }
#else
            if (isDir)
            {
                user = Directory.GetAccessControl(fs.FullName).GetOwner(
                    typeof(System.Security.Principal.NTAccount)).ToString();

                DirectoryInfo di = fs as DirectoryInfo;
                size = di.GetFileSystemInfos().Length;
            }
            else
            {
                user = File.GetAccessControl(fs.FullName).GetOwner(
                    typeof(System.Security.Principal.NTAccount)).ToString();
                FileInfo fi = fs as FileInfo;
                size = fi.Length;

                string[] execs = new string[] { "exe", "bat", "msi" };
                char     x     = execs.Contains(fi.Extension.ToLower()) ? 'x' : '-';
                char     w     = !fi.IsReadOnly ? 'w' : '-';
                permissions = string.Format("r{0}{1}", w, x);
            }
#endif

            string data = string.Format("{0}{1} {2,4} {3,8} {4,8} {5,9} {6,23} {7}",
                                        d, permissions, links, user, group, size, last, name);

            return(data);
        }
Пример #5
0
        public static string CollectFilePermissionInformation(string filePath)
        {
            var bldr = new StringBuilder();

            try
            {
                if (SIL.PlatformUtilities.Platform.IsWindows)
                {
                    var currentUser = System.Security.Principal.WindowsIdentity.GetCurrent();
                    bldr.AppendLine($"current user is {currentUser.Name}");
                    var  principal          = new System.Security.Principal.WindowsPrincipal(currentUser);
                    bool isInRoleWithAccess = false;
                    bool accessDenied       = false;
                    bool accessAllowed      = false;
                    System.Security.AccessControl.FileSystemRights accessRights = System.Security.AccessControl.FileSystemRights.Write;
                    var acl   = File.GetAccessControl(filePath);
                    var rules = acl.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
                    var sid   = acl.GetOwner(typeof(System.Security.Principal.SecurityIdentifier));
                    var acct  = sid.Translate(typeof(System.Security.Principal.NTAccount)) as System.Security.Principal.NTAccount;
                    if (acct != null)
                    {
                        bldr.AppendLine($"owner of \"{filePath}\" is {acct.Value}");
                    }
                    var fileAttributes = RobustFile.GetAttributes(filePath);
                    bldr.AppendLine($"{filePath} current ReadOnly attribute of {filePath} is {(fileAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly}");
                    foreach (System.Security.AccessControl.AuthorizationRule rule in rules)
                    {
                        var fsAccessRule = rule as System.Security.AccessControl.FileSystemAccessRule;
                        if (fsAccessRule == null)
                        {
                            continue;
                        }
                        if ((fsAccessRule.FileSystemRights & accessRights) > 0)
                        {
                            var ntAccount = rule.IdentityReference as System.Security.Principal.NTAccount;
                            if (ntAccount == null)
                            {
                                continue;
                            }
                            if (principal.IsInRole(ntAccount.Value))
                            {
                                if (fsAccessRule.AccessControlType == System.Security.AccessControl.AccessControlType.Deny)
                                {
                                    bldr.AppendLine($"current user is denied write access to {filePath} by {ntAccount.Value}{(rule.IsInherited ? " (inherited)":"")}");
                                    accessDenied = true;
                                }
                                if (fsAccessRule.AccessControlType == System.Security.AccessControl.AccessControlType.Allow)
                                {
                                    bldr.AppendLine($"current user is allowed write access to {filePath} by {ntAccount.Value}{(rule.IsInherited ? " (inherited)":"")}");
                                    accessAllowed = true;
                                }
                                isInRoleWithAccess = true;
                            }
                        }
                    }
                    if (isInRoleWithAccess)
                    {
                        if (!accessAllowed)
                        {
                            bldr.AppendLine($"current user is not explicitly allowed write access to {filePath}");
                        }
                        if (!accessDenied)
                        {
                            bldr.AppendLine($"current user is not explicitly denied write access to {filePath}");
                        }
                    }
                    else
                    {
                        bldr.AppendLine($"current user is not explicitly given access to {filePath}");
                    }
                }
                else
                {
                    var folder   = Path.GetDirectoryName(filePath);
                    var fileInfo = new Mono.Unix.UnixFileInfo(filePath);
                    var dirInfo  = new Mono.Unix.UnixDirectoryInfo(folder);
                    var userInfo = Mono.Unix.UnixUserInfo.GetRealUser();
                    bldr.AppendLine($"current user is {userInfo.UserName}");
                    bldr.AppendLine($"owner of \"{filePath}\" is {fileInfo.OwnerUser.UserName}");
                    bldr.AppendLine($"permissions of \"{filePath}\" = {fileInfo.FileAccessPermissions.ToString()}");
                    bldr.AppendLine($"owner of \"{folder}\" is {dirInfo.OwnerUser.UserName}");
                    bldr.AppendLine($"permissions of \"{folder}\" = {dirInfo.FileAccessPermissions.ToString()}");
                }
            }
            catch (Exception e)
            {
                bldr.AppendLine($"Caught exception {e} while trying to collect information about {filePath}");
            }
            return(bldr.ToString());
        }
Пример #6
0
        /// <summary>
        /// Snapshots the VM and gets its (maybe partial) StorageLayout
        /// </summary>
        /// <returns>
        /// The physical disks.
        /// </returns> retrieve a
        public StorageLayout BuildStorageLayout()
        {
            List <FileSystem> fsList = new List <FileSystem>();

            if (this.loopDevices == null)            // local layout
            {
                fsList = GetMountedFilesystems();
            }

            /*else
             *      fsList = MountLoopFilesystems();*/

            Mono.Unix.UnixDirectoryInfo ud = new Mono.Unix.UnixDirectoryInfo(sysfsRoot);

            foreach (Mono.Unix.Native.Dirent scsiDevice in ud.GetEntries())
            {
                if (this.IsLayoutLoop && !loopDevices.Contains(scsiDevice.d_name))
                {
                    continue;
                }

                Console.WriteLine("device subsystem name : " + scsiDevice.d_name);
                Disk   disk = new Disk();
                string path = "";
                if (this.IsLayoutLoop)
                {
                    path = sysfsRoot + "/" + scsiDevice;
                }
                else
                {
                    path = sysfsRoot + "/" + scsiDevice + "/device/block";
                }

                if (!Directory.Exists(path))
                {
                    disk.Enabled = false;
                }
                else
                {
                    disk.Enabled = true;
                }
                string diskName = "";
                if (this.IsLayoutLoop)
                {
                    diskName = scsiDevice.d_name;
                }
                else
                {
                    Mono.Unix.UnixDirectoryInfo scsiPath = new Mono.Unix.UnixDirectoryInfo(path);
                    diskName = scsiPath.GetEntries()[0].d_name;
                    path    += "/" + diskName;
                }
                disk.Path = "/dev/" + diskName;
                disk.Size = long.Parse(File.ReadAllText(path + "/size"));
                //disk.Enabled =  File.ReadAllText(path+"/removable").StartsWith("0");
                if (!File.ReadAllText(path + "/removable").StartsWith("0"))              // exclude removable devices (external drives, usb keys...)
                {
                    continue;
                }
                disk.Enabled    = true;
                disk.SectorSize = uint.Parse(File.ReadAllText(path + "/queue/hw_sector_size"));
                if (this.IsLayoutLoop)
                {
                    disk.Type = DiskType.Loop;
                }
                try{
                    disk.BlockStream = new FileStream(disk.Path, System.IO.FileMode.Open);
                }
                catch (Exception e) {
                    Console.WriteLine("ERROR : " + e.Message);
                }
                //MBR mbr = new MBR(disk.MbrBytes);

                // gather what MBR sees
                //disk.Children.AddRange(StorageLayoutManager.GetPartitionsFromMBR(disk));
                // now compare with what is inside sysfs and complete information
                List <Partition> sysfsParts = GetSysfsPartitions(path, diskName);

                foreach (Partition sysfsP in sysfsParts)
                {
                    //Console.WriteLine ("@@@@@@@@@@@@@@@@ GetSysfsPartitions SYS current="+sysfsP.Offset+"  ("+sysfsP.Path+")");
                    //foreach(Partition p in disk.Children){
                    //Console.WriteLine ("@@@@@@@@@@@@@@@@ GetSysfsPartitions MBR current="+p.Offset);
                    //if (p.Offset != sysfsP.Offset) continue;
                    //Console.WriteLine ("@@@@@@@@@@@@@@@@ GetSysfsPartitions MATCHED MBR partition "+sysfsP.Path);
                    //p.Path = sysfsP.Path;
                    //p.Size = sysfsP.Size;

                    foreach (FileSystem f in fsList)
                    {
                        string fsDevName = GetPartitionFromPathOrUuid(f.Path);
                        //Console.WriteLine ("@@@@@@@@@@@@@@@@ GetSysfsPartitions FS current="+f.Path+", mntpt="+f.MountPoint+", mapped="+fsDevName);
                        if (fsDevName == sysfsP.Path)
                        {
                            sysfsP.AddChild(f);
                            //Console.WriteLine ("@@@@@@@@@@@@@@@@ GetSysfsPartitions FS MATCHED"+Environment.NewLine);
                        }
                    }
                    //break;
                    disk.AddChild(sysfsP);
                    //}
                }

                layout.Entries.Add(disk);
            }            // end foreach

            // if using loop devices, try to detect fses and mount only now that we have a complete view and access to disks and parts.
            // doing it so late allows to detect things like LVM volumes spread on multiple partitions or disks
            if (fsList.Count == 0)
            {
                //1- try to mount the loop partitions
                foreach (Partition p in layout.GetAllPartitions(null))
                {
                    // quick, hackish and dirty way to avoid mounting an 'extended' partition,
                    // which sould result in an endless loop while burning 100% cPU in zombie state. Yup. Kernel bug?
                    if (p.Size == 2)
                    {
                        continue;
                    }

                    FileSystem mountedFS = MountLoopFilesystem(p);
                    if (mountedFS != null)
                    {
                        p.AddChild(mountedFS);
                    }
                }
                // 2- try to access and read VM /etc/fstab, from there guess the original loop FS mountpoint
                Dictionary <string, string> originalMountpoints = TryGuessOriginalMountPoint(layout.GetAllFileSystems(null));
                foreach (FileSystem fs in layout.GetAllFileSystems(null))
                {
                    foreach (KeyValuePair <string, string> mp in originalMountpoints)
                    {
                        string fsBlockDevice = GetPartitionFromPathOrUuid(mp.Key);
                        //Console.WriteLine ("ORIGINAL LAYOUT FS: mountpoint key="+mp.Key+", value="+mp.Value+", fromuuid="+fsBlockDevice+", fs.path="+fs.Path+", fs.mountpoint="+fs.MountPoint);
                        if (fsBlockDevice == fs.Path)
                        {
                            fs.OriginalMountPoint = mp.Value;
                            if (LogEvent != null)
                            {
                                LogEvent(this, new LogEventArgs(0, Severity.DEBUG, "Filesystem at mountpoint '" + fs.MountPoint + "' was originally mounted as '" + fs.OriginalMountPoint + "'"));
                            }
                            break;;
                        }
                    }
                }
            }

            return(layout);
        }