xref: /illumos-gate/usr/src/cmd/smserverd/myaudit.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 
27 #include <netdb.h>
28 #include <netinet/in.h>
29 #include <pwd.h>
30 #include <sys/errno.h>
31 #include <sys/mutex.h>
32 #include <sys/param.h>
33 #include <sys/socket.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include <stdlib.h>
39 #include <sys/smedia.h>
40 #include <tsol/label.h>
41 #include "smserver.h"
42 #include <bsm/audit.h>
43 #include <bsm/libbsm.h>
44 #include <bsm/audit_uevents.h>
45 #include <bsm/audit_record.h>
46 
47 /* Private Functions */
48 static int selected(au_event_t, au_mask_t *, int);
49 
50 static int audit_selected(door_data_t *);
51 static int audit_na_selected(door_data_t *);
52 static int audit_save_namask(door_data_t *door_dp);
53 static int audit_save_policy(door_data_t *door_dp);
54 
55 /*
56  * can_audit:
57  *	Return 1 if audit module is loaded.
58  *	Return 0 otherwise.
59  *
60  */
61 int
62 can_audit(void)
63 {
64 	static int auc = AUC_UNSET;
65 	int cond = 0;
66 
67 	if (auditon(A_GETCOND, (caddr_t)&cond, sizeof (cond))) {
68 		auc = AUC_DISABLED;
69 	} else {
70 		auc = cond;
71 	}
72 	if (auc == AUC_DISABLED)
73 		return (0);
74 	else return (1);
75 }
76 
77 static int
78 audit_save_policy(door_data_t *door_dp)
79 {
80 	int policy;
81 
82 	if (auditon(A_GETPOLICY, (caddr_t)&policy, sizeof (policy))) {
83 		return (-1);
84 	}
85 	door_dp->audit_policy = policy;
86 	return (0);
87 }
88 
89 /*
90  * audit_init():
91  *	Initialize variables.
92  */
93 void
94 audit_init(door_data_t *door_dp)
95 {
96 	door_dp->audit_auid = (uid_t)-1;
97 	door_dp->audit_uid = (uid_t)-1;
98 	door_dp->audit_euid = (uid_t)-1;
99 	door_dp->audit_gid = (gid_t)-1;
100 	door_dp->audit_egid = (gid_t)-1;
101 	door_dp->audit_pid = -1;
102 	door_dp->audit_tid.at_port = 0;
103 	door_dp->audit_tid.at_type = 0;
104 	door_dp->audit_tid.at_addr[0] = 0;
105 	door_dp->audit_tid.at_addr[1] = 0;
106 	door_dp->audit_tid.at_addr[2] = 0;
107 	door_dp->audit_tid.at_addr[3] = 0;
108 	door_dp->audit_namask.am_success = (int)-1;
109 	door_dp->audit_namask.am_failure = (int)-1;
110 	door_dp->audit_event = 0;
111 	door_dp->audit_sorf = -2;
112 	door_dp->audit_user = NULL;
113 	door_dp->audit_text[0] = NULL;
114 	door_dp->audit_text1[0] = NULL;
115 	door_dp->audit_na = 0;
116 	door_dp->audit_asid = (au_asid_t)(-1);
117 	door_dp->audit_path = NULL;
118 }
119 
120 int
121 audit_save_me(door_data_t	*door_dp)
122 {
123 	door_cred_t	client_cred;
124 	int		ret_val;
125 	int		i;
126 
127 	ret_val = door_cred(&client_cred);
128 	if (ret_val == -1)
129 		return (ret_val);
130 	door_dp->audit_ap.ap_pid = client_cred.dc_pid;
131 	ret_val = auditon(A_GETPINFO_ADDR, (caddr_t)&door_dp->audit_ap,
132 		sizeof (door_dp->audit_ap));
133 	if (ret_val == -1)
134 		return (ret_val);
135 
136 	door_dp->audit_auid = door_dp->audit_ap.ap_auid;
137 	door_dp->audit_euid = client_cred.dc_euid;
138 	door_dp->audit_egid = client_cred.dc_egid;
139 	door_dp->audit_uid = client_cred.dc_ruid;
140 	door_dp->audit_gid = client_cred.dc_rgid;
141 	door_dp->audit_pid = client_cred.dc_pid;
142 	door_dp->audit_asid = door_dp->audit_ap.ap_asid;
143 	door_dp->audit_tid.at_port = door_dp->audit_ap.ap_termid.at_port;
144 	door_dp->audit_tid.at_type = door_dp->audit_ap.ap_termid.at_type;
145 	for (i = 0; i < (door_dp->audit_ap.ap_termid.at_type/4); i++)
146 		door_dp->audit_tid.at_addr[i] =
147 			door_dp->audit_ap.ap_termid.at_addr[i];
148 	(void) audit_save_policy(door_dp);
149 	return (0);
150 }
151 
152 /*
153  * audit_save_namask():
154  *	Save the namask using the naflags entry in the audit_control file.
155  *	Return 0 if successful.
156  *	Return -1, and don't change the namask, if failed.
157  *	Side Effect: Sets audit_na to -1 if error, 1 if successful.
158  */
159 static int
160 audit_save_namask(door_data_t *door_dp)
161 {
162 	au_mask_t mask;
163 
164 	door_dp->audit_na = -1;
165 
166 	/*
167 	 * get non-attributable system event mask from kernel.
168 	 */
169 	if (auditon(A_GETKMASK, (caddr_t)&mask, sizeof (mask)) != 0) {
170 		return (-1);
171 	}
172 
173 	door_dp->audit_namask.am_success = mask.am_success;
174 	door_dp->audit_namask.am_failure = mask.am_failure;
175 	door_dp->audit_na = 1;
176 	return (0);
177 }
178 
179 /*
180  * audit_audit:
181  *	Cut and audit record if it is selected.
182  *	Return 0, if successfully written.
183  *	Return 0, if not written, and not expected to write.
184  *	Return -1, if not written because of unexpected error.
185  */
186 int
187 audit_audit(door_data_t *door_dp)
188 {
189 	int ad;
190 
191 	if (can_audit() == 0) {
192 		return (0);
193 	}
194 
195 	if (door_dp->audit_na) {
196 		if (!audit_na_selected(door_dp)) {
197 			return (0);
198 		}
199 	} else if (!audit_selected(door_dp)) {
200 		return (0);
201 	}
202 
203 	if ((ad = au_open()) == -1) {
204 		return (-1);
205 	}
206 
207 	(void) au_write(ad, au_to_subject_ex(door_dp->audit_auid,
208 		door_dp->audit_euid,
209 		door_dp->audit_egid,
210 		door_dp->audit_uid, door_dp->audit_gid, door_dp->audit_pid,
211 		door_dp->audit_asid, &door_dp->audit_tid));
212 	if (is_system_labeled())
213 		(void) au_write(ad, au_to_mylabel());
214 	if (door_dp->audit_policy & AUDIT_GROUP) {
215 
216 		int ng;
217 		gid_t grplst[NGROUPS_MAX];
218 
219 		(void) memset(grplst, 0, sizeof (grplst));
220 		if ((ng = getgroups(NGROUPS_UMAX, grplst))) {
221 			(void) au_write(ad, au_to_newgroups(ng, grplst));
222 		}
223 	}
224 	if (strlen(door_dp->audit_text) != 0) {
225 		(void) au_write(ad, au_to_text(door_dp->audit_text));
226 	}
227 	if (strlen(door_dp->audit_text1) != 0) {
228 		(void) au_write(ad, au_to_text(door_dp->audit_text1));
229 	}
230 	if (door_dp->audit_path != NULL) {
231 		(void) au_write(ad, au_to_path(door_dp->audit_path));
232 	}
233 #ifdef _LP64
234 	(void) au_write(ad, au_to_return64((door_dp->audit_sorf == 0) ? 0 : -1,
235 		(int64_t)door_dp->audit_sorf));
236 #else
237 	(void) au_write(ad, au_to_return32((door_dp->audit_sorf == 0) ? 0 : -1,
238 		(int32_t)door_dp->audit_sorf));
239 #endif
240 	if (au_close(ad, 1, door_dp->audit_event) < 0) {
241 		(void) au_close(ad, 0, 0);
242 		return (-1);
243 	}
244 
245 	return (0);
246 }
247 
248 static int
249 audit_na_selected(door_data_t *door_dp)
250 {
251 	if (door_dp->audit_na == -1) {
252 		return (-1);
253 	}
254 
255 	return (selected(door_dp->audit_event,
256 		&door_dp->audit_namask, door_dp->audit_sorf));
257 }
258 
259 static int
260 audit_selected(door_data_t *door_dp)
261 {
262 
263 	if (door_dp->audit_uid > MAXUID) {
264 		(void) audit_save_namask(door_dp);
265 		return (audit_na_selected(door_dp));
266 	}
267 
268 	return (selected(door_dp->audit_event,
269 		&door_dp->audit_ap.ap_mask, door_dp->audit_sorf));
270 }
271 
272 static int
273 selected(au_event_t e, au_mask_t *m, int sorf)
274 {
275 	int prs_sorf;
276 
277 	if (sorf == 0) {
278 		prs_sorf = AU_PRS_SUCCESS;
279 	} else if (sorf == -1) {
280 		prs_sorf = AU_PRS_FAILURE;
281 	} else {
282 		prs_sorf = AU_PRS_BOTH;
283 	}
284 
285 	return (au_preselect(e, m, prs_sorf, AU_PRS_REREAD));
286 }
287