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