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