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