diff --git a/doc/user.xml b/doc/user.xml index 85f060a0b..f6c08948b 100644 --- a/doc/user.xml +++ b/doc/user.xml @@ -1158,6 +1158,11 @@ systemctl start mpd.socket + + local_permissions may be used to assign + other permissions to clients connecting on a local socket. + + password allows the client to send a password to gain other permissions. This option may be diff --git a/src/Permission.cxx b/src/Permission.cxx index a3d98a0de..8387b3754 100644 --- a/src/Permission.cxx +++ b/src/Permission.cxx @@ -49,6 +49,10 @@ static std::map permission_passwords; static unsigned permission_default; +#ifdef HAVE_UN +static unsigned local_permissions; +#endif + static unsigned ParsePermission(const char *p) { @@ -121,6 +125,14 @@ void initPermissions(void) if (param) permission_default = parsePermissions(param->value.c_str()); + +#ifdef HAVE_UN + param = config_get_param(ConfigOption::LOCAL_PERMISSIONS); + if (param != nullptr) + local_permissions = parsePermissions(param->value.c_str()); + else + local_permissions = permission_default; +#endif } int getPermissionFromPassword(char const* password, unsigned* permission) @@ -137,3 +149,13 @@ unsigned getDefaultPermissions(void) { return permission_default; } + +#ifdef HAVE_UN + +unsigned +GetLocalPermissions() noexcept +{ + return local_permissions; +} + +#endif diff --git a/src/Permission.hxx b/src/Permission.hxx index 782632644..e0009471e 100644 --- a/src/Permission.hxx +++ b/src/Permission.hxx @@ -20,6 +20,8 @@ #ifndef MPD_PERMISSION_HXX #define MPD_PERMISSION_HXX +#include "check.h" + static constexpr unsigned PERMISSION_NONE = 0; static constexpr unsigned PERMISSION_READ = 1; static constexpr unsigned PERMISSION_ADD = 2; @@ -31,6 +33,11 @@ int getPermissionFromPassword(char const* password, unsigned* permission); unsigned getDefaultPermissions(); +#ifdef HAVE_UN +unsigned +GetLocalPermissions() noexcept; +#endif + void initPermissions(); diff --git a/src/client/Listener.cxx b/src/client/Listener.cxx index 663fd9a7b..a607379b8 100644 --- a/src/client/Listener.cxx +++ b/src/client/Listener.cxx @@ -24,11 +24,27 @@ #include "net/UniqueSocketDescriptor.hxx" #include "net/SocketAddress.hxx" +static unsigned +GetPermissions(SocketAddress address, int uid) noexcept +{ + (void)uid; // TODO: implement option to derive permissions from uid + +#ifdef HAVE_UN + if (address.GetFamily() == AF_LOCAL) + return GetLocalPermissions(); +#else + (void)address; +#endif + + return getDefaultPermissions(); +} + void ClientListener::OnAccept(UniqueSocketDescriptor fd, SocketAddress address, int uid) noexcept { + client_new(GetEventLoop(), partition, std::move(fd), address, uid, - getDefaultPermissions()); + GetPermissions(address, uid)); } diff --git a/src/config/ConfigOption.hxx b/src/config/ConfigOption.hxx index 697909593..6a66fff39 100644 --- a/src/config/ConfigOption.hxx +++ b/src/config/ConfigOption.hxx @@ -48,6 +48,7 @@ enum class ConfigOption { ZEROCONF_NAME, ZEROCONF_ENABLED, PASSWORD, + LOCAL_PERMISSIONS, DEFAULT_PERMS, AUDIO_OUTPUT_FORMAT, MIXER_TYPE, diff --git a/src/config/ConfigTemplates.cxx b/src/config/ConfigTemplates.cxx index 683e30ccd..8a0438340 100644 --- a/src/config/ConfigTemplates.cxx +++ b/src/config/ConfigTemplates.cxx @@ -43,6 +43,7 @@ const ConfigTemplate config_param_templates[] = { { "zeroconf_name" }, { "zeroconf_enabled" }, { "password", true }, + { "local_permissions" }, { "default_permissions" }, { "audio_output_format" }, { "mixer_type" },