From 52c61bd06f6e3ef0130e7a2d0255feca777a7b3f Mon Sep 17 00:00:00 2001 From: knackebrot Date: Sun, 16 Jan 2022 22:32:10 +0100 Subject: [PATCH] Add option to change unix socket permissions There is probably no way to do it when creating the socket --- Jellyfin.Server/Program.cs | 67 +++++++++++++++---- .../Extensions/ConfigurationExtensions.cs | 13 ++++ 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index ce11c63f9a..8667101559 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Net; using System.Reflection; +using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -198,6 +199,13 @@ namespace Jellyfin.Server try { await webHost.StartAsync(_tokenSource.Token).ConfigureAwait(false); + + if (startupConfig.UseUnixSocket() && Environment.OSVersion.Platform == PlatformID.Unix) + { + var socketPath = GetUnixSocketPath(startupConfig, appPaths); + + SetUnixSocketPermissions(startupConfig, socketPath); + } } catch (Exception ex) when (ex is not TaskCanceledException) { @@ -327,20 +335,7 @@ namespace Jellyfin.Server // Bind to unix socket (only on unix systems) if (startupConfig.UseUnixSocket() && Environment.OSVersion.Platform == PlatformID.Unix) { - var socketPath = startupConfig.GetUnixSocketPath(); - if (string.IsNullOrEmpty(socketPath)) - { - var xdgRuntimeDir = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR"); - if (xdgRuntimeDir == null) - { - // Fall back to config dir - socketPath = Path.Join(appPaths.ConfigurationDirectoryPath, "socket.sock"); - } - else - { - socketPath = Path.Join(xdgRuntimeDir, "jellyfin-socket"); - } - } + var socketPath = GetUnixSocketPath(startupConfig, appPaths); // Workaround for https://github.com/aspnet/AspNetCore/issues/14134 if (File.Exists(socketPath)) @@ -664,5 +659,49 @@ namespace Jellyfin.Server return "\"" + arg + "\""; } + + private static string GetUnixSocketPath(IConfiguration startupConfig, IApplicationPaths appPaths) + { + var socketPath = startupConfig.GetUnixSocketPath(); + + if (string.IsNullOrEmpty(socketPath)) + { + var xdgRuntimeDir = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR"); + var socketFile = "jellyfin.sock"; + if (xdgRuntimeDir == null) + { + // Fall back to config dir + socketPath = Path.Join(appPaths.ConfigurationDirectoryPath, socketFile); + } + else + { + socketPath = Path.Join(xdgRuntimeDir, socketFile); + } + } + + return socketPath; + } + + private static void SetUnixSocketPermissions(IConfiguration startupConfig, string socketPath) + { + var socketPerms = startupConfig.GetUnixSocketPermissions(); + + if (!string.IsNullOrEmpty(socketPerms)) + { + [DllImport("libc")] + static extern int chmod(string pathname, int mode); + + var exitCode = chmod(socketPath, Convert.ToInt32(socketPerms, 8)); + + if (exitCode < 0) + { + _logger.LogError("Failed to set Kestrel unix socket permissions to {SocketPerms}, return code: {ExitCode}", socketPerms, exitCode); + } + else + { + _logger.LogInformation("Kestrel unix socket permissions set to {SocketPerms}", socketPerms); + } + } + } } } diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs index f9285c7682..1fedf72052 100644 --- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs @@ -49,6 +49,11 @@ namespace MediaBrowser.Controller.Extensions /// public const string UnixSocketPathKey = "kestrel:socketPath"; + /// + /// The permissions for the unix socket. + /// + public const string UnixSocketPermissionsKey = "kestrel:socketPermissions"; + /// /// Gets a value indicating whether the application should host static web content from the . /// @@ -97,5 +102,13 @@ namespace MediaBrowser.Controller.Extensions /// The unix socket path. public static string GetUnixSocketPath(this IConfiguration configuration) => configuration[UnixSocketPathKey]; + + /// + /// Gets the permissions for the unix socket from the . + /// + /// The configuration to read the setting from. + /// The unix socket permissions. + public static string GetUnixSocketPermissions(this IConfiguration configuration) + => configuration[UnixSocketPermissionsKey]; } }