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 #ifdef LOGNAME_MAX_ILLUMOS 58 #define _LOGNAME_MAX LOGNAME_MAX_ILLUMOS 59 #else /* LOGNAME_MAX_ILLUMOS */ 60 #define _LOGNAME_MAX LOGNAME_MAX 61 #endif /* LOGNAME_MAX_ILLUMOS */ 62 63 static char luser[_LOGNAME_MAX + 1]; 64 65 static void generate_record(char *, int, char *); 66 static int selected(uid_t, char *, au_event_t, int); 67 68 void 69 audit_ftpd_bad_pw(char *uname) 70 { 71 if (cannot_audit(0)) { 72 return; 73 } 74 (void) strncpy(luser, uname, _LOGNAME_MAX); 75 generate_record(luser, BAD_PASSWD, dgettext(bsm_dom, "bad password")); 76 } 77 78 79 void 80 audit_ftpd_unknown(char *uname) 81 { 82 if (cannot_audit(0)) { 83 return; 84 } 85 (void) strncpy(luser, uname, _LOGNAME_MAX); 86 generate_record(luser, UNKNOWN_USER, dgettext(bsm_dom, "unknown user")); 87 } 88 89 90 void 91 audit_ftpd_excluded(char *uname) 92 { 93 if (cannot_audit(0)) { 94 return; 95 } 96 (void) strncpy(luser, uname, _LOGNAME_MAX); 97 generate_record(luser, EXCLUDED_USER, dgettext(bsm_dom, 98 "excluded user")); 99 } 100 101 102 void 103 audit_ftpd_no_anon(void) 104 { 105 if (cannot_audit(0)) { 106 return; 107 } 108 generate_record("", NO_ANONYMOUS, dgettext(bsm_dom, "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, "misc failure")); 118 } 119 120 void 121 audit_ftpd_success(char *uname) 122 { 123 if (cannot_audit(0)) { 124 return; 125 } 126 (void) strncpy(luser, uname, _LOGNAME_MAX); 127 generate_record(luser, 0, ""); 128 } 129 130 131 132 static void 133 generate_record( 134 char *locuser, /* username of local user */ 135 int err, /* error status */ 136 /* (=0 success, >0 error code) */ 137 char *msg) /* error message */ 138 { 139 int rd; /* audit record descriptor */ 140 char buf[256]; /* temporary buffer */ 141 uid_t uid; 142 gid_t gid; 143 uid_t ruid; /* real uid */ 144 gid_t rgid; /* real gid */ 145 pid_t pid; 146 struct passwd *pwd; 147 uid_t ceuid; /* current effective uid */ 148 struct auditinfo_addr info; 149 150 if (cannot_audit(0)) { 151 return; 152 } 153 154 pwd = getpwnam(locuser); 155 if (pwd == NULL) { 156 uid = (uid_t)-1; 157 gid = (gid_t)-1; 158 } else { 159 uid = pwd->pw_uid; 160 gid = pwd->pw_gid; 161 } 162 163 ceuid = geteuid(); /* save current euid */ 164 (void) seteuid(0); /* change to root so you can audit */ 165 166 /* determine if we're preselected */ 167 if (!selected(uid, locuser, AUE_ftpd, err)) { 168 (void) seteuid(ceuid); 169 return; 170 } 171 172 ruid = getuid(); /* get real uid */ 173 rgid = getgid(); /* get real gid */ 174 175 pid = getpid(); 176 177 /* see if terminal id already set */ 178 if (getaudit_addr(&info, sizeof (info)) < 0) { 179 perror("getaudit"); 180 } 181 182 rd = au_open(); 183 184 /* add subject token */ 185 (void) au_write(rd, au_to_subject_ex(uid, uid, gid, 186 ruid, rgid, pid, pid, &info.ai_termid)); 187 188 if (is_system_labeled()) 189 (void) au_write(rd, au_to_mylabel()); 190 191 /* add return token */ 192 errno = 0; 193 if (err) { 194 /* add reason for failure */ 195 if (err == UNKNOWN_USER) 196 (void) snprintf(buf, sizeof (buf), 197 "%s %s", msg, locuser); 198 else 199 (void) snprintf(buf, sizeof (buf), "%s", msg); 200 (void) au_write(rd, au_to_text(buf)); 201 #ifdef _LP64 202 (void) au_write(rd, au_to_return64(-1, (int64_t)err)); 203 #else 204 (void) au_write(rd, au_to_return32(-1, (int32_t)err)); 205 #endif 206 } else { 207 #ifdef _LP64 208 (void) au_write(rd, au_to_return64(0, (int64_t)0)); 209 #else 210 (void) au_write(rd, au_to_return32(0, (int32_t)0)); 211 #endif 212 } 213 214 /* write audit record */ 215 if (au_close(rd, 1, AUE_ftpd) < 0) { 216 (void) au_close(rd, 0, 0); 217 } 218 (void) seteuid(ceuid); 219 } 220 221 222 static int 223 selected( 224 uid_t uid, 225 char *locuser, 226 au_event_t event, 227 int err) 228 { 229 int sorf; 230 struct au_mask mask; 231 232 mask.am_success = mask.am_failure = 0; 233 if (uid > MAXEPHUID) { 234 /* get non-attrib flags */ 235 (void) auditon(A_GETKMASK, (caddr_t)&mask, sizeof (mask)); 236 } else { 237 (void) au_user_mask(locuser, &mask); 238 } 239 240 if (err == 0) { 241 sorf = AU_PRS_SUCCESS; 242 } else if (err >= 1) { 243 sorf = AU_PRS_FAILURE; 244 } else { 245 sorf = AU_PRS_BOTH; 246 } 247 248 return (au_preselect(event, &mask, sorf, AU_PRS_REREAD)); 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 if (is_system_labeled()) 295 (void) au_write(rd, au_to_mylabel()); 296 297 /* add return token */ 298 errno = 0; 299 #ifdef _LP64 300 (void) au_write(rd, au_to_return64(0, (int64_t)0)); 301 #else 302 (void) au_write(rd, au_to_return32(0, (int32_t)0)); 303 #endif 304 305 /* write audit record */ 306 if (au_close(rd, 1, AUE_ftpd_logout) < 0) { 307 (void) au_close(rd, 0, 0); 308 } 309 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_AUDIT, NULL); 310 }