1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  *
  21  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  22  * Use is subject to license terms.
  23  *
  24  * usr/src/cmd/ssh/sshd/bsmaudit.c
  25  *
  26  * Taken from the on81 usr/src/lib/libbsm/common/audit_login.c
  27  */
  28 #include "includes.h"
  29 
  30 #include <sys/systeminfo.h>
  31 #include <sys/param.h>
  32 #include <sys/types.h>
  33 #include <sys/socket.h>
  34 #include <sys/systeminfo.h>
  35 #include <sys/stat.h>
  36 #include <sys/wait.h>
  37 #include <netinet/in.h>
  38 #include <netdb.h>
  39 #include <signal.h>
  40 
  41 #include <stdarg.h>
  42 #include <pwd.h>
  43 #include <shadow.h>
  44 #include <utmpx.h>
  45 #include <unistd.h>
  46 #include <string.h>
  47 
  48 #include <locale.h>
  49 
  50 #include "log.h"
  51 #include "packet.h"
  52 #include "canohost.h"
  53 #include "servconf.h"
  54 #include "xmalloc.h"
  55 #include <errno.h>
  56 #include <bsm/adt.h>
  57 #include <bsm/adt_event.h>
  58 
  59 extern uint_t utmp_len; /* XXX - Yuck; we'll keep this for now */
  60 extern ServerOptions options;
  61         /*
  62          * XXX - Yuck; we should have a
  63          * get_client_name_or_ip that does the
  64          * right thing wrt reverse lookups
  65          */
  66 
  67 void
  68 audit_sshd_chauthtok(int pam_retval, uid_t uid, gid_t gid)
  69 {
  70         adt_session_data_t      *ah     = NULL;
  71         adt_event_data_t        *event  = NULL;
  72         const char              *how = "couldn't start adt session";
  73         int                     saved_errno = 0;
  74 
  75         if (adt_start_session(&ah, NULL, 0) != 0) {
  76                 saved_errno = errno;
  77                 goto fail;
  78         }
  79         if (adt_set_user(ah, uid, gid, uid, gid, NULL, ADT_NEW) != 0) {
  80                 saved_errno = errno;
  81                 how = "couldn't set adt user";
  82                 goto fail;
  83         }
  84 
  85         if ((event = adt_alloc_event(ah, ADT_passwd)) == NULL) {
  86                 saved_errno = errno;
  87                 how = "couldn't allocate adt event";
  88                 goto fail;
  89         }
  90 
  91         if (pam_retval == PAM_SUCCESS) {
  92                 if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
  93                         saved_errno = errno;
  94                         how = "couldn't put adt event";
  95                         goto fail;
  96                 }
  97         } else if (adt_put_event(event, ADT_FAILURE,
  98             ADT_FAIL_PAM + pam_retval) != 0) {
  99                 saved_errno = errno;
 100                 how = "couldn't put adt event";
 101                 goto fail;
 102         }
 103 
 104         adt_free_event(event);
 105         (void) adt_end_session(ah);
 106         return;
 107 
 108 fail:
 109         adt_free_event(event);
 110         (void) adt_end_session(ah);
 111 
 112         fatal("Auditing of password change failed: %s (%s)",
 113             strerror(saved_errno), how);
 114 }
 115 
 116 void
 117 audit_sshd_login(adt_session_data_t **ah, pid_t pid)
 118 {
 119         adt_event_data_t        *event  = NULL;
 120         const char              *how;
 121         int                     saved_errno = 0;
 122         ucred_t                 *ucred = NULL;
 123 
 124         if (ah == NULL) {
 125                 how = "programmer error";
 126                 saved_errno = EINVAL;
 127                 goto fail;
 128         }
 129 
 130         if (adt_start_session(ah, NULL, 0) != 0) {
 131                 saved_errno = errno;
 132                 how = "couldn't start adt session";
 133                 goto fail;
 134         }
 135 
 136         if ((ucred = ucred_get(pid)) == NULL) {
 137                 saved_errno = errno;
 138                 how = "ucred_get() failed to obtain user credential";
 139                 goto fail;
 140         }
 141 
 142         if (adt_set_from_ucred(*ah, ucred, ADT_NEW)) {
 143                 saved_errno = errno;
 144                 how = "adt_set_from_ucred() failed to set user credential";
 145                 goto fail;
 146         }
 147 
 148         if ((event = adt_alloc_event(*ah, ADT_ssh)) == NULL) {
 149                 saved_errno = errno;
 150                 how = "couldn't allocate adt event";
 151                 goto fail;
 152         }
 153 
 154         if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
 155                 saved_errno = errno;
 156                 how = "couldn't put adt event";
 157                 goto fail;
 158         }
 159 
 160         adt_free_event(event);
 161         ucred_free(ucred);
 162         /* Don't end adt session - leave for when logging out */
 163         return;
 164 
 165 fail:
 166         if (ucred != NULL)
 167                 ucred_free(ucred);
 168         adt_free_event(event);
 169         (void) adt_end_session(*ah);
 170 
 171         fatal("Auditing of login failed: %s (%s)",
 172             strerror(saved_errno), how);
 173 }
 174 
 175 void
 176 audit_sshd_login_failure(adt_session_data_t **ah, int pam_retval, char *user)
 177 {
 178         adt_event_data_t        *event  = NULL;
 179         const char              *how;
 180         int                     saved_errno = 0;
 181         struct passwd           pwd;
 182         char                    *pwdbuf = NULL;
 183         size_t                  pwdbuf_len;
 184         long                    pwdbuf_len_max;
 185         uid_t                   uid = ADT_NO_ATTRIB;
 186         gid_t                   gid = ADT_NO_ATTRIB;
 187 
 188         if (ah == NULL) {
 189                 how = "programmer error";
 190                 saved_errno = EINVAL;
 191                 goto fail;
 192         }
 193 
 194         if ((pwdbuf_len_max = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) {
 195                 saved_errno = errno;
 196                 how = "couldn't determine maximum size of password buffer";
 197                 goto fail;
 198         }
 199 
 200         pwdbuf_len = (size_t)pwdbuf_len_max;
 201         pwdbuf = xmalloc(pwdbuf_len);
 202 
 203         if (adt_start_session(ah, NULL, ADT_USE_PROC_DATA) != 0) {
 204                 saved_errno = errno;
 205                 how = "couldn't start adt session";
 206                 goto fail;
 207         }
 208 
 209         /*
 210          * Its possible to reach this point with user being invalid so
 211          * we check here to make sure that the user in question has a valid
 212          * password entry.
 213          */
 214         if ((user != NULL) &&
 215             (getpwnam_r(user, &pwd, pwdbuf, pwdbuf_len) != NULL)) {
 216                 uid = pwd.pw_uid;
 217                 gid = pwd.pw_gid;
 218         }
 219 
 220         if (adt_set_user(*ah, uid, gid, uid, gid, NULL, ADT_NEW) != 0) {
 221                 saved_errno = errno;
 222                 how = "couldn't set adt user";
 223                 goto fail;
 224         }
 225 
 226         if ((event = adt_alloc_event(*ah, ADT_ssh)) == NULL) {
 227                 saved_errno = errno;
 228                 how = "couldn't allocate adt event";
 229                 goto fail;
 230         }
 231 
 232         if (adt_put_event(event, ADT_FAILURE, ADT_FAIL_PAM + pam_retval) != 0) {
 233                 saved_errno = errno;
 234                 how = "couldn't put adt event";
 235                 goto fail;
 236         }
 237 
 238         xfree(pwdbuf);
 239         adt_free_event(event);
 240         (void) adt_end_session(*ah);
 241         *ah = NULL;
 242         return;
 243 
 244 fail:
 245         if (pwdbuf != NULL)
 246                 xfree(pwdbuf);
 247         adt_free_event(event);
 248         (void) adt_end_session(*ah);
 249 
 250         fatal("Auditing of login failed: %s (%s)",
 251             strerror(saved_errno), how);
 252 }
 253 
 254 void
 255 audit_sshd_logout(adt_session_data_t **ah)
 256 {
 257         adt_event_data_t        *event  = NULL;
 258         const char              *how = "programmer error";
 259         int                     saved_errno = 0;
 260 
 261         if (!ah) {
 262                 saved_errno = EINVAL;
 263                 goto fail;
 264         }
 265 
 266         if ((event = adt_alloc_event(*ah, ADT_logout)) == NULL) {
 267                 saved_errno = errno;
 268                 how = "couldn't allocate adt event";
 269                 goto fail;
 270         }
 271 
 272         if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
 273                 saved_errno = errno;
 274                 how = "couldn't put adt event";
 275                 goto fail;
 276         }
 277 
 278         adt_free_event(event);
 279         (void) adt_end_session(*ah);
 280         *ah = NULL;
 281         return;
 282 
 283 fail:
 284         adt_free_event(event);
 285         (void) adt_end_session(*ah);
 286 
 287         fatal("Auditing of logout failed: %s (%s)",
 288             how, strerror(saved_errno));
 289 }
 290 
 291 /*
 292  * audit_sshd_settid stores the terminal id while it is still
 293  * available.
 294  *
 295  * The failure cases are lack of resources or incorrect permissions.
 296  * libbsm generates syslog messages, so there's no value doing more
 297  * here.  ADT_NO_AUDIT leaves the auid at AU_NOAUDITID and will be
 298  * replaced when one of the above functions is called.
 299  */
 300 void
 301 audit_sshd_settid(int sock)
 302 {
 303         adt_session_data_t      *ah;
 304         adt_termid_t            *termid;
 305 
 306         if (adt_start_session(&ah, NULL, 0) == 0) {
 307                 if (adt_load_termid(sock, &termid) == 0) {
 308                         if (adt_set_user(ah, ADT_NO_AUDIT,
 309                             ADT_NO_AUDIT, 0, ADT_NO_AUDIT,
 310                             termid, ADT_SETTID) == 0)
 311                                 (void) adt_set_proc(ah);
 312                         free(termid);
 313                 }
 314                 (void) adt_end_session(ah);
 315         }
 316 }