git: 1238610a27d5 - main - setaudit: Add an update mode

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 18 Nov 2025 16:24:43 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=1238610a27d5bc0914f524296ff587d86eec4c52

commit 1238610a27d5bc0914f524296ff587d86eec4c52
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-11-17 16:45:29 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-11-18 16:24:20 +0000

    setaudit: Add an update mode
    
    By default, setaudit(8) overwrites the whole audit session state.  For
    the purpose of overwriting only a single field, e.g., the audit user,
    this is inconvenient.  Add -U to accomodate this case: when specified,
    setaudit(8) will first fetch the current session state block and then
    will only overwrite those fields specified on the command line.
    
    Reviewed by:    csjp
    MFC after:      2 weeks
    Sponsored by:   Modirum MDPay
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D53672
---
 usr.sbin/setaudit/setaudit.8 | 12 +++++++++++-
 usr.sbin/setaudit/setaudit.c | 38 ++++++++++++++++++++++++++++----------
 2 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/usr.sbin/setaudit/setaudit.8 b/usr.sbin/setaudit/setaudit.8
index 7dc3e05a4473..7dd66225979c 100644
--- a/usr.sbin/setaudit/setaudit.8
+++ b/usr.sbin/setaudit/setaudit.8
@@ -28,7 +28,7 @@
 .Nd "specify audit configurations on a process"
 .Sh SYNOPSIS
 .Nm
-.Op Fl 46
+.Op Fl 46U
 .Op Fl a Ar auid
 .Op Fl m Ar mask
 .Op Fl s Ar source
@@ -44,6 +44,16 @@ The following options are available:
 Use IPv4.
 .It Fl 6
 Use IPv6.
+.It Fl U
+Update audit session state rather than overwriting it.
+By default,
+.Nm
+will overwrite the entire audit session state using the specified
+parameters.
+If
+.Fl U
+is specified, only the parameters given on the command line will be
+updated, leaving the rest unchanged.
 .It Fl a Ar auid
 Audit user ID or user name.
 .It Fl m Ar mask
diff --git a/usr.sbin/setaudit/setaudit.c b/usr.sbin/setaudit/setaudit.c
index adea52a83a8d..af8f481afcb3 100644
--- a/usr.sbin/setaudit/setaudit.c
+++ b/usr.sbin/setaudit/setaudit.c
@@ -35,6 +35,7 @@
 #include <err.h>
 #include <netdb.h>
 #include <pwd.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -44,7 +45,7 @@ static void
 usage(char *prog)
 {
 	(void)fprintf(stderr,
-	    "usage: %s [-46] [-a auid] [-m mask] [-s source] [-p port] command ...\n",
+    "usage: %s [-46U] [-a auid] [-m mask] [-p port] [-s source] command ...\n",
 	    prog);
 	exit(1);
 }
@@ -56,19 +57,21 @@ main(int argc, char *argv [])
 	struct sockaddr_in *sin;
 	struct addrinfo hints;
 	auditinfo_addr_t aia;
-	struct addrinfo *res;
-	struct passwd *pwd;
 	char *aflag, *mflag, *sflag, *prog;
+	dev_t term_port;
+	uint32_t term_type;
 	int ch, error;
+	bool Uflag;
 
 	aflag = mflag = sflag = NULL;
+	Uflag = false;
 
 	prog = argv[0];
 	bzero(&aia, sizeof(aia));
 	bzero(&hints, sizeof(hints));
-	aia.ai_termid.at_type = AU_IPv4;
+	term_type = AU_IPv4;
 	hints.ai_family = PF_UNSPEC;
-	while ((ch = getopt(argc, argv, "46a:m:p:s:")) != -1)
+	while ((ch = getopt(argc, argv, "46a:m:p:s:U")) != -1)
 		switch (ch) {
 		case '4':
 			hints.ai_family = PF_INET;
@@ -83,11 +86,14 @@ main(int argc, char *argv [])
 			mflag = optarg;
 			break;
 		case 'p':
-			aia.ai_termid.at_port = htons(atoi(optarg));
+			term_port = htons(atoi(optarg));
 			break;
 		case 's':
 			sflag = optarg;
 			break;
+		case 'U':
+			Uflag = true;
+			break;
 		default:
 			usage(prog);
 			/* NOT REACHED */
@@ -96,7 +102,14 @@ main(int argc, char *argv [])
 	argv += optind;
 	if (argc == 0)
 		usage(prog);
+
+	if (Uflag) {
+		if (getaudit_addr(&aia, sizeof(aia)) < 0)
+			err(1, "getaudit_addr");
+	}
 	if (aflag) {
+		struct passwd *pwd;
+
 		pwd = getpwnam(aflag);
 		if (pwd == NULL) {
 			char *r;
@@ -112,6 +125,8 @@ main(int argc, char *argv [])
 			err(1, "getauditflagsbin");
 	}
 	if (sflag) {
+		struct addrinfo *res;
+
 		error = getaddrinfo(sflag, NULL, &hints, &res);
 		if (error)
 			errx(1, "%s", gai_strerror(error));
@@ -121,20 +136,23 @@ main(int argc, char *argv [])
 			bcopy(&sin6->sin6_addr.s6_addr,
 			    &aia.ai_termid.at_addr[0],
 			    sizeof(struct in6_addr));
-			aia.ai_termid.at_type = AU_IPv6;
+			term_type = AU_IPv6;
 			break;
 		case PF_INET:
 			sin = (struct sockaddr_in *)(void *)res->ai_addr;
 			bcopy(&sin->sin_addr.s_addr,
 			    &aia.ai_termid.at_addr[0],
 			    sizeof(struct in_addr));
-			aia.ai_termid.at_type = AU_IPv4;
+			term_type = AU_IPv4;
 			break;
 		}
 	}
-	if (setaudit_addr(&aia, sizeof(aia)) < 0) {
-		err(1, "setaudit_addr");
+	if (!Uflag || sflag) {
+		aia.ai_termid.at_port = term_port;
+		aia.ai_termid.at_type = term_type;
 	}
+	if (setaudit_addr(&aia, sizeof(aia)) < 0)
+		err(1, "setaudit_addr");
 	(void)execvp(*argv, argv);
 	err(1, "%s", *argv);
 }