xref: /titanic_50/usr/src/lib/libbsm/common/audit_ftpd.c (revision 554ff184129088135ad2643c1c9832174a17be88)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/types.h>
30 #include <stdio.h>
31 #include <sys/fcntl.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <syslog.h>
35 #include <unistd.h>
36 
37 #include <sys/socket.h>
38 #include <sys/sockio.h>
39 #include <netinet/in.h>
40 
41 #include <bsm/audit.h>
42 #include <bsm/audit_record.h>
43 #include <bsm/audit_uevents.h>
44 #include <bsm/libbsm.h>
45 #include <bsm/audit_private.h>
46 
47 #include <locale.h>
48 #include <pwd.h>
49 #include <generic.h>
50 
51 #define	BAD_PASSWD	(1)
52 #define	UNKNOWN_USER	(2)
53 #define	EXCLUDED_USER	(3)
54 #define	NO_ANONYMOUS	(4)
55 #define	MISC_FAILURE	(5)
56 
57 static char		luser[16];
58 
59 static void generate_record(char *, int, char *);
60 static int selected(uid_t, char *, au_event_t, int);
61 
62 void
63 audit_ftpd_bad_pw(char *uname)
64 {
65 	if (cannot_audit(0)) {
66 		return;
67 	}
68 	(void) strncpy(luser, uname, 8);
69 	luser[8] = '\0';
70 	generate_record(luser, BAD_PASSWD, dgettext(bsm_dom,
71 		"bad password"));
72 }
73 
74 
75 void
76 audit_ftpd_unknown(char	*uname)
77 {
78 	if (cannot_audit(0)) {
79 		return;
80 	}
81 	(void) strncpy(luser, uname, 8);
82 	luser[8] = '\0';
83 	generate_record(luser, UNKNOWN_USER, dgettext(bsm_dom,
84 		"unknown user"));
85 }
86 
87 
88 void
89 audit_ftpd_excluded(char *uname)
90 {
91 	if (cannot_audit(0)) {
92 		return;
93 	}
94 	(void) strncpy(luser, uname, 8);
95 	luser[8] = '\0';
96 	generate_record(luser, EXCLUDED_USER, dgettext(bsm_dom,
97 		"excluded user"));
98 }
99 
100 
101 void
102 audit_ftpd_no_anon(void)
103 {
104 	if (cannot_audit(0)) {
105 		return;
106 	}
107 	generate_record("", NO_ANONYMOUS, dgettext(bsm_dom,
108 		"no anonymous"));
109 }
110 
111 void
112 audit_ftpd_failure(char *uname)
113 {
114 	if (cannot_audit(0)) {
115 		return;
116 	}
117 	generate_record(uname, MISC_FAILURE, dgettext(bsm_dom,
118 		"misc failure"));
119 }
120 
121 void
122 audit_ftpd_success(char	*uname)
123 {
124 	if (cannot_audit(0)) {
125 		return;
126 	}
127 	(void) strncpy(luser, uname, 8);
128 	luser[8] = '\0';
129 	generate_record(luser, 0, "");
130 }
131 
132 
133 
134 static void
135 generate_record(
136 		char	*locuser,	/* username of local user */
137 		int	err,		/* error status */
138 					/* (=0 success, >0 error code) */
139 		char	*msg)		/* error message */
140 {
141 	int	rd;		/* audit record descriptor */
142 	char	buf[256];	/* temporary buffer */
143 	uid_t	uid;
144 	gid_t	gid;
145 	uid_t	ruid;		/* real uid */
146 	gid_t	rgid;		/* real gid */
147 	pid_t	pid;
148 	struct passwd *pwd;
149 	uid_t	ceuid;		/* current effective uid */
150 	struct auditinfo_addr info;
151 
152 	if (cannot_audit(0)) {
153 		return;
154 	}
155 
156 	pwd = getpwnam(locuser);
157 	if (pwd == NULL) {
158 		uid = -1;
159 		gid = -1;
160 	} else {
161 		uid = pwd->pw_uid;
162 		gid = pwd->pw_gid;
163 	}
164 
165 	ceuid = geteuid();	/* save current euid */
166 	(void) seteuid(0);	/* change to root so you can audit */
167 
168 	/* determine if we're preselected */
169 	if (!selected(uid, locuser, AUE_ftpd, err)) {
170 		(void) seteuid(ceuid);
171 		return;
172 	}
173 
174 	ruid = getuid();	/* get real uid */
175 	rgid = getgid();	/* get real gid */
176 
177 	pid = getpid();
178 
179 	/* see if terminal id already set */
180 	if (getaudit_addr(&info, sizeof (info)) < 0) {
181 		perror("getaudit");
182 	}
183 
184 	rd = au_open();
185 
186 	/* add subject token */
187 	(void) au_write(rd, au_to_subject_ex(uid, uid, gid,
188 		ruid, rgid, pid, pid, &info.ai_termid));
189 
190 	/* add return token */
191 	errno = 0;
192 	if (err) {
193 		/* add reason for failure */
194 		if (err == UNKNOWN_USER)
195 			(void) snprintf(buf, sizeof (buf),
196 			    "%s %s", msg, locuser);
197 		else
198 			(void) snprintf(buf, sizeof (buf), "%s", msg);
199 		(void) au_write(rd, au_to_text(buf));
200 #ifdef _LP64
201 		(void) au_write(rd, au_to_return64(-1, (int64_t)err));
202 #else
203 		(void) au_write(rd, au_to_return32(-1, (int32_t)err));
204 #endif
205 	} else {
206 #ifdef _LP64
207 		(void) au_write(rd, au_to_return64(0, (int64_t)0));
208 #else
209 		(void) au_write(rd, au_to_return32(0, (int32_t)0));
210 #endif
211 	}
212 
213 	/* write audit record */
214 	if (au_close(rd, 1, AUE_ftpd) < 0) {
215 		(void) au_close(rd, 0, 0);
216 	}
217 	(void) seteuid(ceuid);
218 }
219 
220 
221 static int
222 selected(
223 	uid_t		uid,
224 	char		*locuser,
225 	au_event_t	event,
226 	int	err)
227 {
228 	int	rc, sorf;
229 	char	naflags[512];
230 	struct au_mask mask;
231 
232 	mask.am_success = mask.am_failure = 0;
233 	if (uid < 0) {
234 		rc = getacna(naflags, 256); /* get non-attrib flags */
235 		if (rc == 0)
236 			(void) getauditflagsbin(naflags, &mask);
237 	} else {
238 		rc = au_user_mask(locuser, &mask);
239 	}
240 
241 	if (err == 0)
242 		sorf = AU_PRS_SUCCESS;
243 	else if (err >= 1)
244 		sorf = AU_PRS_FAILURE;
245 	else
246 		sorf = AU_PRS_BOTH;
247 	rc = au_preselect(event, &mask, sorf, AU_PRS_REREAD);
248 	return (rc);
249 }
250 
251 
252 void
253 audit_ftpd_logout(void)
254 {
255 	int	rd;		/* audit record descriptor */
256 	uid_t	euid;
257 	gid_t	egid;
258 	uid_t	uid;
259 	gid_t	gid;
260 	pid_t	pid;
261 	struct auditinfo_addr info;
262 
263 	if (cannot_audit(0)) {
264 		return;
265 	}
266 
267 	(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_AUDIT, NULL);
268 
269 	/* see if terminal id already set */
270 	if (getaudit_addr(&info, sizeof (info)) < 0) {
271 		perror("getaudit");
272 	}
273 
274 	/* determine if we're preselected */
275 	if (au_preselect(AUE_ftpd_logout, &info.ai_mask, AU_PRS_SUCCESS,
276 		AU_PRS_USECACHE) == 0) {
277 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_AUDIT,
278 		    NULL);
279 		return;
280 	}
281 
282 	euid = geteuid();
283 	egid = getegid();
284 	uid = getuid();
285 	gid = getgid();
286 	pid = getpid();
287 
288 	rd = au_open();
289 
290 	/* add subject token */
291 	(void) au_write(rd, au_to_subject_ex(info.ai_auid, euid,
292 		egid, uid, gid, pid, pid, &info.ai_termid));
293 
294 	/* add return token */
295 	errno = 0;
296 #ifdef _LP64
297 	(void) au_write(rd, au_to_return64(0, (int64_t)0));
298 #else
299 	(void) au_write(rd, au_to_return32(0, (int32_t)0));
300 #endif
301 
302 	/* write audit record */
303 	if (au_close(rd, 1, AUE_ftpd_logout) < 0) {
304 		(void) au_close(rd, 0, 0);
305 	}
306 	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_AUDIT, NULL);
307 }
308