2 +++ b/modules/droproot.cpp
7 + * Copyright (c) 2009 Vadtec (vadtec@vadtec.net)
8 + * This program is free software; you can redistribute it and/or modify it
9 + * under the terms of the GNU General Public License version 2 as published
10 + * by the Free Software Foundation.
12 + * Copyright (C) 2004-2012 See the AUTHORS file for details.
14 + * This program is free software; you can redistribute it and/or modify it
15 + * under the terms of the GNU General Public License version 2 as published
16 + * by the Free Software Foundation.
20 +#include <znc/User.h>
24 +class CDroproot : public CModule {
27 + MODCONSTRUCTOR(CDroproot) {
30 + virtual ~CDroproot() {
33 + uid_t GetUser(const CString& sUser, CString& sMessage) {
34 + uid_t ret = sUser.ToUInt();
39 + struct passwd *pUser = getpwnam(sUser.c_str());
42 + sMessage = "User [" + sUser + "] not found!";
46 + return pUser->pw_uid;
49 + gid_t GetGroup(const CString& sGroup, CString& sMessage) {
50 + gid_t ret = sGroup.ToUInt();
55 + struct group *pGroup = getgrnam(sGroup.c_str());
58 + sMessage = "Group [" + sGroup + "] not found!";
62 + return pGroup->gr_gid;
65 + virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
66 + CString sUser = sArgs.Token(0);
67 + CString sGroup = sArgs.Token(1, true);
69 + if (sUser.empty() || sGroup.empty()) {
70 + sMessage = "Usage: LoadModule = Droproot <uid> <gid>";
74 + m_user = GetUser(sUser, sMessage);
78 + = "Error: Cannot run as root, check your config file | Useage: LoadModule = Droproot <uid> <gid>";
82 + m_group = GetGroup(sGroup, sMessage);
86 + = "Error: Cannot run as root, check your config file | Useage: LoadModule = Droproot <uid> <gid>";
93 + virtual bool OnBoot() {
94 + int u, eu, g, eg, sg;
96 + if ((geteuid() == 0) || (getuid() == 0) || (getegid() == 0) || (getgid()
99 + CUtils::PrintAction("Dropping root permissions");
101 + // Clear all the supplementary groups
102 + sg = setgroups(0, NULL);
105 + CUtils::PrintStatus(false,
106 + "Could not remove supplementary groups! ["
107 + + CString(strerror(errno)) + "]");
112 + // Set the group (if we are root, this sets all three group IDs)
113 + g = setgid(m_group);
114 + eg = setegid(m_group);
116 + if ((g < 0) || (eg < 0)) {
117 + CUtils::PrintStatus(false, "Could not switch group id! ["
118 + + CString(strerror(errno)) + "]");
123 + // and set the user (if we are root, this sets all three user IDs)
124 + u = setuid(m_user);
125 + eu = seteuid(m_user);
127 + if ((u < 0) || (eu < 0)) {
128 + CUtils::PrintStatus(false, "Could not switch user id! ["
129 + + CString(strerror(errno)) + "]");
134 + CUtils::PrintStatus(true);
147 +GLOBALMODULEDEFS(CDroproot, "Allows ZNC to drop root privileges and run as an un-privileged user.")