Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorvald Natvig <slicer@users.sourceforge.net>2009-02-26 17:03:27 +0300
committerThorvald Natvig <slicer@users.sourceforge.net>2009-02-26 17:03:27 +0300
commit7fc01d602e63cf7d764a7c14dbe6f53941604dda (patch)
tree11e7561f226b3defd14f0cb93c57a062e005e6d4 /src/murmur
parent0df61d2f2d12782516f32e5a15e08670dc09c3ac (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/murmur')
-rw-r--r--src/murmur/DBus.cpp20
-rw-r--r--src/murmur/DBus.h1
-rw-r--r--src/murmur/Meta.cpp16
-rw-r--r--src/murmur/Meta.h2
-rw-r--r--src/murmur/UnixMurmur.cpp58
-rw-r--r--src/murmur/UnixMurmur.h4
-rw-r--r--src/murmur/main.cpp14
-rw-r--r--src/murmur/murmur.pro3
-rw-r--r--src/murmur/murmur_pch.h6
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