unleashed-userland README
[unleashed-userland.git] / components / network / openssh / patches / 0014-Solaris-Auditing-support.patch
bloba91717d758db69e7be3a6e5df821f69ff172886e
1 From 785d51f8667359a362893f13e8762d0e814ceeda Mon Sep 17 00:00:00 2001
2 From: oracle <solaris@oracle.com>
3 Date: Mon, 3 Aug 2015 14:37:01 -0700
4 Subject: [PATCH 14/34] Solaris Auditing support
7 # Add Solaris Auditing configuration (--with-audit=solaris) to openssh-6.5p1.
9 # Add phase 1 Solaris Auditing of sshd login/logout to openssh-6.5p1.
11 # Additional Solaris Auditing should include audit of password
12 # change.
13 # Presuming it is appropriate, this patch should/will be updated
14 # with additional files and updates to sources/audit-solaris.c
16 # Code is developed by the Solaris Audit team.
17 # It should/will likely be contributed up stream when done.
18 # This patch relies on sources/audit-solaris.c being copied into
19 # the openssh source directory by the Makefile that configures
20 # using --with-audit=solaris.
22 # The up stream community has been contacted about the plans.
23 # No reply has yet been received.
25 # An additional patch relying on the --with-audit=solaris configuration
26 # should/will be created for sftp Solaris Audit and password change.
28 ---
29 INSTALL | 15 +-
30 Makefile.in | 2 +-
31 README.platform | 7 +-
32 audit-solaris.c | 562 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
33 configure.ac | 9 +-
34 defines.h | 5 +
35 sshd.c | 6 +
36 7 files changed, 597 insertions(+), 9 deletions(-)
37 create mode 100644 audit-solaris.c
39 diff --git a/INSTALL b/INSTALL
40 index cbbb2df..765d4aa 100644
41 --- a/INSTALL
42 +++ b/INSTALL
43 @@ -92,9 +92,13 @@ http://www.gnu.org/software/autoconf/
45 Basic Security Module (BSM):
47 -Native BSM support is know to exist in Solaris from at least 2.5.1,
48 -FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM
49 -implementation (http://www.openbsm.org).
50 +Native BSM support is known to exist in Solaris from at least 2.5.1
51 +to Solaris 10. From Solaris 11 the previously documented BSM (libbsm)
52 +interfaces are no longer public and are unsupported. While not public
53 +interfaces, audit-solaris.c implements Solaris Audit from Solaris 11.
54 +Native BSM support is known to exist in FreeBSD 6.1 and OS X.
55 +Alternatively, you may use the OpenBSM implementation
56 +(http://www.openbsm.org).
59 2. Building / Installation
60 @@ -147,8 +151,9 @@ name).
61 There are a few other options to the configure script:
63 --with-audit=[module] enable additional auditing via the specified module.
64 -Currently, drivers for "debug" (additional info via syslog) and "bsm"
65 -(Sun's Basic Security Module) are supported.
66 +Currently, drivers for "debug" (additional info via syslog), and "bsm"
67 +(Sun's Legacy Basic Security Module prior to Solaris 11), and "solaris"
68 +(Sun's Audit infrastructure from Solaris 11) are supported.
70 --with-pam enables PAM support. If PAM support is compiled in, it must
71 also be enabled in sshd_config (refer to the UsePAM directive).
72 diff --git a/Makefile.in b/Makefile.in
73 index 61a97de..abc9285 100644
74 --- a/Makefile.in
75 +++ b/Makefile.in
76 @@ -100,7 +100,7 @@ SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
77 sshconnect.o sshconnect1.o sshconnect2.o mux.o
79 SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
80 - audit.o audit-bsm.o audit-linux.o platform.o \
81 + audit.o audit-bsm.o audit-linux.o audit-solaris.o platform.o \
82 sshpty.o sshlogin.o servconf.o serverloop.o \
83 auth.o auth1.o auth2.o auth-options.o session.o \
84 auth-chall.o auth2-chall.o groupaccess.o \
85 diff --git a/README.platform b/README.platform
86 index 8d75c16..616200b 100644
87 --- a/README.platform
88 +++ b/README.platform
89 @@ -71,8 +71,8 @@ zlib-devel and pam-devel, on Debian based distros these may be
90 libssl-dev, libz-dev and libpam-dev.
93 -Solaris
94 --------
95 +Prior to Solaris 11
96 +-------------------
97 If you enable BSM auditing on Solaris, you need to update audit_event(4)
98 for praudit(1m) to give sensible output. The following line needs to be
99 added to /etc/security/audit_event:
100 @@ -85,6 +85,9 @@ There is no official registry of 3rd party event numbers, so if this
101 number is already in use on your system, you may change it at build time
102 by configure'ing --with-cflags=-DAUE_openssh=32801 then rebuilding.
104 +From Solaris 11
105 +---------------
106 +Solaris Audit is supported by configuring --with-audit=solaris.
108 Platforms using PAM
109 -------------------
110 diff --git a/audit-solaris.c b/audit-solaris.c
111 new file mode 100644
112 index 0000000..abf870c
113 --- /dev/null
114 +++ b/audit-solaris.c
115 @@ -0,0 +1,574 @@
117 + * CDDL HEADER START
119 + * The contents of this file are subject to the terms of the
120 + * Common Development and Distribution License (the "License").
121 + * You may not use this file except in compliance with the License.
123 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
124 + * or http://www.opensolaris.org/os/licensing.
125 + * See the License for the specific language governing permissions
126 + * and limitations under the License.
128 + * When distributing Covered Code, include this CDDL HEADER in each
129 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
130 + * If applicable, add the following below this CDDL HEADER, with the
131 + * fields enclosed by brackets "[]" replaced with your own identifying
132 + * information: Portions Copyright [yyyy] [name of copyright owner]
134 + * CDDL HEADER END
135 + */
138 + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
139 + */
141 +#include "includes.h"
142 +#if defined(USE_SOLARIS_AUDIT)
144 +#include "audit.h"
145 +#include "buffer.h"
146 +#include "key.h"
147 +#include "hostfile.h"
148 +#include "auth.h"
149 +#include "log.h"
150 +#include "packet.h"
152 +#include <errno.h>
153 +#include <pwd.h>
154 +#include <string.h>
156 +#include <bsm/adt.h>
157 +#include <bsm/adt_event.h>
159 +#ifdef ADT_DEBUG
160 +#include <bsm/audit.h>
161 +#include <arpa/inet.h>
162 +#include <netinet/in.h>
163 +#include <values.h>
164 +#include <errno.h>
165 +#include <pwd.h>
166 +#include <stdio.h>
167 +#include <unistd.h>
168 +#include <stdarg.h>
169 +#include <string.h>
170 +#include <ucred.h>
171 +#include <values.h>
173 +#include <bsm/adt.h>
174 +#include <bsm/audit.h>
176 +#include <sys/types.h>
177 +#include <sys/stat.h>
179 +/* semi private adt functions to extract information */
181 +extern void adt_get_asid(const adt_session_data_t *, au_asid_t *);
182 +extern void adt_get_auid(const adt_session_data_t *, au_id_t *);
183 +extern void adt_get_mask(const adt_session_data_t *, au_mask_t *);
184 +extern void adt_get_termid(const adt_session_data_t *, au_tid_addr_t *);
186 +extern void __auditd_debug(char *, ...);
188 +void
189 +__audit_pidinfo(void)
191 + adt_session_data_t *ah = NULL;
192 + au_id_t auid;
193 + char *auid_name = "badname";
194 + struct passwd *pwd;
195 + au_asid_t asid;
196 + au_mask_t mask;
197 + char flags[512];
198 + au_tid_addr_t tid;
199 + char pbuf[INET6_ADDRSTRLEN];
200 + int af = AF_INET;
201 + int remote;
202 + int local;
204 + if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
205 + __auditd_debug("cannot start session %s\n", strerror(errno));
206 + return;
208 + if (ah == NULL) {
209 + __auditd_debug("ah is NULL\n");
210 + return;
212 + adt_get_auid(ah, &auid);
213 + if ((pwd = getpwuid((uid_t)auid)) != NULL) {
214 + auid_name = pwd->pw_name;
216 + __auditd_debug("audit id = %s(%d)\n", auid_name, auid);
218 + adt_get_mask(ah, &mask);
219 + if (getauditflagschar(flags, &mask, NULL) < 0) {
220 + (void) strlcpy(flags, "badflags", sizeof (flags));
222 +#ifdef _LP64
223 + __auditd_debug("preselection mask = %s(0x%lx,0x%lx)\n", flags,
224 + mask.am_success, mask.am_failure);
225 +#else /* _ILP32 */
226 + __auditd_debug("preselection mask = %s(0x%llx,0x%llx)\n", flags,
227 + mask.am_success, mask.am_failure);
228 +#endif /* _LP64 */
230 + adt_get_termid(ah, &tid);
231 + __auditd_debug("tid type=%d, maj=%u, min=%u, addr=%x:%x:%x:%x\n",
232 + tid.at_type,
233 + (uint16_t)((tid.at_port) >> BITS(uint16_t)),
234 + (uint16_t)(tid.at_port & UINT16_MAX),
235 + tid.at_addr[0],
236 + tid.at_addr[1],
237 + tid.at_addr[2],
238 + tid.at_addr[3]);
239 + if (tid.at_type == AU_IPv6) {
240 + af = AF_INET6;
242 + (void) inet_ntop(af, (void *)(tid.at_addr), pbuf,
243 + sizeof (pbuf));
244 + remote = (tid.at_port >> BITS(uint16_t));
245 + local = (tid.at_port & UINT16_MAX);
246 + __auditd_debug("tid type-%d (remote,local,host)= %u,%u,%s\n",
247 + tid.at_type, remote, local, pbuf);
248 + adt_get_asid(ah, &asid);
249 + __auditd_debug("audit session id = %u\n", asid);
250 + (void) adt_end_session(ah);
252 +#else /* !ADT_DEBUG */
253 +/*ARGSUSED*/
254 +/*PRINTFLIKE1*/
255 +static void
256 +__auditd_debug(char *fmt, ...)
259 +static void
260 +__audit_pidinfo()
263 +#endif /* ADT_DEBUG */
265 +#include <security/pam_appl.h>
267 +#include <sys/types.h>
269 +extern Authctxt *the_authctxt;
271 +extern const char *audit_username(void);
272 +extern const char *audit_event_lookup(ssh_audit_event_t);
274 +static adt_session_data_t *ah = NULL; /* audit session handle */
275 +static adt_termid_t *tid = NULL; /* peer terminal id */
277 +static void audit_login(void);
278 +static void audit_logout(void);
279 +static void audit_fail(int);
281 +/* Below is the sshd audit API Solaris adt interpretation */
284 + * Called after a connection has been accepted but before any authentication
285 + * has been attempted.
286 + */
287 +/* ARGSUSED */
288 +void
289 +audit_connection_from(const char *host, int port)
291 + int peer = packet_get_connection_in();
292 + adt_session_data_t *ah = NULL;
294 + if (adt_load_termid(peer, &tid) != 0) {
295 + error("adt audit_connection_from: unable to load tid for %d:%s",
296 + peer, strerror(errno));
297 + return;
299 + if (adt_start_session(&ah, NULL, 0) != 0) {
300 + error("adt audit_connection_from: unable to start session "
301 + "for %s:%d:%s", host, port, strerror(errno));
302 + free(tid);
303 + tid = NULL;
304 + return;
306 + if (adt_set_user(ah, ADT_NO_AUDIT, ADT_NO_AUDIT, 0,
307 + ADT_NO_AUDIT, tid, ADT_SETTID) != 0) {
308 + error("adt audit_connection_from: unable to set user "
309 + "for %s:%d:%s", host, port, strerror(errno));
310 + free(tid);
311 + tid = NULL;
312 + (void) adt_end_session(ah);
313 + return;
315 + if (adt_set_proc(ah) != 0) {
316 + error("adt audit_connection_from: unable to set proc "
317 + "for %s:%d:%s", host, port, strerror(errno));
318 + free(tid);
319 + tid = NULL;
320 + (void) adt_end_session(ah);
321 + return;
323 + (void) adt_end_session(ah);
324 + debug("adt audit_connection_from(%s, %d): peerfd=%d", host, port,
325 + peer);
326 + __auditd_debug("%d/%d:%d-adt audit_connection_from(%s, %d)ctxt=%p: "
327 + "peerfd=%d\n", getpid(), getuid(), geteuid(), host, port,
328 + (void *)the_authctxt, peer);
329 + __audit_pidinfo();
333 + * Called when various events occur (see audit.h for a list of possible
334 + * events and what they mean).
336 + * Entry the_authcntxt
337 + */
338 +void
339 +audit_event(ssh_audit_event_t event)
341 + static boolean_t logged_in = B_FALSE; /* if user did login */
342 + int fail = PAM_IGNORE; /* default unset */
343 + static boolean_t did_maxtries = B_FALSE; /* if interactive and abort */
345 + debug("adt audit_event(%s)", audit_event_lookup(event));
346 + __auditd_debug("%d/%d:%d-adt audit_event(%s/%s)ctxt=%p\n",
347 + getpid(), getuid(), geteuid(), audit_event_lookup(event),
348 + audit_username(), (void *)the_authctxt);
349 + __audit_pidinfo();
351 + switch (event) {
352 + case SSH_AUTH_SUCCESS: /* authentication success */
353 + logged_in = B_TRUE;
354 + audit_login(); /* ADT_ssh; */
355 + return;
357 + case SSH_CONNECTION_CLOSE: /* connection closed, all done */
358 + if (logged_in) {
359 + audit_logout(); /* ADT_logout; */
360 + logged_in = B_FALSE;
361 + } else {
362 + error("adt audit_event logout without login");
364 + free(tid);
365 + tid = NULL;
366 + return;
368 + /* Translate fail events to Solaris PAM errors */
370 + /* auth2.c: userauth_finish as audit_event(SSH_LOGIN_EXCEED_MAXTRIES) */
371 + /* auth1.c:do_authloop audit_event(SSH_LOGIN_EXCEED_MAXTRIES) */
372 + case SSH_LOGIN_EXCEED_MAXTRIES:
373 + fail = PAM_MAXTRIES;
374 + did_maxtries = B_TRUE;
375 + break;
377 + /* auth2.c: userauth_finish as audit_event(SSH_LOGIN_ROOT_DENIED) */
378 + /* auth1.c:do_authloop audit_event(SSH_LOGIN_ROOT_DENIED) */
379 + case SSH_LOGIN_ROOT_DENIED:
380 + fail = PAM_PERM_DENIED;
381 + break;
383 + /* auth2.c: input_userauth_request as audit_event(SSH_INVALID_USER) */
384 + /* auth.c: getpwnamallow as audit_event(SSH_INVALID_USER) */
385 + case SSH_INVALID_USER:
386 + fail = PAM_USER_UNKNOWN;
387 + break;
389 + /* seems unused, but translate to the Solaris PAM error */
390 + case SSH_NOLOGIN:
391 + fail = PAM_ACCT_EXPIRED;
392 + break;
394 + /*
395 + * auth.c in auth_log as it's walking through methods calls
396 + * audit_classify_method(method) which maps
398 + * none -> SSH_AUTH_FAIL_NONE
399 + * password -> SSH_AUTH_FAIL_PASSWD
401 + * publickey -> SSH_AUTH_FAIL_PUBKEY
402 + * rsa -> SSH_AUTH_FAIL_PUBKEY
404 + * keyboard-interactive -> SSH_AUTH_FAIL_KBDINT
405 + * challenge-response -> SSH_AUTH_FAIL_KBDINT
407 + * hostbased -> SSH_AUTH_FAIL_HOSTBASED
408 + * rhosts-rsa -> SSH_AUTH_FAIL_HOSTBASED
410 + * gssapi-with-mic -> SSH_AUTH_FAIL_GSSAPI
412 + * unknown method -> SSH_AUDIT_UNKNOWN
413 + */
414 + /*
415 + * see mon_table mon_dispatch_proto20[], mon_dispatch_postauth20[],
416 + * mon_dispatch_proto15[], mon_dispatch_postauth15[]:
417 + * MONITOR_REQ_AUDIT_EVENT
418 + * called from monitor.c:mm_answer_audit_event()
419 + * SSH_AUTH_FAIL_PUBKEY, SSH_AUTH_FAIL_HOSTBASED,
420 + * SSH_AUTH_FAIL_GSSAPI, SSH_LOGIN_EXCEED_MAXTRIES,
421 + * SSH_LOGIN_ROOT_DENIED, SSH_CONNECTION_CLOSE SSH_INVALID_USER
422 + * monitor_wrap.c: mm_audit_event()
423 + */
424 + case SSH_AUTH_FAIL_NONE: /* auth type none */
425 + case SSH_AUTH_FAIL_PUBKEY: /* authtype publickey */
426 + break;
428 + case SSH_AUTH_FAIL_PASSWD: /* auth type password */
429 + case SSH_AUTH_FAIL_KBDINT: /* authtype keyboard-interactive */
430 + case SSH_AUTH_FAIL_HOSTBASED: /* auth type hostbased */
431 + case SSH_AUTH_FAIL_GSSAPI: /* auth type gssapi-with-mic */
432 + case SSH_AUDIT_UNKNOWN: /* auth type unknown */
433 + fail = PAM_AUTH_ERR;
434 + break;
436 + /* sshd.c: cleanup_exit: server specific fatal cleanup */
437 + case SSH_CONNECTION_ABANDON: /* bailing with fatal error */
438 + /*
439 + * This seems to occur with OpenSSH client when
440 + * the user login shell exits.
441 + */
442 + if (logged_in) {
443 + audit_logout(); /* ADT_logout; */
444 + logged_in = B_FALSE;
445 + return;
446 + } else if (!did_maxtries) {
447 + fail = PAM_AUTHINFO_UNAVAIL;
448 + } else {
449 + /* reset saw max tries */
450 + did_maxtries = FALSE;
452 + free(tid);
453 + tid = NULL;
454 + break;
456 + default:
457 + error("adt audit_event: unknown event %d", event);
458 + __auditd_debug("%d/%d:%d-unknown event %d",
459 + getpid(), getuid(), geteuid(), event);
460 + __audit_pidinfo();
461 + break;
463 + audit_fail(fail);
467 + * Called when a user session is started. Argument is the tty allocated to
468 + * the session, or NULL if no tty was allocated.
470 + * Note that this may be called multiple times if multiple sessions are used
471 + * within a single connection.
472 + */
473 +/* ARGSUSED */
474 +void
475 +audit_session_open(struct logininfo *li)
477 + const char *t = li->line ? li->line : "(no tty)";
479 + debug("adt audit_session_open: user=%s:tty=%s", audit_username(),
480 + t);
481 + __auditd_debug("%d/%d:%d-adt audit_session_open:ctxt=%p "
482 + "user=%s:tty=%s\n", getpid(), getuid(), geteuid(),
483 + (void *)the_authctxt, audit_username(), t);
484 + __audit_pidinfo();
488 + * Called when a user session is closed. Argument is the tty allocated to
489 + * the session, or NULL if no tty was allocated.
491 + * Note that this may be called multiple times if multiple sessions are used
492 + * within a single connection.
493 + */
494 +/* ARGSUSED */
495 +void
496 +audit_session_close(struct logininfo *li)
498 + const char *t = li->line ? li->line : "(no tty)";
500 + debug("adt audit_session_close: user=%s:tty=%s", audit_username(),
501 + t);
502 + __auditd_debug("%d/%d:%d-adt audit_session_close:ctxt=%p "
503 + "user=%s:tty=%s\n", getpid(), getuid(), geteuid(),
504 + (void *)the_authctxt, audit_username(), t);
505 + __audit_pidinfo();
509 + * This will be called when a user runs a non-interactive command. Note that
510 + * it may be called multiple times for a single connection since SSH2 allows
511 + * multiple sessions within a single connection.
512 + */
513 +/* ARGSUSED */
514 +void
515 +audit_run_command(const char *command)
517 + debug("adt audit_run_command: \"%s\"", command);
518 + __auditd_debug("%d/%d:%d-adt audit_run_command:ctxt=%p \"%s\"\n",
519 + getpid(), getuid(), geteuid(), (void *)the_authctxt, command);
520 + __audit_pidinfo();
524 + * audit_login - audit successful login
526 + * Entry the_authctxt should be valid ;-)
527 + * and pam_setcred called.
528 + * adt_info & ADT_INFO_PW_SUCCESS if successful
529 + * password change.
531 + * Exit ah = audit session established for audit_logout();
532 + */
533 +static void
534 +audit_login(void)
536 + adt_event_data_t *event;
537 + uid_t uid = ADT_NO_ATTRIB;
538 + gid_t gid = (gid_t)ADT_NO_ATTRIB;
539 + au_id_t auid;
541 + if ((the_authctxt != NULL) && (the_authctxt->valid != 0)) {
542 + uid = the_authctxt->pw->pw_uid;
543 + gid = the_authctxt->pw->pw_gid;
546 + if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
547 + error("adt_start_session: %s", strerror(errno));
548 + return;
551 + adt_get_auid(ah, &auid);
553 + if (adt_set_user(ah, uid, gid, uid, gid, NULL,
554 + auid == AU_NOAUDITID ? ADT_NEW : ADT_USER)) {
555 + error("adt_set_user auid=%d, uid=%d", auid, uid);
556 + (void) adt_end_session(ah);
557 + ah = NULL;
558 + free(tid);
559 + tid = NULL;
560 + return;
562 + if ((event = adt_alloc_event(ah, ADT_ssh)) == NULL) {
563 + error("adt_alloc_event(ADT_ssh): %s", strerror(errno));
564 + return;
566 + if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
567 + error("adt_put_event(ADT_ssh, ADT_SUCCESS): %s",
568 + strerror(errno));
570 + /* should audit successful password change here */
571 + adt_free_event(event);
575 + * audit_logout - audit the logout
577 + * Entry ah = audit session.
578 + */
579 +static void
580 +audit_logout(void)
582 + adt_event_data_t *event;
584 + if ((event = adt_alloc_event(ah, ADT_logout)) == NULL) {
585 + error("adt_alloc_event(ADT_logout): %s", strerror(errno));
586 + return;
588 + if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
589 + error("adt_put_event(ADT_logout, ADT_SUCCESS): %s",
590 + strerror(errno));
592 + adt_free_event(event);
593 + (void) adt_end_session(ah);
594 + ah = NULL;
598 + * audit_fail - audit login failure.
600 + * Entry the_authctxt assumed to have some info.
601 + * user = user who asked to be authenticated.
602 + * tid = connection audit TID set by audit_connect_from();
604 + * N.B. pam_strerror() prototype takes a pam handle and error number.
605 + * At least on Solaris, pam_strerror never uses the pam handle.
606 + * Since there doesn't seem to be a pam handle available, this
607 + * code just uses NULL.
608 + */
609 +static void
610 +audit_fail(int pamerr)
612 + adt_session_data_t *ah = NULL;
613 + adt_event_data_t *event;
614 + uid_t uid = ADT_NO_ATTRIB;
615 + gid_t gid = (gid_t)ADT_NO_ATTRIB;
617 + __auditd_debug("%d/%d:%d-audit_fail(%s) ctxt=%p\n",
618 + getpid(), getuid(), geteuid(), pam_strerror(NULL, pamerr),
619 + (void *)the_authctxt);
620 + if (the_authctxt != NULL) {
621 + uid_t pwuid = ADT_NO_ATTRIB;
623 + if (the_authctxt->pw != NULL) {
624 + pwuid = the_authctxt->pw->pw_uid;
626 + __auditd_debug("valid=%d, user=%s, uid=%d\n",
627 + the_authctxt->valid, audit_username(), pwuid);
628 + } else {
629 + __auditd_debug("\tNo autxctxt\n");
631 + __audit_pidinfo();
632 + if (pamerr == PAM_IGNORE) {
633 + return;
635 + if ((the_authctxt != NULL) && (the_authctxt->valid != 0)) {
636 + uid = the_authctxt->pw->pw_uid;
637 + gid = the_authctxt->pw->pw_gid;
638 + } else if ((the_authctxt != NULL) && (the_authctxt->user != NULL)) {
639 + struct passwd *pw;
641 + if ((pw = getpwnam(the_authctxt->user)) != NULL) {
642 + uid = pw->pw_uid;
643 + gid = pw->pw_gid;
646 + if (adt_start_session(&ah, NULL, 0) != 0) {
647 + error("adt_start_session(ADT_ssh, 0, fail=%s):"
648 + " %s", pam_strerror(NULL, pamerr), strerror(errno));
649 + __auditd_debug("%d/%d:%d-adt_start_session(ADT_ssh, "
650 + "PROC_DATA, fail=%s): %s", getpid(), getuid(),
651 + geteuid(), pam_strerror(NULL, pamerr),
652 + strerror(errno));
653 + return;
655 + __auditd_debug("%d/%d:%d-audit_fail+start_session() ah=%p\n",
656 + getpid(), getuid(), geteuid(), (void *)ah);
657 + if (adt_set_user(ah, uid, gid, uid, gid, tid, ADT_NEW) != 0) {
658 + error("adt_set_user(ADT_ssh, PROC_DATA, fail=%s): %s",
659 + pam_strerror(NULL, pamerr), strerror(errno));
660 + __auditd_debug("%d/%d:%d-adt_set_user(ADT_ssh, "
661 + "PROC_DATA, fail=%s): %s", getpid(), getuid(),
662 + geteuid(), pam_strerror(NULL, pamerr),
663 + strerror(errno));
664 + goto done;
666 + __auditd_debug("%d/%d:%d-audit_fail+set_user() ah=%p\n", getpid(),
667 + getuid(), geteuid(), (void *)ah);
668 + if ((event = adt_alloc_event(ah, ADT_ssh)) == NULL) {
669 + error("adt_alloc_event(ADT_ssh, fail=%s): %s",
670 + pam_strerror(NULL, pamerr), strerror(errno));
671 + __auditd_debug("%d/%d:%d-adt_set_user(ADT_ssh, 0, "
672 + "fail=%s): %s", getpid(), getuid(), geteuid(),
673 + pam_strerror(NULL, pamerr), strerror(errno));
674 + } else if (adt_put_event(event, ADT_FAILURE,
675 + ADT_FAIL_PAM + pamerr) != 0) {
676 + error("adt_put_event(ADT_ssh, fail=%s): %s",
677 + pam_strerror(NULL, pamerr), strerror(errno));
678 + __auditd_debug("%d/%d:%d-adt_put_event(ADT_ssh, fail=%s): %s",
679 + getpid(), getuid(), geteuid(), pam_strerror(NULL, pamerr),
680 + strerror(errno));
682 + __auditd_debug("%d/%d:%d-audit_fail+put_event() ah=%p\n", getpid(),
683 + getuid(), geteuid(), (void *)ah);
684 + /* should audit authentication with failed password change here. */
685 + adt_free_event(event);
686 +done:
687 + (void) adt_end_session(ah);
689 +#endif /* USE_SOLARIS_AUDIT */
690 diff --git a/configure.ac b/configure.ac
691 index 5dceabd..4192a45 100644
692 --- a/configure.ac
693 +++ b/configure.ac
694 @@ -1551,7 +1551,7 @@ AC_ARG_WITH([libedit],
696 AUDIT_MODULE=none
697 AC_ARG_WITH([audit],
698 - [ --with-audit=module Enable audit support (modules=debug,bsm,linux)],
699 + [ --with-audit=module Enable audit support (modules=debug,bsm,linux,solaris)],
701 AC_MSG_CHECKING([for supported audit module])
702 case "$withval" in
703 @@ -1588,6 +1588,13 @@ AC_ARG_WITH([audit],
704 SSHDLIBS="$SSHDLIBS -laudit"
705 AC_DEFINE([USE_LINUX_AUDIT], [1], [Use Linux audit module])
707 + solaris)
708 + AC_MSG_RESULT([solaris])
709 + AUDIT_MODULE=solaris
710 + AC_CHECK_HEADERS([bsm/adt.h])
711 + SSHDLIBS="$SSHDLIBS -lbsm"
712 + AC_DEFINE([USE_SOLARIS_AUDIT], [1], [Use Solaris audit module])
713 + ;;
714 debug)
715 AUDIT_MODULE=debug
716 AC_MSG_RESULT([debug])
717 diff --git a/defines.h b/defines.h
718 index a438ddd..6196188 100644
719 --- a/defines.h
720 +++ b/defines.h
721 @@ -635,6 +635,11 @@ struct winsize {
722 # define CUSTOM_SSH_AUDIT_EVENTS
723 #endif
725 +#ifdef USE_SOLARIS_AUDIT
726 +# define SSH_AUDIT_EVENTS
727 +# define CUSTOM_SSH_AUDIT_EVENTS
728 +#endif
730 #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__)
731 # define __func__ __FUNCTION__
732 #elif !defined(HAVE___func__)
733 diff --git a/sshd.c b/sshd.c
734 index 418e1fd..37cb5fa 100644
735 --- a/sshd.c
736 +++ b/sshd.c
737 @@ -2234,7 +2234,9 @@ main(int ac, char **av)
740 #ifdef SSH_AUDIT_EVENTS
741 +#ifndef USE_SOLARIS_AUDIT
742 audit_event(SSH_AUTH_SUCCESS);
743 +#endif /* !USE_SOLARIS_AUDIT */
744 #endif
746 #ifdef GSSAPI
747 @@ -2264,6 +2266,10 @@ main(int ac, char **av)
748 do_pam_session();
750 #endif
751 +#ifdef USE_SOLARIS_AUDIT
752 + /* Audit should take place after all successful pam */
753 + audit_event(SSH_AUTH_SUCCESS);
754 +#endif /* USE_SOLARIS_AUDIT */
757 * In privilege separation, we fork another child and prepare
759 2.5.4 (Apple Git-61)