auditsys.c revision f89940742f5d14dde79b69b98a414dd7b7f585c7
/*
* 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
* 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
*/
/*
*/
#include <c2/audit_kernel.h>
#include <c2/audit_record.h>
#define CLEAR_VAL -1
/*ARGSUSED1*/
int
{
int err;
int result = 0;
if (audit_active == C2AUDIT_DISABLED)
return (ENOTSUP);
case BSM_GETAUID:
break;
case BSM_SETAUID:
break;
case BSM_GETAUDIT:
break;
case BSM_GETAUDIT_ADDR:
break;
case BSM_SETAUDIT:
break;
case BSM_SETAUDIT_ADDR:
break;
case BSM_AUDITCTL:
break;
case BSM_AUDIT:
if (audit_active == C2AUDIT_UNLOADED)
return (0);
break;
case BSM_AUDITDOOR:
if (audit_active == C2AUDIT_LOADED) {
break;
}
default:
if (audit_active == C2AUDIT_LOADED) {
break;
}
/* Return a different error when not privileged */
if (err == 0)
return (EINVAL);
else
return (err);
}
return (result);
}
/*
* Return the audit user ID for the current process. Currently only
* the privileged processes may see the audit id. That may change.
* If copyout is unsucessful return EFAULT.
*/
int
{
const auditinfo_addr_t *ainfo;
return (EPERM);
return (EINVAL);
return (EFAULT);
return (0);
}
/*
* Set the audit userid, for a process. This can only be changed by
* privileged processes. The audit userid is inherited across forks & execs.
* Passed in is a pointer to the au_id_t; if copyin unsuccessful return EFAULT.
*/
int
{
proc_t *p;
if (secpolicy_audit_config(CRED()) != 0)
return (EPERM);
return (EFAULT);
}
return (EINVAL);
}
/* grab p_crlock and switch to new cred */
p = curproc;
mutex_enter(&p->p_crlock);
/* unlock and broadcast the cred changes */
mutex_exit(&p->p_crlock);
return (0);
}
/*
* Get the audit state information from the current process.
* Return EFAULT if copyout fails.
*/
int
{
const auditinfo_addr_t *ainfo;
return (EPERM);
model = get_udatamodel();
return (EINVAL);
/* trying to read a process with an IPv6 address? */
return (EOVERFLOW);
#ifdef _LP64
if (model == DATAMODEL_ILP32) {
/* convert internal 64 bit form to 32 bit version */
return (EOVERFLOW);
}
} else
#else
#endif
return (EFAULT);
return (0);
}
/*
* Get the audit state information from the current process.
* Return EFAULT if copyout fails.
*/
int
{
const auditinfo_addr_t *ainfo;
return (EPERM);
model = get_udatamodel();
return (EOVERFLOW);
return (EINVAL);
#ifdef _LP64
if (model == DATAMODEL_ILP32) {
/* convert internal 64 bit form to 32 bit version */
return (EOVERFLOW);
}
} else
#else
#endif
return (EFAULT);
return (0);
}
/*
* Set the audit state information for the current process.
* Return EFAULT if copyout fails.
*/
int
{
proc_t *p;
if (secpolicy_audit_config(CRED()) != 0)
return (EPERM);
model = get_udatamodel();
return (EFAULT);
return (EINVAL);
}
/* grab p_crlock and switch to new cred */
p = curproc;
mutex_enter(&p->p_crlock);
/* Set audit mask, id, termid and session id as specified */
#ifdef _LP64
/* only convert to 64 bit if coming from a 32 bit binary */
if (model == DATAMODEL_ILP32)
else
#else
#endif
/* unlock and broadcast the cred changes */
mutex_exit(&p->p_crlock);
return (0);
}
/*
* Set the audit state information for the current process.
* Return EFAULT if copyin fails.
*/
int
{
proc_t *p;
int i;
int type;
if (secpolicy_audit_config(CRED()) != 0)
return (EPERM);
model = get_udatamodel();
return (EOVERFLOW);
return (EFAULT);
return (EINVAL);
return (EINVAL);
}
/* grab p_crlock and switch to new cred */
p = curproc;
mutex_enter(&p->p_crlock);
/* Set audit mask, id, termid and session id as specified */
#ifdef _LP64
/* only convert to 64 bit if coming from a 32 bit binary */
if (model == DATAMODEL_ILP32)
else
#else
#endif
for (i = 0; i < (type/sizeof (int)); i++)
}
/* unlock and broadcast the cred changes */
mutex_exit(&p->p_crlock);
return (0);
}
/*
* Get the global policy flag
*/
static int
{
return (EFAULT);
return (0);
}
/*
* Set the global and local policy flags
*
* The global flags only make sense from the global zone;
* the local flags depend on the AUDIT_PERZONE policy:
* if the perzone policy is set, then policy is set separately
* per zone, else held only in the global zone.
*
* The initial value of a local zone's policy flag is determined
* by the value of the global zone's flags at the time the
* local zone is created.
*
* While auditconfig(1M) allows setting and unsetting policies one bit
* at a time, the mask passed in from auditconfig() is created by a
* syscall to getpolicy and then modified based on the auditconfig()
* cmd line, so the input policy value is used to replace the existing
* policy.
*/
static int
{
return (EFAULT);
kctx = GET_KCTX_NGZ;
if (INGLOBALZONE(curproc)) {
return (EINVAL);
} else {
if (!(audit_policy & AUDIT_PERZONE))
return (EINVAL);
return (EINVAL);
}
/*
* auk_current_vp is NULL before auditd starts (or during early
* auditd starup) or if auditd is halted; in either case,
* notification of a policy change is not needed, since auditd
* reads policy as it comes up. The error return from au_doormsg()
* is ignored to avoid a race condition -- for example if auditd
* segv's, the audit state may be "auditing" but the door may
* be closed. Returning an error if the door is open makes it
* impossible for Greenline to restart auditd.
*/
/*
* Wake up anyone who might have blocked on full audit
* partitions. audit daemons need to set AUDIT_FULL when no
* space so we can tell if we should start dropping records.
*/
return (0);
}
static int
{
kctx = GET_KCTX_PZ;
return (EFAULT);
return (0);
}
static int
{
return (EINVAL);
kctx = GET_KCTX_NGZ;
return (EFAULT);
return (0);
}
static int
{
kctx = GET_KCTX_PZ;
return (EFAULT);
return (0);
}
static int
{
return (EINVAL);
kctx = GET_KCTX_NGZ;
return (EFAULT);
return (0);
}
static int
{
model = get_udatamodel();
return (EOVERFLOW);
#ifdef _LP64
if (model == DATAMODEL_ILP32) {
/* convert internal 64 bit form to 32 bit version */
return (EOVERFLOW);
}
} else {
}
#else
#endif
return (EFAULT);
return (0);
}
/*
* the host address for AUDIT_PERZONE == 0 is that of the global
* zone and for local zones it is of the current zone.
*/
static int
{
return (EINVAL);
kctx = GET_KCTX_NGZ;
model = get_udatamodel();
return (EOVERFLOW);
return (EFAULT);
return (EINVAL);
/* Set audit mask, termid and session id as specified */
#ifdef _LP64
/* only convert to 64 bit if coming from a 32 bit binary */
if (model == DATAMODEL_ILP32)
else
#else
#endif
}
else
return (0);
}
static int
{
return (EFAULT);
return (0);
}
static int
{
return (EINVAL);
kctx = GET_KCTX_NGZ;
return (EFAULT);
/* enforce sane values */
return (EINVAL);
return (EINVAL);
return (EINVAL);
return (EINVAL);
return (EINVAL);
return (EINVAL);
return (EINVAL);
/* update everything at once so things are consistant */
return (0);
}
static int
{
struct p_audit_data *pad;
struct audit_path *app;
int pathlen;
return (E2BIG);
}
return (EFAULT);
}
return (0);
}
static int
{
struct p_audit_data *pad;
struct audit_path *app;
int pathlen;
return (E2BIG);
}
return (EFAULT);
}
return (0);
}
static int
{
return (EFAULT);
return (0);
}
static int
{
return (EINVAL);
return (EFAULT);
return (0);
}
static int
{
struct proc *p;
const auditinfo_addr_t *ainfo;
/* setumask not applicable in non-global zones without perzone policy */
return (EINVAL);
model = get_udatamodel();
return (EFAULT);
/* if in non-global zone only modify processes in same zone */
continue;
/* skip system processes and ones being created or going away */
mutex_exit(&p->p_lock);
continue;
}
mutex_enter(&p->p_crlock);
mutex_exit(&p->p_crlock);
mutex_exit(&p->p_lock);
continue;
}
int err;
/*
* Here's a process which matches the specified auid.
* If its mask doesn't already match the new mask,
* save the new mask in the pad, to be picked up
* next syscall.
*/
if (err != 0) {
/*
* No need to call set_proc_pre_sys(), since
* t_pre_sys is ALWAYS on when audit is
* enabled...due to syscall auditing.
*/
}
} else {
}
mutex_exit(&p->p_lock);
}
return (0);
}
static int
{
struct proc *p;
const auditinfo_addr_t *ainfo;
/* setsmask not applicable in non-global zones without perzone policy */
return (EINVAL);
model = get_udatamodel();
return (EFAULT);
/* if in non-global zone only modify processes in same zone */
continue;
/* skip system processes and ones being created or going away */
mutex_exit(&p->p_lock);
continue;
}
mutex_enter(&p->p_crlock);
mutex_exit(&p->p_crlock);
mutex_exit(&p->p_lock);
continue;
}
int err;
/*
* Here's a process which matches the specified asid.
* If its mask doesn't already match the new mask,
* save the new mask in the pad, to be picked up
* next syscall.
*/
if (err != 0) {
/*
* No need to call set_proc_pre_sys(), since
* t_pre_sys is ALWAYS on when audit is
* enabled...due to syscall auditing.
*/
}
} else {
}
mutex_exit(&p->p_lock);
}
return (0);
}
/*
* Get the current audit state of the system
*/
static int
{
return (EFAULT);
return (0);
}
/*
* Set the current audit state of the system to on (AUC_AUDITING) or
* off (AUC_NOAUDIT).
*/
/* ARGSUSED */
static int
{
int auditstate;
return (EINVAL);
kctx = GET_KCTX_NGZ;
return (EFAULT);
switch (auditstate) {
case AUC_AUDITING: /* Turn auditing on */
if (audit_active == C2AUDIT_UNLOADED)
else
break;
case AUC_NOAUDIT: /* Turn auditing off */
break;
/* clear out the audit queue */
/* unblock au_output_thread */
break;
default:
return (EINVAL);
}
return (0);
}
static int
{
return (EFAULT);
return (EINVAL);
return (EFAULT);
return (0);
}
static int
{
return (EINVAL);
kctx = GET_KCTX_NGZ;
return (EFAULT);
return (EINVAL);
return (0);
}
static int
{
const auditinfo_addr_t *ainfo;
model = get_udatamodel();
return (EFAULT);
return (ESRCH); /* no such process */
}
return (EINVAL);
}
/* designated process has an ipv6 address? */
return (EOVERFLOW);
}
#ifdef _LP64
if (model == DATAMODEL_ILP32) {
/* convert internal 64 bit form to 32 bit version */
return (EOVERFLOW);
}
} else
#else
#endif
return (EFAULT);
return (0);
}
static int
{
const auditinfo_addr_t *ainfo;
model = get_udatamodel();
return (EOVERFLOW);
return (EFAULT);
return (ESRCH);
}
return (EINVAL);
}
#ifdef _LP64
if (model == DATAMODEL_ILP32) {
/* convert internal 64 bit form to 32 bit version */
return (EOVERFLOW);
}
} else
#else
#endif
return (EFAULT);
return (0);
}
static int
{
struct p_audit_data *pad;
model = get_udatamodel();
return (EFAULT);
return (ESRCH);
}
return (EINVAL);
}
/*
* Unlock. No need to broadcast changes via set_proc_pre_sys(),
* since t_pre_sys is ALWAYS on when audit is enabled... due to
* syscall auditing.
*/
/* Reset flag for any previous pending mask change; this supercedes */
return (0);
}
/*
* The out of control system call
* This is audit kitchen sink aka auditadm, aka auditon
*/
int
int cmd,
int length)
{
int result;
switch (cmd) {
case A_GETAMASK:
case A_GETCOND:
case A_GETCAR:
case A_GETCLASS:
case A_GETCWD:
case A_GETKAUDIT:
case A_GETKMASK:
case A_GETPINFO:
case A_GETPINFO_ADDR:
case A_GETPOLICY:
case A_GETQCTRL:
case A_GETSTAT:
return (EPERM);
break;
default:
if (secpolicy_audit_config(CRED()) != 0)
return (EPERM);
break;
}
switch (cmd) {
case A_GETPOLICY:
break;
case A_SETPOLICY:
break;
case A_GETAMASK:
break;
case A_SETAMASK:
break;
case A_GETKMASK:
break;
case A_SETKMASK:
break;
case A_GETKAUDIT:
break;
case A_SETKAUDIT:
break;
case A_GETQCTRL:
break;
case A_SETQCTRL:
break;
case A_GETCWD:
break;
case A_GETCAR:
break;
case A_GETSTAT:
break;
case A_SETSTAT:
break;
case A_SETUMASK:
break;
case A_SETSMASK:
break;
case A_GETCOND:
break;
case A_SETCOND:
break;
case A_GETCLASS:
break;
case A_SETCLASS:
break;
case A_GETPINFO:
break;
case A_GETPINFO_ADDR:
break;
case A_SETPMASK:
break;
default:
break;
}
return (result);
}