usr/src/lib/libbsm/common/audit_user.c
author jpk
Fri, 24 Mar 2006 12:29:20 -0800
changeset 1676 37f4a3e2bd99
parent 0 68f95e015346
child 1914 8a8c5f225b1b
permissions -rw-r--r--
PSARC/2002/762 Layered Trusted Solaris PSARC/2005/060 TSNET: Trusted Networking with Security Labels PSARC/2005/259 Layered Trusted Solaris Label Interfaces PSARC/2005/573 Solaris Trusted Extensions for Printing PSARC/2005/691 Trusted Extensions for Device Allocation PSARC/2005/723 Solaris Trusted Extensions Filesystem Labeling PSARC/2006/009 Labeled Auditing PSARC/2006/155 Trusted Extensions RBAC Changes PSARC/2006/191 is_system_labeled 6293271 Zone processes should use zone_kcred instead of kcred 6394554 integrate Solaris Trusted Extensions

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (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 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */
#pragma ident	"%Z%%M%	%I%	%E% SMI"

/*
 * Interfaces to audit_user(4)  (/etc/security/audit_user)
 */

#include <stdio.h>
#include <limits.h>
#include <sys/types.h>
#include <string.h>
#include <bsm/audit.h>
#include <bsm/libbsm.h>
#include <synch.h>
#include <nss_dbdefs.h>
#include <stdlib.h>


#define	MAX_USERNAME	32	/* same size as utmpx.ut_user */


static char	au_user_fname[PATH_MAX] = AUDITUSERFILE;
static FILE *au_user_file = NULL;
static mutex_t mutex_userfile = DEFAULTMUTEX;
static int use_nsswitch = 1;
static au_user_ent_t *auuserstr2ent(au_user_ent_t *, au_user_str_t *);

extern int _mutex_lock(mutex_t *);
extern int _mutex_unlock(mutex_t *);

/*
 * Externs from libnsl
 */
extern void _setauuser(void);
extern void _endauuser(void);
extern au_user_str_t *_getauuserent(au_user_str_t *, char *, int, int *);
extern au_user_str_t *_getauusernam(char *, au_user_str_t *, char *, int,
    int *);

#ifdef __STDC__
int
setauuserfile(char *fname)
#else
int
setauuserfile(fname)
	char *fname;
#endif
{
	_mutex_lock(&mutex_userfile);
	if (fname) {
		(void) strcpy(au_user_fname, fname);
		use_nsswitch = 0;
	}
	_mutex_unlock(&mutex_userfile);
	return (0);
}


void
setauuser()
{
	_mutex_lock(&mutex_userfile);
	if (use_nsswitch)
		_setauuser();
	else if (au_user_file) {
		(void) fseek(au_user_file, 0L, 0);
	}
	_mutex_unlock(&mutex_userfile);
}


void
endauuser()
{
	_mutex_lock(&mutex_userfile);
	if (use_nsswitch)
		_endauuser();
	else if (au_user_file) {
		(void) fclose(au_user_file);
		au_user_file = NULL;
	}
	_mutex_unlock(&mutex_userfile);
}

au_user_ent_t *
getauuserent()
{
	static au_user_ent_t au_user_entry;
	static char	logname[MAX_USERNAME+1];

	/* initialize au_user_entry structure */
	au_user_entry.au_name = logname;

	return (getauuserent_r(&au_user_entry));

}

au_user_ent_t *
getauuserent_r(au_user_ent_t *au_user_entry)
{
	int	i, error = 0, found = 0;
	char	*s, input[256];


	_mutex_lock(&mutex_userfile);

	if (use_nsswitch) {
		au_user_str_t us;
		au_user_str_t *tmp;
		char buf[NSS_BUFLEN_AUDITUSER];
		int errp = 0;

		(void) memset(buf, NULL, NSS_BUFLEN_AUDITUSER);
		tmp = _getauuserent(&us, buf, NSS_BUFLEN_AUDITUSER, &errp);
		_mutex_unlock(&mutex_userfile);
		return (auuserstr2ent(au_user_entry, tmp));
	}

	/* open audit user file if it isn't already */
	if (!au_user_file)
		if (!(au_user_file = fopen(au_user_fname, "r"))) {
			_mutex_unlock(&mutex_userfile);
			return (NULL);
		}

	while (fgets(input, 256, au_user_file)) {
		if (input[0] != '#') {
			s = input + strspn(input, " \t\r\n");
			if ((*s == '\0') || (*s == '#')) {
				continue;
			}
			found = 1;
			s = input;

			/* parse login name */
			i = strcspn(s, ":");

			s[i] = '\0';
			(void) strncpy(au_user_entry->au_name, s, MAX_USERNAME);
			s = &s[i+1];

			/* parse first mask */
			i = strcspn(s, ":");

			s[i] = '\0';
			if (getauditflagsbin(s,
			    &au_user_entry->au_always) < 0)
				error = 1;
			s = &s[i+1];


			/* parse second mask */

			i = strcspn(s, "\n\0");

			s[i] = '\0';
			if (getauditflagsbin(s,
			    &au_user_entry->au_never) < 0)
				error = 1;


			break;
		}
	}

	_mutex_unlock(&mutex_userfile);

	if (!error && found) {
		return (au_user_entry);
	} else {
		return (NULL);
	}
}


#ifdef __STDC__
au_user_ent_t *
getauusernam(char *name)
#else
au_user_ent_t *
getauusernam(name)
	char *name;
#endif
{
	static au_user_ent_t u;
	static char	logname[MAX_USERNAME+1];

	/* initialize au_user_entry structure */
	u.au_name = logname;

	return (getauusernam_r(&u, name));
}

#ifdef __STDC__
au_user_ent_t *
getauusernam_r(au_user_ent_t *u, char *name)
#else
au_user_ent_t *
getauusernam_r(u, name)
	au_user_ent_t *u;
	char *name;
#endif
{

	if (use_nsswitch) {
		au_user_str_t us;
		au_user_str_t *tmp;
		char buf[NSS_BUFLEN_AUDITUSER];
		int errp = 0;

		if (name == NULL) {
			return ((au_user_ent_t *)NULL);
		}
		tmp = _getauusernam(name, &us, buf, NSS_BUFLEN_AUDITUSER,
		    &errp);
		return (auuserstr2ent(u, tmp));
	}
	while (getauuserent_r(u) != NULL) {
		if (strcmp(u->au_name, name) == 0) {
			return (u);
		}
	}
	return ((au_user_ent_t *)NULL);
}

static au_user_ent_t *
auuserstr2ent(au_user_ent_t *ue, au_user_str_t *us)
{
	if (us == NULL)
		return (NULL);

	if (getauditflagsbin(us->au_always, &ue->au_always) < 0) {
		return (NULL);
	}
	if (getauditflagsbin(us->au_never, &ue->au_never) < 0) {
		ue->au_never.am_success = AU_MASK_NONE;
		ue->au_never.am_failure = AU_MASK_NONE;
	}
	(void) strncpy(ue->au_name, us->au_name, MAX_USERNAME);
	return (ue);
}

#ifdef DEBUG
void
print_auuser(au_user_ent_t *ue)
{
	char *empty = "empty";
	char *bad = "bad flags";
	char always[256];
	char never[256];
	int retval;

	if (ue == NULL) {
		printf("NULL\n");
		return;
	}

	printf("name=%s\n", ue->au_name ? ue->au_name : empty);
	retval = getauditflagschar(always, ue->au_always, 0);
	printf("always=%s\n", retval == 0 ? always : bad);
	retval = getauditflagschar(never, ue->au_never, 0);
	printf("never=%s\n", retval == 0 ? never : bad);
}
#endif	/* DEBUG */