1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2024-12-16 11:37:58 +02:00

Support for setting uid/gid on *nix systems

This commit is contained in:
Mark McDowall 2014-01-30 21:24:32 -08:00
parent 3ed37997c5
commit 7218772b32
10 changed files with 93 additions and 17 deletions

View File

@ -21,7 +21,7 @@ enum TransferAction
public abstract long? GetAvailableSpace(string path); public abstract long? GetAvailableSpace(string path);
public abstract void InheritFolderPermissions(string filename); 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 abstract long? GetTotalSize(string path);
public DateTime GetLastFolderWrite(string path) public DateTime GetLastFolderWrite(string path)

View File

@ -1,13 +1,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.AccessControl; using System.Security.AccessControl;
using System.Security.Principal; using System.Security.Principal;
using NLog;
using NzbDrone.Common.EnsureThat;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation;
namespace NzbDrone.Common.Disk namespace NzbDrone.Common.Disk
{ {
@ -15,7 +9,7 @@ public interface IDiskProvider
{ {
long? GetAvailableSpace(string path); long? GetAvailableSpace(string path);
void InheritFolderPermissions(string filename); void InheritFolderPermissions(string filename);
void SetPermissions(string path, string mask); void SetPermissions(string path, string mask, string user, string group);
long? GetTotalSize(string path); long? GetTotalSize(string path);
DateTime GetLastFolderWrite(string path); DateTime GetLastFolderWrite(string path);

View File

@ -305,6 +305,20 @@ public String FolderChmod
set { SetValue("FolderChmod", value); } 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) private string GetValue(string key)
{ {
return GetValue(key, String.Empty); return GetValue(key, String.Empty);

View File

@ -45,5 +45,7 @@ public interface IConfigService
Boolean SetPermissionsLinux { get; set; } Boolean SetPermissionsLinux { get; set; }
String FileChmod { get; set; } String FileChmod { get; set; }
String FolderChmod { get; set; } String FolderChmod { get; set; }
String ChownUser { get; set; }
String ChownGroup { get; set; }
} }
} }

View File

@ -152,7 +152,7 @@ private void SetPermissions(string path, string permissions)
try try
{ {
_diskProvider.SetPermissions(path, permissions); _diskProvider.SetPermissions(path, permissions, _configService.ChownUser, _configService.ChownGroup);
} }
catch (Exception ex) catch (Exception ex)
@ -162,6 +162,10 @@ private void SetPermissions(string path, string permissions)
_logger.Debug("Unable to apply permissions to: ", path); _logger.Debug("Unable to apply permissions to: ", path);
_logger.TraceException(ex.Message, ex); _logger.TraceException(ex.Message, ex);
} }
else
{
throw;
}
} }
} }

View File

@ -49,7 +49,7 @@ public override void InheritFolderPermissions(string filename)
} }
} }
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); Logger.Trace("Setting permissions: {0} on {1}", mask, path);
@ -59,14 +59,41 @@ public override void SetPermissions(string path, string mask)
{ {
var error = Stdlib.GetLastError(); 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(); var error = Stdlib.GetLastError();
throw new Exception("Error setting file owner: " + error); throw new LinuxPermissionsException("Error setting file owner: " + error);
} }
} }

View File

@ -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)
{
}
}
}

View File

@ -69,11 +69,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="DiskProvider.cs" /> <Compile Include="DiskProvider.cs" />
<Compile Include="LinuxPermissionsException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<WCFMetadata Include="Service References\" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj"> <ProjectReference Include="..\NzbDrone.Common\NzbDrone.Common.csproj">
<Project>{f2be0fdf-6e47-4827-a420-dd4ef82407f8}</Project> <Project>{f2be0fdf-6e47-4827-a420-dd4ef82407f8}</Project>

View File

@ -40,7 +40,7 @@ public override void InheritFolderPermissions(string filename)
File.SetAccessControl(filename, fs); File.SetAccessControl(filename, fs);
} }
public override void SetPermissions(string path, string mask) public override void SetPermissions(string path, string mask, string user, string group)
{ {
} }

View File

@ -43,5 +43,27 @@
</span> </span>
</div> </div>
</div> </div>
<div class="control-group">
<label class="control-label">chown User</label>
<div class="controls">
<input type="text" name="chownUser"/>
<span class="help-inline">
<i class="icon-nd-form-info" title="Username or uid. Use uid for remote file systems."/>
</span>
</div>
</div>
<div class="control-group">
<label class="control-label">chown Group</label>
<div class="controls">
<input type="text" name="chownGroup"/>
<span class="help-inline">
<i class="icon-nd-form-info" title="Group name or gid. Use gid for remote file systems."/>
</span>
</div>
</div>
</fieldset> </fieldset>
{{/if_linux}} {{/if_linux}}