131 lines
3.9 KiB
Diff
131 lines
3.9 KiB
Diff
|
From 41006c79225199fb6faaed3bc0228a35e9e51514 Mon Sep 17 00:00:00 2001
|
||
|
From: Ludwig Nussel <ludwig.nussel@suse.de>
|
||
|
Date: Fri, 24 Dec 2010 18:20:34 +0100
|
||
|
Subject: [PATCH 2/2] fix user switching
|
||
|
|
||
|
- don't keep saved uid 0. That's bad as an attacker that manages to
|
||
|
execute code could switch back to uid 0
|
||
|
- set $HOME as Qt doesn't look at passwd information
|
||
|
- initialize supplementary groups
|
||
|
- use "mumble-server" as fallback if no user is specified
|
||
|
---
|
||
|
src/murmur/Meta.cpp | 19 +++++++++++++------
|
||
|
src/murmur/Meta.h | 4 ++++
|
||
|
src/murmur/UnixMurmur.cpp | 12 ++++++++++--
|
||
|
src/murmur/main.cpp | 4 +++-
|
||
|
src/murmur/murmur_pch.h | 1 +
|
||
|
5 files changed, 31 insertions(+), 9 deletions(-)
|
||
|
|
||
|
diff --git a/src/murmur/Meta.cpp b/src/murmur/Meta.cpp
|
||
|
index 05cd03e..5efc52a 100644
|
||
|
--- a/src/murmur/Meta.cpp
|
||
|
+++ b/src/murmur/Meta.cpp
|
||
|
@@ -264,15 +264,22 @@ void MetaParams::read(QString fname) {
|
||
|
iBanTime = qsSettings->value("autobanTime", iBanTime).toInt();
|
||
|
|
||
|
#ifdef Q_OS_UNIX
|
||
|
- const QString uname = qsSettings->value("uname").toString();
|
||
|
- if (! uname.isEmpty() && (geteuid() == 0)) {
|
||
|
- struct passwd *pw = getpwnam(qPrintable(uname));
|
||
|
+ qsName = qsSettings->value("uname").toString();
|
||
|
+ if (geteuid() == 0) {
|
||
|
+ // TODO: remove this silent fallback to enforce running as non-root
|
||
|
+ bool requested = true;
|
||
|
+ if (qsName.isEmpty()) {
|
||
|
+ // default server user name
|
||
|
+ qsName = "mumble-server";
|
||
|
+ requested = false;
|
||
|
+ }
|
||
|
+ struct passwd *pw = getpwnam(qPrintable(qsName));
|
||
|
if (pw) {
|
||
|
uiUid = pw->pw_uid;
|
||
|
uiGid = pw->pw_gid;
|
||
|
- }
|
||
|
- if (uiUid == 0) {
|
||
|
- qFatal("Cannot find username %s", qPrintable(uname));
|
||
|
+ qsHome = pw->pw_dir;
|
||
|
+ } else if (requested) {
|
||
|
+ qFatal("Cannot find username %s", qPrintable(qsName));
|
||
|
}
|
||
|
endpwent();
|
||
|
}
|
||
|
diff --git a/src/murmur/Meta.h b/src/murmur/Meta.h
|
||
|
index 7924640..1ec2d2b 100644
|
||
|
--- a/src/murmur/Meta.h
|
||
|
+++ b/src/murmur/Meta.h
|
||
|
@@ -96,7 +96,11 @@ struct MetaParams {
|
||
|
|
||
|
QMap<QString, QString> qmConfig;
|
||
|
|
||
|
+#ifdef Q_OS_UNIX
|
||
|
unsigned int uiUid, uiGid;
|
||
|
+ QString qsHome;
|
||
|
+ QString qsName;
|
||
|
+#endif
|
||
|
|
||
|
QSettings *qsSettings;
|
||
|
|
||
|
diff --git a/src/murmur/UnixMurmur.cpp b/src/murmur/UnixMurmur.cpp
|
||
|
index eeeb67c..773701c 100644
|
||
|
--- a/src/murmur/UnixMurmur.cpp
|
||
|
+++ b/src/murmur/UnixMurmur.cpp
|
||
|
@@ -231,14 +231,22 @@ void UnixMurmur::setuid() {
|
||
|
} else
|
||
|
qFatal("Couldn't switch uid/gid.");
|
||
|
#else
|
||
|
- if (setregid(Meta::mp.uiGid, Meta::mp.uiGid) != 0)
|
||
|
+ if (::initgroups(qPrintable(Meta::mp.qsName), Meta::mp.uiGid) != 0)
|
||
|
+ qCritical("Can't initialize supplementary groups");
|
||
|
+ if (::setgid(Meta::mp.uiGid) != 0)
|
||
|
qCritical("Failed to switch to gid %d", Meta::mp.uiGid);
|
||
|
- if (setresuid(Meta::mp.uiUid, Meta::mp.uiUid, 0) != 0) {
|
||
|
+ if (::setuid(Meta::mp.uiUid) != 0) {
|
||
|
qFatal("Failed to become uid %d", Meta::mp.uiUid);
|
||
|
} else {
|
||
|
qCritical("Successfully switched to uid %d", Meta::mp.uiUid);
|
||
|
initialcap();
|
||
|
}
|
||
|
+ if (!Meta::mp.qsHome.isEmpty()) {
|
||
|
+ // QDir::homePath is broken. It only looks at $HOME
|
||
|
+ // instead of getpwuid() so we have to set our home
|
||
|
+ // ourselves
|
||
|
+ ::setenv("HOME", qPrintable(Meta::mp.qsHome), 1);
|
||
|
+ }
|
||
|
#endif
|
||
|
} else if (bRoot) {
|
||
|
qCritical("WARNING: You are running murmurd as root, without setting a uname in the ini file. This might be a security risk.");
|
||
|
diff --git a/src/murmur/main.cpp b/src/murmur/main.cpp
|
||
|
index 7a11250..5a4810d 100644
|
||
|
--- a/src/murmur/main.cpp
|
||
|
+++ b/src/murmur/main.cpp
|
||
|
@@ -272,11 +272,13 @@ int main(int argc, char **argv) {
|
||
|
|
||
|
|
||
|
Meta::mp.read(inifile);
|
||
|
- MumbleSSL::addSystemCA();
|
||
|
|
||
|
#ifdef Q_OS_UNIX
|
||
|
unixhandler.setuid();
|
||
|
#endif
|
||
|
+
|
||
|
+ MumbleSSL::addSystemCA();
|
||
|
+
|
||
|
ServerDB db;
|
||
|
|
||
|
meta = new Meta();
|
||
|
diff --git a/src/murmur/murmur_pch.h b/src/murmur/murmur_pch.h
|
||
|
index 27c38a1..c36d5ae 100644
|
||
|
--- a/src/murmur/murmur_pch.h
|
||
|
+++ b/src/murmur/murmur_pch.h
|
||
|
@@ -61,6 +61,7 @@ extern "C" {
|
||
|
#include <sys/prctl.h>
|
||
|
#endif
|
||
|
#include <pwd.h>
|
||
|
+#include <grp.h>
|
||
|
#ifdef __FreeBSD__
|
||
|
#include <netinet/in_systm.h>
|
||
|
#endif
|
||
|
--
|
||
|
1.7.1
|
||
|
|