znc: run as user znc & use procd
Create & run znc as a specific user rather than nobody. Converted to use procd, removing dependencies on znc's 'droproot' module & 'su' Signed-off-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
This commit is contained in:
parent
b791b2aa9c
commit
a6715c17ff
3 changed files with 22 additions and 186 deletions
|
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=znc
|
PKG_NAME:=znc
|
||||||
PKG_VERSION:=1.6.3
|
PKG_VERSION:=1.6.3
|
||||||
PKG_RELEASE:=3
|
PKG_RELEASE:=4
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=http://znc.in/releases \
|
PKG_SOURCE_URL:=http://znc.in/releases \
|
||||||
|
@ -31,6 +31,7 @@ define Package/znc/default
|
||||||
CATEGORY:=Network
|
CATEGORY:=Network
|
||||||
TITLE:=ZNC
|
TITLE:=ZNC
|
||||||
URL:=http://en.znc.in/
|
URL:=http://en.znc.in/
|
||||||
|
USERID:=znc:znc
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/znc
|
define Package/znc
|
||||||
|
@ -62,12 +63,11 @@ define Package/znc/install
|
||||||
$(INSTALL_DIR) $(1)/etc/config
|
$(INSTALL_DIR) $(1)/etc/config
|
||||||
$(INSTALL_DATA) ./files/znc.conf $(1)/etc/config/znc
|
$(INSTALL_DATA) ./files/znc.conf $(1)/etc/config/znc
|
||||||
$(INSTALL_DIR) $(1)/usr/lib/znc/
|
$(INSTALL_DIR) $(1)/usr/lib/znc/
|
||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/modules/droproot.so $(1)/usr/lib/znc/
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|
||||||
ZNC_MODULES :=
|
ZNC_MODULES :=
|
||||||
ZNC_MODULE_TARGETS := droproot.so
|
ZNC_MODULE_TARGETS :=
|
||||||
|
|
||||||
define module
|
define module
|
||||||
define Package/znc-mod-$(strip $(1))
|
define Package/znc-mod-$(strip $(1))
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
START=60
|
START=60
|
||||||
|
|
||||||
|
USE_PROCD=1
|
||||||
|
|
||||||
ZNC_CONFIG_PATH=/tmp/etc/znc
|
ZNC_CONFIG_PATH=/tmp/etc/znc
|
||||||
PID_FILE=${ZNC_CONFIG_PATH}/znc.pid
|
PID_FILE=${ZNC_CONFIG_PATH}/znc.pid
|
||||||
ZNC_CONFIG=${ZNC_CONFIG_PATH}/configs/znc.conf
|
ZNC_CONFIG=${ZNC_CONFIG_PATH}/configs/znc.conf
|
||||||
|
@ -12,7 +14,6 @@ DISABLED=
|
||||||
|
|
||||||
RUNAS_USER=
|
RUNAS_USER=
|
||||||
RUNAS_GROUP=
|
RUNAS_GROUP=
|
||||||
RUNAS_SHELL=
|
|
||||||
|
|
||||||
add_param() {
|
add_param() {
|
||||||
echo "$1 = $2" >> $ZNC_CONFIG
|
echo "$1 = $2" >> $ZNC_CONFIG
|
||||||
|
@ -59,9 +60,8 @@ znc_global() {
|
||||||
|
|
||||||
config_get znc_config_path "$znc" znc_config_path
|
config_get znc_config_path "$znc" znc_config_path
|
||||||
|
|
||||||
config_get RUNAS_USER "$znc" runas_user
|
config_get RUNAS_USER "$znc" runas_user znc
|
||||||
config_get RUNAS_GROUP "$znc" runas_group
|
config_get RUNAS_GROUP "$znc" runas_group znc
|
||||||
config_get RUNAS_SHELL "$znc" runas_shell
|
|
||||||
|
|
||||||
if [ "${znc_config_path}" ]
|
if [ "${znc_config_path}" ]
|
||||||
then
|
then
|
||||||
|
@ -90,8 +90,6 @@ znc_global() {
|
||||||
|
|
||||||
config_list_foreach "$znc" listener "add_param Listener"
|
config_list_foreach "$znc" listener "add_param Listener"
|
||||||
config_list_foreach "$znc" module "add_param LoadModule"
|
config_list_foreach "$znc" module "add_param LoadModule"
|
||||||
|
|
||||||
add_param LoadModule "droproot ${RUNAS_USER:-nobody} ${RUNAS_GROUP:-nogroup}"
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,45 +154,30 @@ add_user() {
|
||||||
echo "</User>" >> $ZNC_CONFIG
|
echo "</User>" >> $ZNC_CONFIG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
start() {
|
|
||||||
config_load znc
|
config_load znc
|
||||||
config_foreach znc_global znc
|
config_foreach znc_global znc
|
||||||
|
|
||||||
if [ "$DISABLED" -eq 1 ]; then
|
[ "$DISABLED" -eq 0 ] || return 0
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$EXTERNAL_CONFIG" -eq 0 ]
|
if [ "$EXTERNAL_CONFIG" -eq 0 ]
|
||||||
then
|
then
|
||||||
config_foreach add_listener listener
|
config_foreach add_listener listener
|
||||||
config_foreach add_user user
|
config_foreach add_user user
|
||||||
|
|
||||||
chown -hR ${RUNAS_USER:-nobody}:${RUNAS_GROUP:-nogroup} ${ZNC_CONFIG_PATH}
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$EXTERNAL_CONFIG" -eq 1 -a "$RUNAS_USER" ]
|
chown -hR ${RUNAS_USER}:${RUNAS_GROUP} ${ZNC_CONFIG_PATH} || {
|
||||||
then
|
logger -s -t ZNC -p daemon.err "Invalid UID/GID. Aborting startup"
|
||||||
local SU=$(which su)
|
|
||||||
if [ "$SU" ]
|
|
||||||
then
|
|
||||||
chown -hR ${RUNAS_USER:-nobody}:${RUNAS_GROUP:-nogroup} ${ZNC_CONFIG_PATH}
|
|
||||||
$SU ${RUNAS_SHELL:+s $RUNAS_SHELL} -c "/usr/bin/znc -d$ZNC_CONFIG_PATH >/dev/null &" $RUNAS_USER
|
|
||||||
else
|
|
||||||
logger -s -t ZNC -p daemon.err "Could not run ZNC as user $RUNAS_USER: su not found."
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
}
|
||||||
else
|
|
||||||
/usr/bin/znc -d$ZNC_CONFIG_PATH >/dev/null &
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() {
|
procd_open_instance
|
||||||
if [ -f "$PID_FILE" ]
|
procd_set_param file /etc/config/znc
|
||||||
then
|
[ "$EXTERNAL_CONFIG" -eq 1 ] && procd_set_param file "${ZNC_CONFIG}/configs/znc.conf"
|
||||||
kill $(cat "$PID_FILE")
|
procd_set_param command /usr/bin/znc
|
||||||
else
|
procd_append_param command -f -d$ZNC_CONFIG_PATH
|
||||||
killall znc
|
procd_set_param user ${RUNAS_USER}
|
||||||
fi
|
procd_set_param respawn
|
||||||
|
procd_close_instance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
--- /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.")
|
|
Loading…
Reference in a new issue