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