You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

147 lines
3.3 KiB

--- /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 | Usage: 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 | Usage: 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.")