diff options
author | Thorvald Natvig <slicer@users.sourceforge.net> | 2009-02-26 17:03:27 +0300 |
---|---|---|
committer | Thorvald Natvig <slicer@users.sourceforge.net> | 2009-02-26 17:03:27 +0300 |
commit | 7fc01d602e63cf7d764a7c14dbe6f53941604dda (patch) | |
tree | 11e7561f226b3defd14f0cb93c57a062e005e6d4 /src | |
parent | 0df61d2f2d12782516f32e5a15e08670dc09c3ac (diff) |
Use Linux capabilities to allow us to really use high priority threads
git-svn-id: https://mumble.svn.sourceforge.net/svnroot/mumble/trunk@1587 05730e5d-ab1b-0410-a4ac-84af385074fa
Diffstat (limited to 'src')
-rw-r--r-- | src/murmur/DBus.cpp | 20 | ||||
-rw-r--r-- | src/murmur/DBus.h | 1 | ||||
-rw-r--r-- | src/murmur/Meta.cpp | 16 | ||||
-rw-r--r-- | src/murmur/Meta.h | 2 | ||||
-rw-r--r-- | src/murmur/UnixMurmur.cpp | 58 | ||||
-rw-r--r-- | src/murmur/UnixMurmur.h | 4 | ||||
-rw-r--r-- | src/murmur/main.cpp | 14 | ||||
-rw-r--r-- | src/murmur/murmur.pro | 3 | ||||
-rw-r--r-- | src/murmur/murmur_pch.h | 6 |
9 files changed, 102 insertions, 22 deletions
diff --git a/src/murmur/DBus.cpp b/src/murmur/DBus.cpp index 7b32fae67..0f4ded712 100644 --- a/src/murmur/DBus.cpp +++ b/src/murmur/DBus.cpp @@ -1016,26 +1016,6 @@ void MetaDBus::setSuperUserPassword(int server_id, const QString &pw, const QDBu } } -extern QFile *qfLog; - -void MetaDBus::rotateLogs(const QDBusMessage &msg) { - if (! qfLog || ! qfLog->isOpen()) { - MurmurDBus::qdbc.send(msg.createErrorReply("net.sourceforge.mumble.Error.nolog", "Logfile not in use")); - return; - } - qWarning("Logfile rotation requested from D-Bus, will reopen %s", qPrintable(Meta::mp.qsLogfile)); - qfLog->close(); - qfLog->setFileName(Meta::mp.qsLogfile); - if (! qfLog->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { - delete qfLog; - qfLog = NULL; - MurmurDBus::qdbc.send(msg.createErrorReply("net.sourceforge.mumble.Error.logfail", "Failed to reopen log")); - } else { - qfLog->setTextModeEnabled(true); - qWarning("Log rotated successfully"); - } -} - void MetaDBus::quit() { qCritical("Quit requested from D-Bus"); QCoreApplication::instance()->quit(); diff --git a/src/murmur/DBus.h b/src/murmur/DBus.h index 67ad7c202..f06ab6b41 100644 --- a/src/murmur/DBus.h +++ b/src/murmur/DBus.h @@ -246,7 +246,6 @@ class MetaDBus : public QDBusAbstractAdaptor { void getDefaultConf(ConfigMap &values); void setConf(int server_id, const QString &key, const QString &value, const QDBusMessage &); void setSuperUserPassword(int server_id, const QString &pw, const QDBusMessage &); - void rotateLogs(const QDBusMessage &); void getLog(int server_id, int min_offset, int max_offset, const QDBusMessage &, QList<LogEntry> &entries); void getVersion(int &major, int &minor, int &patch, QString &string); void quit(); diff --git a/src/murmur/Meta.cpp b/src/murmur/Meta.cpp index c07ffaaf2..14eb66e8d 100644 --- a/src/murmur/Meta.cpp +++ b/src/murmur/Meta.cpp @@ -58,6 +58,8 @@ MetaParams::MetaParams() { iBanTries = 10; iBanTimeframe = 120; iBanTime = 300; + + uiUid = uiGid = 0; qrPlayerName = QRegExp(QLatin1String("[-=\\w\\[\\]\\{\\}\\(\\)\\@\\|\\.]+")); qrChannelName = QRegExp(QLatin1String("[ \\-=\\w\\#\\[\\]\\{\\}\\(\\)\\@\\|]+")); @@ -166,6 +168,20 @@ void MetaParams::read(QString fname) { iBanTries = qs.value("autobanAttempts", iBanTries).toInt(); iBanTimeframe = qs.value("autobanTimeframe", iBanTimeframe).toInt(); iBanTime = qs.value("autobanTime", iBanTime).toInt(); + +#ifdef Q_OS_UNIX + const QString uname = qs.value("uname").toString(); + if (! uname.isEmpty() && (geteuid() == 0)) { + struct passwd *pw = getpwnam(qPrintable(uname)); + if (pw) { + uiUid = pw->pw_uid; + uiGid = pw->pw_gid; + } + if (uiUid == 0) { + qFatal("Cannot find username %s", qPrintable(uname)); + } + } +#endif qrPlayerName = QRegExp(qs.value("playername", qrPlayerName.pattern()).toString()); qrChannelName = QRegExp(qs.value("channelname", qrChannelName.pattern()).toString()); diff --git a/src/murmur/Meta.h b/src/murmur/Meta.h index 7e3451573..6f3fd2d84 100644 --- a/src/murmur/Meta.h +++ b/src/murmur/Meta.h @@ -84,6 +84,8 @@ struct MetaParams { QByteArray qbaPassPhrase; QMap<QString, QString> qmConfig; + + unsigned int uiUid, uiGid; MetaParams(); void read(QString fname = QString("murmur.ini")); diff --git a/src/murmur/UnixMurmur.cpp b/src/murmur/UnixMurmur.cpp index a99b98885..81ef84a2b 100644 --- a/src/murmur/UnixMurmur.cpp +++ b/src/murmur/UnixMurmur.cpp @@ -165,7 +165,12 @@ void UnixMurmur::handleSigHup() { qWarning("Caught SIGHUP, will reopen %s", qPrintable(Meta::mp.qsLogfile)); qfLog->close(); qfLog->setFileName(Meta::mp.qsLogfile); - if (! qfLog->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { + if (Meta::mp.uiUid != 0) + setresuid(0,0,0); + bool result = qfLog->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text); + if (Meta::mp.uiUid != 0) + setresuid(Meta::mp.uiUid, Meta::mp.uiUid, 0); + if (! result) { delete qfLog; qfLog = NULL; } else { @@ -187,3 +192,54 @@ void UnixMurmur::handleSigTerm() { qsnTerm->setEnabled(true); } + +void UnixMurmur::setuid() { + if (Meta::mp.uiUid != 0) { + if (setregid(Meta::mp.uiGid, Meta::mp.uiGid) != 0) + qCritical("Failed to switch to gid %d", Meta::mp.uiGid); + if (setresuid(Meta::mp.uiUid, Meta::mp.uiUid, 0) != 0) { + qFatal("Failed to become uid %d", Meta::mp.uiUid); + } else { + qCritical("Successfully switched to uid %d", Meta::mp.uiUid); + } + } +} + +void UnixMurmur::initialcap() { +#ifdef Q_OS_LINUX + cap_value_t caps[] = {CAP_DAC_OVERRIDE, CAP_SYS_NICE, CAP_SETUID }; + + if (geteuid() != 0) + return; + + cap_t c = cap_init(); + cap_clear(c); + cap_set_flag(c, CAP_EFFECTIVE, sizeof(caps)/sizeof(cap_value_t), caps, CAP_SET); + cap_set_flag(c, CAP_INHERITABLE, sizeof(caps)/sizeof(cap_value_t), caps, CAP_SET); + cap_set_flag(c, CAP_PERMITTED, sizeof(caps)/sizeof(cap_value_t), caps, CAP_SET); + if (cap_set_proc(c) != 0) { + qCritical("Failed to set initial capabilities"); + } else { + qWarning("Successfully dropped initial capabilities"); + } +#endif +} + +void UnixMurmur::finalcap() { +#ifdef Q_OS_LINUX + cap_value_t caps[] = {CAP_DAC_OVERRIDE, CAP_SYS_NICE, CAP_SETUID }; + + if (Meta::mp.uiUid == 0) + return; + + cap_t c = cap_init(); + cap_clear(c); + cap_set_flag(c, CAP_EFFECTIVE, sizeof(caps)/sizeof(cap_value_t), caps, CAP_SET); + cap_set_flag(c, CAP_PERMITTED, sizeof(caps)/sizeof(cap_value_t), caps, CAP_SET); + if (cap_set_proc(c) != 0) { + qCritical("Failed to set final capabilities"); + } else { + qWarning("Successfully dropped capabilities"); + } +#endif +} diff --git a/src/murmur/UnixMurmur.h b/src/murmur/UnixMurmur.h index f00ed6216..86b137c01 100644 --- a/src/murmur/UnixMurmur.h +++ b/src/murmur/UnixMurmur.h @@ -58,6 +58,10 @@ class UnixMurmur : public QObject { void handleSigHup();
void handleSigTerm();
public:
+ void setuid();
+ void initialcap();
+ void finalcap();
+
UnixMurmur();
~UnixMurmur();
};
diff --git a/src/murmur/main.cpp b/src/murmur/main.cpp index 9727bb41e..c77e3ad71 100644 --- a/src/murmur/main.cpp +++ b/src/murmur/main.cpp @@ -155,6 +155,7 @@ int main(int argc, char **argv) { #else QCoreApplication a(argc, argv); UnixMurmur unixhandler; + unixhandler.initialcap(); #endif a.setApplicationName("Murmur"); a.setOrganizationName("Mumble"); @@ -256,6 +257,10 @@ int main(int argc, char **argv) { } Meta::mp.read(inifile); + +#ifdef Q_OS_UNIX + unixhandler.setuid(); +#endif ServerDB db; meta = new Meta(); @@ -297,6 +302,10 @@ int main(int argc, char **argv) { if (detach && ! Meta::mp.qsLogfile.isEmpty()) { qfLog = new QFile(Meta::mp.qsLogfile); +#ifdef Q_OS_UNIX + if (Meta::mp.uiUid != 0) + setresuid(Meta::mp.uiUid,0,0); +#endif if (! qfLog->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { delete qfLog; qfLog = NULL; @@ -311,6 +320,10 @@ int main(int argc, char **argv) { QFileInfo qfi(*qfLog); Meta::mp.qsLogfile = qfi.absoluteFilePath(); } +#ifdef Q_OS_UNIX + if (Meta::mp.uiUid != 0) + setresuid(Meta::mp.uiUid,Meta::mp.uiUid,0); +#endif } else { detach = false; } @@ -351,6 +364,7 @@ int main(int argc, char **argv) { dup2(fd, 2); close(fd); } + unixhandler.finalcap(); #endif #ifdef USE_DBUS diff --git a/src/murmur/murmur.pro b/src/murmur/murmur.pro index 7135dd214..6339e3626 100644 --- a/src/murmur/murmur.pro +++ b/src/murmur/murmur.pro @@ -46,6 +46,9 @@ win32 { unix { UNAME=$$system(uname -s) CONFIG *= link_pkgconfig + contains(UNAME, Linux) { + LIBS *= -lcap + } contains(UNAME, FreeBSD) { LIBS *= -lcrypto diff --git a/src/murmur/murmur_pch.h b/src/murmur/murmur_pch.h index b83cacd54..06f178d36 100644 --- a/src/murmur/murmur_pch.h +++ b/src/murmur/murmur_pch.h @@ -37,6 +37,12 @@ #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> +#ifdef Q_OS_LINUX +#include <sys/capability.h> +#endif +#include <sys/time.h> +#include <sys/resource.h> +#include <pwd.h> #ifdef __FreeBSD__ #include <netinet/in_systm.h> #endif |