#include <sys/param.h>
#include <sys/types.h>
#include <sys/vnode.h>
#include <sys/vnode_internal.h>
#include <sys/kauth.h>
#include <sys/queue.h>
#include <security/mac_internal.h>
#include <bsd/bsm/audit.h>
#include <bsd/bsm/audit_kernel.h>
#include <bsd/sys/malloc.h>
#include <vm/vm_kern.h>
#include <kern/kalloc.h>
#include <kern/zalloc.h>
#if AUDIT
zone_t mac_audit_data_zone;
int
mac_system_check_audit(struct ucred *cred, void *record, int length)
{
int error;
MAC_CHECK(system_check_audit, cred, record, length);
return (error);
}
int
mac_system_check_auditon(struct ucred *cred, int cmd)
{
int error;
MAC_CHECK(system_check_auditon, cred, cmd);
return (error);
}
int
mac_system_check_auditctl(struct ucred *cred, struct vnode *vp)
{
int error;
struct label *vl = vp ? vp->v_label : NULL;
MAC_CHECK(system_check_auditctl, cred, vp, vl);
return (error);
}
int
mac_proc_check_getauid(struct proc *curp)
{
kauth_cred_t cred;
int error;
if (!mac_proc_enforce ||
!mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
return 0;
cred = kauth_cred_proc_ref(curp);
MAC_CHECK(proc_check_getauid, cred);
kauth_cred_unref(&cred);
return (error);
}
int
mac_proc_check_setauid(struct proc *curp, uid_t auid)
{
kauth_cred_t cred;
int error;
if (!mac_proc_enforce ||
!mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
return 0;
cred = kauth_cred_proc_ref(curp);
MAC_CHECK(proc_check_setauid, cred, auid);
kauth_cred_unref(&cred);
return (error);
}
int
mac_proc_check_getaudit(struct proc *curp)
{
kauth_cred_t cred;
int error;
if (!mac_proc_enforce ||
!mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
return 0;
cred = kauth_cred_proc_ref(curp);
MAC_CHECK(proc_check_getaudit, cred);
kauth_cred_unref(&cred);
return (error);
}
int
mac_proc_check_setaudit(struct proc *curp, struct auditinfo *ai)
{
kauth_cred_t cred;
int error;
if (!mac_proc_enforce ||
!mac_proc_check_enforce(curp, MAC_PROC_ENFORCE))
return 0;
cred = kauth_cred_proc_ref(curp);
MAC_CHECK(proc_check_setaudit, cred, ai);
kauth_cred_unref(&cred);
return (error);
}
#if 0
int
mac_audit_data(int len, u_char *data, mac_policy_handle_t handle)
{
char *sanitized;
if ((len <= 0) || (len > MAC_AUDIT_DATA_LIMIT))
return (EINVAL);
sanitized = (char *)zalloc(mac_audit_data_zone);
bcopy(data, sanitized, len);
return (audit_mac_data(MAC_AUDIT_DATA_TYPE, len, sanitized));
}
#endif
int
mac_audit_text(char *text, mac_policy_handle_t handle)
{
char *sanitized;
const char *name;
int i, size, plen, len;
name = mac_get_mpc(handle)->mpc_name;
len = strlen(text);
plen = 2 + strlen(name);
if (plen + len >= MAC_AUDIT_DATA_LIMIT)
return (EINVAL);
for (i=0; i < len; i++)
if (text[i] < (char) 32 || text[i] > (char) 126)
return (EINVAL);
size = len + plen + 1;
sanitized = (char *)zalloc(mac_audit_data_zone);
strlcpy(sanitized, name, MAC_AUDIT_DATA_LIMIT);
strncat(sanitized, ": ", MAC_AUDIT_DATA_LIMIT - plen + 2);
strncat(sanitized, text, MAC_AUDIT_DATA_LIMIT - plen);
return (audit_mac_data(MAC_AUDIT_TEXT_TYPE, size, (u_char *)sanitized));
}
int
mac_audit_check_preselect(struct ucred *cred, unsigned short syscode, void *args)
{
struct mac_policy_conf *mpc;
int ret, error;
u_int i;
ret = MAC_AUDIT_DEFAULT;
for (i = 0; i < mac_policy_list.staticmax; i++) {
mpc = mac_policy_list.entries[i].mpc;
if (mpc == NULL)
continue;
if (mpc->mpc_ops->mpo_audit_check_preselect != NULL) {
error = mpc->mpc_ops->mpo_audit_check_preselect(cred,
syscode, args);
ret = (ret > error ? ret : error);
}
}
if (mac_policy_list_conditional_busy() != 0) {
for (; i <= mac_policy_list.maxindex; i++) {
mpc = mac_policy_list.entries[i].mpc;
if (mpc == NULL)
continue;
if (mpc->mpc_ops->mpo_audit_check_preselect != NULL) {
error = mpc->mpc_ops->mpo_audit_check_preselect(cred,
syscode, args);
ret = (ret > error ? ret : error);
}
}
mac_policy_list_unbusy();
}
return (ret);
}
int
mac_audit_check_postselect(struct ucred *cred, unsigned short syscode,
void *args, int error, int retval, int mac_forced)
{
struct mac_policy_conf *mpc;
int ret, mac_error;
u_int i;
if (mac_forced)
return (MAC_AUDIT_YES);
ret = MAC_AUDIT_DEFAULT;
for (i = 0; i < mac_policy_list.staticmax; i++) {
mpc = mac_policy_list.entries[i].mpc;
if (mpc == NULL)
continue;
if (mpc->mpc_ops->mpo_audit_check_postselect != NULL) {
mac_error = mpc->mpc_ops->mpo_audit_check_postselect(cred,
syscode, args, error, retval);
ret = (ret > mac_error ? ret : mac_error);
}
}
if (mac_policy_list_conditional_busy() != 0) {
for (; i <= mac_policy_list.maxindex; i++) {
mpc = mac_policy_list.entries[i].mpc;
if (mpc == NULL)
continue;
if (mpc->mpc_ops->mpo_audit_check_postselect != NULL) {
mac_error = mpc->mpc_ops->mpo_audit_check_postselect(cred,
syscode, args, error, retval);
ret = (ret > mac_error ? ret : mac_error);
}
}
mac_policy_list_unbusy();
}
return (ret);
}
#else
int
mac_system_check_audit(struct ucred *cred, void *record, int length)
{
return (0);
}
int
mac_system_check_auditon(struct ucred *cred, int cmd)
{
return (0);
}
int
mac_system_check_auditctl(struct ucred *cred, struct vnode *vp)
{
return (0);
}
int
mac_proc_check_getauid(__unused struct proc *curp)
{
return (0);
}
int
mac_proc_check_setauid(__unused struct proc *curp, __unused uid_t auid)
{
return (0);
}
int
mac_proc_check_getaudit(__unused struct proc *curp)
{
return (0);
}
int
mac_proc_check_setaudit(__unused struct proc *curp, struct auditinfo *ai)
{
return (0);
}
int
mac_audit_check_preselect(__unused struct ucred *cred, __unused unsigned short syscode,
__unused void *args)
{
return (MAC_AUDIT_DEFAULT);
}
int
mac_audit_check_postselect(__unused struct ucred *cred, __unused unsigned short syscode,
__unused void *args, __unused int error, __unused int retval, __unused int mac_forced)
{
return (MAC_AUDIT_DEFAULT);
}
int
mac_audit(int len, u_char *data)
{
return (0);
}
int
mac_audit_text(__unused char *text, __unused mac_policy_handle_t handle)
{
return (0);
}
#endif