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 }