17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*bca3984eSBrent Paulson * Common Development and Distribution License (the "License").
6*bca3984eSBrent Paulson * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate *
21*bca3984eSBrent Paulson * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
227c478bd9Sstevel@tonic-gate * Use is subject to license terms.
237c478bd9Sstevel@tonic-gate *
247c478bd9Sstevel@tonic-gate * usr/src/cmd/ssh/sshd/bsmaudit.c
257c478bd9Sstevel@tonic-gate *
267c478bd9Sstevel@tonic-gate * Taken from the on81 usr/src/lib/libbsm/common/audit_login.c
277c478bd9Sstevel@tonic-gate */
287c478bd9Sstevel@tonic-gate #include "includes.h"
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
317c478bd9Sstevel@tonic-gate #include <sys/param.h>
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <sys/socket.h>
347c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
357c478bd9Sstevel@tonic-gate #include <sys/stat.h>
367c478bd9Sstevel@tonic-gate #include <sys/wait.h>
377c478bd9Sstevel@tonic-gate #include <netinet/in.h>
387c478bd9Sstevel@tonic-gate #include <netdb.h>
397c478bd9Sstevel@tonic-gate #include <signal.h>
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate #include <stdarg.h>
427c478bd9Sstevel@tonic-gate #include <pwd.h>
437c478bd9Sstevel@tonic-gate #include <shadow.h>
447c478bd9Sstevel@tonic-gate #include <utmpx.h>
457c478bd9Sstevel@tonic-gate #include <unistd.h>
467c478bd9Sstevel@tonic-gate #include <string.h>
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate #include <locale.h>
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate #include "log.h"
517c478bd9Sstevel@tonic-gate #include "packet.h"
527c478bd9Sstevel@tonic-gate #include "canohost.h"
537c478bd9Sstevel@tonic-gate #include "servconf.h"
54*bca3984eSBrent Paulson #include "xmalloc.h"
557c478bd9Sstevel@tonic-gate #include <errno.h>
567c478bd9Sstevel@tonic-gate #include <bsm/adt.h>
577c478bd9Sstevel@tonic-gate #include <bsm/adt_event.h>
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate extern uint_t utmp_len; /* XXX - Yuck; we'll keep this for now */
607c478bd9Sstevel@tonic-gate extern ServerOptions options;
617c478bd9Sstevel@tonic-gate /*
627c478bd9Sstevel@tonic-gate * XXX - Yuck; we should have a
637c478bd9Sstevel@tonic-gate * get_client_name_or_ip that does the
647c478bd9Sstevel@tonic-gate * right thing wrt reverse lookups
657c478bd9Sstevel@tonic-gate */
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate void
audit_sshd_chauthtok(int pam_retval,uid_t uid,gid_t gid)687c478bd9Sstevel@tonic-gate audit_sshd_chauthtok(int pam_retval, uid_t uid, gid_t gid)
697c478bd9Sstevel@tonic-gate {
707c478bd9Sstevel@tonic-gate adt_session_data_t *ah = NULL;
717c478bd9Sstevel@tonic-gate adt_event_data_t *event = NULL;
727c478bd9Sstevel@tonic-gate const char *how = "couldn't start adt session";
737c478bd9Sstevel@tonic-gate int saved_errno = 0;
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate if (adt_start_session(&ah, NULL, 0) != 0) {
767c478bd9Sstevel@tonic-gate saved_errno = errno;
777c478bd9Sstevel@tonic-gate goto fail;
787c478bd9Sstevel@tonic-gate }
797c478bd9Sstevel@tonic-gate if (adt_set_user(ah, uid, gid, uid, gid, NULL, ADT_NEW) != 0) {
807c478bd9Sstevel@tonic-gate saved_errno = errno;
817c478bd9Sstevel@tonic-gate how = "couldn't set adt user";
827c478bd9Sstevel@tonic-gate goto fail;
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate if ((event = adt_alloc_event(ah, ADT_passwd)) == NULL) {
867c478bd9Sstevel@tonic-gate saved_errno = errno;
877c478bd9Sstevel@tonic-gate how = "couldn't allocate adt event";
887c478bd9Sstevel@tonic-gate goto fail;
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate if (pam_retval == PAM_SUCCESS) {
927c478bd9Sstevel@tonic-gate if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
937c478bd9Sstevel@tonic-gate saved_errno = errno;
947c478bd9Sstevel@tonic-gate how = "couldn't put adt event";
957c478bd9Sstevel@tonic-gate goto fail;
967c478bd9Sstevel@tonic-gate }
977c478bd9Sstevel@tonic-gate } else if (adt_put_event(event, ADT_FAILURE,
987c478bd9Sstevel@tonic-gate ADT_FAIL_PAM + pam_retval) != 0) {
997c478bd9Sstevel@tonic-gate saved_errno = errno;
1007c478bd9Sstevel@tonic-gate how = "couldn't put adt event";
1017c478bd9Sstevel@tonic-gate goto fail;
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate adt_free_event(event);
1057c478bd9Sstevel@tonic-gate (void) adt_end_session(ah);
1067c478bd9Sstevel@tonic-gate return;
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate fail:
1097c478bd9Sstevel@tonic-gate adt_free_event(event);
1107c478bd9Sstevel@tonic-gate (void) adt_end_session(ah);
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate fatal("Auditing of password change failed: %s (%s)",
1137c478bd9Sstevel@tonic-gate strerror(saved_errno), how);
1147c478bd9Sstevel@tonic-gate }
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate void
audit_sshd_login(adt_session_data_t ** ah,pid_t pid)117*bca3984eSBrent Paulson audit_sshd_login(adt_session_data_t **ah, pid_t pid)
1187c478bd9Sstevel@tonic-gate {
1197c478bd9Sstevel@tonic-gate adt_event_data_t *event = NULL;
120*bca3984eSBrent Paulson const char *how;
1217c478bd9Sstevel@tonic-gate int saved_errno = 0;
122*bca3984eSBrent Paulson ucred_t *ucred = NULL;
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate if (ah == NULL) {
1257c478bd9Sstevel@tonic-gate how = "programmer error";
1267c478bd9Sstevel@tonic-gate saved_errno = EINVAL;
1277c478bd9Sstevel@tonic-gate goto fail;
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
130*bca3984eSBrent Paulson if (adt_start_session(ah, NULL, 0) != 0) {
1317c478bd9Sstevel@tonic-gate saved_errno = errno;
1327c478bd9Sstevel@tonic-gate how = "couldn't start adt session";
1337c478bd9Sstevel@tonic-gate goto fail;
1347c478bd9Sstevel@tonic-gate }
135*bca3984eSBrent Paulson
136*bca3984eSBrent Paulson if ((ucred = ucred_get(pid)) == NULL) {
1377c478bd9Sstevel@tonic-gate saved_errno = errno;
138*bca3984eSBrent Paulson how = "ucred_get() failed to obtain user credential";
1397c478bd9Sstevel@tonic-gate goto fail;
1407c478bd9Sstevel@tonic-gate }
141*bca3984eSBrent Paulson
142*bca3984eSBrent Paulson if (adt_set_from_ucred(*ah, ucred, ADT_NEW)) {
143*bca3984eSBrent Paulson saved_errno = errno;
144*bca3984eSBrent Paulson how = "adt_set_from_ucred() failed to set user credential";
145*bca3984eSBrent Paulson goto fail;
146*bca3984eSBrent Paulson }
147*bca3984eSBrent Paulson
1487c478bd9Sstevel@tonic-gate if ((event = adt_alloc_event(*ah, ADT_ssh)) == NULL) {
1497c478bd9Sstevel@tonic-gate saved_errno = errno;
1507c478bd9Sstevel@tonic-gate how = "couldn't allocate adt event";
1517c478bd9Sstevel@tonic-gate goto fail;
1527c478bd9Sstevel@tonic-gate }
153*bca3984eSBrent Paulson
1547c478bd9Sstevel@tonic-gate if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
1557c478bd9Sstevel@tonic-gate saved_errno = errno;
1567c478bd9Sstevel@tonic-gate how = "couldn't put adt event";
1577c478bd9Sstevel@tonic-gate goto fail;
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate adt_free_event(event);
161*bca3984eSBrent Paulson ucred_free(ucred);
1627c478bd9Sstevel@tonic-gate /* Don't end adt session - leave for when logging out */
1637c478bd9Sstevel@tonic-gate return;
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate fail:
166*bca3984eSBrent Paulson if (ucred != NULL)
167*bca3984eSBrent Paulson ucred_free(ucred);
1687c478bd9Sstevel@tonic-gate adt_free_event(event);
1697c478bd9Sstevel@tonic-gate (void) adt_end_session(*ah);
1707c478bd9Sstevel@tonic-gate
1717c478bd9Sstevel@tonic-gate fatal("Auditing of login failed: %s (%s)",
1727c478bd9Sstevel@tonic-gate strerror(saved_errno), how);
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate
1757c478bd9Sstevel@tonic-gate void
audit_sshd_login_failure(adt_session_data_t ** ah,int pam_retval,char * user)176*bca3984eSBrent Paulson audit_sshd_login_failure(adt_session_data_t **ah, int pam_retval, char *user)
1777c478bd9Sstevel@tonic-gate {
1787c478bd9Sstevel@tonic-gate adt_event_data_t *event = NULL;
179*bca3984eSBrent Paulson const char *how;
1807c478bd9Sstevel@tonic-gate int saved_errno = 0;
181*bca3984eSBrent Paulson struct passwd pwd;
182*bca3984eSBrent Paulson char *pwdbuf = NULL;
183*bca3984eSBrent Paulson size_t pwdbuf_len;
184*bca3984eSBrent Paulson long pwdbuf_len_max;
185*bca3984eSBrent Paulson uid_t uid = ADT_NO_ATTRIB;
186*bca3984eSBrent Paulson gid_t gid = ADT_NO_ATTRIB;
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate if (ah == NULL) {
1897c478bd9Sstevel@tonic-gate how = "programmer error";
1907c478bd9Sstevel@tonic-gate saved_errno = EINVAL;
1917c478bd9Sstevel@tonic-gate goto fail;
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate
194*bca3984eSBrent Paulson if ((pwdbuf_len_max = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) {
195*bca3984eSBrent Paulson saved_errno = errno;
196*bca3984eSBrent Paulson how = "couldn't determine maximum size of password buffer";
197*bca3984eSBrent Paulson goto fail;
198*bca3984eSBrent Paulson }
199*bca3984eSBrent Paulson
200*bca3984eSBrent Paulson pwdbuf_len = (size_t)pwdbuf_len_max;
201*bca3984eSBrent Paulson pwdbuf = xmalloc(pwdbuf_len);
202*bca3984eSBrent Paulson
2037c478bd9Sstevel@tonic-gate if (adt_start_session(ah, NULL, ADT_USE_PROC_DATA) != 0) {
2047c478bd9Sstevel@tonic-gate saved_errno = errno;
2057c478bd9Sstevel@tonic-gate how = "couldn't start adt session";
2067c478bd9Sstevel@tonic-gate goto fail;
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate
209*bca3984eSBrent Paulson /*
210*bca3984eSBrent Paulson * Its possible to reach this point with user being invalid so
211*bca3984eSBrent Paulson * we check here to make sure that the user in question has a valid
212*bca3984eSBrent Paulson * password entry.
213*bca3984eSBrent Paulson */
214*bca3984eSBrent Paulson if ((user != NULL) &&
215*bca3984eSBrent Paulson (getpwnam_r(user, &pwd, pwdbuf, pwdbuf_len) != NULL)) {
216*bca3984eSBrent Paulson uid = pwd.pw_uid;
217*bca3984eSBrent Paulson gid = pwd.pw_gid;
218*bca3984eSBrent Paulson }
219*bca3984eSBrent Paulson
220*bca3984eSBrent Paulson if (adt_set_user(*ah, uid, gid, uid, gid, NULL, ADT_NEW) != 0) {
2217c478bd9Sstevel@tonic-gate saved_errno = errno;
2227c478bd9Sstevel@tonic-gate how = "couldn't set adt user";
2237c478bd9Sstevel@tonic-gate goto fail;
2247c478bd9Sstevel@tonic-gate }
225*bca3984eSBrent Paulson
2267c478bd9Sstevel@tonic-gate if ((event = adt_alloc_event(*ah, ADT_ssh)) == NULL) {
2277c478bd9Sstevel@tonic-gate saved_errno = errno;
2287c478bd9Sstevel@tonic-gate how = "couldn't allocate adt event";
2297c478bd9Sstevel@tonic-gate goto fail;
2307c478bd9Sstevel@tonic-gate }
231*bca3984eSBrent Paulson
2327c478bd9Sstevel@tonic-gate if (adt_put_event(event, ADT_FAILURE, ADT_FAIL_PAM + pam_retval) != 0) {
2337c478bd9Sstevel@tonic-gate saved_errno = errno;
2347c478bd9Sstevel@tonic-gate how = "couldn't put adt event";
2357c478bd9Sstevel@tonic-gate goto fail;
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate
238*bca3984eSBrent Paulson xfree(pwdbuf);
2397c478bd9Sstevel@tonic-gate adt_free_event(event);
2407c478bd9Sstevel@tonic-gate (void) adt_end_session(*ah);
2417c478bd9Sstevel@tonic-gate *ah = NULL;
2427c478bd9Sstevel@tonic-gate return;
2437c478bd9Sstevel@tonic-gate
2447c478bd9Sstevel@tonic-gate fail:
245*bca3984eSBrent Paulson if (pwdbuf != NULL)
246*bca3984eSBrent Paulson xfree(pwdbuf);
2477c478bd9Sstevel@tonic-gate adt_free_event(event);
2487c478bd9Sstevel@tonic-gate (void) adt_end_session(*ah);
2497c478bd9Sstevel@tonic-gate
2507c478bd9Sstevel@tonic-gate fatal("Auditing of login failed: %s (%s)",
2517c478bd9Sstevel@tonic-gate strerror(saved_errno), how);
2527c478bd9Sstevel@tonic-gate }
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate void
audit_sshd_logout(adt_session_data_t ** ah)2557c478bd9Sstevel@tonic-gate audit_sshd_logout(adt_session_data_t **ah)
2567c478bd9Sstevel@tonic-gate {
2577c478bd9Sstevel@tonic-gate adt_event_data_t *event = NULL;
2587c478bd9Sstevel@tonic-gate const char *how = "programmer error";
2597c478bd9Sstevel@tonic-gate int saved_errno = 0;
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate if (!ah) {
2627c478bd9Sstevel@tonic-gate saved_errno = EINVAL;
2637c478bd9Sstevel@tonic-gate goto fail;
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate if ((event = adt_alloc_event(*ah, ADT_logout)) == NULL) {
2677c478bd9Sstevel@tonic-gate saved_errno = errno;
2687c478bd9Sstevel@tonic-gate how = "couldn't allocate adt event";
2697c478bd9Sstevel@tonic-gate goto fail;
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate
2727c478bd9Sstevel@tonic-gate if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
2737c478bd9Sstevel@tonic-gate saved_errno = errno;
2747c478bd9Sstevel@tonic-gate how = "couldn't put adt event";
2757c478bd9Sstevel@tonic-gate goto fail;
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate adt_free_event(event);
2797c478bd9Sstevel@tonic-gate (void) adt_end_session(*ah);
2807c478bd9Sstevel@tonic-gate *ah = NULL;
2817c478bd9Sstevel@tonic-gate return;
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate fail:
2847c478bd9Sstevel@tonic-gate adt_free_event(event);
2857c478bd9Sstevel@tonic-gate (void) adt_end_session(*ah);
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate fatal("Auditing of logout failed: %s (%s)",
2887c478bd9Sstevel@tonic-gate how, strerror(saved_errno));
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate /*
2927c478bd9Sstevel@tonic-gate * audit_sshd_settid stores the terminal id while it is still
2937c478bd9Sstevel@tonic-gate * available.
2947c478bd9Sstevel@tonic-gate *
2957c478bd9Sstevel@tonic-gate * The failure cases are lack of resources or incorrect permissions.
2967c478bd9Sstevel@tonic-gate * libbsm generates syslog messages, so there's no value doing more
2977c478bd9Sstevel@tonic-gate * here. ADT_NO_AUDIT leaves the auid at AU_NOAUDITID and will be
2987c478bd9Sstevel@tonic-gate * replaced when one of the above functions is called.
2997c478bd9Sstevel@tonic-gate */
3007c478bd9Sstevel@tonic-gate void
audit_sshd_settid(int sock)3017c478bd9Sstevel@tonic-gate audit_sshd_settid(int sock)
3027c478bd9Sstevel@tonic-gate {
3037c478bd9Sstevel@tonic-gate adt_session_data_t *ah;
3047c478bd9Sstevel@tonic-gate adt_termid_t *termid;
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate if (adt_start_session(&ah, NULL, 0) == 0) {
3077c478bd9Sstevel@tonic-gate if (adt_load_termid(sock, &termid) == 0) {
3087c478bd9Sstevel@tonic-gate if (adt_set_user(ah, ADT_NO_AUDIT,
3097c478bd9Sstevel@tonic-gate ADT_NO_AUDIT, 0, ADT_NO_AUDIT,
3107c478bd9Sstevel@tonic-gate termid, ADT_SETTID) == 0)
3117c478bd9Sstevel@tonic-gate (void) adt_set_proc(ah);
3127c478bd9Sstevel@tonic-gate free(termid);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate (void) adt_end_session(ah);
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate }
317