znc: run as user znc & use procd 3504/head
authorKevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
Thu, 8 Sep 2016 11:17:21 +0000 (12:17 +0100)
committerKevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
Thu, 17 Nov 2016 10:28:43 +0000 (10:28 +0000)
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>
net/znc/Makefile
net/znc/files/znc.init
net/znc/patches/102-restore_droproot.patch [deleted file]

index 4fa31c4687c9f64b7941501b13169c71b6edb414..a36c8e01096cfb814f7282ea29816cafa7832b3d 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=znc
 PKG_VERSION:=1.6.3
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://znc.in/releases \
@@ -31,6 +31,7 @@ define Package/znc/default
   CATEGORY:=Network
   TITLE:=ZNC
   URL:=http://en.znc.in/
+  USERID:=znc:znc
 endef
 
 define Package/znc
@@ -62,12 +63,11 @@ define Package/znc/install
        $(INSTALL_DIR) $(1)/etc/config
        $(INSTALL_DATA) ./files/znc.conf $(1)/etc/config/znc
        $(INSTALL_DIR) $(1)/usr/lib/znc/
-       $(INSTALL_BIN) $(PKG_BUILD_DIR)/modules/droproot.so $(1)/usr/lib/znc/
 endef
 
 
 ZNC_MODULES :=
-ZNC_MODULE_TARGETS := droproot.so
+ZNC_MODULE_TARGETS :=
 
 define module
   define Package/znc-mod-$(strip $(1))
index 91f3ecaa7eb00e7df22a76505f4d693ab24846fa..0277afff611664f1b5091d2a43799b41f64aa2c9 100644 (file)
@@ -3,6 +3,8 @@
 
 START=60
 
+USE_PROCD=1
+
 ZNC_CONFIG_PATH=/tmp/etc/znc
 PID_FILE=${ZNC_CONFIG_PATH}/znc.pid
 ZNC_CONFIG=${ZNC_CONFIG_PATH}/configs/znc.conf
@@ -12,7 +14,6 @@ DISABLED=
 
 RUNAS_USER=
 RUNAS_GROUP=
-RUNAS_SHELL=
 
 add_param() {
        echo "$1 = $2" >> $ZNC_CONFIG
@@ -59,9 +60,8 @@ znc_global() {
 
        config_get znc_config_path "$znc" znc_config_path
 
-       config_get RUNAS_USER "$znc" runas_user
-       config_get RUNAS_GROUP "$znc" runas_group
-       config_get RUNAS_SHELL "$znc" runas_shell
+       config_get RUNAS_USER "$znc" runas_user znc
+       config_get RUNAS_GROUP "$znc" runas_group znc
 
        if [ "${znc_config_path}" ]
        then
@@ -90,8 +90,6 @@ znc_global() {
 
                config_list_foreach "$znc" listener "add_param Listener"
                config_list_foreach "$znc" module "add_param LoadModule"
-
-               add_param LoadModule "droproot ${RUNAS_USER:-nobody} ${RUNAS_GROUP:-nogroup}"
        fi
 }
 
@@ -156,45 +154,30 @@ add_user() {
        echo "</User>" >> $ZNC_CONFIG
 }
 
-
-start() {
+start_service() {
        config_load znc
        config_foreach znc_global znc
 
-       if [ "$DISABLED" -eq 1 ]; then
-               return 0
-       fi
+       [ "$DISABLED" -eq 0 ] || return 0
 
        if [ "$EXTERNAL_CONFIG" -eq 0 ]
        then
                config_foreach add_listener listener
                config_foreach add_user user
 
-               chown -hR ${RUNAS_USER:-nobody}:${RUNAS_GROUP:-nogroup} ${ZNC_CONFIG_PATH}
-       fi
-
-       if [ "$EXTERNAL_CONFIG" -eq 1 -a "$RUNAS_USER"  ]
-       then
-               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
-               fi
-       else
-               /usr/bin/znc -d$ZNC_CONFIG_PATH >/dev/null &
        fi
-}
 
-stop() {
-       if [ -f "$PID_FILE" ]
-       then
-               kill $(cat "$PID_FILE")
-       else
-               killall znc
-       fi
+       chown -hR ${RUNAS_USER}:${RUNAS_GROUP} ${ZNC_CONFIG_PATH} || {
+               logger -s -t ZNC -p daemon.err "Invalid UID/GID. Aborting startup"
+               exit 1
+       }
+
+       procd_open_instance
+       procd_set_param file /etc/config/znc
+       [ "$EXTERNAL_CONFIG" -eq 1 ] && procd_set_param file "${ZNC_CONFIG}/configs/znc.conf"
+       procd_set_param command /usr/bin/znc
+       procd_append_param command -f -d$ZNC_CONFIG_PATH
+       procd_set_param user ${RUNAS_USER}
+       procd_set_param respawn
+       procd_close_instance
 }
-
diff --git a/net/znc/patches/102-restore_droproot.patch b/net/znc/patches/102-restore_droproot.patch
deleted file mode 100644 (file)
index 1cacce4..0000000
+++ /dev/null
@@ -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.")