jaedb / Iris

Discover, explore and manage your music library across multiple sources with this beautiful web-based interface. Iris is a Mopidy frontend extension.
Apache License 2.0
1.13k stars 131 forks source link

Config doesn't follow Mopidy config paths for local user. Unnecessary privilege escalation. #636

Open TMSL opened 3 years ago

TMSL commented 3 years ago

Iris 1.53.1 with Mopidy 3.0.2 and Mopidy-Local

Iris doesn't seem to follow the same .config path that Mopidy uses when doing a local scan as a local user. This may be only for doing the local scan that creates and maintains library.db. When I run mopidy config I see that the mopidy does pick up the settings for the Iris [iris] section, such as iris/country and iris/locale. However, settings for [local] seem to be ignored.

When Mopidy is run as a local user (not as a service), Mopidy first loads its internal defaults, then applies the .config in $HOME/.config/mopidy/mopidy.conf, then applies command line parameters. Instead, it appears Iris uses the configuration for Mopidy running as a Service. This includes not applying where files are located as well as all other configuration for [iris] and [local] .

Example: When mopidy local scan is run as a local user, the music database is built in $HOME/.local/share/mopidy/local/library.db But Iris system.sh runs sudo mopidctl local scan and by default builds the library database in /var/lib/mopidy/local/library.db. This means the library database built by mopidy local scan and _sudo mopidyctl_localscan wind up in different locations even if they follow use same media_dirs.

Unlike the mopidy command, mopidyctl does not apply the user .config. You can see this when sudo mopidyctl local scan is run from Iris, the Mopidy status output is: Running "/usr/bin/mopidy --config /usr/share/mopidy/conf.d:/etc/mopidy/mopidy.conf local scan" as user mopidy.

I think the mopidyctl command should only be used for Mopidy running as a Service. According to the Mopidy documentation "The mopidyctl command runs mopidy subcommands in the same environment as the Mopidy system service is running in. That is, as the same user and with the same config as the Mopidy system service is using."

There seem to be a few problems when using Iris with Mopidy running as a local command here: 1) Iris ignores the user's .config for local scan library location and requires using the [local] config section in /etc/mopidy. 2) Iris system.sh runs sudo mopidyctl local scan instead of running mopidy local scan to build and maintain library.db. This builds the library in a different place than mopidy local scan. 3) In order to run mopidyctl, it needs to run as mopidy and run the command using sudo. It requires a privilege escalation that should not be needed when running Mopidy as a local user.

I think the fix may require detecting whether the Iris was launched from Mopidy as a Service or locally to determine whether Iris should run mopidyctl local scan or mopidy local scan .

diabl0w commented 3 years ago

This is definitely also related to my issue reported here: https://github.com/jaedb/Iris/issues/624

I knew I was having inconsistencies when debugging that issue, but never ended up digging into it further because the whole installation was just too unstable, so I am no longer using iris at the moment. The system.sh workarounds seem like they need to be revamped.

TMSL commented 3 years ago

Thank you for your response! Yes, the inconsistency I noticed was that I could run mopidy local and see it build the database, but things didn't work until after I built the database from the web through Iris. Turns out that was because Iris was building the database in a different directory as if Mopidy were running as a daemon while the mopidy local scan command built is as a 'user'.

I really like the Iris concept and Mopidy. I'm thinking about doing my own build but I'm still getting used to Linux development. (I've done most of my work with C++/Windows). If I do that I might also try seeing if I can build a version of Mopidy to work with Python 3.6.9 since that's the latest version that seems to be available for 32-bit Ubuntu/Debian Linux distributions. While it's possible to install a later Python version alongside the 'native' Python version, doing that adds its own complexities.

kingosticks commented 3 years ago

to work with Python 3.6.9 since that's the latest version that seems to be available for 32-bit Ubuntu/Debian Linux distributions

Out of interest which distributions are stuck on Python 3.6.x? Or are these outdated releases that you need to use for their 32bit support?

jaedb commented 3 years ago

@diabl0w if you're experiencing a specific and replicatable problem, please create an issue on this repository. There is every chance other users are experiencing the same frustrations. Without an bug report there is nothing for me to fix 😄

The system.sh workaround is exactly that. I don't believe these commands should be executed in this manner, and I am hesitant to putting significant effort into revisiting this 'workaround'. I would love to see Mopidy accept a scan_library command to achieve this similar functionality. Would you be interested in contributing to this?

s-hamann commented 2 years ago

I think I have a different problem with the same underlying issue. I run Mopidy as a system service and would like to give Iris the permission to refresh the local library cache, but not restart Mopidy or update extensions. Also, I'd like to generally restrict what system service in general and Mopidy in particular can do, so my systemd unit includes NoNewPrivileges=true. This prevents the use of sudo.

I'm aware that Iris updates and service restarts are not going to work with NoNewPrivileges=true. Refreshing the library, however, should be possible, since this needs to run in the same user context as the Mopidy service.

Currently, when a rescan is triggered from the web interface, system.py runs sudo system.sh, which runs sudo mopidyctl, which runs su mopidy -c 'mopidy local scan'. By running just mopidy local scan from system.sh (or system.py) and not using sudo at all, both @TMSL's and my problem would be solved.

I'm willing to work on this myself, if it seems like a sensible approach. @jaedb, what do you think?

While I'm at it, I'd also like to clean up the double sudo calls for Mopidy restart and Iris updates. I think it's cleaner to remove the sudo call from system.py, keeping only the sudo calls in system.sh. This has two advantages:

Unfortunately, this would be a breaking change, since existing sudo rules would not work any longer.