--- a/components/krb5/Makefile Fri Dec 16 19:19:44 2016 -0800
+++ b/components/krb5/Makefile Sat Dec 17 21:18:50 2016 -0800
@@ -100,6 +100,8 @@
CONFIGURE_OPTIONS += --with-prng-alg=os
CONFIGURE_OPTIONS += --with-tcl=$(USRDIR)
CONFIGURE_OPTIONS += --without-system-verto
+# Documented as with-audit-plugin, but it's really enable-audit-plugin
+CONFIGURE_OPTIONS += --enable-audit-plugin=solaris
COMPONENT_PRE_CONFIGURE_ACTION = \
cd $(SOURCE_DIR)/src/ && $(SOURCE_DIR)/src/util/reconf
@@ -115,6 +117,9 @@
COMPONENT_TEST_PERFORM_TRANSFORM=
COMPONENT_TEST_COMPARE=
+# Audit plugin directory for Solaris
+AUDIT_DIR = $(SOURCE_DIR)/src/plugins/audit/solaris
+
# We don't ship Solaris specific files as patches to ease maintenance.
# We rather copy the files to the right directories.
COMPONENT_PREP_ACTION= \
@@ -132,12 +137,14 @@
$(CP) Solaris/rc_mem.c $(SOURCE_DIR)/src/lib/krb5/rcache; \
$(CP) Solaris/rc_mem.h $(SOURCE_DIR)/src/lib/krb5/rcache; \
$(CP) Solaris/safechown.c $(SOURCE_DIR)/src/lib/krb5/os; \
- $(CP) Solaris/util_ordering.c $(SOURCE_DIR)/src/lib/gssapi/generic
+ $(CP) Solaris/util_ordering.c $(SOURCE_DIR)/src/lib/gssapi/generic; \
+ $(MKDIR) -p $(AUDIT_DIR); $(CP) Solaris/audit/* $(AUDIT_DIR); \
+ $(CP) Solaris/audit/kadmind_audit.* $(SOURCE_DIR)/src/kadmin/server;
# We move xdr_alloc.c and supporting dyn code from libgssrpc directly
# into libkadm5srv_mit. kadmind is the only consumer anyway.
SRCLIB=$(SOURCE_DIR)/src/lib
-COMPONENT_PREP_ACTION += ;\
+COMPONENT_PREP_ACTION += \
$(CP) $(SRCLIB)/rpc/xdr_alloc.c $(SRCLIB)/kadm5/srv/; \
$(CP) $(SRCLIB)/rpc/dyn.c $(SRCLIB)/kadm5/srv/; \
$(CP) $(SRCLIB)/rpc/dyn.h $(SRCLIB)/kadm5/srv/; \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/Solaris/audit/Makefile.in Sat Dec 17 21:18:50 2016 -0800
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+mydir=plugins$(S)audit$(S)solaris
+BUILDTOP=$(REL)..$(S)..$(S)..
+MODULE_INSTALL_DIR = $(KRB5_AU_MODULE_DIR)
+
+LOCALINCLUDES = -I$(top_srcdir)/plugins/audit
+
+LIBBASE=solaris
+LIBMAJOR=0
+LIBMINOR=0
+RELDIR=../plugins/audit/solaris
+
+#Depends on libkrb5, libkrb5support, and libbsm.
+SHLIB_EXPDEPS= $(KRB5_BASE_DEPLIBS)
+SHLIB_EXPLIBS= $(KRB5_BASE_LIBS) -lbsm
+
+STOBJLISTS= OBJS.ST ../OBJS.ST
+STLIBOBJS= au_solaris_main.o
+
+SRCS= $(srcdir)/au_solaris_main.c
+
+all-unix:: all-liblinks
+install-unix:: install-libs
+clean-unix:: clean-liblinks clean-libs clean-libobjs
+
[email protected][email protected]
[email protected][email protected]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/Solaris/audit/au_solaris_main.c Sat Dec 17 21:18:50 2016 -0800
@@ -0,0 +1,657 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This is a Solaris plugin for auditing the KDC.
+ */
+
+#include <k5-int.h>
+#include <krb5/audit_plugin.h>
+#include <kdc_j_encode.h>
+#include "j_dict.h"
+#include <syslog.h>
+#include <bsm/adt.h>
+#include <bsm/adt_event.h>
+#include <k5-json.h>
+
+extern krb5_error_code data_to_value(krb5_data *, k5_json_object, const char *);
+extern krb5_error_code req_to_value(krb5_kdc_req *, const krb5_boolean,
+ k5_json_object);
+extern krb5_error_code rep_to_value(krb5_kdc_rep *, const krb5_boolean,
+ k5_json_object);
+
+krb5_error_code
+audit_solaris_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable);
+
+struct krb5_audit_moddata_st {
+ adt_session_data_t *ah;
+};
+
+/* Create handle to the audit system. Returns 0 on success. */
+static krb5_error_code
+open_au(krb5_audit_moddata *auctx_out)
+{
+ adt_session_data_t *ah;
+ krb5_error_code ret;
+ krb5_audit_moddata auctx;
+
+ auctx = k5calloc(1, sizeof (*auctx), &ret);
+ if (ret)
+ return (ENOMEM);
+
+ if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_start_session(): %m");
+ free(auctx);
+ return (KRB5_PLUGIN_NO_HANDLE);
+ }
+
+ auctx->ah = ah;
+ *auctx_out = auctx;
+
+ return (0);
+}
+
+/* Close connection to the audit system. Returns 0 on success. */
+static krb5_error_code
+close_au(krb5_audit_moddata auctx)
+{
+ adt_session_data_t *ah = auctx->ah;
+
+ (void) adt_end_session(ah);
+
+ return (0);
+}
+
+/* Log KDC-start event. Returns 0 on success. */
+static krb5_error_code
+kdc_start(krb5_audit_moddata auctx, krb5_boolean ev_success)
+{
+ adt_session_data_t *ah = auctx->ah;
+ adt_event_data_t *event;
+ int status = ev_success ? ADT_SUCCESS : ADT_FAILURE;
+
+ if (ah == NULL)
+ return (KRB5_PLUGIN_NO_HANDLE); /* audit handle unavailable */
+
+ if ((event = adt_alloc_event(ah, ADT_krb5kdc_start)) == NULL) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(): %m");
+ (void) adt_end_session(ah);
+ return (KRB5_PLUGIN_NO_HANDLE);
+ }
+
+ if (adt_put_event(event, status, status) != 0) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_put_event(): %m");
+ adt_free_event(event);
+ (void) adt_end_session(ah);
+ return (KRB5_PLUGIN_NO_HANDLE);
+ }
+
+ adt_free_event(event);
+
+ return (0);
+}
+
+/* Log KDC-stop event. Returns 0 on success. */
+static krb5_error_code
+kdc_stop(krb5_audit_moddata auctx, krb5_boolean ev_success)
+{
+ adt_session_data_t *ah = auctx->ah;
+ adt_event_data_t *event;
+ int status = ev_success ? ADT_SUCCESS : ADT_FAILURE;
+
+ if (ah == NULL)
+ return (KRB5_PLUGIN_NO_HANDLE); /* audit handle unavailable */
+
+ if ((event = adt_alloc_event(ah, ADT_krb5kdc_stop)) == NULL) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(): %m");
+ (void) adt_end_session(ah);
+ return (KRB5_PLUGIN_NO_HANDLE);
+ }
+
+ if (adt_put_event(event, status, status) != 0) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_put_event(): %m");
+ adt_free_event(event);
+ (void) adt_end_session(ah);
+ return (KRB5_PLUGIN_NO_HANDLE);
+ }
+
+ adt_free_event(event);
+
+ return (0);
+}
+
+/* Log AS_REQ event. Returns 0 on success */
+static krb5_error_code
+as_req(krb5_audit_moddata auctx, krb5_boolean ev_success,
+ krb5_audit_state *state)
+{
+ adt_session_data_t *ah = auctx->ah;
+ adt_event_data_t *event;
+ int status = ev_success ? ADT_SUCCESS : ADT_FAILURE;
+ krb5_error_code ret = 0;
+ char *cprinc = NULL, *sprinc = NULL;
+ krb5_context context;
+
+ if (ah == NULL)
+ return (KRB5_PLUGIN_NO_HANDLE);
+ /* Return success if NULL state */
+ if (state == NULL)
+ return (0);
+
+ if (ret = krb5_init_context(&context)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_init_context(): %m");
+ goto error;
+ }
+
+ if ((event = adt_alloc_event(ah, ADT_as_req)) == NULL) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(): %m");
+ ret = ENOMEM;
+ goto error;
+ }
+
+ event->adt_as_req.cl_port = state->cl_port;
+
+ if (state->cl_addr && state->cl_addr->addrtype == ADDRTYPE_INET)
+ event->adt_as_req.cl_addr_type = ADT_IPv4;
+ else if (state->cl_addr && state->cl_addr->addrtype == ADDRTYPE_INET6)
+ event->adt_as_req.cl_addr_type = ADT_IPv6;
+ else {
+ syslog(LOG_AUTH | LOG_ALERT, "invalid address type(): %m");
+ ret = EIO;
+ goto error;
+ }
+ (void) memcpy(event->adt_as_req.cl_addr_address,
+ state->cl_addr->contents, state->cl_addr->length);
+
+ if (state->request && state->request->client != NULL) {
+ if (ret = krb5_unparse_name(context, state->request->client,
+ &cprinc)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_unparse_name(): %m");
+ goto error;
+ }
+ event->adt_as_req.client = strdup(cprinc);
+ } else
+ event->adt_as_req.client = strdup("<none>");
+ if (event->adt_as_req.client == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (state->request && state->request->server != NULL) {
+ if (ret = krb5_unparse_name(context, state->request->server,
+ &sprinc)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_unparse_name(): %m");
+ goto error;
+ }
+ event->adt_as_req.service = strdup(sprinc);
+ } else
+ event->adt_as_req.service = strdup("<none>");
+ if (event->adt_as_req.service == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (state->status != NULL)
+ event->adt_as_req.status = strdup(state->status);
+ else
+ event->adt_as_req.status = strdup("SUCCESS");
+ if (event->adt_as_req.status == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (adt_put_event(event, status, status) != 0) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_put_event(): %m");
+ ret = ENOMEM;
+ }
+
+error:
+ if (event != NULL)
+ adt_free_event(event);
+ if (cprinc != NULL)
+ free(cprinc);
+ if (sprinc != NULL)
+ free(sprinc);
+ if (ret != 0)
+ (void) adt_end_session(ah);
+
+ return (ret);
+}
+
+/* Log TGS_REQ event. Returns 0 on success */
+static krb5_error_code
+tgs_req(krb5_audit_moddata auctx, krb5_boolean ev_success,
+ krb5_audit_state *state)
+{
+ adt_session_data_t *ah = auctx->ah;
+ adt_event_data_t *event;
+ int status = ev_success ? ADT_SUCCESS : ADT_FAILURE;
+ krb5_error_code ret = 0;
+ char *cprinc = NULL, *sprinc = NULL;
+ krb5_context context;
+
+ if (ah == NULL)
+ return (KRB5_PLUGIN_NO_HANDLE);
+ /* Return success if NULL state */
+ if (state == NULL)
+ return (0);
+
+ if (ret = krb5_init_context(&context)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_init_context(): %m");
+ goto error;
+ }
+
+ if ((event = adt_alloc_event(ah, ADT_tgs_req)) == NULL) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(): %m");
+ ret = ENOMEM;
+ goto error;
+ }
+
+ event->adt_tgs_req.cl_port = state->cl_port;
+
+ if (state->cl_addr && state->cl_addr->addrtype == ADDRTYPE_INET)
+ event->adt_tgs_req.cl_addr_type = ADT_IPv4;
+ else if (state->cl_addr && state->cl_addr->addrtype == ADDRTYPE_INET6)
+ event->adt_tgs_req.cl_addr_type = ADT_IPv6;
+ else {
+ syslog(LOG_AUTH | LOG_ALERT, "invalid address type(): %m");
+ ret = EIO;
+ goto error;
+ }
+ (void) memcpy(event->adt_tgs_req.cl_addr_address,
+ state->cl_addr->contents, state->cl_addr->length);
+
+ if (state->reply && state->reply->client != NULL) {
+ if (ret = krb5_unparse_name(context, state->reply->client,
+ &cprinc)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_unparse_name(): %m");
+ goto error;
+ }
+ event->adt_tgs_req.client = strdup(cprinc);
+ } else
+ event->adt_tgs_req.client = strdup("<none>");
+ if (event->adt_tgs_req.client == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (state->request && state->request->server != NULL) {
+ if (ret = krb5_unparse_name(context, state->request->server,
+ &sprinc)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_unparse_name(): %m");
+ goto error;
+ }
+ event->adt_tgs_req.service = strdup(sprinc);
+ } else
+ event->adt_tgs_req.service = strdup("<none>");
+ if (event->adt_tgs_req.service == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (state->status != NULL)
+ event->adt_tgs_req.status = strdup(state->status);
+ else
+ event->adt_tgs_req.status = strdup("SUCCESS");
+ if (event->adt_tgs_req.status == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (adt_put_event(event, status, status) != 0) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_put_event(): %m");
+ ret = ENOMEM;
+ }
+
+error:
+ if (event != NULL)
+ adt_free_event(event);
+ if (cprinc != NULL)
+ free(cprinc);
+ if (sprinc != NULL)
+ free(sprinc);
+ if (ret != 0)
+ (void) adt_end_session(ah);
+
+ return (ret);
+}
+
+/* Log TGS_S4U2SELF event. Returns 0 on success */
+static krb5_error_code
+tgs_s4u2self(krb5_audit_moddata auctx, krb5_boolean ev_success,
+ krb5_audit_state *state)
+{
+ adt_session_data_t *ah = auctx->ah;
+ adt_event_data_t *event;
+ int status = ev_success ? ADT_SUCCESS : ADT_FAILURE;
+ krb5_error_code ret = 0;
+ char *cprinc = NULL, *sprinc = NULL;
+ krb5_context context;
+
+ if (ah == NULL)
+ return (KRB5_PLUGIN_NO_HANDLE);
+ /* Return success if NULL state */
+ if (state == NULL)
+ return (0);
+
+ if (ret = krb5_init_context(&context)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_init_context(): %m");
+ goto error;
+ }
+
+ if ((event = adt_alloc_event(ah, ADT_tgs_s4u2self)) == NULL) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(): %m");
+ ret = ENOMEM;
+ goto error;
+ }
+
+ event->adt_tgs_s4u2self.cl_port = state->cl_port;
+
+ if (state->cl_addr && state->cl_addr->addrtype == ADDRTYPE_INET)
+ event->adt_tgs_s4u2self.cl_addr_type = ADT_IPv4;
+ else if (state->cl_addr && state->cl_addr->addrtype == ADDRTYPE_INET6)
+ event->adt_tgs_s4u2self.cl_addr_type = ADT_IPv6;
+ else {
+ syslog(LOG_AUTH | LOG_ALERT, "invalid address type(): %m");
+ ret = EIO;
+ goto error;
+ }
+ (void) memcpy(event->adt_tgs_s4u2self.cl_addr_address,
+ state->cl_addr->contents, state->cl_addr->length);
+
+ if (state->reply && state->reply->client != NULL) {
+ if (ret = krb5_unparse_name(context, state->reply->client,
+ &cprinc)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_unparse_name(): %m");
+ goto error;
+ }
+ event->adt_tgs_s4u2self.client = strdup(cprinc);
+ } else
+ event->adt_tgs_s4u2self.client = strdup("<none>");
+ if (event->adt_tgs_s4u2self.client == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (state->request && state->request->server != NULL) {
+ if (ret = krb5_unparse_name(context, state->request->server,
+ &sprinc)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_unparse_name(): %m");
+ goto error;
+ }
+ event->adt_tgs_s4u2self.service = strdup(sprinc);
+ } else
+ event->adt_tgs_s4u2self.service = strdup("<none>");
+ if (event->adt_tgs_s4u2self.service == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (state->status != NULL)
+ event->adt_tgs_s4u2self.status = strdup(state->status);
+ else
+ event->adt_tgs_s4u2self.status = strdup("SUCCESS");
+ if (event->adt_tgs_s4u2self.status == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (adt_put_event(event, status, status) != 0) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_put_event(): %m");
+ ret = ENOMEM;
+ }
+
+error:
+ if (event != NULL)
+ adt_free_event(event);
+ if (cprinc != NULL)
+ free(cprinc);
+ if (sprinc != NULL)
+ free(sprinc);
+ if (ret != 0)
+ (void) adt_end_session(ah);
+
+ return (ret);
+}
+
+/* Log TGS_S4U2PROXY event. Returns 0 on success */
+static krb5_error_code
+tgs_s4u2proxy(krb5_audit_moddata auctx, krb5_boolean ev_success,
+ krb5_audit_state *state)
+{
+ adt_session_data_t *ah = auctx->ah;
+ adt_event_data_t *event;
+ int status = ev_success ? ADT_SUCCESS : ADT_FAILURE;
+ krb5_error_code ret = 0;
+ char *cprinc = NULL, *sprinc = NULL;
+ krb5_context context;
+
+ if (ah == NULL)
+ return (KRB5_PLUGIN_NO_HANDLE);
+ /* Return success if NULL state */
+ if (state == NULL)
+ return (0);
+
+ if (ret = krb5_init_context(&context)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_init_context(): %m");
+ goto error;
+ }
+
+ if ((event = adt_alloc_event(ah, ADT_tgs_s4u2proxy)) == NULL) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(): %m");
+ ret = ENOMEM;
+ goto error;
+ }
+
+ event->adt_tgs_s4u2proxy.cl_port = state->cl_port;
+
+ if (state->cl_addr && state->cl_addr->addrtype == ADDRTYPE_INET)
+ event->adt_tgs_s4u2proxy.cl_addr_type = ADT_IPv4;
+ else if (state->cl_addr && state->cl_addr->addrtype == ADDRTYPE_INET6)
+ event->adt_tgs_s4u2proxy.cl_addr_type = ADT_IPv6;
+ else {
+ syslog(LOG_AUTH | LOG_ALERT, "invalid address type(): %m");
+ ret = EIO;
+ goto error;
+ }
+ (void) memcpy(event->adt_tgs_s4u2proxy.cl_addr_address,
+ state->cl_addr->contents, state->cl_addr->length);
+
+ if (state->reply && state->reply->client != NULL) {
+ if (ret = krb5_unparse_name(context, state->reply->client,
+ &cprinc)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_unparse_name(): %m");
+ goto error;
+ }
+ event->adt_tgs_s4u2proxy.client = strdup(cprinc);
+ } else
+ event->adt_tgs_s4u2proxy.client = strdup("<none>");
+ if (event->adt_tgs_s4u2proxy.client == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (state->request && state->request->server != NULL) {
+ if (ret = krb5_unparse_name(context, state->request->server,
+ &sprinc)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_unparse_name(): %m");
+ goto error;
+ }
+ event->adt_tgs_s4u2proxy.service = strdup(sprinc);
+ } else
+ event->adt_tgs_s4u2proxy.service = strdup("<none>");
+ if (event->adt_tgs_s4u2proxy.service == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (state->status != NULL)
+ event->adt_tgs_s4u2proxy.status = strdup(state->status);
+ else
+ event->adt_tgs_s4u2proxy.status = strdup("SUCCESS");
+ if (event->adt_tgs_s4u2proxy.status == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (adt_put_event(event, status, status) != 0) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_put_event(): %m");
+ ret = ENOMEM;
+ }
+
+error:
+ if (event != NULL)
+ adt_free_event(event);
+ if (cprinc != NULL)
+ free(cprinc);
+ if (sprinc != NULL)
+ free(sprinc);
+ if (ret != 0)
+ (void) adt_end_session(ah);
+
+ return (ret);
+}
+
+/* Log TGS_U2U event. Returns 0 on success */
+static krb5_error_code
+tgs_u2u(krb5_audit_moddata auctx, krb5_boolean ev_success,
+ krb5_audit_state *state)
+{
+ adt_session_data_t *ah = auctx->ah;
+ adt_event_data_t *event;
+ int status = ev_success ? ADT_SUCCESS : ADT_FAILURE;
+ krb5_error_code ret = 0;
+ char *cprinc = NULL, *sprinc = NULL;
+ krb5_context context;
+
+ if (ah == NULL)
+ return (KRB5_PLUGIN_NO_HANDLE);
+ /* Return success if NULL state */
+ if (state == NULL)
+ return (0);
+
+ if (ret = krb5_init_context(&context)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_init_context(): %m");
+ goto error;
+ }
+
+ if ((event = adt_alloc_event(ah, ADT_tgs_u2u)) == NULL) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(): %m");
+ ret = ENOMEM;
+ goto error;
+ }
+
+ event->adt_tgs_u2u.cl_port = state->cl_port;
+
+ if (state->cl_addr && state->cl_addr->addrtype == ADDRTYPE_INET)
+ event->adt_tgs_u2u.cl_addr_type = ADT_IPv4;
+ else if (state->cl_addr && state->cl_addr->addrtype == ADDRTYPE_INET6)
+ event->adt_tgs_u2u.cl_addr_type = ADT_IPv6;
+ else {
+ syslog(LOG_AUTH | LOG_ALERT, "invalid address type(): %m");
+ ret = EIO;
+ goto error;
+ }
+ (void) memcpy(event->adt_tgs_u2u.cl_addr_address,
+ state->cl_addr->contents, state->cl_addr->length);
+
+ if (state->reply && state->reply->client != NULL) {
+ if (ret = krb5_unparse_name(context, state->reply->client,
+ &cprinc)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_unparse_name(): %m");
+ goto error;
+ }
+ event->adt_tgs_u2u.client = strdup(cprinc);
+ } else
+ event->adt_tgs_u2u.client = strdup("<none>");
+ if (event->adt_tgs_u2u.client == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (state->request && state->request->server != NULL) {
+ if (ret = krb5_unparse_name(context, state->request->server,
+ &sprinc)) {
+ syslog(LOG_AUTH | LOG_ALERT, "krb5_unparse_name(): %m");
+ goto error;
+ }
+ event->adt_tgs_u2u.service = strdup(sprinc);
+ } else
+ event->adt_tgs_u2u.service = strdup("<none>");
+ if (event->adt_tgs_u2u.service == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (state->status != NULL)
+ event->adt_tgs_u2u.status = strdup(state->status);
+ else
+ event->adt_tgs_u2u.status = strdup("SUCCESS");
+ if (event->adt_tgs_u2u.status == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ if (adt_put_event(event, status, status) != 0) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_put_event(): %m");
+ ret = ENOMEM;
+ }
+
+error:
+ if (event != NULL)
+ adt_free_event(event);
+ if (cprinc != NULL)
+ free(cprinc);
+ if (sprinc != NULL)
+ free(sprinc);
+ if (ret != 0)
+ (void) adt_end_session(ah);
+
+ return (ret);
+}
+
+krb5_error_code
+audit_solaris_initvt(krb5_context context, int maj_ver,
+ int min_ver, krb5_plugin_vtable vtable)
+{
+ krb5_audit_vtable vt;
+
+ if (maj_ver != 1)
+ return (KRB5_PLUGIN_VER_NOTSUPP);
+ vt = (krb5_audit_vtable)vtable;
+ vt->name = "solaris";
+ vt->open = open_au;
+ vt->close = close_au;
+ vt->kdc_start = kdc_start;
+ vt->kdc_stop = kdc_stop;
+ vt->as_req = as_req;
+ vt->tgs_req = tgs_req;
+ vt->tgs_s4u2self = tgs_s4u2self;
+ vt->tgs_s4u2proxy = tgs_s4u2proxy;
+ vt->tgs_u2u = tgs_u2u;
+
+ return (0);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/Solaris/audit/deps Sat Dec 17 21:18:50 2016 -0800
@@ -0,0 +1,38 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+#
+#
+# Generated makefile dependencies follow.
+#
+au_solaris_main.so au_solaris_main.po $(OUTPRE)au_solaris_main.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/kdc_j_encode.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h $(top_srcdir)/plugins/audit/j_dict.h \
+ $(top_srcdir)/include/krb5/audit_plugin.h au_solaris_main.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/Solaris/audit/kadmind_audit.c Sat Dec 17 21:18:50 2016 -0800
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <socket-utils.h>
+#include <rpc/rpc.h>
+#include <syslog.h>
+#include <bsm/adt.h>
+#include <bsm/adt_event.h>
+
+void
+audit_kadmind(char *op, char *target, char *client, char *service, char *status,
+ SVCXPRT *xprt, int failure)
+{
+ adt_session_data_t *ah;
+ adt_event_data_t *event;
+ adt_termid_t *termid;
+ int adtstat = failure ? ADT_FAILURE : ADT_SUCCESS;
+ void *p = (void *)xprt->xp_rtaddr.buf;
+ struct sockaddr_in *p4;
+ struct sockaddr_in6 *p6;
+
+ if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_start_session(): %m");
+ return;
+ }
+
+ if ((event = adt_alloc_event(ah, ADT_kadmind)) == NULL) {
+ syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(): %m");
+ (void) adt_end_session(ah);
+ return;
+ }
+
+ if (((struct sockaddr *)p)->sa_family == AF_INET) {
+ p4 = (struct sockaddr_in *)p;
+ event->adt_kadmind.cl_port = ntohs(p4->sin_port);
+ event->adt_kadmind.cl_addr_type = ADT_IPv4;
+ event->adt_kadmind.cl_addr_address[0] =
+ (uint32_t)p4->sin_addr.s_addr;
+ } else if (((struct sockaddr *)p)->sa_family == AF_INET6) {
+ p6 = (struct sockaddr_in6 *)p;
+ event->adt_kadmind.cl_port = ntohs(p6->sin6_port);
+ event->adt_kadmind.cl_addr_type = ADT_IPv6;
+ (void) memcpy(event->adt_kadmind.cl_addr_address,
+ &p6->sin6_addr, 4 * sizeof (uint_t));
+ }
+
+ event->adt_kadmind.op = op;
+ event->adt_kadmind.target = target;
+ event->adt_kadmind.client = client;
+ event->adt_kadmind.service = service;
+ event->adt_kadmind.status = status;
+
+ if (adt_put_event(event, adtstat, adtstat) != 0)
+ syslog(LOG_AUTH | LOG_ALERT, "adt_put_event(): %m");
+
+ adt_free_event(event);
+ (void) adt_end_session(ah);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/Solaris/audit/kadmind_audit.h Sat Dec 17 21:18:50 2016 -0800
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _KADMIND_AUDIT_H
+#define _KADMIND_AUDIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void audit_kadmind(char *, char *, char *, char *, char *, SVCXPRT *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KADMIND_AUDIT_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/Solaris/audit/solaris.exports Sat Dec 17 21:18:50 2016 -0800
@@ -0,0 +1,1 @@
+audit_solaris_initvt
--- a/components/krb5/krb5-kdc.p5m Fri Dec 16 19:19:44 2016 -0800
+++ b/components/krb5/krb5-kdc.p5m Sat Dec 17 21:18:50 2016 -0800
@@ -42,7 +42,7 @@
restart_fmri=svc:/system/manifest-import:default
file Solaris/krb5kdc.xml path=lib/svc/manifest/network/security/krb5kdc.xml \
restart_fmri=svc:/system/manifest-import:default
-dir path=usr/lib/$(MACH64)/krb5/plugins/kdb
+file path=usr/lib/$(MACH64)/krb5/plugins/audit/solaris.so
file path=usr/lib/$(MACH64)/krb5/plugins/kdb/db2.so
file path=usr/lib/$(MACH64)/krb5/plugins/kdb/kldap.so
link path=usr/lib/$(MACH64)/libkdb_ldap.so target=libkdb_ldap.so.1.0
@@ -52,7 +52,7 @@
file usr/sbin/kprop path=usr/lib/krb5/kprop mode=0555
file usr/sbin/kpropd path=usr/lib/krb5/kpropd mode=0555
file usr/sbin/krb5kdc path=usr/lib/krb5/krb5kdc mode=0500
-dir path=usr/lib/krb5/plugins/kdb
+file path=usr/lib/krb5/plugins/audit/solaris.so
file path=usr/lib/krb5/plugins/kdb/db2.so
file path=usr/lib/krb5/plugins/kdb/kldap.so
link path=usr/lib/libkdb_ldap.so target=libkdb_ldap.so.1.0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/patches/077-solaris-audit.patch Sat Dec 17 21:18:50 2016 -0800
@@ -0,0 +1,239 @@
+#
+# This patch provides a check to see if bsm is supported and if so then
+# configures the build for the KRB5KDC audit plugin support for Solaris based
+# systems.
+#
+# The patch also builds a temporary audit module for kadmind that provides a
+# temporary solution until an adminstrative plugin framework is available,
+# upstream.
+#
+# This patch is not intended to be contributed to MIT as the changes are Solaris
+# specific and, in the case for kadmind, a temporary solution.
+#
+# Patch source: in-house
+#
+--- a/src/config/pre.in
++++ b/src/config/pre.in
[email protected]@ -212,6 +212,7 @@ MODULE_DIR = @[email protected]/krb5/plugins
+ KRB5_DB_MODULE_DIR = $(MODULE_DIR)/kdb
+ KRB5_PA_MODULE_DIR = $(MODULE_DIR)/preauth
+ KRB5_AD_MODULE_DIR = $(MODULE_DIR)/authdata
++KRB5_AU_MODULE_DIR = $(MODULE_DIR)/audit
+ KRB5_LIBKRB5_MODULE_DIR = $(MODULE_DIR)/libkrb5
+ KRB5_TLS_MODULE_DIR = $(MODULE_DIR)/tls
+ KRB5_LOCALEDIR = @[email protected]
+--- a/src/configure.in
++++ b/src/configure.in
[email protected]@ -188,7 +188,7 @@ if test "$withval" = yes; then
+ fi
+
+ # Check which (if any) audit plugin to build
+-audit_plugin=""
++audit_plugin="solaris"
+ AC_ARG_ENABLE([audit-plugin],
+ AC_HELP_STRING([--enable-audit-plugin=IMPL],
+ [use audit plugin @<:@ do not use audit @:>@]), , enableval=no)
[email protected]@ -203,6 +203,13 @@ if test "$enableval" != no; then
+ audit_plugin=plugins/audit/simple ],
+ AC_MSG_ERROR([libaudit not found or undefined symbol audit_log_user_message]))
+ ;;
++ solaris)
++ AC_CHECK_LIB(bsm, adt_start_session,
++ [AUDIT_IMPL_LIBS=-lbsm
++ K5_GEN_MAKEFILE(plugins/audit/solaris)
++ audit_plugin=plugins/audit/solaris ],
++ AC_MSG_ERROR([bsm not found or undefined symbol adt_start_session]))
++ ;;
+ *)
+ AC_MSG_ERROR([Unknown audit plugin implementation $enableval.])
+ ;;
+--- a/src/kadmin/server/deps
++++ b/src/kadmin/server/deps
[email protected]@ -132,4 +132,23 @@ $(OUTPRE)ipropd_svc.$(OBJEXT): $(BUILDTO
+ $(top_srcdir)/include/kdb_log.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/net-server.h \
+ $(top_srcdir)/lib/gssapi/krb5/gssapi_krb5.h $(top_srcdir)/lib/kadm5/srv/server_acl.h \
+- ipropd_svc.c misc.h
++ ipropd_svc.c misc.h kadmind_audit.h
++$(OUTPRE)kadmind_audit.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
++ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
++ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/kadm5/admin.h \
++ $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
++ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \
++ $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/krb5/krb5.h \
++ $(BUILDTOP)/include/osconf.h $(COM_ERR_DEPS) $(VERTO_DEPS) \
++ $(top_srcdir)/include/adm_proto.h $(top_srcdir)/include/gssrpc/auth.h \
++ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \
++ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \
++ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \
++ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \
++ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/iprop.h \
++ $(top_srcdir)/include/iprop_hdr.h $(top_srcdir)/include/k5-platform.h \
++ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/kdb.h \
++ $(top_srcdir)/include/kdb_log.h $(top_srcdir)/include/krb5.h \
++ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/net-server.h \
++ $(top_srcdir)/lib/gssapi/krb5/gssapi_krb5.h $(top_srcdir)/lib/kadm5/srv/server_acl.h \
++ kadmind_audit.c kadmind_audit.h
+--- a/src/kadmin/server/ipropd_svc.c
++++ b/src/kadmin/server/ipropd_svc.c
[email protected]@ -191,6 +191,9 @@ iprop_get_updates_1_svc(kdb_last_t *arg,
+ DPRINT("%s: PERMISSION DENIED: clprinc=`%s'\n\tsvcprinc=`%s'\n",
+ whoami, client_name, service_name);
+
++ audit_kadmind("Incremental updates", "null", client_name, service_name,
++ "Unauthorized request", rqstp->rq_xprt, ret.ret);
++
+ krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, whoami,
+ client_name, service_name,
+ client_addr(rqstp->rq_xprt));
[email protected]@ -217,6 +220,10 @@ iprop_get_updates_1_svc(kdb_last_t *arg,
+ ((kret == 0) ? "success" : error_message(kret)),
+ client_name, service_name);
+
++ audit_kadmind("Incremental updates", "null", client_name, service_name,
++ ((kret == 0) ? "success" : (char *)error_message(kret)), rqstp->rq_xprt,
++ ret.ret);
++
+ krb5_klog_syslog(LOG_NOTICE,
+ _("Request: %s, %s, %s, client=%s, service=%s, addr=%s"),
+ whoami,
[email protected]@ -336,6 +343,10 @@ ipropx_resync(uint32_t vers, struct svc_
+ ret.ret = UPDATE_PERM_DENIED;
+
+ DPRINT("%s: Permission denied\n", whoami);
++
++ audit_kadmind("Full resync", "null", client_name, service_name,
++ "Unauthorized request", rqstp->rq_xprt, ret.ret);
++
+ krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, whoami,
+ client_name, service_name,
+ client_addr(rqstp->rq_xprt));
[email protected]@ -444,6 +455,10 @@ ipropx_resync(uint32_t vers, struct svc_
+ DPRINT("%s: spawned resync process %d, client=%s, "
+ "service=%s, addr=%s\n", whoami, fret, client_name,
+ service_name, client_addr(rqstp->rq_xprt));
++
++ audit_kadmind("Full resync", "null", client_name, service_name,
++ "success", rqstp->rq_xprt, ret.ret);
++
+ krb5_klog_syslog(LOG_NOTICE,
+ _("Request: %s, spawned resync process %d, client=%s, service=%s, addr=%s"),
+ whoami, fret,
+--- a/src/kadmin/server/Makefile.in
++++ b/src/kadmin/server/Makefile.in
[email protected]@ -7,13 +7,15 @@ LOCALINCLUDES = -I$(top_srcdir)/lib/gssa
+ -I$(BUILDTOP)/lib/gssapi/krb5 -I$(top_srcdir)/lib/kadm5/srv
+
+ PROG = kadmind
+-OBJS = kadm_rpc_svc.o server_stubs.o ovsec_kadmd.o schpw.o misc.o ipropd_svc.o
+-SRCS = kadm_rpc_svc.c server_stubs.c ovsec_kadmd.c schpw.c misc.c ipropd_svc.c
++OBJS = kadm_rpc_svc.o server_stubs.o ovsec_kadmd.o schpw.o misc.o ipropd_svc.o \
++ kadmind_audit.o
++SRCS = kadm_rpc_svc.c server_stubs.c ovsec_kadmd.c schpw.c misc.c ipropd_svc.c \
++ kadmind_audit.c
+
+ all:: $(PROG)
+
+ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB) $(VERTO_DEPLIB)
+- $(CC_LINK) -o $(PROG) $(OBJS) $(APPUTILS_LIB) $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) $(VERTO_LIBS) -lpam
++ $(CC_LINK) -o $(PROG) $(OBJS) $(APPUTILS_LIB) $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) $(VERTO_LIBS) -lpam -lbsm
+
+ install::
+ $(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(SERVER_BINDIR)/$(PROG)
+--- a/src/kadmin/server/misc.h
++++ b/src/kadmin/server/misc.h
[email protected]@ -8,6 +8,7 @@
+ #define _MISC_H 1
+
+ #include "net-server.h" /* for krb5_fulladdr */
++#include "kadmind_audit.h"
+
+ int
+ setup_gss_names(struct svc_req *, gss_buffer_desc *,
+--- a/src/kadmin/server/server_stubs.c
++++ b/src/kadmin/server/server_stubs.c
[email protected]@ -312,6 +312,29 @@ log_unauth(
+ slen = server->length;
+ trunc_name(&slen, &sdots);
+
++ {
++ char *client_str = NULL, *server_str = NULL;
++ int len;
++
++ len = asprintf(&client_str, "%.*s%s", (int)clen, (char *)client->value,
++ cdots);
++ if (len == -1)
++ return ENOMEM;
++
++ len = asprintf(&server_str, "%.*s%s", (int)slen, (char *)server->value,
++ sdots);
++ if (len == -1) {
++ free(client_str);
++ return ENOMEM;
++ }
++
++ audit_kadmind(op, target, client_str, server_str,
++ _("Unauthorized request"), rqstp->rq_xprt, 1);
++
++ free(client_str);
++ free(server_str);
++ }
++
+ /* okay to cast lengths to int because trunc_name limits max value */
+ return krb5_klog_syslog(LOG_NOTICE,
+ _("Unauthorized request: %s, %.*s%s, "
[email protected]@ -343,6 +366,29 @@ log_done(
+ slen = server->length;
+ trunc_name(&slen, &sdots);
+
++ {
++ char *client_str = NULL, *server_str = NULL;
++ int len;
++
++ len = asprintf(&client_str, "%.*s%s", (int)clen, (char *)client->value,
++ cdots);
++ if (len == -1)
++ return ENOMEM;
++
++ len = asprintf(&server_str, "%.*s%s", (int)slen, (char *)server->value,
++ sdots);
++ if (len == -1) {
++ free(client_str);
++ return ENOMEM;
++ }
++
++ audit_kadmind(op, target, client_str, server_str, (char *)errmsg,
++ rqstp->rq_xprt, strcmp("success", errmsg) ? 1 : 0);
++
++ free(client_str);
++ free(server_str);
++ }
++
+ /* okay to cast lengths to int because trunc_name limits max value */
+ return krb5_klog_syslog(LOG_NOTICE,
+ _("Request: %s, %.*s%s, %s, "
+--- a/src/kdc/kdc_audit.c
++++ b/src/kdc/kdc_audit.c
[email protected]@ -80,6 +80,11 @@ load_audit_modules(krb5_context context)
+ if (context == NULL || handles != NULL)
+ return EINVAL;
+
++ ret = k5_plugin_register_dyn(context, PLUGIN_INTERFACE_AUDIT, "solaris",
++ "audit");
++ if (ret)
++ return ret;
++
+ /* Get audit plugin vtable. */
+ ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_AUDIT, &modules);
+ if (ret)
+--- a/src/Makefile.in
++++ b/src/Makefile.in
[email protected]@ -65,7 +65,7 @@ INSTALLMKDIRS = $(KRB5ROOT) $(KRB5MANROO
+ $(FILE_CATDIR) \
+ $(KRB5_LIBDIR) $(KRB5_INCDIR) \
+ $(KRB5_DB_MODULE_DIR) $(KRB5_PA_MODULE_DIR) \
+- $(KRB5_AD_MODULE_DIR) \
++ $(KRB5_AD_MODULE_DIR) $(KRB5_AU_MODULE_DIR) \
+ $(KRB5_LIBKRB5_MODULE_DIR) $(KRB5_TLS_MODULE_DIR) \
+ @[email protected] @[email protected]/krb5kdc \
+ @[email protected] @[email protected]/krb5kdc \