xref: /titanic_41/usr/src/cmd/ssh/sshd/bsmaudit.c (revision bca3984e29c8c75c0e473a3f1134d686db15e937)
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
audit_sshd_chauthtok(int pam_retval,uid_t uid,gid_t gid)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
audit_sshd_login(adt_session_data_t ** ah,pid_t pid)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
audit_sshd_login_failure(adt_session_data_t ** ah,int pam_retval,char * user)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
audit_sshd_logout(adt_session_data_t ** ah)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
audit_sshd_settid(int sock)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