File 0001-fix-user-switching.diff of Package mumble

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

openSUSE Build Service is sponsored by