diff -wpruN --no-dereference '--exclude=*.orig' a~/INSTALL a/INSTALL --- a~/INSTALL 1970-01-01 00:00:00 +++ a/INSTALL 1970-01-01 00:00:00 @@ -103,9 +103,13 @@ http://www.gnu.org/software/automake/ Basic Security Module (BSM): -Native BSM support is known to exist in Solaris from at least 2.5.1, -FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM -implementation (http://www.openbsm.org). +Native BSM support is known to exist in Solaris from at least 2.5.1 +to Solaris 10. From Solaris 11 the previously documented BSM (libbsm) +interfaces are no longer public and are unsupported. While not public +interfaces, audit-solaris.c implements Solaris Audit from Solaris 11. +Native BSM support is known to exist in FreeBSD 6.1 and OS X. +Alternatively, you may use the OpenBSM implementation +(http://www.openbsm.org). makedepend: @@ -171,8 +175,9 @@ name). There are a few other options to the configure script: --with-audit=[module] enable additional auditing via the specified module. -Currently, drivers for "debug" (additional info via syslog) and "bsm" -(Sun's Basic Security Module) are supported. +Currently, drivers for "debug" (additional info via syslog), and "bsm" +(Sun's Legacy Basic Security Module prior to Solaris 11), and "solaris" +(Sun's Audit infrastructure from Solaris 11) are supported. --with-pam enables PAM support. If PAM support is compiled in, it must also be enabled in sshd_config (refer to the UsePAM directive). diff -wpruN --no-dereference '--exclude=*.orig' a~/Makefile.in a/Makefile.in --- a~/Makefile.in 1970-01-01 00:00:00 +++ a/Makefile.in 1970-01-01 00:00:00 @@ -128,7 +128,7 @@ SSHDOBJS=sshd.o \ $(SKOBJS) SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ - audit.o audit-bsm.o audit-linux.o platform.o \ + audit.o audit-bsm.o audit-linux.o audit-solaris.o platform.o \ sshpty.o sshlogin.o servconf.o serverloop.o \ auth.o auth2.o auth2-methods.o auth-options.o session.o \ auth2-chall.o groupaccess.o \ diff -wpruN --no-dereference '--exclude=*.orig' a~/README.platform a/README.platform --- a~/README.platform 1970-01-01 00:00:00 +++ a/README.platform 1970-01-01 00:00:00 @@ -72,10 +72,10 @@ zlib-devel and pam-devel, on Debian base libssl-dev, libz-dev and libpam-dev. -Solaris -------- -If you enable BSM auditing on Solaris, you need to update audit_event(4) -for praudit(1m) to give sensible output. The following line needs to be +Prior to Solaris 11 +------------------- +If you enable BSM auditing on Solaris, you need to update audit_event(5) +for praudit(8) to give sensible output. The following line needs to be added to /etc/security/audit_event: 32800:AUE_openssh:OpenSSH login:lo @@ -86,6 +86,9 @@ There is no official registry of 3rd par number is already in use on your system, you may change it at build time by configure'ing --with-cflags=-DAUE_openssh=32801 then rebuilding. +From Solaris 11 +--------------- +Solaris Audit is supported by configuring --with-audit=solaris. Platforms using PAM ------------------- diff -wpruN --no-dereference '--exclude=*.orig' a~/audit-bsm.c a/audit-bsm.c --- a~/audit-bsm.c 1970-01-01 00:00:00 +++ a/audit-bsm.c 1970-01-01 00:00:00 @@ -348,7 +348,7 @@ bsm_audit_bad_login(const char *what) /* Below is the sshd audit API code */ void -audit_connection_from(const char *host, int port) +audit_connection_from(struct ssh *ssh, const char *host, int port) { AuditInfoTermID *tid = &ssh_bsm_tid; char buf[1024]; diff -wpruN --no-dereference '--exclude=*.orig' a~/audit-linux.c a/audit-linux.c --- a~/audit-linux.c 1970-01-01 00:00:00 +++ a/audit-linux.c 1970-01-01 00:00:00 @@ -71,7 +71,7 @@ linux_audit_record_event(int uid, const /* Below is the sshd audit API code */ void -audit_connection_from(const char *host, int port) +audit_connection_from(struct ssh *ssh, const char *host, int port) { /* not implemented */ } diff -wpruN --no-dereference '--exclude=*.orig' a~/audit-solaris.c a/audit-solaris.c --- a~/audit-solaris.c 1970-01-01 00:00:00 +++ a/audit-solaris.c 1970-01-01 00:00:00 @@ -0,0 +1,574 @@ +/* + * 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) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + */ + +#include "includes.h" +#if defined(USE_SOLARIS_AUDIT) + +#include "audit.h" +#include "sshbuf.h" +#include "sshkey.h" +#include "hostfile.h" +#include "auth.h" +#include "log.h" +#include "packet.h" + +#include +#include +#include + +#include +#include + +#ifdef ADT_DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/* semi private adt functions to extract information */ + +extern void adt_get_asid(const adt_session_data_t *, au_asid_t *); +extern void adt_get_auid(const adt_session_data_t *, au_id_t *); +extern void adt_get_mask(const adt_session_data_t *, au_mask_t *); +extern void adt_get_termid(const adt_session_data_t *, au_tid_addr_t *); + +extern void __auditd_debug(char *, ...); + +void +__audit_pidinfo(void) +{ + adt_session_data_t *ah = NULL; + au_id_t auid; + char *auid_name = "badname"; + struct passwd *pwd; + au_asid_t asid; + au_mask_t mask; + char flags[512]; + au_tid_addr_t tid; + char pbuf[INET6_ADDRSTRLEN]; + int af = AF_INET; + int remote; + int local; + + if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) { + __auditd_debug("cannot start session %s\n", strerror(errno)); + return; + } + if (ah == NULL) { + __auditd_debug("ah is NULL\n"); + return; + } + adt_get_auid(ah, &auid); + if ((pwd = getpwuid((uid_t)auid)) != NULL) { + auid_name = pwd->pw_name; + } + __auditd_debug("audit id = %s(%d)\n", auid_name, auid); + + adt_get_mask(ah, &mask); + if (getauditflagschar(flags, &mask, NULL) < 0) { + (void) strlcpy(flags, "badflags", sizeof (flags)); + } +#ifdef _LP64 + __auditd_debug("preselection mask = %s(0x%lx,0x%lx)\n", flags, + mask.am_success, mask.am_failure); +#else /* _ILP32 */ + __auditd_debug("preselection mask = %s(0x%llx,0x%llx)\n", flags, + mask.am_success, mask.am_failure); +#endif /* _LP64 */ + + adt_get_termid(ah, &tid); + __auditd_debug("tid type=%d, maj=%u, min=%u, addr=%x:%x:%x:%x\n", + tid.at_type, + (uint16_t)((tid.at_port) >> BITS(uint16_t)), + (uint16_t)(tid.at_port & UINT16_MAX), + tid.at_addr[0], + tid.at_addr[1], + tid.at_addr[2], + tid.at_addr[3]); + if (tid.at_type == AU_IPv6) { + af = AF_INET6; + } + (void) inet_ntop(af, (void *)(tid.at_addr), pbuf, + sizeof (pbuf)); + remote = (tid.at_port >> BITS(uint16_t)); + local = (tid.at_port & UINT16_MAX); + __auditd_debug("tid type-%d (remote,local,host)= %u,%u,%s\n", + tid.at_type, remote, local, pbuf); + adt_get_asid(ah, &asid); + __auditd_debug("audit session id = %u\n", asid); + (void) adt_end_session(ah); +} +#else /* !ADT_DEBUG */ +/*ARGSUSED*/ +/*PRINTFLIKE1*/ +static void +__auditd_debug(char *fmt, ...) +{ +} +static void +__audit_pidinfo() +{ +} +#endif /* ADT_DEBUG */ + +#include + +#include + +extern Authctxt *the_authctxt; + +extern const char *audit_username(void); +extern const char *audit_event_lookup(ssh_audit_event_t); + +static adt_session_data_t *ah = NULL; /* audit session handle */ +static adt_termid_t *tid = NULL; /* peer terminal id */ + +static void audit_login(void); +static void audit_logout(void); +static void audit_fail(int); + +/* Below is the sshd audit API Solaris adt interpretation */ + +/* + * Called after a connection has been accepted but before any authentication + * has been attempted. + */ +/* ARGSUSED */ +void +audit_connection_from(struct ssh *ssh, const char *host, int port) +{ + int peer = ssh_packet_get_connection_in(ssh); + adt_session_data_t *ah = NULL; + + if (adt_load_termid(peer, &tid) != 0) { + error("adt audit_connection_from: unable to load tid for %d:%s", + peer, strerror(errno)); + goto err; + } + if (adt_start_session(&ah, NULL, 0) != 0) { + error("adt audit_connection_from: unable to start session " + "for %s:%d:%s", host, port, strerror(errno)); + goto err; + } + if (adt_set_user(ah, ADT_NO_AUDIT, ADT_NO_AUDIT, 0, + ADT_NO_AUDIT, tid, ADT_SETTID) != 0) { + error("adt audit_connection_from: unable to set user " + "for %s:%d:%s", host, port, strerror(errno)); + goto err; + } + if (adt_set_proc(ah) != 0) { + error("adt audit_connection_from: unable to set proc " + "for %s:%d:%s", host, port, strerror(errno)); + goto err; + } + (void) adt_end_session(ah); + debug("adt audit_connection_from(%s, %d): peerfd=%d", host, port, + peer); + __auditd_debug("%d/%d:%d-adt audit_connection_from(%s, %d)ctxt=%p: " + "peerfd=%d\n", getpid(), getuid(), geteuid(), host, port, + (void *)the_authctxt, peer); + __audit_pidinfo(); + return; + +err: + free(tid); + tid = NULL; + if (ah != NULL) { + (void) adt_end_session(ah); + } +} + +/* + * Called when various events occur (see audit.h for a list of possible + * events and what they mean). + * + * Entry the_authcntxt + */ +void +audit_event(struct ssh *ssh, ssh_audit_event_t event) +{ + static boolean_t logged_in = B_FALSE; /* if user did login */ + int fail = PAM_IGNORE; /* default unset */ + static boolean_t did_maxtries = B_FALSE; /* if interactive and abort */ + + debug("adt audit_event(%s)", audit_event_lookup(event)); + __auditd_debug("%d/%d:%d-adt audit_event(%s/%s)ctxt=%p\n", + getpid(), getuid(), geteuid(), audit_event_lookup(event), + audit_username(), (void *)the_authctxt); + __audit_pidinfo(); + + switch (event) { + case SSH_AUTH_SUCCESS: /* authentication success */ + logged_in = B_TRUE; + audit_login(); /* ADT_ssh; */ + return; + + case SSH_CONNECTION_CLOSE: /* connection closed, all done */ + if (logged_in) { + audit_logout(); /* ADT_logout; */ + logged_in = B_FALSE; + } else { + error("adt audit_event logout without login"); + } + free(tid); + tid = NULL; + return; + + /* Translate fail events to Solaris PAM errors */ + + /* auth2.c: userauth_finish as audit_event(SSH_LOGIN_EXCEED_MAXTRIES) */ + /* auth1.c:do_authloop audit_event(SSH_LOGIN_EXCEED_MAXTRIES) */ + case SSH_LOGIN_EXCEED_MAXTRIES: + fail = PAM_MAXTRIES; + did_maxtries = B_TRUE; + break; + + /* auth2.c: userauth_finish as audit_event(SSH_LOGIN_ROOT_DENIED) */ + /* auth1.c:do_authloop audit_event(SSH_LOGIN_ROOT_DENIED) */ + case SSH_LOGIN_ROOT_DENIED: + fail = PAM_PERM_DENIED; + break; + + /* auth2.c: input_userauth_request as audit_event(SSH_INVALID_USER) */ + /* auth.c: getpwnamallow as audit_event(SSH_INVALID_USER) */ + case SSH_INVALID_USER: + fail = PAM_USER_UNKNOWN; + break; + + /* seems unused, but translate to the Solaris PAM error */ + case SSH_NOLOGIN: + fail = PAM_ACCT_EXPIRED; + break; + + /* + * auth.c in auth_log as it's walking through methods calls + * audit_classify_method(method) which maps + * + * none -> SSH_AUTH_FAIL_NONE + * password -> SSH_AUTH_FAIL_PASSWD + * + * publickey -> SSH_AUTH_FAIL_PUBKEY + * rsa -> SSH_AUTH_FAIL_PUBKEY + * + * keyboard-interactive -> SSH_AUTH_FAIL_KBDINT + * challenge-response -> SSH_AUTH_FAIL_KBDINT + * + * hostbased -> SSH_AUTH_FAIL_HOSTBASED + * rhosts-rsa -> SSH_AUTH_FAIL_HOSTBASED + * + * gssapi-with-mic -> SSH_AUTH_FAIL_GSSAPI + * + * unknown method -> SSH_AUDIT_UNKNOWN + */ + /* + * see mon_table mon_dispatch_proto20[], mon_dispatch_postauth20[], + * mon_dispatch_proto15[], mon_dispatch_postauth15[]: + * MONITOR_REQ_AUDIT_EVENT + * called from monitor.c:mm_answer_audit_event() + * SSH_AUTH_FAIL_PUBKEY, SSH_AUTH_FAIL_HOSTBASED, + * SSH_AUTH_FAIL_GSSAPI, SSH_LOGIN_EXCEED_MAXTRIES, + * SSH_LOGIN_ROOT_DENIED, SSH_CONNECTION_CLOSE SSH_INVALID_USER + * monitor_wrap.c: mm_audit_event() + */ + case SSH_AUTH_FAIL_NONE: /* auth type none */ + case SSH_AUTH_FAIL_PUBKEY: /* authtype publickey */ + break; + + case SSH_AUTH_FAIL_PASSWD: /* auth type password */ + case SSH_AUTH_FAIL_KBDINT: /* authtype keyboard-interactive */ + case SSH_AUTH_FAIL_HOSTBASED: /* auth type hostbased */ + case SSH_AUTH_FAIL_GSSAPI: /* auth type gssapi-with-mic */ + case SSH_AUDIT_UNKNOWN: /* auth type unknown */ + fail = PAM_AUTH_ERR; + break; + + /* sshd.c: cleanup_exit: server specific fatal cleanup */ + case SSH_CONNECTION_ABANDON: /* bailing with fatal error */ + /* + * This seems to occur with OpenSSH client when + * the user login shell exits. + */ + if (logged_in) { + audit_logout(); /* ADT_logout; */ + logged_in = B_FALSE; + return; + } else if (!did_maxtries) { + fail = PAM_AUTHINFO_UNAVAIL; + } else { + /* reset saw max tries */ + did_maxtries = FALSE; + } + free(tid); + tid = NULL; + break; + + default: + error("adt audit_event: unknown event %d", event); + __auditd_debug("%d/%d:%d-unknown event %d", + getpid(), getuid(), geteuid(), event); + __audit_pidinfo(); + break; + } + audit_fail(fail); +} + +/* + * Called when a user session is started. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. + * + * Note that this may be called multiple times if multiple sessions are used + * within a single connection. + */ +/* ARGSUSED */ +void +audit_session_open(struct logininfo *li) +{ + const char *t = li->line ? li->line : "(no tty)"; + + debug("adt audit_session_open: user=%s:tty=%s", audit_username(), + t); + __auditd_debug("%d/%d:%d-adt audit_session_open:ctxt=%p " + "user=%s:tty=%s\n", getpid(), getuid(), geteuid(), + (void *)the_authctxt, audit_username(), t); + __audit_pidinfo(); +} + +/* + * Called when a user session is closed. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. + * + * Note that this may be called multiple times if multiple sessions are used + * within a single connection. + */ +/* ARGSUSED */ +void +audit_session_close(struct logininfo *li) +{ + const char *t = li->line ? li->line : "(no tty)"; + + debug("adt audit_session_close: user=%s:tty=%s", audit_username(), + t); + __auditd_debug("%d/%d:%d-adt audit_session_close:ctxt=%p " + "user=%s:tty=%s\n", getpid(), getuid(), geteuid(), + (void *)the_authctxt, audit_username(), t); + __audit_pidinfo(); +} + +/* + * This will be called when a user runs a non-interactive command. Note that + * it may be called multiple times for a single connection since SSH2 allows + * multiple sessions within a single connection. + */ +/* ARGSUSED */ +void +audit_run_command(const char *command) +{ + debug("adt audit_run_command: \"%s\"", command); + __auditd_debug("%d/%d:%d-adt audit_run_command:ctxt=%p \"%s\"\n", + getpid(), getuid(), geteuid(), (void *)the_authctxt, command); + __audit_pidinfo(); +} + +/* + * audit_login - audit successful login + * + * Entry the_authctxt should be valid ;-) + * and pam_setcred called. + * adt_info & ADT_INFO_PW_SUCCESS if successful + * password change. + * + * Exit ah = audit session established for audit_logout(); + */ +static void +audit_login(void) +{ + adt_event_data_t *event; + uid_t uid = ADT_NO_ATTRIB; + gid_t gid = (gid_t)ADT_NO_ATTRIB; + au_id_t auid; + + if ((the_authctxt != NULL) && (the_authctxt->valid != 0)) { + uid = the_authctxt->pw->pw_uid; + gid = the_authctxt->pw->pw_gid; + } + + if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) { + error("adt_start_session: %s", strerror(errno)); + return; + } + + adt_get_auid(ah, &auid); + + if (adt_set_user(ah, uid, gid, uid, gid, NULL, + auid == AU_NOAUDITID ? ADT_NEW : ADT_USER)) { + error("adt_set_user auid=%d, uid=%d", auid, uid); + (void) adt_end_session(ah); + ah = NULL; + free(tid); + tid = NULL; + return; + } + if ((event = adt_alloc_event(ah, ADT_ssh)) == NULL) { + error("adt_alloc_event(ADT_ssh): %s", strerror(errno)); + return; + } + if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) { + error("adt_put_event(ADT_ssh, ADT_SUCCESS): %s", + strerror(errno)); + } + /* should audit successful password change here */ + adt_free_event(event); +} + +/* + * audit_logout - audit the logout + * + * Entry ah = audit session. + */ +static void +audit_logout(void) +{ + adt_event_data_t *event; + + if ((event = adt_alloc_event(ah, ADT_logout)) == NULL) { + error("adt_alloc_event(ADT_logout): %s", strerror(errno)); + return; + } + if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) { + error("adt_put_event(ADT_logout, ADT_SUCCESS): %s", + strerror(errno)); + } + adt_free_event(event); + (void) adt_end_session(ah); + ah = NULL; +} + +/* + * audit_fail - audit login failure. + * + * Entry the_authctxt assumed to have some info. + * user = user who asked to be authenticated. + * tid = connection audit TID set by audit_connect_from(); + * + * N.B. pam_strerror() prototype takes a pam handle and error number. + * At least on Solaris, pam_strerror never uses the pam handle. + * Since there doesn't seem to be a pam handle available, this + * code just uses NULL. + */ +static void +audit_fail(int pamerr) +{ + adt_session_data_t *ah = NULL; + adt_event_data_t *event; + uid_t uid = ADT_NO_ATTRIB; + gid_t gid = (gid_t)ADT_NO_ATTRIB; + + __auditd_debug("%d/%d:%d-audit_fail(%s) ctxt=%p\n", + getpid(), getuid(), geteuid(), pam_strerror(NULL, pamerr), + (void *)the_authctxt); + if (the_authctxt != NULL) { + uid_t pwuid = ADT_NO_ATTRIB; + + if (the_authctxt->pw != NULL) { + pwuid = the_authctxt->pw->pw_uid; + } + __auditd_debug("valid=%d, user=%s, uid=%d\n", + the_authctxt->valid, audit_username(), pwuid); + } else { + __auditd_debug("\tNo autxctxt\n"); + } + __audit_pidinfo(); + if (pamerr == PAM_IGNORE) { + return; + } + if ((the_authctxt != NULL) && (the_authctxt->valid != 0)) { + uid = the_authctxt->pw->pw_uid; + gid = the_authctxt->pw->pw_gid; + } else if ((the_authctxt != NULL) && (the_authctxt->user != NULL)) { + struct passwd *pw; + + if ((pw = getpwnam(the_authctxt->user)) != NULL) { + uid = pw->pw_uid; + gid = pw->pw_gid; + } + } + if (adt_start_session(&ah, NULL, 0) != 0) { + error("adt_start_session(ADT_ssh, 0, fail=%s):" + " %s", pam_strerror(NULL, pamerr), strerror(errno)); + __auditd_debug("%d/%d:%d-adt_start_session(ADT_ssh, " + "PROC_DATA, fail=%s): %s", getpid(), getuid(), + geteuid(), pam_strerror(NULL, pamerr), + strerror(errno)); + return; + } + __auditd_debug("%d/%d:%d-audit_fail+start_session() ah=%p\n", + getpid(), getuid(), geteuid(), (void *)ah); + if (adt_set_user(ah, uid, gid, uid, gid, tid, ADT_NEW) != 0) { + error("adt_set_user(ADT_ssh, PROC_DATA, fail=%s): %s", + pam_strerror(NULL, pamerr), strerror(errno)); + __auditd_debug("%d/%d:%d-adt_set_user(ADT_ssh, " + "PROC_DATA, fail=%s): %s", getpid(), getuid(), + geteuid(), pam_strerror(NULL, pamerr), + strerror(errno)); + goto done; + } + __auditd_debug("%d/%d:%d-audit_fail+set_user() ah=%p\n", getpid(), + getuid(), geteuid(), (void *)ah); + if ((event = adt_alloc_event(ah, ADT_ssh)) == NULL) { + error("adt_alloc_event(ADT_ssh, fail=%s): %s", + pam_strerror(NULL, pamerr), strerror(errno)); + __auditd_debug("%d/%d:%d-adt_set_user(ADT_ssh, 0, " + "fail=%s): %s", getpid(), getuid(), geteuid(), + pam_strerror(NULL, pamerr), strerror(errno)); + } else if (adt_put_event(event, ADT_FAILURE, + ADT_FAIL_PAM + pamerr) != 0) { + error("adt_put_event(ADT_ssh, fail=%s): %s", + pam_strerror(NULL, pamerr), strerror(errno)); + __auditd_debug("%d/%d:%d-adt_put_event(ADT_ssh, fail=%s): %s", + getpid(), getuid(), geteuid(), pam_strerror(NULL, pamerr), + strerror(errno)); + } + __auditd_debug("%d/%d:%d-audit_fail+put_event() ah=%p\n", getpid(), + getuid(), geteuid(), (void *)ah); + /* should audit authentication with failed password change here. */ + adt_free_event(event); +done: + (void) adt_end_session(ah); +} +#endif /* USE_SOLARIS_AUDIT */ diff -wpruN --no-dereference '--exclude=*.orig' a~/audit.c a/audit.c --- a~/audit.c 1970-01-01 00:00:00 +++ a/audit.c 1970-01-01 00:00:00 @@ -120,7 +120,7 @@ audit_event_lookup(ssh_audit_event_t ev) * has been attempted. */ void -audit_connection_from(const char *host, int port) +audit_connection_from(struct ssh *ssh, const char *host, int port) { debug("audit connection from %s port %d euid %d", host, port, (int)geteuid()); diff -wpruN --no-dereference '--exclude=*.orig' a~/audit.h a/audit.h --- a~/audit.h 1970-01-01 00:00:00 +++ a/audit.h 1970-01-01 00:00:00 @@ -47,7 +47,7 @@ enum ssh_audit_event_type { }; typedef enum ssh_audit_event_type ssh_audit_event_t; -void audit_connection_from(const char *, int); +void audit_connection_from(struct ssh *, const char *, int); void audit_event(struct ssh *, ssh_audit_event_t); void audit_session_open(struct logininfo *); void audit_session_close(struct logininfo *); diff -wpruN --no-dereference '--exclude=*.orig' a~/configure.ac a/configure.ac --- a~/configure.ac 1970-01-01 00:00:00 +++ a/configure.ac 1970-01-01 00:00:00 @@ -1777,7 +1777,7 @@ AC_ARG_WITH([libedit], AUDIT_MODULE=none AC_ARG_WITH([audit], - [ --with-audit=module Enable audit support (modules=debug,bsm,linux)], + [ --with-audit=module Enable audit support (modules=debug,bsm,linux,solaris)], [ AC_MSG_CHECKING([for supported audit module]) case "$withval" in @@ -1814,6 +1814,13 @@ AC_ARG_WITH([audit], SSHDLIBS="$SSHDLIBS -laudit" AC_DEFINE([USE_LINUX_AUDIT], [1], [Use Linux audit module]) ;; + solaris) + AC_MSG_RESULT([solaris]) + AUDIT_MODULE=solaris + AC_CHECK_HEADERS([bsm/adt.h]) + SSHDLIBS="$SSHDLIBS -lbsm" + AC_DEFINE([USE_SOLARIS_AUDIT], [1], [Use Solaris audit module]) + ;; debug) AUDIT_MODULE=debug AC_MSG_RESULT([debug]) diff -wpruN --no-dereference '--exclude=*.orig' a~/defines.h a/defines.h --- a~/defines.h 1970-01-01 00:00:00 +++ a/defines.h 1970-01-01 00:00:00 @@ -715,6 +715,11 @@ struct winsize { # define CUSTOM_SSH_AUDIT_EVENTS #endif +#ifdef USE_SOLARIS_AUDIT +# define SSH_AUDIT_EVENTS +# define CUSTOM_SSH_AUDIT_EVENTS +#endif + #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__) # define __func__ __FUNCTION__ #elif !defined(HAVE___func__) diff -wpruN --no-dereference '--exclude=*.orig' a~/sshd-session.c a/sshd-session.c --- a~/sshd-session.c 1970-01-01 00:00:00 +++ a/sshd-session.c 1970-01-01 00:00:00 @@ -1254,7 +1254,7 @@ main(int ac, char **av) remote_ip = ssh_remote_ipaddr(ssh); #ifdef SSH_AUDIT_EVENTS - audit_connection_from(remote_ip, remote_port); + audit_connection_from(ssh, remote_ip, remote_port); #endif rdomain = ssh_packet_rdomain_in(ssh); @@ -1348,8 +1348,10 @@ main(int ac, char **av) set_process_rdomain(ssh, options.routing_domain); #ifdef SSH_AUDIT_EVENTS +#ifndef USE_SOLARIS_AUDIT audit_event(ssh, SSH_AUTH_SUCCESS); #endif +#endif #ifdef GSSAPI if (options.gss_authentication) {