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 (c) 2013 Gary Mills
23 *
24 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
25 */
26
27 #include <sys/types.h>
28 #include <sys/param.h>
29 #include <stdio.h>
30 #include <sys/fcntl.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <syslog.h>
34 #include <unistd.h>
35
36 #include <sys/socket.h>
37 #include <sys/sockio.h>
38 #include <netinet/in.h>
39 #include <tsol/label.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[LOGNAME_MAX_ILLUMOS + 1];
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, LOGNAME_MAX_ILLUMOS);
69 generate_record(luser, BAD_PASSWD, dgettext(bsm_dom, "bad password"));
70 }
71
72
73 void
74 audit_ftpd_unknown(char *uname)
75 {
76 if (cannot_audit(0)) {
77 return;
78 }
79 (void) strncpy(luser, uname, LOGNAME_MAX_ILLUMOS);
80 generate_record(luser, UNKNOWN_USER, dgettext(bsm_dom, "unknown user"));
81 }
82
83
84 void
85 audit_ftpd_excluded(char *uname)
86 {
87 if (cannot_audit(0)) {
88 return;
89 }
90 (void) strncpy(luser, uname, LOGNAME_MAX_ILLUMOS);
91 generate_record(luser, EXCLUDED_USER, dgettext(bsm_dom,
92 "excluded user"));
93 }
94
95
96 void
97 audit_ftpd_no_anon(void)
98 {
99 if (cannot_audit(0)) {
100 return;
101 }
102 generate_record("", NO_ANONYMOUS, dgettext(bsm_dom, "no anonymous"));
103 }
104
105 void
106 audit_ftpd_failure(char *uname)
107 {
108 if (cannot_audit(0)) {
109 return;
110 }
111 generate_record(uname, MISC_FAILURE, dgettext(bsm_dom, "misc failure"));
112 }
113
114 void
115 audit_ftpd_success(char *uname)
116 {
117 if (cannot_audit(0)) {
118 return;
119 }
120 (void) strncpy(luser, uname, LOGNAME_MAX_ILLUMOS);
121 generate_record(luser, 0, "");
122 }
123
124
125
126 static void
127 generate_record(
128 char *locuser, /* username of local user */
129 int err, /* error status */
130 /* (=0 success, >0 error code) */
131 char *msg) /* error message */
132 {
133 int rd; /* audit record descriptor */
134 char buf[256]; /* temporary buffer */
135 uid_t uid;
136 gid_t gid;
137 uid_t ruid; /* real uid */
138 gid_t rgid; /* real gid */
139 pid_t pid;
140 struct passwd *pwd;
141 uid_t ceuid; /* current effective uid */
142 struct auditinfo_addr info;
143
144 if (cannot_audit(0)) {
145 return;
146 }
147
148 pwd = getpwnam(locuser);
149 if (pwd == NULL) {
150 uid = (uid_t)-1;
151 gid = (gid_t)-1;
152 } else {
153 uid = pwd->pw_uid;
154 gid = pwd->pw_gid;
155 }
156
157 ceuid = geteuid(); /* save current euid */
158 (void) seteuid(0); /* change to root so you can audit */
159
160 /* determine if we're preselected */
161 if (!selected(uid, locuser, AUE_ftpd, err)) {
162 (void) seteuid(ceuid);
163 return;
164 }
165
166 ruid = getuid(); /* get real uid */
167 rgid = getgid(); /* get real gid */
168
169 pid = getpid();
170
171 /* see if terminal id already set */
172 if (getaudit_addr(&info, sizeof (info)) < 0) {
173 perror("getaudit");
174 }
175
176 rd = au_open();
177
178 /* add subject token */
179 (void) au_write(rd, au_to_subject_ex(uid, uid, gid,
180 ruid, rgid, pid, pid, &info.ai_termid));
181
182 if (is_system_labeled())
183 (void) au_write(rd, au_to_mylabel());
184
185 /* add return token */
186 errno = 0;
187 if (err) {
188 /* add reason for failure */
189 if (err == UNKNOWN_USER)
190 (void) snprintf(buf, sizeof (buf),
191 "%s %s", msg, locuser);
192 else
193 (void) snprintf(buf, sizeof (buf), "%s", msg);
194 (void) au_write(rd, au_to_text(buf));
195 #ifdef _LP64
196 (void) au_write(rd, au_to_return64(-1, (int64_t)err));
197 #else
198 (void) au_write(rd, au_to_return32(-1, (int32_t)err));
199 #endif
200 } else {
201 #ifdef _LP64
202 (void) au_write(rd, au_to_return64(0, (int64_t)0));
203 #else
204 (void) au_write(rd, au_to_return32(0, (int32_t)0));
205 #endif
206 }
207
208 /* write audit record */
209 if (au_close(rd, 1, AUE_ftpd) < 0) {
210 (void) au_close(rd, 0, 0);
211 }
212 (void) seteuid(ceuid);
213 }
214
215
216 static int
217 selected(
218 uid_t uid,
219 char *locuser,
220 au_event_t event,
221 int err)
222 {
223 int sorf;
224 struct au_mask mask;
225
226 mask.am_success = mask.am_failure = 0;
227 if (uid > MAXEPHUID) {
228 /* get non-attrib flags */
229 (void) auditon(A_GETKMASK, (caddr_t)&mask, sizeof (mask));
230 } else {
231 (void) au_user_mask(locuser, &mask);
232 }
233
234 if (err == 0) {
235 sorf = AU_PRS_SUCCESS;
236 } else if (err >= 1) {
237 sorf = AU_PRS_FAILURE;
238 } else {
239 sorf = AU_PRS_BOTH;
240 }
241
242 return (au_preselect(event, &mask, sorf, AU_PRS_REREAD));
243 }
244
245
246 void
247 audit_ftpd_logout(void)
248 {
249 int rd; /* audit record descriptor */
250 uid_t euid;
251 gid_t egid;
252 uid_t uid;
253 gid_t gid;
254 pid_t pid;
255 struct auditinfo_addr info;
256
257 if (cannot_audit(0)) {
258 return;
259 }
260
261 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_AUDIT, NULL);
262
263 /* see if terminal id already set */
264 if (getaudit_addr(&info, sizeof (info)) < 0) {
265 perror("getaudit");
266 }
267
268 /* determine if we're preselected */
269 if (au_preselect(AUE_ftpd_logout, &info.ai_mask, AU_PRS_SUCCESS,
270 AU_PRS_USECACHE) == 0) {
271 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_AUDIT,
272 NULL);
273 return;
274 }
275
276 euid = geteuid();
277 egid = getegid();
278 uid = getuid();
279 gid = getgid();
280 pid = getpid();
281
282 rd = au_open();
283
284 /* add subject token */
285 (void) au_write(rd, au_to_subject_ex(info.ai_auid, euid,
286 egid, uid, gid, pid, pid, &info.ai_termid));
287
288 if (is_system_labeled())
289 (void) au_write(rd, au_to_mylabel());
290
291 /* add return token */
292 errno = 0;
293 #ifdef _LP64
294 (void) au_write(rd, au_to_return64(0, (int64_t)0));
295 #else
296 (void) au_write(rd, au_to_return32(0, (int32_t)0));
297 #endif
298
299 /* write audit record */
300 if (au_close(rd, 1, AUE_ftpd_logout) < 0) {
301 (void) au_close(rd, 0, 0);
302 }
303 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_AUDIT, NULL);
304 }