OpenSolaris_b135/lib/libbsm/common/audit_ftpd.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <sys/fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/sockio.h>
#include <netinet/in.h>
#include <tsol/label.h>

#include <bsm/audit.h>
#include <bsm/audit_record.h>
#include <bsm/audit_uevents.h>
#include <bsm/libbsm.h>
#include <bsm/audit_private.h>

#include <locale.h>
#include <pwd.h>
#include <generic.h>

#define	BAD_PASSWD	(1)
#define	UNKNOWN_USER	(2)
#define	EXCLUDED_USER	(3)
#define	NO_ANONYMOUS	(4)
#define	MISC_FAILURE	(5)

static char		luser[16];

static void generate_record(char *, int, char *);
static int selected(uid_t, char *, au_event_t, int);

void
audit_ftpd_bad_pw(char *uname)
{
	if (cannot_audit(0)) {
		return;
	}
	(void) strncpy(luser, uname, 8);
	luser[8] = '\0';
	generate_record(luser, BAD_PASSWD, dgettext(bsm_dom,
		"bad password"));
}


void
audit_ftpd_unknown(char	*uname)
{
	if (cannot_audit(0)) {
		return;
	}
	(void) strncpy(luser, uname, 8);
	luser[8] = '\0';
	generate_record(luser, UNKNOWN_USER, dgettext(bsm_dom,
		"unknown user"));
}


void
audit_ftpd_excluded(char *uname)
{
	if (cannot_audit(0)) {
		return;
	}
	(void) strncpy(luser, uname, 8);
	luser[8] = '\0';
	generate_record(luser, EXCLUDED_USER, dgettext(bsm_dom,
		"excluded user"));
}


void
audit_ftpd_no_anon(void)
{
	if (cannot_audit(0)) {
		return;
	}
	generate_record("", NO_ANONYMOUS, dgettext(bsm_dom,
		"no anonymous"));
}

void
audit_ftpd_failure(char *uname)
{
	if (cannot_audit(0)) {
		return;
	}
	generate_record(uname, MISC_FAILURE, dgettext(bsm_dom,
		"misc failure"));
}

void
audit_ftpd_success(char	*uname)
{
	if (cannot_audit(0)) {
		return;
	}
	(void) strncpy(luser, uname, 8);
	luser[8] = '\0';
	generate_record(luser, 0, "");
}



static void
generate_record(
		char	*locuser,	/* username of local user */
		int	err,		/* error status */
					/* (=0 success, >0 error code) */
		char	*msg)		/* error message */
{
	int	rd;		/* audit record descriptor */
	char	buf[256];	/* temporary buffer */
	uid_t	uid;
	gid_t	gid;
	uid_t	ruid;		/* real uid */
	gid_t	rgid;		/* real gid */
	pid_t	pid;
	struct passwd *pwd;
	uid_t	ceuid;		/* current effective uid */
	struct auditinfo_addr info;

	if (cannot_audit(0)) {
		return;
	}

	pwd = getpwnam(locuser);
	if (pwd == NULL) {
		uid = (uid_t)-1;
		gid = (gid_t)-1;
	} else {
		uid = pwd->pw_uid;
		gid = pwd->pw_gid;
	}

	ceuid = geteuid();	/* save current euid */
	(void) seteuid(0);	/* change to root so you can audit */

	/* determine if we're preselected */
	if (!selected(uid, locuser, AUE_ftpd, err)) {
		(void) seteuid(ceuid);
		return;
	}

	ruid = getuid();	/* get real uid */
	rgid = getgid();	/* get real gid */

	pid = getpid();

	/* see if terminal id already set */
	if (getaudit_addr(&info, sizeof (info)) < 0) {
		perror("getaudit");
	}

	rd = au_open();

	/* add subject token */
	(void) au_write(rd, au_to_subject_ex(uid, uid, gid,
		ruid, rgid, pid, pid, &info.ai_termid));

	if (is_system_labeled())
		(void) au_write(rd, au_to_mylabel());

	/* add return token */
	errno = 0;
	if (err) {
		/* add reason for failure */
		if (err == UNKNOWN_USER)
			(void) snprintf(buf, sizeof (buf),
			    "%s %s", msg, locuser);
		else
			(void) snprintf(buf, sizeof (buf), "%s", msg);
		(void) au_write(rd, au_to_text(buf));
#ifdef _LP64
		(void) au_write(rd, au_to_return64(-1, (int64_t)err));
#else
		(void) au_write(rd, au_to_return32(-1, (int32_t)err));
#endif
	} else {
#ifdef _LP64
		(void) au_write(rd, au_to_return64(0, (int64_t)0));
#else
		(void) au_write(rd, au_to_return32(0, (int32_t)0));
#endif
	}

	/* write audit record */
	if (au_close(rd, 1, AUE_ftpd) < 0) {
		(void) au_close(rd, 0, 0);
	}
	(void) seteuid(ceuid);
}


static int
selected(
	uid_t		uid,
	char		*locuser,
	au_event_t	event,
	int	err)
{
	int	rc, sorf;
	char	naflags[512];
	struct au_mask mask;

	mask.am_success = mask.am_failure = 0;
	if (uid > MAXEPHUID) {
		rc = getacna(naflags, 256); /* get non-attrib flags */
		if (rc == 0)
			(void) getauditflagsbin(naflags, &mask);
	} else {
		rc = au_user_mask(locuser, &mask);
	}

	if (err == 0)
		sorf = AU_PRS_SUCCESS;
	else if (err >= 1)
		sorf = AU_PRS_FAILURE;
	else
		sorf = AU_PRS_BOTH;
	rc = au_preselect(event, &mask, sorf, AU_PRS_REREAD);
	return (rc);
}


void
audit_ftpd_logout(void)
{
	int	rd;		/* audit record descriptor */
	uid_t	euid;
	gid_t	egid;
	uid_t	uid;
	gid_t	gid;
	pid_t	pid;
	struct auditinfo_addr info;

	if (cannot_audit(0)) {
		return;
	}

	(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_AUDIT, NULL);

	/* see if terminal id already set */
	if (getaudit_addr(&info, sizeof (info)) < 0) {
		perror("getaudit");
	}

	/* determine if we're preselected */
	if (au_preselect(AUE_ftpd_logout, &info.ai_mask, AU_PRS_SUCCESS,
		AU_PRS_USECACHE) == 0) {
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_AUDIT,
		    NULL);
		return;
	}

	euid = geteuid();
	egid = getegid();
	uid = getuid();
	gid = getgid();
	pid = getpid();

	rd = au_open();

	/* add subject token */
	(void) au_write(rd, au_to_subject_ex(info.ai_auid, euid,
		egid, uid, gid, pid, pid, &info.ai_termid));

	if (is_system_labeled())
		(void) au_write(rd, au_to_mylabel());

	/* add return token */
	errno = 0;
#ifdef _LP64
	(void) au_write(rd, au_to_return64(0, (int64_t)0));
#else
	(void) au_write(rd, au_to_return32(0, (int32_t)0));
#endif

	/* write audit record */
	if (au_close(rd, 1, AUE_ftpd_logout) < 0) {
		(void) au_close(rd, 0, 0);
	}
	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_AUDIT, NULL);
}