From 7218772b32522949bdb6fcd75e1df1a98d30f5f0 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 30 Jan 2014 21:24:32 -0800 Subject: [PATCH] Support for setting uid/gid on *nix systems --- src/NzbDrone.Common/Disk/DiskProviderBase.cs | 2 +- src/NzbDrone.Common/Disk/IDiskProvider.cs | 8 +---- .../Configuration/ConfigService.cs | 14 ++++++++ .../Configuration/IConfigService.cs | 2 ++ .../MediaFiles/EpisodeFileMovingService.cs | 6 +++- src/NzbDrone.Mono/DiskProvider.cs | 35 ++++++++++++++++--- .../LinuxPermissionsException.cs | 15 ++++++++ src/NzbDrone.Mono/NzbDrone.Mono.csproj | 4 +-- src/NzbDrone.Windows/DiskProvider.cs | 2 +- .../Permissions/PermissionsViewTemplate.html | 22 ++++++++++++ 10 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 src/NzbDrone.Mono/LinuxPermissionsException.cs diff --git a/src/NzbDrone.Common/Disk/DiskProviderBase.cs b/src/NzbDrone.Common/Disk/DiskProviderBase.cs index 14ce5f4fa..b9c506a2e 100644 --- a/src/NzbDrone.Common/Disk/DiskProviderBase.cs +++ b/src/NzbDrone.Common/Disk/DiskProviderBase.cs @@ -21,7 +21,7 @@ namespace NzbDrone.Common.Disk public abstract long? GetAvailableSpace(string path); public abstract void InheritFolderPermissions(string filename); - public abstract void SetPermissions(string path, string mask); + public abstract void SetPermissions(string path, string mask, string user, string group); public abstract long? GetTotalSize(string path); public DateTime GetLastFolderWrite(string path) diff --git a/src/NzbDrone.Common/Disk/IDiskProvider.cs b/src/NzbDrone.Common/Disk/IDiskProvider.cs index 5426c18db..3e8b8ceff 100644 --- a/src/NzbDrone.Common/Disk/IDiskProvider.cs +++ b/src/NzbDrone.Common/Disk/IDiskProvider.cs @@ -1,13 +1,7 @@ using System; using System.IO; -using System.Linq; -using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; -using NLog; -using NzbDrone.Common.EnsureThat; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Instrumentation; namespace NzbDrone.Common.Disk { @@ -15,7 +9,7 @@ namespace NzbDrone.Common.Disk { long? GetAvailableSpace(string path); void InheritFolderPermissions(string filename); - void SetPermissions(string path, string mask); + void SetPermissions(string path, string mask, string user, string group); long? GetTotalSize(string path); DateTime GetLastFolderWrite(string path); diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs index 17b5eba03..e0a026835 100644 --- a/src/NzbDrone.Core/Configuration/ConfigService.cs +++ b/src/NzbDrone.Core/Configuration/ConfigService.cs @@ -305,6 +305,20 @@ namespace NzbDrone.Core.Configuration set { SetValue("FolderChmod", value); } } + public String ChownUser + { + get { return GetValue("User", ""); } + + set { SetValue("User", value); } + } + + public String ChownGroup + { + get { return GetValue("User", ""); } + + set { SetValue("User", value); } + } + private string GetValue(string key) { return GetValue(key, String.Empty); diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs index d70d36def..6c19d6c36 100644 --- a/src/NzbDrone.Core/Configuration/IConfigService.cs +++ b/src/NzbDrone.Core/Configuration/IConfigService.cs @@ -45,5 +45,7 @@ namespace NzbDrone.Core.Configuration Boolean SetPermissionsLinux { get; set; } String FileChmod { get; set; } String FolderChmod { get; set; } + String ChownUser { get; set; } + String ChownGroup { get; set; } } } diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs b/src/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs index 4ef693ae9..d9ed02ea3 100644 --- a/src/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs +++ b/src/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs @@ -152,7 +152,7 @@ namespace NzbDrone.Core.MediaFiles try { - _diskProvider.SetPermissions(path, permissions); + _diskProvider.SetPermissions(path, permissions, _configService.ChownUser, _configService.ChownGroup); } catch (Exception ex) @@ -162,6 +162,10 @@ namespace NzbDrone.Core.MediaFiles _logger.Debug("Unable to apply permissions to: ", path); _logger.TraceException(ex.Message, ex); } + else + { + throw; + } } } diff --git a/src/NzbDrone.Mono/DiskProvider.cs b/src/NzbDrone.Mono/DiskProvider.cs index 7582eb7c9..f09ae650e 100644 --- a/src/NzbDrone.Mono/DiskProvider.cs +++ b/src/NzbDrone.Mono/DiskProvider.cs @@ -49,7 +49,7 @@ namespace NzbDrone.Mono } } - public override void SetPermissions(string path, string mask) + public override void SetPermissions(string path, string mask, string user, string group) { Logger.Trace("Setting permissions: {0} on {1}", mask, path); @@ -59,14 +59,41 @@ namespace NzbDrone.Mono { var error = Stdlib.GetLastError(); - throw new Exception("Error setting file permissions: " + error); + throw new LinuxPermissionsException("Error setting file permissions: " + error); } - if (Syscall.chown(path, Syscall.getuid(), Syscall.getgid()) < 0) + uint userId; + uint groupId; + + if (!uint.TryParse(user, out userId)) + { + var u = Syscall.getpwnam(user); + + if (u == null) + { + throw new LinuxPermissionsException("Unknown user: {0}", user); + } + + userId = u.pw_uid; + } + + if (!uint.TryParse(group, out groupId)) + { + var g = Syscall.getgrnam(user); + + if (g == null) + { + throw new LinuxPermissionsException("Unknown group: {0}", group); + } + + groupId = g.gr_gid; + } + + if (Syscall.chown(path, userId, groupId) < 0) { var error = Stdlib.GetLastError(); - throw new Exception("Error setting file owner: " + error); + throw new LinuxPermissionsException("Error setting file owner: " + error); } } diff --git a/src/NzbDrone.Mono/LinuxPermissionsException.cs b/src/NzbDrone.Mono/LinuxPermissionsException.cs new file mode 100644 index 000000000..4b3587c36 --- /dev/null +++ b/src/NzbDrone.Mono/LinuxPermissionsException.cs @@ -0,0 +1,15 @@ +using NzbDrone.Common.Exceptions; + +namespace NzbDrone.Mono +{ + public class LinuxPermissionsException : NzbDroneException + { + public LinuxPermissionsException(string message, params object[] args) : base(message, args) + { + } + + public LinuxPermissionsException(string message) : base(message) + { + } + } +} diff --git a/src/NzbDrone.Mono/NzbDrone.Mono.csproj b/src/NzbDrone.Mono/NzbDrone.Mono.csproj index a5364e8ce..91d0efeb3 100644 --- a/src/NzbDrone.Mono/NzbDrone.Mono.csproj +++ b/src/NzbDrone.Mono/NzbDrone.Mono.csproj @@ -69,11 +69,9 @@ + - - - {f2be0fdf-6e47-4827-a420-dd4ef82407f8} diff --git a/src/NzbDrone.Windows/DiskProvider.cs b/src/NzbDrone.Windows/DiskProvider.cs index 6eb2863f2..db6a02304 100644 --- a/src/NzbDrone.Windows/DiskProvider.cs +++ b/src/NzbDrone.Windows/DiskProvider.cs @@ -40,7 +40,7 @@ namespace NzbDrone.Windows File.SetAccessControl(filename, fs); } - public override void SetPermissions(string path, string mask) + public override void SetPermissions(string path, string mask, string user, string group) { } diff --git a/src/UI/Settings/MediaManagement/Permissions/PermissionsViewTemplate.html b/src/UI/Settings/MediaManagement/Permissions/PermissionsViewTemplate.html index 1c6a0c81e..74cef9c4d 100644 --- a/src/UI/Settings/MediaManagement/Permissions/PermissionsViewTemplate.html +++ b/src/UI/Settings/MediaManagement/Permissions/PermissionsViewTemplate.html @@ -43,5 +43,27 @@ + +
+ + +
+ + + + +
+
+ +
+ + +
+ + + + +
+
{{/if_linux}} \ No newline at end of file