git: 343766e13e0f - main - net/389-ds-base: Add new port

From: Jochen Neumeister <joneum_at_FreeBSD.org>
Date: Sun, 28 Jun 2026 20:54:55 UTC
The branch main has been updated by joneum:

URL: https://cgit.FreeBSD.org/ports/commit/?id=343766e13e0ff9d0279260986ff077bb6819811f

commit 343766e13e0ff9d0279260986ff077bb6819811f
Author:     Jochen Neumeister <joneum@FreeBSD.org>
AuthorDate: 2026-06-28 20:47:41 +0000
Commit:     Jochen Neumeister <joneum@FreeBSD.org>
CommitDate: 2026-06-28 20:54:45 +0000

    net/389-ds-base: Add new port
    
    389 Directory Server is an enterprise-class LDAP directory server
    designed to provide scalable and reliable directory services for
    identity management, authentication, authorization, and centralized
    account data.
    
    It supports features such as replication, access control, schema
    management, plugins, and administrative command-line utilities.
    
    Required for development of the net/freeipa-server port.
    
    WWW: https://www.port389.org/
    
    Sponsored by:   Netzkommune GmbH
---
 net/389-ds-base/Makefile                           |  54 +++++++
 net/389-ds-base/distinfo                           |   3 +
 net/389-ds-base/files/patch-Makefile.am            |  11 ++
 .../patch-ldap_servers_plugins_memberof_memberof.c |  11 ++
 .../patch-ldap_servers_plugins_sync_sync__init.c   |  20 +++
 ...patch-ldap_servers_plugins_sync_sync__persist.c | 126 +++++++++++++++
 ...dap_servers_slapd_back-ldbm_db-mdb_mdb__debug.c |  15 ++
 ...dap_servers_slapd_back-ldbm_db-mdb_mdb__debug.h |  11 ++
 ..._servers_slapd_back-ldbm_db-mdb_mdb__instance.c |  45 ++++++
 .../files/patch-ldap_servers_slapd_daemon.c        |  32 ++++
 .../files/patch-ldap_servers_slapd_libglobs.c      |  22 +++
 .../files/patch-ldap_servers_slapd_slapi__pal.c    |  75 +++++++++
 .../patch-ldap_servers_slapd_tools_ldclt_ldclt.c   |  32 ++++
 net/389-ds-base/pkg-descr                          |   3 +
 net/389-ds-base/pkg-plist                          | 178 +++++++++++++++++++++
 net/Makefile                                       |   1 +
 16 files changed, 639 insertions(+)

diff --git a/net/389-ds-base/Makefile b/net/389-ds-base/Makefile
new file mode 100644
index 000000000000..0b975415be01
--- /dev/null
+++ b/net/389-ds-base/Makefile
@@ -0,0 +1,54 @@
+PORTNAME=	389-ds-base
+DISTVERSION=	3.2.1
+CATEGORIES=	net
+MASTER_SITES=	https://github.com/389ds/389-ds-base/releases/download/${PORTNAME}-${DISTVERSION}/
+
+MAINTAINER=	joneum@FreeBSD.org
+COMMENT=	Enterprise-class LDAP directory server
+WWW=		https://www.port389.org/
+
+LICENSE=	GPLv3+
+LICENSE_FILE=	${WRKSRC}/LICENSE
+
+BUILD_DEPENDS=	${LOCALBASE}/include/crypt.h:security/libxcrypt \
+		cargo:lang/rust \
+		rsync:net/rsync
+
+LIB_DEPENDS=	libcrack.so:security/cracklib \
+		libicui18n.so:devel/icu \
+		libjson-c.so:devel/json-c \
+		liblmdb.so:databases/lmdb \
+		libnetsnmp.so:net-mgmt/net-snmp \
+		libnspr4.so:devel/nspr \
+		libnss3.so:security/nss \
+		libpcre2-8.so:devel/pcre2 \
+		libpkg.so:ports-mgmt/pkg \
+		libsasl2.so:security/cyrus-sasl2
+
+USES=		autoreconf gmake ldap libtool localbase:ldflags perl5 pkgconfig \
+		python:3.12+ shebangfix ssl tar:bzip2
+
+USE_LDCONFIG=	${PREFIX}/lib ${PREFIX}/lib/dirsrv
+USE_PERL5=	run
+
+SHEBANG_FILES=	ldap/admin/src/logconv.pl ldap/admin/src/logconv.py \
+		ldap/admin/src/scripts/ds-logpipe.py \
+		ldap/admin/src/scripts/ds-replcheck \
+		ldap/servers/slapd/mkDBErrStrs.py
+
+GNU_CONFIGURE=	yes
+CONFIGURE_ARGS=	--disable-dependency-tracking \
+		--enable-rust-offline \
+		--with-netsnmp=${LOCALBASE} \
+		--with-openldap=${LOCALBASE} \
+		--with-pythonexec=${PYTHON_CMD}
+
+MAKE_ENV=	CARGO_HOME=${WRKSRC}/.cargo \
+		CARGO_NET_OFFLINE=true \
+		PYTHON=${PYTHON_CMD}
+
+LIBS+=		-lexecinfo
+
+BINARY_ALIAS=	python3=${PYTHON_CMD}
+
+.include <bsd.port.mk>
diff --git a/net/389-ds-base/distinfo b/net/389-ds-base/distinfo
new file mode 100644
index 000000000000..b8bec5a2634e
--- /dev/null
+++ b/net/389-ds-base/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1782503513
+SHA256 (389-ds-base-3.2.1.tar.bz2) = a5b7b533484f16d5271c97b7dbde485b22fa63d2bfb4434ce9b6720849e67559
+SIZE (389-ds-base-3.2.1.tar.bz2) = 23711885
diff --git a/net/389-ds-base/files/patch-Makefile.am b/net/389-ds-base/files/patch-Makefile.am
new file mode 100644
index 000000000000..5525b2616687
--- /dev/null
+++ b/net/389-ds-base/files/patch-Makefile.am
@@ -0,0 +1,11 @@
+--- Makefile.am.orig	2026-04-30 12:45:04 UTC
++++ Makefile.am
+@@ -12,7 +12,7 @@ QUOTE := $(NULLSTRING)"# a double quote"
+ # First, we setup the definitions from configure.ac
+ #
+ 
+-PYTHON := python3
++PYTHON := @pythonexec@
+ if DEBUG
+ # This allows sccache to work correctly with C files.
+ BUILDNUM := "\"0000.000.0000\""
diff --git a/net/389-ds-base/files/patch-ldap_servers_plugins_memberof_memberof.c b/net/389-ds-base/files/patch-ldap_servers_plugins_memberof_memberof.c
new file mode 100644
index 000000000000..abfeffa70788
--- /dev/null
+++ b/net/389-ds-base/files/patch-ldap_servers_plugins_memberof_memberof.c
@@ -0,0 +1,11 @@
+--- ldap/servers/plugins/memberof/memberof.c.orig	2026-06-28 10:10:14 UTC
++++ ldap/servers/plugins/memberof/memberof.c
+@@ -1873,7 +1873,7 @@ memberof_call_foreach_dn(Slapi_PBlock *pb __attribute_
+         ht_grp = ancestors_cache_lookup(config, (const void *)ndn);
+         if (ht_grp) {
+ #if MEMBEROF_CACHE_DEBUG
+-            slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_call_foreach_dn: Ancestors of %s already cached (%lx)\n", ndn, (ulong) ht_grp);
++            slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_call_foreach_dn: Ancestors of %s already cached (%lx)\n", ndn, (unsigned long) ht_grp);
+ #endif
+             add_ancestors_cbdata(ht_grp, callback_data);
+             *cached = 1;
diff --git a/net/389-ds-base/files/patch-ldap_servers_plugins_sync_sync__init.c b/net/389-ds-base/files/patch-ldap_servers_plugins_sync_sync__init.c
new file mode 100644
index 000000000000..90d6237bdb35
--- /dev/null
+++ b/net/389-ds-base/files/patch-ldap_servers_plugins_sync_sync__init.c
@@ -0,0 +1,20 @@
+--- ldap/servers/plugins/sync/sync_init.c.orig	2026-06-28 10:07:36 UTC
++++ ldap/servers/plugins/sync/sync_init.c
+@@ -310,7 +310,7 @@ sync_persist_get_operation_extension(Slapi_PBlock *pb)
+     ident = slapi_get_object_extension(sync_persist_extension_type, op,
+                                        sync_persist_extension_handle);
+     slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "sync_persist_get_operation_extension operation (op=0x%lx) -> %d\n",
+-                    (ulong) op, ident ? ident->idx_pl : -1);
++                    (unsigned long) op, ident ? ident->idx_pl : -1);
+     return (op_ext_ident_t *) ident;
+ 
+ }
+@@ -322,7 +322,7 @@ sync_persist_set_operation_extension(Slapi_PBlock *pb,
+ 
+     slapi_pblock_get(pb, SLAPI_OPERATION, &op);
+     slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "sync_persist_set_operation_extension operation (op=0x%lx) -> %d\n",
+-                    (ulong) op, op_ident ? op_ident->idx_pl : -1);
++                    (unsigned long) op, op_ident ? op_ident->idx_pl : -1);
+     slapi_set_object_extension(sync_persist_extension_type, op,
+                                sync_persist_extension_handle, (void *)op_ident);
+ }
diff --git a/net/389-ds-base/files/patch-ldap_servers_plugins_sync_sync__persist.c b/net/389-ds-base/files/patch-ldap_servers_plugins_sync_sync__persist.c
new file mode 100644
index 000000000000..c3bd5a3e517e
--- /dev/null
+++ b/net/389-ds-base/files/patch-ldap_servers_plugins_sync_sync__persist.c
@@ -0,0 +1,126 @@
+--- ldap/servers/plugins/sync/sync_persist.c.orig	2026-06-28 10:01:47 UTC
++++ ldap/servers/plugins/sync/sync_persist.c
+@@ -153,7 +153,7 @@ sync_update_persist_betxn_pre_op(Slapi_PBlock *pb)
+         PR_ASSERT(current_op->flags == OPERATION_PL_PENDING);
+         slapi_log_err(SLAPI_LOG_WARNING, SYNC_PLUGIN_SUBSYSTEM, "sync_update_persist_betxn_pre_op - DB retried operation targets "
+                       "\"%s\" (op=0x%lx idx_pl=%d) => op not changed in PL\n",
+-                      slapi_sdn_get_dn(sdn), (ulong) op, idx_pl);
++                      slapi_sdn_get_dn(sdn), (unsigned long) op, idx_pl);
+         return 0;
+     }
+ 
+@@ -177,7 +177,7 @@ sync_update_persist_betxn_pre_op(Slapi_PBlock *pb)
+                    */
+         slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "sync_update_persist_betxn_pre_op - nested operation targets "
+                       "\"%s\" (op=0x%lx idx_pl=%d)\n",
+-                      slapi_sdn_get_dn(sdn), (ulong) new_op->op, idx_pl);
++                      slapi_sdn_get_dn(sdn), (unsigned long) new_op->op, idx_pl);
+     } else {
+         /* The current operation is the first/primary one in the txn
+          * registers it directly in the thread private data (head)
+@@ -186,7 +186,7 @@ sync_update_persist_betxn_pre_op(Slapi_PBlock *pb)
+         idx_pl = 0; /* as primary operation, its index in the pending list is 0 */
+         slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "sync_update_persist_betxn_pre_op - primary operation targets "
+                       "\"%s\" (0x%lx)\n",
+-                      slapi_sdn_get_dn(sdn), (ulong) new_op->op);
++                      slapi_sdn_get_dn(sdn), (unsigned long) new_op->op);
+     }
+ 
+     /* records, in the operation extension AND in the pending list, the identifier (index) of
+@@ -225,7 +225,7 @@ ignore_op_pl(Slapi_PBlock *pb)
+          */
+         slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM,
+               "ignore_op_pl - Operation without primary op set (0x%lx)\n",
+-              (ulong) op);
++              (unsigned long) op);
+         return;
+     }
+     ident = sync_persist_get_operation_extension(pb);
+@@ -243,14 +243,14 @@ ignore_op_pl(Slapi_PBlock *pb)
+                  */
+                 PR_ASSERT(curr_op->flags == OPERATION_PL_PENDING);
+                 slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "ignore_op_pl operation (op=0x%lx, idx_pl=%d) from the pending list\n",
+-                        (ulong) op, ident->idx_pl);
++                        (unsigned long) op, ident->idx_pl);
+                 curr_op->flags = OPERATION_PL_IGNORED;
+                 return;
+             }
+         }
+     }
+     slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "ignore_op_pl failing operation (op=0x%lx, idx_pl=%d) was not in the pending list\n",
+-                    (ulong) op, ident ? ident->idx_pl : -1);
++                    (unsigned long) op, ident ? ident->idx_pl : -1);
+ }
+ 
+ /* This is a generic function that is called by betxn_post of this plugin.
+@@ -291,14 +291,14 @@ sync_update_persist_op(Slapi_PBlock *pb, Slapi_Entry *
+         if (0 != rc) {
+             /* The internal operation did not succeed */
+             slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "internal operation Failed (0x%lx) rc=%d\n",
+-                       (ulong) pb_op, rc);
++                       (unsigned long) pb_op, rc);
+         }
+     } else {
+         slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &rc);
+         if (0 != rc) {
+             /* The operation did not succeed */
+             slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "direct operation Failed (0x%lx) rc=%d\n",
+-                       (ulong) pb_op, rc);
++                       (unsigned long) pb_op, rc);
+         }
+     }
+ 
+@@ -312,7 +312,7 @@ sync_update_persist_op(Slapi_PBlock *pb, Slapi_Entry *
+          */
+         slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM,
+                       "sync_update_persist_op - Operation without primary op set (0x%lx)\n",
+-                      (ulong) pb_op);
++                      (unsigned long) pb_op);
+         return;
+     }
+     ident = sync_persist_get_operation_extension(pb);
+@@ -322,7 +322,7 @@ sync_update_persist_op(Slapi_PBlock *pb, Slapi_Entry *
+          * As a NOOP betxn plugins are not called and operation ext is not created
+          */
+         slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "Skip noop operation (0x%lx)\n",
+-                       (ulong) pb_op);
++                       (unsigned long) pb_op);
+         return;
+     }
+     assert(ident);
+@@ -351,7 +351,7 @@ sync_update_persist_op(Slapi_PBlock *pb, Slapi_Entry *
+     }
+     if (!curr_op) {
+         slapi_log_err(SLAPI_LOG_ERR, SYNC_PLUGIN_SUBSYSTEM, "%s - operation (op=0x%lx, idx_pl=%d) not found on the pendling list\n",
+-                      label, (ulong) pb_op, ident->idx_pl);
++                      label, (unsigned long) pb_op, ident->idx_pl);
+         PR_ASSERT(curr_op);
+     }
+ 
+@@ -391,7 +391,7 @@ sync_update_persist_op(Slapi_PBlock *pb, Slapi_Entry *
+ 
+             }
+             slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "dump pending list(0x%lx) %s %s\n",
+-                    (ulong) curr_op->op, entry_str, flags_str);
++                    (unsigned long) curr_op->op, entry_str, flags_str);
+         }
+     }
+ 
+@@ -402,7 +402,7 @@ sync_update_persist_op(Slapi_PBlock *pb, Slapi_Entry *
+         }
+     }
+     if (curr_op) {
+-        slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "%s - It remains a pending operation (0x%lx)\n", label, (ulong) curr_op->op);
++        slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "%s - It remains a pending operation (0x%lx)\n", label, (unsigned long) curr_op->op);
+     } else {
+         OPERATION_PL_CTX_T *next = NULL;
+         PRBool enqueue_it = PR_TRUE;
+@@ -427,7 +427,7 @@ sync_update_persist_op(Slapi_PBlock *pb, Slapi_Entry *
+                 entry = "unknown";
+             }
+             slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, "Do %s enqueue (0x%lx) %s\n",
+-                    enqueue_it ? "" : "not", (ulong) curr_op->op, entry);
++                    enqueue_it ? "" : "not", (unsigned long) curr_op->op, entry);
+             if (enqueue_it) {
+                 sync_queue_change(curr_op);
+             }
diff --git a/net/389-ds-base/files/patch-ldap_servers_slapd_back-ldbm_db-mdb_mdb__debug.c b/net/389-ds-base/files/patch-ldap_servers_slapd_back-ldbm_db-mdb_mdb__debug.c
new file mode 100644
index 000000000000..a97f5d3c0ca6
--- /dev/null
+++ b/net/389-ds-base/files/patch-ldap_servers_slapd_back-ldbm_db-mdb_mdb__debug.c
@@ -0,0 +1,15 @@
+--- ldap/servers/slapd/back-ldbm/db-mdb/mdb_debug.c.orig	2026-06-28 09:36:14 UTC
++++ ldap/servers/slapd/back-ldbm/db-mdb/mdb_debug.c
+@@ -16,7 +16,12 @@
+ #include <string.h>
+ #include <stdlib.h>
+ #include <unistd.h>
++#ifdef __FreeBSD__
++#include <pthread_np.h>
++#define pthread_gettid pthread_getthreadid_np
++#else
+ #include <syscall.h>
++#endif
+ #include <dlfcn.h>
+ 
+ 
diff --git a/net/389-ds-base/files/patch-ldap_servers_slapd_back-ldbm_db-mdb_mdb__debug.h b/net/389-ds-base/files/patch-ldap_servers_slapd_back-ldbm_db-mdb_mdb__debug.h
new file mode 100644
index 000000000000..7a2013029b5d
--- /dev/null
+++ b/net/389-ds-base/files/patch-ldap_servers_slapd_back-ldbm_db-mdb_mdb__debug.h
@@ -0,0 +1,11 @@
+--- ldap/servers/slapd/back-ldbm/db-mdb/mdb_debug.h.orig	2026-06-28 10:10:14 UTC
++++ ldap/servers/slapd/back-ldbm/db-mdb/mdb_debug.h
+@@ -53,7 +53,7 @@ void dbi_str(MDB_cursor *cursor, int dbi, char dbistr[
+ #define TXN_ABORT(txn) dbg_txn_end(__FILE__,__LINE__,__FUNCTION__, txn, 0)
+ #define TXN_RESET(txn) dbg_txn_reset(__FILE__,__LINE__,__FUNCTION__, txn)
+ #define TXN_RENEW(txn) dbg_txn_renew(__FILE__,__LINE__,__FUNCTION__, txn)
+-#define TXN_LOG(msg,txn) dbg_log(__FILE__,__LINE__,__FUNCTION__,DBGMDB_LEVEL_TXN, msg, (ulong)(txn))
++#define TXN_LOG(msg,txn) dbg_log(__FILE__,__LINE__,__FUNCTION__,DBGMDB_LEVEL_TXN, msg, (unsigned long)(txn))
+ #define pthread_gettid() syscall(__NR_gettid)
+ 
+ #define DBG_LOG(...) dbg_log(__FILE__,__LINE__,__FUNCTION__, __VA_ARGS__)
diff --git a/net/389-ds-base/files/patch-ldap_servers_slapd_back-ldbm_db-mdb_mdb__instance.c b/net/389-ds-base/files/patch-ldap_servers_slapd_back-ldbm_db-mdb_mdb__instance.c
new file mode 100644
index 000000000000..c01fe42683e3
--- /dev/null
+++ b/net/389-ds-base/files/patch-ldap_servers_slapd_back-ldbm_db-mdb_mdb__instance.c
@@ -0,0 +1,45 @@
+--- ldap/servers/slapd/back-ldbm/db-mdb/mdb_instance.c.orig	2026-06-28 11:12:50 UTC
++++ ldap/servers/slapd/back-ldbm/db-mdb/mdb_instance.c
+@@ -368,9 +368,20 @@ add_index_dbi(caddr_t attr, caddr_t otx)
+ }
+ 
+ /* Destructor for dbi's tree */
+-void free_dbi_node(void *node)
++static void
++dbmdb_tree_destroy(dbmdb_ctx_t *ctx)
+ {
+-    /* as the tree points on ctx->dbi_slots slots, there is nothing to do here */
++    int i;
++
++    for (i = 0; i < ctx->startcfg.max_dbs; i++) {
++        if (ctx->dbi_slots[i].dbname != NULL) {
++            (void)tdelete(&ctx->dbi_slots[i],
++                          &ctx->dbis_treeroot,
++                          cmp_dbi_names);
++        }
++    }
++
++    ctx->dbis_treeroot = NULL;
+ }
+ 
+ /* Open/creat all the dbis to avoid opening the db in operation towards this backend
+@@ -511,8 +522,7 @@ error:
+     }
+     if (rc) {
+         /* Roll back invalid slots and rebuild dbis tree */
+-        tdestroy(ctx->dbis_treeroot, free_dbi_node);
+-        ctx->dbis_treeroot = NULL;
++        dbmdb_tree_destroy(ctx);
+         for (i=0; i < ctx->startcfg.max_dbs; i++) {
+             if (ctx->dbi_slots[i].dbname) {
+                 if (valid_slots[i]) {
+@@ -791,8 +801,7 @@ void dbmdb_ctx_close(dbmdb_ctx_t *ctx)
+         ctx->env = NULL;
+     }
+     if (ctx->dbi_slots) {
+-        tdestroy(ctx->dbis_treeroot, free_dbi_node);
+-        ctx->dbis_treeroot = NULL;
++        dbmdb_tree_destroy(ctx);
+         for (i=0; i<ctx->startcfg.max_dbs; i++)
+             slapi_ch_free((void**)&ctx->dbi_slots[i].dbname);
+         slapi_ch_free((void**)&ctx->dbi_slots);
diff --git a/net/389-ds-base/files/patch-ldap_servers_slapd_daemon.c b/net/389-ds-base/files/patch-ldap_servers_slapd_daemon.c
new file mode 100644
index 000000000000..038a26c00479
--- /dev/null
+++ b/net/389-ds-base/files/patch-ldap_servers_slapd_daemon.c
@@ -0,0 +1,32 @@
+--- ldap/servers/slapd/daemon.c.orig	2026-06-28 09:01:40 UTC
++++ ldap/servers/slapd/daemon.c
+@@ -805,6 +805,7 @@ disk_monitoring_thread(void *nothing __attribute__((un
+         return;
+ }
+ 
++#ifdef ENABLE_EPOLL
+ char *epoll_event_flags_to_string(PRUint32 events)
+ {
+     static char buf[64];
+@@ -850,6 +851,7 @@ char *epoll_event_flags_to_string(PRUint32 events)
+     }
+     return buf;
+ }
++#endif /* ENABLE_EPOLL */
+ 
+ #ifdef ENABLE_EPOLL
+ static void
+@@ -3115,11 +3117,13 @@ configure_pr_socket(PRFileDesc **pr_socket, int secure
+     } /* else (!enable_nagle) */
+ 
+     if (!local) {
++#ifdef TCP_LINGER2
+         if (setsockopt(ns, IPPROTO_TCP, TCP_LINGER2, (void *)&fin_timeout, sizeof(fin_timeout)) == -1) {
+             slapi_log_err(SLAPI_LOG_ERR,
+                           "configure_pr_socket", "setsockopt(TCP_LINGER2) failed, error %d (%s)\n",
+                           errno, strerror(errno));
+         }
++#endif
+ 
+         if (setsockopt(ns, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepalive_time, sizeof(keepalive_time)) == -1) {
+             slapi_log_err(SLAPI_LOG_ERR,
diff --git a/net/389-ds-base/files/patch-ldap_servers_slapd_libglobs.c b/net/389-ds-base/files/patch-ldap_servers_slapd_libglobs.c
new file mode 100644
index 000000000000..8e72aa6bd5b9
--- /dev/null
+++ b/net/389-ds-base/files/patch-ldap_servers_slapd_libglobs.c
@@ -0,0 +1,22 @@
+--- ldap/servers/slapd/libglobs.c.orig	2026-06-28 10:40:56 UTC
++++ ldap/servers/slapd/libglobs.c
+@@ -10299,6 +10299,9 @@ config_get_malloc_mmap_threshold()
+     return retVal;
+ }
+ 
++#endif /* __GLIBC__ */
++#endif /* LINUX */
++
+ static struct {
+     const char *name;
+     fgot_id_t id;
+@@ -10461,9 +10464,6 @@ config_is_control_criticality_ignored(const char *oid)
+     return res;
+ }
+ 
+-
+-#endif
+-#endif
+ 
+ char *
+ slapi_err2string(int result)
diff --git a/net/389-ds-base/files/patch-ldap_servers_slapd_slapi__pal.c b/net/389-ds-base/files/patch-ldap_servers_slapd_slapi__pal.c
new file mode 100644
index 000000000000..49a809742cec
--- /dev/null
+++ b/net/389-ds-base/files/patch-ldap_servers_slapd_slapi__pal.c
@@ -0,0 +1,75 @@
+--- ldap/servers/slapd/slapi_pal.c.orig	2026-06-28 11:15:27 UTC
++++ ldap/servers/slapd/slapi_pal.c
+@@ -39,6 +39,9 @@
+ #endif
+ 
+ #include <sys/param.h>
++#ifdef __FreeBSD__
++#include <sys/sysctl.h>
++#endif
+ 
+ /* This warns if we have less than 128M avail */
+ #define SPAL_WARN_MIN_BYTES ((uint64_t)134217728)
+@@ -359,6 +362,62 @@ spal_meminfo_get()
+ }
+ 
+ 
++#endif
++
++#ifdef __FreeBSD__
++static uint64_t
++_spal_freebsd_sysctl_value(const char *name)
++{
++    uint64_t value = 0;
++    size_t size = sizeof(value);
++
++    if (sysctlbyname(name, &value, &size, NULL, 0) != 0) {
++        return 0;
++    }
++
++    return value;
++}
++
++slapi_pal_meminfo *
++spal_meminfo_get()
++{
++    slapi_pal_meminfo *mi =
++        (slapi_pal_meminfo *)slapi_ch_calloc(1, sizeof(slapi_pal_meminfo));
++    struct rusage usage = {0};
++    uint64_t free_pages;
++    uint64_t inactive_pages;
++
++    mi->pagesize_bytes = (uint64_t)getpagesize();
++    mi->system_total_bytes =
++        _spal_freebsd_sysctl_value("hw.physmem");
++    mi->system_total_pages =
++        mi->system_total_bytes / mi->pagesize_bytes;
++
++    free_pages =
++        _spal_freebsd_sysctl_value("vm.stats.vm.v_free_count");
++    inactive_pages =
++        _spal_freebsd_sysctl_value("vm.stats.vm.v_inactive_count");
++
++    mi->system_available_pages = free_pages + inactive_pages;
++    mi->system_available_bytes =
++        mi->system_available_pages * mi->pagesize_bytes;
++
++    if (mi->system_available_bytes == 0) {
++        mi->system_available_bytes =
++            (mi->system_total_bytes * 8) / 10;
++        mi->system_available_pages =
++            mi->system_available_bytes / mi->pagesize_bytes;
++    }
++
++    if (getrusage(RUSAGE_SELF, &usage) == 0) {
++        mi->process_consumed_bytes =
++            (uint64_t)usage.ru_maxrss * 1024;
++        mi->process_consumed_pages =
++            mi->process_consumed_bytes / mi->pagesize_bytes;
++    }
++
++    return mi;
++}
+ #endif
+ 
+ #ifdef OS_solaris
diff --git a/net/389-ds-base/files/patch-ldap_servers_slapd_tools_ldclt_ldclt.c b/net/389-ds-base/files/patch-ldap_servers_slapd_tools_ldclt_ldclt.c
new file mode 100644
index 000000000000..099d875eaf49
--- /dev/null
+++ b/net/389-ds-base/files/patch-ldap_servers_slapd_tools_ldclt_ldclt.c
@@ -0,0 +1,32 @@
+--- ldap/servers/slapd/tools/ldclt/ldclt.c.orig	2026-06-28 09:51:29 UTC
++++ ldap/servers/slapd/tools/ldclt/ldclt.c
+@@ -821,13 +821,8 @@ initMainThread(void)
+ /*
+    * Trap SIGINT.
+    */
+-#ifdef LDCLT_CAST_SIGACTION                     /*JLS 01-12-00*/
+-    act.sa_handler = (void (*)(int))trapVector; /*JLS 14-11-00*/
+-#else                                           /*JLS 14-11-00*/
+-    act.sa_handler = trapVector;
+-#endif                                          /*JLS 14-11-00*/
+     act.sa_sigaction = trapVector;
+-    act.sa_flags = SA_NODEFER;
++    act.sa_flags = SA_NODEFER | SA_SIGINFO;
+     sigemptyset(&(act.sa_mask));
+     sigaddset(&(act.sa_mask), SIGINT);
+     sigfillset(&(act.sa_mask));
+@@ -841,13 +836,8 @@ initMainThread(void)
+ /*
+    * Trap SIGQUIT.
+    */
+-#ifdef LDCLT_CAST_SIGACTION                     /*JLS 01-12-00*/
+-    act.sa_handler = (void (*)(int))trapVector; /*JLS 14-11-00*/
+-#else                                           /*JLS 14-11-00*/
+-    act.sa_handler = trapVector;
+-#endif                                          /*JLS 14-11-00*/
+     act.sa_sigaction = trapVector;
+-    act.sa_flags = SA_NODEFER;
++    act.sa_flags = SA_NODEFER | SA_SIGINFO;
+     sigemptyset(&(act.sa_mask));
+     sigaddset(&(act.sa_mask), SIGQUIT);
+     sigfillset(&(act.sa_mask));
diff --git a/net/389-ds-base/pkg-descr b/net/389-ds-base/pkg-descr
new file mode 100644
index 000000000000..ae5959e1d755
--- /dev/null
+++ b/net/389-ds-base/pkg-descr
@@ -0,0 +1,3 @@
+389 Directory Server is an enterprise-class LDAP server that provides
+a scalable directory service for identity, authentication, and
+authorization data.
diff --git a/net/389-ds-base/pkg-plist b/net/389-ds-base/pkg-plist
new file mode 100644
index 000000000000..e1305c4897b6
--- /dev/null
+++ b/net/389-ds-base/pkg-plist
@@ -0,0 +1,178 @@
+bin/dbscan
+bin/ds-logpipe.py
+bin/ds-replcheck
+bin/ldclt
+bin/logconv.pl
+bin/logconv.py
+bin/pwdhash
+etc/dirsrv/config/certmap.conf
+etc/dirsrv/config/ldap-agent.conf
+etc/dirsrv/config/slapd-collations.conf
+etc/dirsrv/schema/99user.ldif
+include/dirsrv/repl-session-plugin.h
+include/dirsrv/slapi-plugin.h
+include/dirsrv/slapi_pal.h
+include/dirsrv/winsync-plugin.h
+include/svrcore.h
+lib/dirsrv/libldaputil.so
+lib/dirsrv/libldaputil.so.0
+lib/dirsrv/libldaputil.so.0.0.0
+lib/dirsrv/libns-dshttpd.so
+lib/dirsrv/libns-dshttpd.so.0
+lib/dirsrv/libns-dshttpd.so.0.0.0
+lib/dirsrv/librewriters.so
+lib/dirsrv/librewriters.so.0
+lib/dirsrv/librewriters.so.0.0.0
+lib/dirsrv/librobdb.so
+lib/dirsrv/libslapd.so
+lib/dirsrv/libslapd.so.0
+lib/dirsrv/libslapd.so.0.1.0
+lib/dirsrv/plugins/libacctpolicy-plugin.so
+lib/dirsrv/plugins/libacctusability-plugin.so
+lib/dirsrv/plugins/libacl-plugin.so
+lib/dirsrv/plugins/libaddn-plugin.so
+lib/dirsrv/plugins/libalias-entries-plugin.so
+lib/dirsrv/plugins/libattr-unique-plugin.so
+lib/dirsrv/plugins/libautomember-plugin.so
+lib/dirsrv/plugins/libback-ldbm.so
+lib/dirsrv/plugins/libbitwise-plugin.so
+lib/dirsrv/plugins/libchainingdb-plugin.so
+lib/dirsrv/plugins/libcollation-plugin.so
+lib/dirsrv/plugins/libcontentsync-plugin.so
+lib/dirsrv/plugins/libcos-plugin.so
+lib/dirsrv/plugins/libderef-plugin.so
+lib/dirsrv/plugins/libdistrib-plugin.so
+lib/dirsrv/plugins/libdna-plugin.so
+lib/dirsrv/plugins/libentryuuid-plugin.so
+lib/dirsrv/plugins/libentryuuid-syntax-plugin.so
+lib/dirsrv/plugins/liblinkedattrs-plugin.so
+lib/dirsrv/plugins/libmanagedentries-plugin.so
+lib/dirsrv/plugins/libmemberof-plugin.so
+lib/dirsrv/plugins/libpam-passthru-plugin.so
+lib/dirsrv/plugins/libpassthru-plugin.so
+lib/dirsrv/plugins/libpbe-plugin.so
+lib/dirsrv/plugins/libposix-winsync-plugin.so
+lib/dirsrv/plugins/libpwdchan-plugin.so
+lib/dirsrv/plugins/libpwdstorage-plugin.so
+lib/dirsrv/plugins/libreferint-plugin.so
+lib/dirsrv/plugins/libreplication-plugin.so
+lib/dirsrv/plugins/libretrocl-plugin.so
+lib/dirsrv/plugins/libroles-plugin.so
+lib/dirsrv/plugins/librootdn-access-plugin.so
+lib/dirsrv/plugins/libschemareload-plugin.so
+lib/dirsrv/plugins/libstatechange-plugin.so
+lib/dirsrv/plugins/libsyntax-plugin.so
+lib/dirsrv/plugins/libusn-plugin.so
+lib/dirsrv/plugins/libviews-plugin.so
+lib/dirsrv/plugins/libwhoami-plugin.so
+lib/dirsrv/python/failedbinds.py
+lib/dirsrv/python/logregex.py
+lib/libsvrcore.so
+lib/libsvrcore.so.0
+lib/libsvrcore.so.0.0.0
+lib/sysctl.d/70-dirsrv.conf
+libdata/pkgconfig/dirsrv.pc
+libdata/pkgconfig/svrcore.pc
+sbin/ldap-agent
+sbin/ns-slapd
+share/cockpit/389-console/index.css.gz
+share/cockpit/389-console/index.html
+share/cockpit/389-console/index.js.LEGAL.txt
+share/cockpit/389-console/index.js.gz
+share/cockpit/389-console/manifest.json
+share/cockpit/389-console/po.de.js.gz
+share/cockpit/389-console/po.ja.js.gz
+share/cockpit/389-console/po.manifest.de.js.gz
+share/cockpit/389-console/po.manifest.ja.js.gz
+share/dirsrv/data/10rfc2307bis.ldif
+share/dirsrv/data/10rfc2307compat.ldif
+share/dirsrv/data/60changelog.ldif
+share/dirsrv/data/60inetmail.ldif
+share/dirsrv/data/60kerberos.ldif
+share/dirsrv/data/60krb5kdc.ldif
+share/dirsrv/data/60nis.ldif
+share/dirsrv/data/60qmail.ldif
+share/dirsrv/data/60radius.ldif
+share/dirsrv/data/60rfc4876.ldif
+share/dirsrv/data/60samba.ldif
+share/dirsrv/data/60sendmail.ldif
+share/dirsrv/data/Ace.ldif
+share/dirsrv/data/European.ldif
+share/dirsrv/data/Eurosuffix.ldif
+share/dirsrv/data/Example-roles.ldif
+share/dirsrv/data/Example-views.ldif
+share/dirsrv/data/Example.ldif
+share/dirsrv/data/dbgen-FamilyNames
+share/dirsrv/data/dbgen-GivenNames
+share/dirsrv/data/dbgen-OrgUnits
+share/dirsrv/data/dsee.schema
+share/dirsrv/data/template-baseacis.ldif
+share/dirsrv/data/template-country.ldif
+share/dirsrv/data/template-domain.ldif
+share/dirsrv/data/template-dse-minimal.ldif
+share/dirsrv/data/template-dse.ldif
+share/dirsrv/data/template-ldapi-autobind.ldif
+share/dirsrv/data/template-ldapi-default.ldif
+share/dirsrv/data/template-ldapi.ldif
+share/dirsrv/data/template-locality.ldif
+share/dirsrv/data/template-org.ldif
+share/dirsrv/data/template-orgunit.ldif
+share/dirsrv/data/template-sasl.ldif
+share/dirsrv/data/template-state.ldif
+share/dirsrv/data/template-suffix-db.ldif
+share/dirsrv/data/template.ldif
+share/dirsrv/inf/defaults.inf
+share/dirsrv/inf/slapd.inf
+share/dirsrv/mibs/redhat-directory.mib
+share/dirsrv/schema/00core.ldif
+share/dirsrv/schema/01core389.ldif
+share/dirsrv/schema/02common.ldif
+share/dirsrv/schema/03entryuuid.ldif
+share/dirsrv/schema/05rfc2927.ldif
+share/dirsrv/schema/05rfc4523.ldif
+share/dirsrv/schema/05rfc4524.ldif
+share/dirsrv/schema/06inetorgperson.ldif
+share/dirsrv/schema/10automember-plugin.ldif
+share/dirsrv/schema/10dna-plugin.ldif
+share/dirsrv/schema/10mep-plugin.ldif
+share/dirsrv/schema/10rfc2307compat.ldif
+share/dirsrv/schema/20subscriber.ldif
+share/dirsrv/schema/25java-object.ldif
+share/dirsrv/schema/28pilot.ldif
+share/dirsrv/schema/30ns-common.ldif
+share/dirsrv/schema/50ns-admin.ldif
+share/dirsrv/schema/50ns-certificate.ldif
+share/dirsrv/schema/50ns-directory.ldif
+share/dirsrv/schema/50ns-mail.ldif
+share/dirsrv/schema/50ns-value.ldif
+share/dirsrv/schema/50ns-web.ldif
+share/dirsrv/schema/60acctpolicy.ldif
+share/dirsrv/schema/60autofs.ldif
+share/dirsrv/schema/60eduperson.ldif
+share/dirsrv/schema/60mozilla.ldif
+share/dirsrv/schema/60nss-ldap.ldif
+share/dirsrv/schema/60pam-plugin.ldif
+share/dirsrv/schema/60posix-winsync-plugin.ldif
+share/dirsrv/schema/60pureftpd.ldif
+share/dirsrv/schema/60rfc2739.ldif
+share/dirsrv/schema/60rfc3712.ldif
+share/dirsrv/schema/60sabayon.ldif
+share/dirsrv/schema/60samba3.ldif
+share/dirsrv/schema/60sudo.ldif
+share/dirsrv/schema/60trust.ldif
+share/gdb/auto-load/usr/local/sbin/ns-slapd-gdb.py
+share/man/man1/dbscan.1.gz
+share/man/man1/ds-logpipe.py.1.gz
+share/man/man1/ds-replcheck.1.gz
+share/man/man1/ldap-agent.1.gz
+share/man/man1/ldclt.1.gz
+share/man/man1/logconv.pl.1.gz
+share/man/man1/logconv.py.1.gz
+share/man/man1/pwdhash.1.gz
+share/man/man5/99user.ldif.5.gz
+share/man/man5/certmap.conf.5.gz
+share/man/man5/dirsrv.5.gz
+share/man/man5/dirsrv.systemd.5.gz
+share/man/man5/slapd-collations.conf.5.gz
+share/man/man8/ns-slapd.8.gz
+share/metainfo/389-console/org.port389.cockpit_console.metainfo.xml
diff --git a/net/Makefile b/net/Makefile
index a3c6185e5131..372552f8f5ee 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -1,6 +1,7 @@
     COMMENT = Networking tools
 
     SUBDIR += 3proxy
+    SUBDIR += 389-ds-base
     SUBDIR += 44bsd-rdist
     SUBDIR += 6tunnel
     SUBDIR += R-cran-pingr