diff --git a/src/client/Client.hxx b/src/client/Client.hxx index 10411cb93..82149016e 100644 --- a/src/client/Client.hxx +++ b/src/client/Client.hxx @@ -176,9 +176,12 @@ public: * We cannot fix this as long as there are plugins that open a file by * its name, and not by file descriptor / callbacks. * + * Throws #std::runtime_error on error. + * * @param path_fs the absolute path name in filesystem encoding - * @return true if access is allowed */ + void AllowFile(Path path_fs) const; + bool AllowFile(Path path_fs, Error &error) const; /** diff --git a/src/client/ClientFile.cxx b/src/client/ClientFile.cxx index 15c40df9e..e3715485f 100644 --- a/src/client/ClientFile.cxx +++ b/src/client/ClientFile.cxx @@ -26,6 +26,31 @@ #include +void +Client::AllowFile(Path path_fs) const +{ +#ifdef WIN32 + (void)path_fs; + + throw ProtocolError(ACK_ERROR_PERMISSION, "Access denied"); +#else + if (uid >= 0 && (uid_t)uid == geteuid()) + /* always allow access if user runs his own MPD + instance */ + return; + + if (uid < 0) + /* unauthenticated client */ + throw ProtocolError(ACK_ERROR_PERMISSION, "Access denied"); + + const FileInfo fi(path_fs); + + if (fi.GetUid() != (uid_t)uid && (fi.GetMode() & 0444) != 0444) + /* client is not owner */ + throw ProtocolError(ACK_ERROR_PERMISSION, "Access denied"); +#endif +} + bool Client::AllowFile(Path path_fs, Error &error) const {