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 } 317