mumble/0001-fix-user-switching.diff

131 lines
3.9 KiB
Diff
Raw Normal View History

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