From owner-trustedbsd-cvs@FreeBSD.ORG  Tue Apr 18 04:44:27 2006
Return-Path: <owner-trustedbsd-cvs@FreeBSD.ORG>
X-Original-To: trustedbsd-cvs@freebsd.org
Delivered-To: trustedbsd-cvs@freebsd.org
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id C63EC16A402
	for <trustedbsd-cvs@freebsd.org>; Tue, 18 Apr 2006 04:44:27 +0000 (UTC)
	(envelope-from owner-perforce@freebsd.org)
Received: from cyrus.watson.org (cyrus.watson.org [209.31.154.42])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 3F16243D45
	for <trustedbsd-cvs@freebsd.org>; Tue, 18 Apr 2006 04:44:27 +0000 (GMT)
	(envelope-from owner-perforce@freebsd.org)
Received: from mx2.freebsd.org (mx2.freebsd.org [216.136.204.119])
	by cyrus.watson.org (Postfix) with ESMTP id 98D9546CCD
	for <trustedbsd-cvs@trustedbsd.org>;
	Tue, 18 Apr 2006 00:44:26 -0400 (EDT)
Received: from hub.freebsd.org (hub.freebsd.org [216.136.204.18])
	by mx2.freebsd.org (Postfix) with ESMTP id C42AC559CB;
	Tue, 18 Apr 2006 04:44:24 +0000 (GMT)
	(envelope-from owner-perforce@freebsd.org)
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id BBBC916A404; Tue, 18 Apr 2006 04:44:24 +0000 (UTC)
X-Original-To: perforce@freebsd.org
Delivered-To: perforce@freebsd.org
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 97D9116A401
	for <perforce@freebsd.org>; Tue, 18 Apr 2006 04:44:24 +0000 (UTC)
	(envelope-from csjp@freebsd.org)
Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 5934843D45
	for <perforce@freebsd.org>; Tue, 18 Apr 2006 04:44:24 +0000 (GMT)
	(envelope-from csjp@freebsd.org)
Received: from repoman.freebsd.org (localhost [127.0.0.1])
	by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k3I4iOtJ029687
	for <perforce@freebsd.org>; Tue, 18 Apr 2006 04:44:24 GMT
	(envelope-from csjp@freebsd.org)
Received: (from perforce@localhost)
	by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k3I4iNNS029684
	for perforce@freebsd.org; Tue, 18 Apr 2006 04:44:23 GMT
	(envelope-from csjp@freebsd.org)
Date: Tue, 18 Apr 2006 04:44:23 GMT
Message-Id: <200604180444.k3I4iNNS029684@repoman.freebsd.org>
X-Authentication-Warning: repoman.freebsd.org: perforce set sender to
	csjp@freebsd.org using -f
From: "Christian S.J. Peron" <csjp@FreeBSD.org>
To: Perforce Change Reviews <perforce@freebsd.org>
Cc: 
Subject: PERFORCE change 95476 for review
X-BeenThere: trustedbsd-cvs@FreeBSD.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: TrustedBSD CVS and Perforce commit message list
	<trustedbsd-cvs.FreeBSD.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/listinfo/trustedbsd-cvs>, 
	<mailto:trustedbsd-cvs-request@FreeBSD.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/trustedbsd-cvs>
List-Post: <mailto:trustedbsd-cvs@FreeBSD.org>
List-Help: <mailto:trustedbsd-cvs-request@FreeBSD.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/trustedbsd-cvs>,
	<mailto:trustedbsd-cvs-request@FreeBSD.org?subject=subscribe>
X-List-Received-Date: Tue, 18 Apr 2006 04:44:27 -0000

http://perforce.freebsd.org/chv.cgi?CH=95476

Change 95476 by csjp@csjp_xor on 2006/04/18 04:43:39

	- Add to the openbsm programming API and introduce the audit_submit(3)
	  in raw form. This is the first stab at things, so it's possible that
	  things might change from here.
	
	- A sample implementation might be as follows:
	
	 int
	 audit_bad_su(char *from_login, char *to_login)
	 {
		 int error;
	
		 error = audit_submit(AUE_su, getuid(), 1, EPERM,
		     "bad su from %s to %s", from_login, to_login);
		 return (error);
	 }
	
	 Will generate the followng audit record:
	
	 header,94,1,su(1),0,Mon Apr 17 23:23:59 2006, + 271 msec
	 subject,root,root,wheel,root,wheel,652,652,0,0.0.0.0
	 text,bad su from from csjp to root
	 return,failure : Operation not permitted,1
	 trailer,94
	
	This function will be very useful for the on-going userspace
	integration of the audit code, and hopefully this little helper
	function can be used to prevent a lot of code replication.
	
	Discussed with:	rwatson, wsalamon

Affected files ...

.. //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#19 edit
.. //depot/projects/trustedbsd/openbsm/libbsm/audit_submit.3#1 add
.. //depot/projects/trustedbsd/openbsm/libbsm/bsm_wrappers.c#21 edit

Differences ...

==== //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#19 (text+ko) ====

@@ -26,7 +26,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#18 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#19 $
  */
 
 #ifndef _LIBBSM_H_
@@ -695,6 +695,9 @@
 
 typedef struct tokenstr tokenstr_t;
 
+int			 audit_submit(short au_event, au_id_t au_ctx,
+			    char status, int reterr, const char *fmt, ...);
+
 /*
  * Functions relating to querying audit class information.
  */

==== //depot/projects/trustedbsd/openbsm/libbsm/bsm_wrappers.c#21 (text+ko) ====

@@ -26,7 +26,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_wrappers.c#20 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_wrappers.c#21 $
  */
 
 #ifdef __APPLE__
@@ -46,6 +46,7 @@
 
 #include <unistd.h>
 #include <syslog.h>
+#include <stdarg.h>
 #include <string.h>
 #include <errno.h>
 
@@ -53,6 +54,110 @@
 int audit_set_terminal_port(dev_t *p);
 int audit_set_terminal_host(uint32_t *m);
 
+/*
+ * General purpose audit submission mechanism for userspace.
+ */
+int
+audit_submit(short au_event, au_id_t au_ctx, char status,
+    int reterr, const char *fmt, ...)
+{
+	char text[MAX_AUDITSTRING_LEN];
+	au_tid_t termid;
+	token_t *token;
+	long acond;
+	va_list ap;
+	pid_t pid;
+	int error, afd;
+
+	if (auditon(A_GETCOND, &acond, sizeof(acond)) < 0) {
+		/*
+		 * If auditon(2) returns ENOSYS, then audit has not been
+		 * compiled into the kernel, so just return.
+		 */
+		if (errno == ENOSYS)
+			return (0);
+		error = errno;
+		syslog(LOG_AUTH | LOG_ERR, "audit: auditon failed: %s",
+		    strerror(errno));
+		errno = error;
+		return (-1);
+	}
+	if (acond == AUC_NOAUDIT)
+		return (0);
+	afd = au_open();
+	if (afd < 0) {
+		error = errno;
+		syslog(LOG_AUTH | LOG_ERR, "audit: au_open failed: %s",
+		    strerror(errno));
+		errno = error;
+		return (-1);
+	}
+	/* XXX what should we do for termid? */
+	bzero(&termid, sizeof(termid));
+	pid = getpid();
+	token = au_to_subject32(au_ctx, geteuid(), getegid(),
+	    getuid(), getgid(), pid, pid, &termid);
+	if (token == NULL) {
+		syslog(LOG_AUTH | LOG_ERR,
+		    "audit: unable to build subject token");
+		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
+		errno = EPERM;
+		return (-1);
+	}
+	if (au_write(afd, token) < 0) {
+		error = errno;
+		syslog(LOG_AUTH | LOG_ERR,
+		    "audit: au_write failed: %s", strerror(errno));
+		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
+		errno = error;
+		return (-1);
+	}
+	if (fmt != NULL) {
+		va_start(ap, fmt);
+		(void) vsnprintf(text, MAX_AUDITSTRING_LEN, fmt, ap);
+		va_end(ap);
+		token = au_to_text(text);
+		if (token == NULL) {
+			syslog(LOG_AUTH | LOG_ERR,
+			    "audit: failed to generate text token");
+			(void) au_close(afd, AU_TO_NO_WRITE, au_event);
+			errno = EPERM;
+			return (-1);
+		}
+		if (au_write(afd, token) < 0) {
+			error = errno;
+			syslog(LOG_AUTH | LOG_ERR,
+			    "audit: au_write failed: %s", strerror(errno));
+			(void) au_close(afd, AU_TO_NO_WRITE, au_event);
+			errno = error;
+			return (-1);
+		}
+	}
+	token = au_to_return32(status, reterr);
+	if (token == NULL) {
+		syslog(LOG_AUTH | LOG_ERR,
+		    "audit: enable to build return token");
+		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
+		errno = EPERM;
+		return (-1);
+	}
+	if (au_write(afd, token) < 0) {
+		error = errno;
+		syslog(LOG_AUTH | LOG_ERR,
+		    "audit: au_write failed: %s", strerror(errno));
+		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
+		errno = error;
+		return (-1);
+	}
+	if (au_close(afd, AU_TO_WRITE, au_event) < 0) {
+		error = errno;
+		syslog(LOG_AUTH | LOG_ERR, "audit: record not committed");
+		errno = error;
+		return (-1);
+	}
+	return (0);
+}
+
 int
 audit_set_terminal_port(dev_t *p)
 {