xref: /titanic_44/usr/src/cmd/ssh/sshd/bsmaudit.c (revision bca3984e29c8c75c0e473a3f1134d686db15e937)
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