git: 77487a63f99d - main - net-mgmt/net-snmp: Let snmpd run as a non-root user

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 09 May 2024 17:04:06 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/ports/commit/?id=77487a63f99d87e3e468d26008baf267ec600760

commit 77487a63f99d87e3e468d26008baf267ec600760
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-04-11 13:58:18 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-05-09 16:41:29 +0000

    net-mgmt/net-snmp: Let snmpd run as a non-root user
    
    - Compile without /dev/kmem access.  This requires a small patch which
      opens libkvm in a dummy mode which uses sysctls to implement most of
      its interfaces rather than /dev/kmem access.  This way we can drop the
      dependency on /dev/kmem without rewriting existing code.
    - Add a new snmpd user.  Configure snmpd to drop privileges once it's
      finished initialization.
    - Remove the JAIL option.  Now that snmpd avoids using /dev/kmem,
      there's no need to have a special mode for running snmpd in jails.
    
    The patch has been proposed upstream here:
    https://sourceforge.net/p/net-snmp/mailman/net-snmp-coders/thread/ZjEwNV5BiTOQ-Adi%40nuc/#msg58766857
    
    Approved by:    zi
    Sponsored by:   Klara, Inc.
    Sponsored by:   Stormshield
    Differential Revision:  https://reviews.freebsd.org/D45031
---
 GIDs                                         |  2 +-
 UIDs                                         |  2 +-
 net-mgmt/net-snmp/Makefile                   | 14 +++++-----
 net-mgmt/net-snmp/files/patch-agent_kernel.c | 40 ++++++++++++++++++++++++++++
 net-mgmt/net-snmp/files/snmpd.in             |  2 +-
 5 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/GIDs b/GIDs
index d98be0309a9c..ea5e397c234b 100644
--- a/GIDs
+++ b/GIDs
@@ -284,7 +284,7 @@ wildfire:*:340:
 stunnel:*:341:
 openfire:*:342:
 gunicorn:*:343:
-# free: 344
+snmpd:*:344:
 # free: 345
 # free: 346
 eturnal:*:347:
diff --git a/UIDs b/UIDs
index 0e43c506f91e..ceba79b7c0fc 100644
--- a/UIDs
+++ b/UIDs
@@ -289,7 +289,7 @@ wildfire:*:340:340::0:0:Wildfire Daemon:/nonexistent:/usr/sbin/nologin
 stunnel:*:341:341::0:0:Stunnel Daemon:/nonexistent:/usr/sbin/nologin
 openfire:*:342:342::0:0:Openfire IM Daemon:/nonexistent:/usr/sbin/nologin
 gunicorn:*:343:343::0:0:Gunicorn Daemon:/nonexistent:/usr/sbin/nologin
-# free: 344
+snmpd:*:344:344::0:0:Net-SNMP Daemon:/nonexistent:/usr/sbin/nologin
 # free: 345
 # free: 346
 eturnal:*:347:347::0:0:eturnal User:/var/spool/eturnal:/bin/sh
diff --git a/net-mgmt/net-snmp/Makefile b/net-mgmt/net-snmp/Makefile
index 71ad983bf18d..5fca4ba36051 100644
--- a/net-mgmt/net-snmp/Makefile
+++ b/net-mgmt/net-snmp/Makefile
@@ -1,6 +1,7 @@
 PORTNAME=	snmp
 PORTVERSION=	5.9.4
 PORTEPOCH=	1
+PORTREVISION=	1
 CATEGORIES=	net-mgmt
 MASTER_SITES=	SF/net-${PORTNAME}/net-${PORTNAME}/${PORTVERSION} \
 		ZI
@@ -18,7 +19,7 @@ NOT_FOR_ARCHS=		mips mips64
 NOT_FOR_ARCHS_REASON=	SSP is currently broken on MIPS
 
 OPTIONS_DEFINE=	MFD_REWRITES PERL PERL_EMBEDDED PYTHON DUMMY TKMIB \
-		MYSQL AX_SOCKONLY UNPRIVILEGED SMUX DOCS JAIL AX_DISABLE_TRAP \
+		MYSQL AX_SOCKONLY UNPRIVILEGED SMUX DOCS AX_DISABLE_TRAP \
 		TLS NEWSYSLOG NOLIBPKG SCTP
 OPTIONS_DEFAULT=PERL PERL_EMBEDDED DUMMY SMUX NEWSYSLOG
 OPTIONS_SUB=	yes
@@ -31,11 +32,13 @@ AX_SOCKONLY_DESC=	Disable UDP/TCP transports for agentx
 AX_DISABLE_TRAP_DESC=	Disable agentx subagent code in snmptrapd
 UNPRIVILEGED_DESC=	Allow unprivileged users to execute net-snmp
 SMUX_DESC=		Build with SNMP multiplexing (SMUX) support
-JAIL_DESC=		Options for running snmpd within a jail(8)
 NEWSYSLOG_DESC=		Automatically rotate snmpd.log via newsyslog
 NOLIBPKG_DESC=		Build without libpkg
 SCTP_DESC=		Build with SCTP MIB support
 
+USERS=		snmpd
+GROUPS=		snmpd
+
 GNU_CONFIGURE=	yes
 GNU_CONFIGURE_MANPREFIX=${PREFIX}/share
 USES=		cpe libtool perl5 ssl
@@ -55,6 +58,7 @@ CONFIGURE_ARGS+=--enable-shared --enable-internal-md5 \
 		--with-logfile="${NET_SNMP_LOGFILE}" \
 		--with-persistent-directory="${NET_SNMP_PERSISTENTDIR}" \
 		--with-gnu-ld --without-libwrap --enable-ipv6 \
+		--without-kmem-usage \
 		--with-ldflags="-lm -lkvm -ldevstat -L${PKG_PREFIX}/lib -L${LOCALBASE}/lib ${LCRYPTO}"
 SUB_FILES=	pkg-message
 
@@ -154,12 +158,6 @@ CONFIGURE_ARGS+=--enable-mfd-rewrites
 NET_SNMP_WITH_MIB_MODULE_LIST+=	if-mib
 .endif
 
-.if ${PORT_OPTIONS:MJAIL}
-NET_SNMP_WITHOUT_MIB_MODULE_LIST+=	host
-NET_SNMP_WITHOUT_MIB_MODULE_LIST+=	ucd-snmp/memory
-CONFIGURE_ARGS+=			--without-kmem-usage
-.endif
-
 .if ${PORT_OPTIONS:MSMUX}
 NET_SNMP_WITH_MIB_MODULE_LIST+=		smux
 .else
diff --git a/net-mgmt/net-snmp/files/patch-agent_kernel.c b/net-mgmt/net-snmp/files/patch-agent_kernel.c
new file mode 100644
index 000000000000..133b04bd1824
--- /dev/null
+++ b/net-mgmt/net-snmp/files/patch-agent_kernel.c
@@ -0,0 +1,40 @@
+--- agent/kernel.c.orig	2023-08-15 20:32:01 UTC
++++ agent/kernel.c
+@@ -252,7 +252,37 @@ free_kmem(void)
+         kmem = -1;
+     }
+ }
++#elif defined(__FreeBSD__)
++kvm_t *kd;
+ 
++/**
++ * Initialize the libkvm descriptor. On FreeBSD we can use most of libkvm
++ * without requiring /dev/kmem access.  Only kvm_nlist() and kvm_read() need
++ * that, and we don't use them.
++ *
++ * @return TRUE upon success; FALSE upon failure.
++ */
++int
++init_kmem(const char *file)
++{
++    char err[4096];
++
++    kd = kvm_openfiles(NULL, "/dev/null", NULL, O_RDONLY, err);
++    if (!kd) {
++        snmp_log(LOG_CRIT, "init_kmem: kvm_openfiles failed: %s\n", err);
++        return FALSE;
++    }
++    return TRUE;
++}
++
++void
++free_kmem(void)
++{
++    if (kd != NULL) {
++        (void)kvm_close(kd);
++        kd = NULL;
++    }
++}
+ #else
+ int
+ init_kmem(const char *file)
diff --git a/net-mgmt/net-snmp/files/snmpd.in b/net-mgmt/net-snmp/files/snmpd.in
index a98404d22bd0..7f140200aa45 100644
--- a/net-mgmt/net-snmp/files/snmpd.in
+++ b/net-mgmt/net-snmp/files/snmpd.in
@@ -57,7 +57,7 @@ net_snmpd_precmd () {
 	if [ -n "${snmpd_conffile_set}" ]; then
 		rc_flags="-c ${snmpd_conffile_set#,} ${rc_flags}"
 	fi
-	rc_flags="-p ${pidfile} ${rc_flags}"
+	rc_flags="-u snmpd -g snmpd -p ${pidfile} ${rc_flags}"
 }
 
 run_rc_command "$1"