mirror of
https://github.com/znc/znc.git
synced 2026-03-28 17:42:41 +01:00
MODCONSTRUCTOR does that job just fine (now). Signed-off-by: Uli Schlachter <psychon@znc.in>
145 lines
3.1 KiB
C++
145 lines
3.1 KiB
C++
/*
|
|
* 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-2008 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.h"
|
|
#include "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.")
|