Home | History | Annotate | Download | only in common
      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