--- /dev/null
+++ b/modules/droproot.cpp
@@ -0,0 +1,144 @@
+/*
+ * droproot.cpp
+ *
+ * Copyright (c) 2009 Vadtec (vadtec@vadtec.net)
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2004-2012  See the AUTHORS file for details.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <znc/znc.h>
+#include <znc/User.h>
+#include <pwd.h>
+#include <grp.h>
+
+class CDroproot : public CModule {
+
+public:
+	MODCONSTRUCTOR(CDroproot) {
+	}
+
+	virtual ~CDroproot() {
+	}
+
+	uid_t GetUser(const CString& sUser, CString& sMessage) {
+		uid_t ret = sUser.ToUInt();
+
+		if (ret != 0)
+			return ret;
+
+		struct passwd *pUser = getpwnam(sUser.c_str());
+
+		if (!pUser) {
+			sMessage = "User [" + sUser + "] not found!";
+			return 0;
+		}
+
+		return pUser->pw_uid;
+	}
+
+	gid_t GetGroup(const CString& sGroup, CString& sMessage) {
+		gid_t ret = sGroup.ToUInt();
+
+		if (ret != 0)
+			return ret;
+
+		struct group *pGroup = getgrnam(sGroup.c_str());
+
+		if (!pGroup) {
+			sMessage = "Group [" + sGroup + "] not found!";
+			return 0;
+		}
+
+		return pGroup->gr_gid;
+	}
+
+	virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
+		CString sUser = sArgs.Token(0);
+		CString sGroup = sArgs.Token(1, true);
+
+		if (sUser.empty() || sGroup.empty()) {
+			sMessage = "Usage: LoadModule = Droproot <uid> <gid>";
+			return false;
+		}
+
+		m_user = GetUser(sUser, sMessage);
+
+		if (m_user == 0) {
+			sMessage
+					= "Error: Cannot run as root, check your config file | Useage: LoadModule = Droproot <uid> <gid>";
+			return false;
+		}
+
+		m_group = GetGroup(sGroup, sMessage);
+
+		if (m_group == 0) {
+			sMessage
+					= "Error: Cannot run as root, check your config file | Useage: LoadModule = Droproot <uid> <gid>";
+			return false;
+		}
+
+		return true;
+	}
+
+	virtual bool OnBoot() {
+		int u, eu, g, eg, sg;
+
+		if ((geteuid() == 0) || (getuid() == 0) || (getegid() == 0) || (getgid()
+				== 0)) {
+
+			CUtils::PrintAction("Dropping root permissions");
+
+			// Clear all the supplementary groups
+			sg = setgroups(0, NULL);
+
+			if (sg < 0) {
+				CUtils::PrintStatus(false,
+						"Could not remove supplementary groups! ["
+								+ CString(strerror(errno)) + "]");
+
+				return false;
+			}
+
+			// Set the group (if we are root, this sets all three group IDs)
+			g = setgid(m_group);
+			eg = setegid(m_group);
+
+			if ((g < 0) || (eg < 0)) {
+				CUtils::PrintStatus(false, "Could not switch group id! ["
+						+ CString(strerror(errno)) + "]");
+
+				return false;
+			}
+
+			// and set the user (if we are root, this sets all three user IDs)
+			u = setuid(m_user);
+			eu = seteuid(m_user);
+
+			if ((u < 0) || (eu < 0)) {
+				CUtils::PrintStatus(false, "Could not switch user id! ["
+						+ CString(strerror(errno)) + "]");
+
+				return false;
+			}
+
+			CUtils::PrintStatus(true);
+
+			return true;
+		}
+
+		return true;
+	}
+
+protected:
+	uid_t m_user;
+	gid_t m_group;
+};
+
+GLOBALMODULEDEFS(CDroproot, "Allows ZNC to drop root privileges and run as an un-privileged user.")