/*
* 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
* 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
*/
/*
*/
#include "includes.h"
#if defined(USE_SOLARIS_AUDIT)
#include "audit.h"
#include "buffer.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "log.h"
#include "packet.h"
#include <errno.h>
#include <pwd.h>
#include <string.h>
#include <bsm/adt_event.h>
#ifdef ADT_DEBUG
#include <values.h>
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <ucred.h>
#include <values.h>
/* semi private adt functions to extract information */
extern void __auditd_debug(char *, ...);
void
__audit_pidinfo(void)
{
int remote;
int local;
return;
}
__auditd_debug("ah is NULL\n");
return;
}
}
}
#ifdef _LP64
#else /* _ILP32 */
#endif /* _LP64 */
__auditd_debug("tid type=%d, maj=%u, min=%u, addr=%x:%x:%x:%x\n",
}
sizeof (pbuf));
__auditd_debug("tid type-%d (remote,local,host)= %u,%u,%s\n",
(void) adt_end_session(ah);
}
#else /* !ADT_DEBUG */
/*ARGSUSED*/
/*PRINTFLIKE1*/
static void
{
}
static void
{
}
#endif /* ADT_DEBUG */
#include <security/pam_appl.h>
extern Authctxt *the_authctxt;
extern const char *audit_username(void);
extern const char *audit_event_lookup(ssh_audit_event_t);
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
{
error("adt audit_connection_from: unable to load tid for %d:%s",
}
error("adt audit_connection_from: unable to start session "
}
error("adt audit_connection_from: unable to set user "
(void) adt_end_session(ah);
}
if (adt_set_proc(ah) != 0) {
error("adt audit_connection_from: unable to set proc "
}
(void) adt_end_session(ah);
peer);
__auditd_debug("%d/%d:%d-adt audit_connection_from(%s, %d)ctxt=%p: "
(void *)the_authctxt, peer);
}
/*
* Called when various events occur (see audit.h for a list of possible
* events and what they mean).
*
* Entry the_authcntxt
*/
void
{
__auditd_debug("%d/%d:%d-adt audit_event(%s/%s)ctxt=%p\n",
audit_username(), (void *)the_authctxt);
switch (event) {
case SSH_AUTH_SUCCESS: /* authentication success */
audit_login(); /* ADT_ssh; */
return;
case SSH_CONNECTION_CLOSE: /* connection closed, all done */
if (logged_in) {
audit_logout(); /* ADT_logout; */
} else {
error("adt audit_event logout without login");
}
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) */
fail = PAM_MAXTRIES;
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:
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:
break;
/* seems unused, but translate to the Solaris PAM error */
case SSH_NOLOGIN:
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; */
return;
} else if (!did_maxtries) {
} else {
/* reset saw max tries */
}
break;
default:
__auditd_debug("%d/%d:%d-unknown event %d",
break;
}
}
/*
* 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
{
t);
__auditd_debug("%d/%d:%d-adt audit_session_open:ctxt=%p "
(void *)the_authctxt, audit_username(), t);
}
/*
* 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
{
t);
__auditd_debug("%d/%d:%d-adt audit_session_close:ctxt=%p "
(void *)the_authctxt, audit_username(), t);
}
/*
* 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
{
__auditd_debug("%d/%d:%d-adt audit_run_command:ctxt=%p \"%s\"\n",
}
/*
* 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)
{
}
return;
}
(void) adt_end_session(ah);
return;
}
return;
}
error("adt_put_event(ADT_ssh, ADT_SUCCESS): %s",
}
/* should audit successful password change here */
}
/*
* audit_logout - audit the logout
*
* Entry ah = audit session.
*/
static void
audit_logout(void)
{
return;
}
error("adt_put_event(ADT_logout, ADT_SUCCESS): %s",
}
(void) adt_end_session(ah);
}
/*
* 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
{
__auditd_debug("%d/%d:%d-audit_fail(%s) ctxt=%p\n",
(void *)the_authctxt);
if (the_authctxt != NULL) {
}
__auditd_debug("valid=%d, user=%s, uid=%d\n",
} else {
__auditd_debug("\tNo autxctxt\n");
}
if (pamerr == PAM_IGNORE) {
return;
}
}
}
error("adt_start_session(ADT_ssh, 0, fail=%s):"
__auditd_debug("%d/%d:%d-adt_start_session(ADT_ssh, "
return;
}
__auditd_debug("%d/%d:%d-audit_fail+start_session() ah=%p\n",
error("adt_set_user(ADT_ssh, PROC_DATA, fail=%s): %s",
__auditd_debug("%d/%d:%d-adt_set_user(ADT_ssh, "
goto done;
}
error("adt_alloc_event(ADT_ssh, fail=%s): %s",
__auditd_debug("%d/%d:%d-adt_set_user(ADT_ssh, 0, "
ADT_FAIL_PAM + pamerr) != 0) {
error("adt_put_event(ADT_ssh, fail=%s): %s",
__auditd_debug("%d/%d:%d-adt_put_event(ADT_ssh, fail=%s): %s",
}
/* should audit authentication with failed password change here. */
done:
(void) adt_end_session(ah);
}
#endif /* USE_SOLARIS_AUDIT */