[PATCH] One more XFRM audit fix
by Paul Moore
The following patch is backed against David's net-2.6 tree and is pretty
trivial. I know we're late in the 2.6.24 cycle but I think this is worth
merging, if you guys don't feel that way let me know and I'll resubmit it
for 2.6.25.
As a side note, I'm unable to actually test the patch because I can't get
the kernel to compile (M=net/xfrm works just fine). The problem I keep
seeing is below:
make[3]: *** No rule to make target \
`/blah/kernels/net-2.6_xfrm-auid-secid-fix/include/linux/ticable.h', \
needed by \
`/blah/kernels/net-2.6_xfrm-auid-secid-fix/usr/include/linux/ticable.h'. \
Stop.
--
paul moore
linux security @ hp
17 years
[PATCH -v3] Audit: add uid, loginuid, and comm to OBJ_PID records
by Eric Paris
Add uid, loginuid, and comm collection to OBJ_PID records. This just
gives users a little more information about the task that received a
signal. pid is rather meaningless after the fact, and even though comm
isn't great we can't collect exe reasonably on this code path for
performance reasons.
Signed-off-by: Eric Paris <eparis(a)redhat.com>
---
changes since -v2
- change ordering to put auid before uid
- add 'o' to everything in the record
- use uid_t not pid_t (types are hard)
type=OBJ_PID msg=audit(12/12/2007 17:06:05.328:17) : opid=2223 oauid=0 ouid=root obj=root:system_r:unconfined_t:s0-s0:c0.c1023 ocomm="tmp"
type=OBJ_PID msg=audit(12/12/2007 17:06:05.328:17) : opid=2222 oauid=0 ouid=root obj=root:system_r:unconfined_t:s0-s0:c0.c1023 ocomm="tmp"
type=SYSCALL msg=audit(12/12/2007 17:06:05.328:17) : arch=x86_64 syscall=kill success=yes exit=0 a0=fffff752 a1=9 a2=0 a3=0 items=0 ppid=2191 pid=2221 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 comm=tmp exe=/tmp/tmp subj=root:system_r:unconfined_t:s0-s0:c0.c1023 key=(null)
----
type=OBJ_PID msg=audit(12/12/2007 17:07:16.389:38) : opid=2291 oauid=0 ouid=test obj=root:system_r:httpd_t:s0-s0:c0.c1023 ocomm="bash"
type=SYSCALL msg=audit(12/12/2007 17:07:16.389:38) : arch=x86_64 syscall=kill success=yes exit=0 a0=8f3 a1=f a2=0 a3=0 items=0 ppid=2186 pid=2191 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 comm=bash exe=/bin/bash subj=root:system_r:unconfined_t:s0-s0:c0.c1023 key=(null)
kernel/auditsc.c | 32 +++++++++++++++++++++++++++-----
1 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index bce9ecd..6d53e75 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -176,7 +176,10 @@ struct audit_aux_data_fd_pair {
struct audit_aux_data_pids {
struct audit_aux_data d;
pid_t target_pid[AUDIT_AUX_PIDS];
+ uid_t target_auid[AUDIT_AUX_PIDS];
+ uid_t target_uid[AUDIT_AUX_PIDS];
u32 target_sid[AUDIT_AUX_PIDS];
+ char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
int pid_count;
};
@@ -215,7 +218,10 @@ struct audit_context {
int arch;
pid_t target_pid;
+ uid_t target_auid;
+ uid_t target_uid;
u32 target_sid;
+ char target_comm[TASK_COMM_LEN];
struct audit_tree_refs *trees, *first_trees;
int tree_count;
@@ -922,7 +928,7 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk
}
static int audit_log_pid_context(struct audit_context *context, pid_t pid,
- u32 sid)
+ uid_t auid, uid_t uid, u32 sid, char *comm)
{
struct audit_buffer *ab;
char *s = NULL;
@@ -933,11 +939,14 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
if (!ab)
return 1;
+ audit_log_format(ab, "opid=%d oauid=%d ouid=%d", pid, auid, uid);
if (selinux_sid_to_string(sid, &s, &len)) {
- audit_log_format(ab, "opid=%d obj=(none)", pid);
+ audit_log_format(ab, " obj=(none)");
rc = 1;
} else
- audit_log_format(ab, "opid=%d obj=%s", pid, s);
+ audit_log_format(ab, " obj=%s", s);
+ audit_log_format(ab, " ocomm=");
+ audit_log_untrustedstring(ab, comm);
audit_log_end(ab);
kfree(s);
@@ -1168,13 +1177,17 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
for (i = 0; i < axs->pid_count; i++)
if (audit_log_pid_context(context, axs->target_pid[i],
- axs->target_sid[i]))
+ axs->target_auid[i],
+ axs->target_uid[i],
+ axs->target_sid[i],
+ axs->target_comm[i]))
call_panic = 1;
}
if (context->target_pid &&
audit_log_pid_context(context, context->target_pid,
- context->target_sid))
+ context->target_auid, context->target_uid,
+ context->target_sid, context->target_comm))
call_panic = 1;
if (context->pwd && context->pwdmnt) {
@@ -2193,7 +2206,10 @@ void __audit_ptrace(struct task_struct *t)
struct audit_context *context = current->audit_context;
context->target_pid = t->pid;
+ context->target_auid = audit_get_loginuid(t->audit_context);
+ context->target_uid = t->uid;
selinux_get_task_sid(t, &context->target_sid);
+ memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
}
/**
@@ -2230,7 +2246,10 @@ int __audit_signal_info(int sig, struct task_struct *t)
* in audit_context */
if (!ctx->target_pid) {
ctx->target_pid = t->tgid;
+ ctx->target_auid = audit_get_loginuid(t->audit_context);
+ ctx->target_uid = t->uid;
selinux_get_task_sid(t, &ctx->target_sid);
+ memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
return 0;
}
@@ -2247,7 +2266,10 @@ int __audit_signal_info(int sig, struct task_struct *t)
BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
axp->target_pid[axp->pid_count] = t->tgid;
+ axp->target_auid[axp->pid_count] = audit_get_loginuid(t->audit_context);
+ axp->target_uid[axp->pid_count] = t->uid;
selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]);
+ memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
axp->pid_count++;
return 0;
17 years
[PATCH] Audit: add session id to audit messages
by Eric Paris
In order to correlate audit records to an individual login add a session
id. This is incremented every time a user logs in and is included in
almost all messages which currently output the auid. The field is
labeled ses= or oses=
Signed-off-by: Eric Paris <eparis(a)redhat.com>
---
This patch does not currently implement sessionid information for audit
messages generated from netlink messages. That means no sessionid will
be found in things like userspace generated audit messages, audit system
configuration changes, or changes to labeled networking. A patch to
support those messages (and the requisite changes to netlink) will be
forthcoming.
This patch applies on top of the previous OBJ_PID record changes.
Example records:
type=LOGIN msg=audit(1197663142.722:137): login pid=2764 uid=0 old auid=0 new auid=0 old ses=1 new ses=13
type=SYSCALL msg=audit(1197665485.338:142): arch=c000003e syscall=62 success=yes exit=0 a0=1 a1=f a2=0 a3=0 items=0 ppid=2184 pid=2189 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=13 comm="bash" exe="/bin/bash" subj=root:system_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=OBJ_PID msg=audit(1197665485.338:142): opid=1 oauid=-1 ouid=0 oses=-1 obj=system_u:system_r:init_t:s0 ocomm="init"
drivers/char/tty_audit.c | 21 +++++++++++-----
include/linux/audit.h | 2 +
kernel/auditsc.c | 50 ++++++++++++++++++++++++++++++++--------
net/core/dev.c | 5 ++-
security/selinux/selinuxfs.c | 17 ++++++++-----
security/selinux/ss/services.c | 5 ++-
6 files changed, 72 insertions(+), 28 deletions(-)
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c
index d222012..490fea3 100644
--- a/drivers/char/tty_audit.c
+++ b/drivers/char/tty_audit.c
@@ -73,7 +73,7 @@ static void tty_audit_buf_put(struct tty_audit_buf *buf)
* @tsk with @loginuid. @buf->mutex must be locked.
*/
static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
- struct tty_audit_buf *buf)
+ unsigned int sessionid, struct tty_audit_buf *buf)
{
struct audit_buffer *ab;
@@ -85,9 +85,9 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
if (ab) {
char name[sizeof(tsk->comm)];
- audit_log_format(ab, "tty pid=%u uid=%u auid=%u major=%d "
- "minor=%d comm=", tsk->pid, tsk->uid,
- loginuid, buf->major, buf->minor);
+ audit_log_format(ab, "tty pid=%u uid=%u auid=%u ses=%u "
+ "major=%d minor=%d comm=", tsk->pid, tsk->uid,
+ loginuid, sessionid, buf->major, buf->minor);
get_task_comm(name, tsk);
audit_log_untrustedstring(ab, name);
audit_log_format(ab, " data=");
@@ -105,8 +105,10 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
*/
static void tty_audit_buf_push_current(struct tty_audit_buf *buf)
{
- tty_audit_buf_push(current, audit_get_loginuid(current->audit_context),
- buf);
+ struct audit_context *ctx = current->audit_context;
+ uid_t auid = audit_get_loginuid(ctx);
+ unsigned int sessionid = audit_get_sessionid(ctx);
+ tty_audit_buf_push(current, auid, sessionid, buf);
}
/**
@@ -152,6 +154,11 @@ void tty_audit_fork(struct signal_struct *sig)
void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid)
{
struct tty_audit_buf *buf;
+ /* FIXME I think this is correct. Check against netlink once that is
+ * I really need to read this code more closely. But that's for
+ * another patch.
+ */
+ unsigned int sessionid = audit_get_sessionid(tsk->audit_context);
spin_lock_irq(&tsk->sighand->siglock);
buf = tsk->signal->tty_audit_buf;
@@ -162,7 +169,7 @@ void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid)
return;
mutex_lock(&buf->mutex);
- tty_audit_buf_push(tsk, loginuid, buf);
+ tty_audit_buf_push(tsk, loginuid, sessionid, buf);
mutex_unlock(&buf->mutex);
tty_audit_buf_put(buf);
diff --git a/include/linux/audit.h b/include/linux/audit.h
index c687816..2f2ab1f 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -408,6 +408,7 @@ extern void auditsc_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial);
extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
extern uid_t audit_get_loginuid(struct audit_context *ctx);
+extern unsigned int audit_get_sessionid(struct audit_context *ctx);
extern void audit_log_task_context(struct audit_buffer *ab);
extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
@@ -487,6 +488,7 @@ extern int audit_signals;
#define audit_core_dumps(i) do { ; } while (0)
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
#define audit_get_loginuid(c) ({ -1; })
+#define audit_get_sessionid(c) ({ -1; })
#define audit_log_task_context(b) do { ; } while (0)
#define audit_ipc_obj(i) ({ 0; })
#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 6d53e75..1feb9ec 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -178,6 +178,7 @@ struct audit_aux_data_pids {
pid_t target_pid[AUDIT_AUX_PIDS];
uid_t target_auid[AUDIT_AUX_PIDS];
uid_t target_uid[AUDIT_AUX_PIDS];
+ unsigned int target_sessionid[AUDIT_AUX_PIDS];
u32 target_sid[AUDIT_AUX_PIDS];
char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
int pid_count;
@@ -196,6 +197,7 @@ struct audit_context {
unsigned int serial; /* serial number for record */
struct timespec ctime; /* time of syscall entry */
uid_t loginuid; /* login uid (identity) */
+ unsigned int sessionid; /* each login gets a session id */
int major; /* syscall number */
unsigned long argv[4]; /* syscall arguments */
int return_valid; /* return code is valid */
@@ -220,6 +222,7 @@ struct audit_context {
pid_t target_pid;
uid_t target_auid;
uid_t target_uid;
+ unsigned int target_sessionid;
u32 target_sid;
char target_comm[TASK_COMM_LEN];
@@ -790,10 +793,12 @@ static inline void audit_zero_context(struct audit_context *context,
enum audit_state state)
{
uid_t loginuid = context->loginuid;
+ unsigned int sessionid = context->sessionid;
memset(context, 0, sizeof(*context));
context->state = state;
context->loginuid = loginuid;
+ context->sessionid = sessionid;
}
static inline struct audit_context *audit_alloc_context(enum audit_state state)
@@ -834,8 +839,11 @@ int audit_alloc(struct task_struct *tsk)
/* Preserve login uid */
context->loginuid = -1;
- if (current->audit_context)
+ context->sessionid = -1;
+ if (current->audit_context) {
context->loginuid = current->audit_context->loginuid;
+ context->sessionid = current->audit_context->sessionid;
+ }
tsk->audit_context = context;
set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
@@ -928,7 +936,8 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk
}
static int audit_log_pid_context(struct audit_context *context, pid_t pid,
- uid_t auid, uid_t uid, u32 sid, char *comm)
+ uid_t auid, uid_t uid, unsigned int sessionid,
+ u32 sid, char *comm)
{
struct audit_buffer *ab;
char *s = NULL;
@@ -939,7 +948,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
if (!ab)
return 1;
- audit_log_format(ab, "opid=%d oauid=%d ouid=%d", pid, auid, uid);
+ audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid,
+ uid, sessionid);
if (selinux_sid_to_string(sid, &s, &len)) {
audit_log_format(ab, " obj=(none)");
rc = 1;
@@ -1048,7 +1058,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
" a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
" ppid=%d pid=%d auid=%u uid=%u gid=%u"
" euid=%u suid=%u fsuid=%u"
- " egid=%u sgid=%u fsgid=%u tty=%s",
+ " egid=%u sgid=%u fsgid=%u tty=%s ses=%u",
context->argv[0],
context->argv[1],
context->argv[2],
@@ -1060,7 +1070,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
context->uid,
context->gid,
context->euid, context->suid, context->fsuid,
- context->egid, context->sgid, context->fsgid, tty);
+ context->egid, context->sgid, context->fsgid, tty,
+ context->sessionid);
mutex_unlock(&tty_mutex);
@@ -1179,6 +1190,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
if (audit_log_pid_context(context, axs->target_pid[i],
axs->target_auid[i],
axs->target_uid[i],
+ axs->target_sessionid[i],
axs->target_sid[i],
axs->target_comm[i]))
call_panic = 1;
@@ -1187,6 +1199,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
if (context->target_pid &&
audit_log_pid_context(context, context->target_pid,
context->target_auid, context->target_uid,
+ context->target_sessionid,
context->target_sid, context->target_comm))
call_panic = 1;
@@ -1779,6 +1792,9 @@ void auditsc_get_stamp(struct audit_context *ctx,
ctx->auditable = 1;
}
+/* global counter which is incremented every time something logs in */
+static atomic_t session_id = ATOMIC_INIT(0);
+
/**
* audit_set_loginuid - set a task's audit_context loginuid
* @task: task whose audit context is being modified
@@ -1793,6 +1809,7 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
struct audit_context *context = task->audit_context;
if (context) {
+ unsigned int sessionid = atomic_inc_return(&session_id);
/* Only log if audit is enabled */
if (context->in_syscall) {
struct audit_buffer *ab;
@@ -1800,13 +1817,16 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
if (ab) {
audit_log_format(ab, "login pid=%d uid=%u "
- "old auid=%u new auid=%u",
+ "old auid=%u new auid=%u"
+ " old ses=%u new ses=%u",
task->pid, task->uid,
- context->loginuid, loginuid);
+ context->loginuid, loginuid,
+ context->sessionid, sessionid);
audit_log_end(ab);
}
}
context->loginuid = loginuid;
+ context->sessionid = sessionid;
}
return 0;
}
@@ -1824,6 +1844,11 @@ uid_t audit_get_loginuid(struct audit_context *ctx)
EXPORT_SYMBOL(audit_get_loginuid);
+unsigned int audit_get_sessionid(struct audit_context *ctx)
+{
+ return ctx ? ctx->sessionid : -1;
+}
+
/**
* __audit_mq_open - record audit data for a POSIX MQ open
* @oflag: open flag
@@ -2208,6 +2233,7 @@ void __audit_ptrace(struct task_struct *t)
context->target_pid = t->pid;
context->target_auid = audit_get_loginuid(t->audit_context);
context->target_uid = t->uid;
+ context->target_sessionid = audit_get_sessionid(t->audit_context);
selinux_get_task_sid(t, &context->target_sid);
memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
}
@@ -2248,6 +2274,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
ctx->target_pid = t->tgid;
ctx->target_auid = audit_get_loginuid(t->audit_context);
ctx->target_uid = t->uid;
+ ctx->target_sessionid = audit_get_sessionid(t->audit_context);
selinux_get_task_sid(t, &ctx->target_sid);
memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
return 0;
@@ -2268,6 +2295,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
axp->target_pid[axp->pid_count] = t->tgid;
axp->target_auid[axp->pid_count] = audit_get_loginuid(t->audit_context);
axp->target_uid[axp->pid_count] = t->uid;
+ axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t->audit_context);
selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]);
memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
axp->pid_count++;
@@ -2285,7 +2313,10 @@ int __audit_signal_info(int sig, struct task_struct *t)
void audit_core_dumps(long signr)
{
struct audit_buffer *ab;
+ struct audit_context *ctx = current->audit_context;
u32 sid;
+ uid_t auid = audit_get_loginuid(ctx);
+ unsigned int sessionid = audit_get_sessionid(ctx);
if (!audit_enabled)
return;
@@ -2294,9 +2325,8 @@ void audit_core_dumps(long signr)
return;
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
- audit_log_format(ab, "auid=%u uid=%u gid=%u",
- audit_get_loginuid(current->audit_context),
- current->uid, current->gid);
+ audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u",
+ auid, current->uid, current->gid, sessionid);
selinux_get_task_sid(current, &sid);
if (sid) {
char *ctx = NULL;
diff --git a/net/core/dev.c b/net/core/dev.c
index 26a3a3a..07d3963 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2759,10 +2759,11 @@ static void __dev_set_promiscuity(struct net_device *dev, int inc)
"left");
audit_log(current->audit_context, GFP_ATOMIC,
AUDIT_ANOM_PROMISCUOUS,
- "dev=%s prom=%d old_prom=%d auid=%u",
+ "dev=%s prom=%d old_prom=%d auid=%u ses=%u",
dev->name, (dev->flags & IFF_PROMISC),
(old_flags & IFF_PROMISC),
- audit_get_loginuid(current->audit_context));
+ audit_get_loginuid(current->audit_context),
+ audit_get_sessionid(current->audit_context));
if (dev->change_rx_flags)
dev->change_rx_flags(dev, IFF_PROMISC);
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 2fa483f..432e803 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -158,9 +158,10 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
if (length)
goto out;
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
- "enforcing=%d old_enforcing=%d auid=%u", new_value,
- selinux_enforcing,
- audit_get_loginuid(current->audit_context));
+ "enforcing=%d old_enforcing=%d auid=%u ses=%u",
+ new_value, selinux_enforcing,
+ audit_get_loginuid(current->audit_context),
+ audit_get_sessionid(current->audit_context));
selinux_enforcing = new_value;
if (selinux_enforcing)
avc_ss_reset(0);
@@ -229,8 +230,9 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf,
if (length < 0)
goto out;
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
- "selinux=0 auid=%u",
- audit_get_loginuid(current->audit_context));
+ "selinux=0 auid=%u ses=%u",
+ audit_get_loginuid(current->audit_context),
+ audit_get_sessionid(current->audit_context));
}
length = count;
@@ -335,8 +337,9 @@ out1:
(security_get_allow_unknown() ? "allow" : "deny")));
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
- "policy loaded auid=%u",
- audit_get_loginuid(current->audit_context));
+ "policy loaded auid=%u ses=%u",
+ audit_get_loginuid(current->audit_context),
+ audit_get_sessionid(current->audit_context));
out:
mutex_unlock(&sel_mutex);
vfree(data);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index d572dc9..c1ea08c 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1897,11 +1897,12 @@ int security_set_bools(int len, int *values)
if (!!values[i] != policydb.bool_val_to_struct[i]->state) {
audit_log(current->audit_context, GFP_ATOMIC,
AUDIT_MAC_CONFIG_CHANGE,
- "bool=%s val=%d old_val=%d auid=%u",
+ "bool=%s val=%d old_val=%d auid=%u ses=%u",
policydb.p_bool_val_to_name[i],
!!values[i],
policydb.bool_val_to_struct[i]->state,
- audit_get_loginuid(current->audit_context));
+ audit_get_loginuid(current->audit_context),
+ audit_get_sessionid(current->audit_context));
}
if (values[i]) {
policydb.bool_val_to_struct[i]->state = 1;
17 years
New Version of Certification Test Suite
by Jon Wallace
HP has posted an updated version of the audit-test suite for the audit and MLS
portions of CAPP/LSPP/RBACPP certification on RHEL5.1.
http://sourceforge.net/projects/audit-test/
The suite is available as a tarball, a source rpm, and as a noarch
rpm which will install files into /usr/local/eal4_testing/audit-test.
There are 3 README files which describe how to run the tests, how to
develop tests, and how to configure the test server for network tests.
These tests are known to pass on RHEL5.1 plus the updated packages listed
in our security target in both CAPP mode (optional targeted policy) and
LSPP mode (mls policy) on x86_64 and ia64 architectures. Code exists for
other architectures but no other architectures have been tested with this
version of the test suite. The updated tests fix failures that were due to
changes in some of the pam audit records.
We would appreciate feedback as well as patches through the
sourceforge project trackers if you use and update the suite.
We are especially interested in hearing from people running the
tests on other distros, with or without SELinux.
Thanks,
Jon
17 years
some problem with my event dispatcher
by Abhishek Gupta
This is a just a sample real time event dispatcher program from
http://people.redhat.com/sgrubb/audit/audit-rt-events.txt.
I am just trying to write the data coming from daemon in some regular file
instead of syslog.But it seems that even the file is not getting
created.Isthere some kind of restriction that we can't call functions
like
fopen(),open(),etc ?
Please tell what's the problem and how it can be solved.
And if possible just give an sample example so that i can understand it
better.
The added lines of code i have marked with "+".
Here is the code..
#include <stdio.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <locale.h>
#include "libaudit.h"
// Local data
static volatile int signaled = 0;
static int pipe_fd;
static const char *pgm = "skeleton";
// Local functions
static int event_loop(void);
// SIGTERM handler
static void term_handler( int sig )
{
signaled = 1;
}
/*
* main is started by auditd. See dispatcher in auditd.conf
*/
int main(int argc, char *argv[])
{
struct sigaction sa;
setlocale (LC_ALL, "");
openlog(pgm, LOG_PID, LOG_DAEMON);
syslog(LOG_NOTICE, "starting...");
#ifndef DEBUG
// Make sure we are root
if (getuid() != 0) {
syslog(LOG_ERR, "You must be root to run this program.");
return 4;
}
#endif
// register sighandlers
sa.sa_flags = 0 ;
sa.sa_handler = term_handler;
sigemptyset( &sa.sa_mask ) ;
sigaction( SIGTERM, &sa, NULL );
sa.sa_handler = term_handler;
sigemptyset( &sa.sa_mask ) ;
sigaction( SIGCHLD, &sa, NULL );
sa.sa_handler = SIG_IGN;
sigaction( SIGHUP, &sa, NULL );
(void)chdir("/");
// change over to pipe_fd
pipe_fd = dup(0);
close(0);
open("/dev/null", O_RDONLY);
fcntl(pipe_fd, F_SETFD, FD_CLOEXEC);
// Start the program
return event_loop();
}
static int event_loop(void)
{
void* data;
+ FILE* fp=NULL;
struct iovec vec[2];
struct audit_dispatcher_header hdr;
// allocate data structures
data = malloc(MAX_AUDIT_MESSAGE_LENGTH);
if (data == NULL) {
syslog(LOG_ERR, "Cannot allocate buffer");
return 1;
}
memset(data, 0, MAX_AUDIT_MESSAGE_LENGTH);
memset(&hdr, 0, sizeof(hdr));
do {
int rc;
struct timeval tv;
fd_set fd;
tv.tv_sec = 1;
tv.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(pipe_fd, &fd);
rc = select(pipe_fd+1, &fd, NULL, NULL, &tv);
if (rc == 0)
continue;
else if (rc == -1)
break;
/* Get header first. it is fixed size */
vec[0].iov_base = (void*)&hdr;
vec[0].iov_len = sizeof(hdr);
// Next payload
vec[1].iov_base = data;
vec[1].iov_len = MAX_AUDIT_MESSAGE_LENGTH;
rc = readv(pipe_fd, vec, 2);
if (rc == 0 || rc == -1) {
syslog(LOG_ERR, "rc == %d(%s)", rc, strerror(errno));
break;
}
// handle events here. Just for illustration, we print
// to syslog, but you will want to do something else.
+ //I want to write the data in some regular file instead of syslog
but in doing that it seems that even
+ // the file doesn't get created or open.Given below is just a
simple code
+ fp=fopen("tempfile.txt","w+");
+ fwrite((char*)data,sizeof(char),30,fp);
+ fclose(fp);
syslog(LOG_NOTICE,"type=%d, payload size=%d",
hdr.type, hdr.size);
syslog(LOG_NOTICE,"data=\"%.*s\"", hdr.size,
(char *)data);
} while(!signaled);
return 0;
}
17 years
Matt Weale/UK/CSC is out of the office.
by Matt Weale
I will be out of the office starting 12/12/2007 and will not return until
03/01/2008.
In my absence please contact either Les Klein or Andy Booth.
17 years
Audit DB support.........
by kunal chandarana
Hey people I am planning to add DB support in audit functionality in linux.
I have some queries so if u ppl could reply to this then it will help me a
lot.
1) Should each name/value pair be turned into fields with a record?
2) Should each record be a table?
3) Should each event be a table?
4) Should event and its subrecords be reworked into one record that pulls
out only the important data?
5) what kind of reports will be useful to run from the database. ?
6) what kind of reporting user will find useful. ?
7) What are the main reports and what information should they contain?
17 years
Re: [PATCH, v3 8/8] audispd-zos-remote plugin - build and packaging infrastructure
by Klaus Heinrich Kiwi
This patch brings the Makefiles and spec files integration. The spec
file builds the policy module for strict, targeted and mls modules,
installing the compiled .pp files
into /usr/share/selinux/{mls,strict,targeted}/zos-remote.pp.
The mechanics for doing this is based on
http://fedoraproject.org/wiki/PackagingDrafts/SELinux/PolicyModules, but
with a little change on how to get the %{selinux_policyver} variable
(reason: wasn't able to load policy built on RHEL5.1 on RHEL5 GA, even
though the policy version is the same - so we must also track for
package releases).
Using rpm to query the selinux-policy package version inside a spec file
is ugly - I know. Please tell me if you think of a better approach.
Signed-off-by: Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
diff -purN audit-1.6.2/audisp/plugins/Makefile.am audit-1.6.2_zos-remote/audisp/plugins/Makefile.am
--- audit-1.6.2/audisp/plugins/Makefile.am 2007-09-12 14:25:13.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/Makefile.am 2007-12-04 12:55:30.000000000 -0200
@@ -22,5 +22,5 @@
CONFIG_CLEAN_FILES = Makefile.in *.loT *.rej *.orig
-SUBDIRS = builtins ids remote
+SUBDIRS = builtins ids remote zos-remote
diff -purN audit-1.6.2/audisp/plugins/zos-remote/Makefile.am audit-1.6.2_zos-remote/audisp/plugins/zos-remote/Makefile.am
--- audit-1.6.2/audisp/plugins/zos-remote/Makefile.am 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/Makefile.am 2007-12-04 16:32:02.000000000 -0200
@@ -0,0 +1,52 @@
+# Makefile.am--
+# Copyright (C) 2007 International Business Machines Corp.
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Authors:
+# Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
+#
+
+INCLUDES = -I.. -I${top_srcdir}/lib -I${top_srcdir}/auparse
+CONFIG_CLEAN_FILES = Makefile.in *.rej *.orig
+AUTOMAKE_OPTIONS = no-dependencies
+EXTRA_DIST = zos-remote.conf audispd-zos-remote.conf \
+ policy/audispd-zos-remote.te policy/audispid-zos-remote.fc\
+ policy/audispd-zos-remote.if policy/build.sh policy/install.sh
+LIBS = -L${top_srcdir}/auparse -lauparse
+LDADD = -lpthread -lldap -llber
+dispatcher_confdir = $(sysconfdir)/audisp
+plugin_confdir=$(dispatcher_confdir)/plugins.d
+plugin_conf = zos-remote.conf
+dispatcher_conf = audispd-zos-remote.conf
+sbin_PROGRAMS = audispd-zos-remote
+
+noinst_HEADERS = zos-remote-log.h zos-remote-ldap.h zos-remote-config.h \
+ zos-remote-queue.h
+audispd_zos_remote_SOURCES = zos-remote-plugin.c zos-remote-log.c \
+ zos-remote-ldap.c zos-remote-config.c zos-remote-queue.c
+audispd_zos_remote_CFLAGS = -W -Wall -Wundef -D_GNU_SOURCE
+
+install-data-hook:
+ mkdir -p -m 0750 ${DESTDIR}${plugin_confdir}
+ $(INSTALL_DATA) -D -m 640 ${srcdir}/$(plugin_conf) \
+ ${DESTDIR}${dispatcher_confdir}
+ $(INSTALL_DATA) -D -m 640 ${srcdir}/$(dispatcher_conf) \
+ ${DESTDIR}${plugin_confdir}
+
+uninstall-hook:
+ rm ${DESTDIR}${plugin_confdir}/$(dispatcher_conf)
+ rm ${DESTDIR}${dispatcher_confdir}/$(plugin_conf)
diff -purN audit-1.6.2/audit.spec audit-1.6.2_zos-remote/audit.spec
--- audit-1.6.2/audit.spec 2007-09-25 08:46:49.000000000 -0300
+++ audit-1.6.2_zos-remote/audit.spec 2007-12-13 13:12:46.000000000 -0200
@@ -1,4 +1,6 @@
%define sca_version 0.4.3
+%define selinux_variants mls strict targeted
+%define selinux_policyver %(rpm -q selinux-policy | sed -e 's,^selinux-policy-\\([^/]*\\)$,\\1,')
Summary: User space tools for 2.6 kernel auditing
Name: audit
@@ -53,18 +55,26 @@ Requires: %{name}-libs = %{version}-%{re
The audit-libs-python package contains the bindings so that libaudit
and libauparse can be used by python.
-##%package -n audispd-plugins
-##Summary: Plugins for the audit event dispatcher
-##License: GPLv2+
-##Group: System Environment/Daemons
-##Requires: %{name} = %{version}-%{release}
-##Requires: %{name}-libs = %{version}-%{release}
-
-##%description -n audispd-plugins
-##The audispd-plugins package provides plugins for the real-time
-##interface to the audit system, audispd. These plugins can do things
-##like relay events to remote machines or analyze events for suspicious
-##behavior.
+%package -n audispd-plugins
+Summary: Plugins for the audit event dispatcher
+License: GPLv2+
+Group: System Environment/Daemons
+BuildRequires: openldap-devel rpm
+BuildRequires: checkpolicy selinux-policy-devel
+Requires: %{name} = %{version}-%{release}
+Requires: %{name}-libs = %{version}-%{release}
+Requires: openldap
+%if "%{selinux_policyver}" != ""
+Requires: selinux-policy >= %{selinux_policyver}
+%endif
+Requires(post): /usr/sbin/semodule /sbin/restorecon
+Requires(postun): /usr/sbin/semodule
+
+%description -n audispd-plugins
+The audispd-plugins package provides plugins for the real-time
+interface to the audit system, audispd. These plugins can do things
+like relay events to remote machines or analyze events for suspicious
+behavior.
%package -n system-config-audit
Summary: Utility for editing audit configuration
@@ -78,12 +88,22 @@ An utility for editing audit configurati
%prep
%setup -q
+mkdir zos-remote-policy
+cp -p audisp/plugins/zos-remote/policy/audispd-zos-remote.* zos-remote-policy
%build
(cd system-config-audit; ./autogen.sh)
aclocal && autoconf && autoheader && automake
%configure --sbindir=/sbin --libdir=/%{_lib}
make
+cd zos-remote-policy
+for selinuxvariant in %{selinux_variants}
+do
+ make NAME=${selinuxvariant} -f /usr/share/selinux/devel/Makefile
+ mv audispd-zos-remote.pp audispd-zos-remote.pp.${selinuxvariant}
+ make NAME=${selinuxvariant} -f /usr/share/selinux/devel/Makefile clean
+done
+cd -
%install
rm -rf $RPM_BUILD_ROOT
@@ -94,6 +114,12 @@ mkdir -p $RPM_BUILD_ROOT/%{_libdir}/audi
mkdir -p $RPM_BUILD_ROOT/%{_var}/log/audit
make DESTDIR=$RPM_BUILD_ROOT install
make -C system-config-audit DESTDIR=$RPM_BUILD_ROOT install-fedora
+for selinuxvariant in %{selinux_variants}
+do
+ install -d $RPM_BUILD_ROOT/%{_datadir}/selinux/${selinuxvariant}
+ install -p -m 644 zos-remote-policy/audispd-zos-remote.pp.${selinuxvariant} \
+ $RPM_BUILD_ROOT/%{_datadir}/selinux/${selinuxvariant}/audispd-zos-remote.pp
+done
mkdir -p $RPM_BUILD_ROOT/%{_libdir}
# This winds up in the wrong place when libtool is involved
@@ -124,13 +150,24 @@ touch -r ./audit.spec $RPM_BUILD_ROOT/et
# Remove the plugin stuff for now
rm -f $RPM_BUILD_ROOT/etc/audisp/plugins.d/au-ids.conf
rm -f $RPM_BUILD_ROOT/etc/audisp/plugins.d/remote.conf
+##rm -f $RPM_BUILD_ROOT/etc/audisp/plugins.d/audispd-zos-remote.conf
+##rm -f $RPM_BUILD_ROOT/etc/audisp/zos-remote.conf
rm -f $RPM_BUILD_ROOT/sbin/audisp-ids
+##rm -f $RPM_BUILD_ROOT/sbin/audispd-zos-remote
%clean
rm -rf $RPM_BUILD_ROOT
%post libs -p /sbin/ldconfig
+%post -n audispd-plugins
+for selinuxvariant in %{selinux_variants}
+do
+ /usr/sbin/semodule -s $selinuxvariant \
+ -i %{_datadir}/selinux/$selinuxvariant/audispd-zos-remote.pp &> /dev/null || :
+done
+/sbin/restorecon -F /sbin/audispd-zos-remote /etc/audisp/zos-remote.conf
+
%post
/sbin/chkconfig --add auditd
if [ -f /etc/auditd.conf ]; then
@@ -157,6 +194,14 @@ fi
%postun libs
/sbin/ldconfig 2>/dev/null
+%postun -n audispd-plugins
+if [ $1 -eq 0 ]; then
+ for selinuxvariant in %{selinux_variants}
+ do
+ /usr/sbin/semodule -s $selinuxvariant -r audispd-zos-remote &>/dev/null || :
+ done
+fi
+
%postun
if [ $1 -ge 1 ]; then
/sbin/service auditd condrestart > /dev/null 2>&1 || :
@@ -189,8 +234,14 @@ fi
%files
%defattr(-,root,root,-)
%doc README COPYING ChangeLog contrib/capp.rules contrib/nispom.rules contrib/lspp.rules init.d/auditd.cron
-%attr(0644,root,root) %{_mandir}/man8/*
-%attr(0644,root,root) %{_mandir}/man5/*
+%attr(0644,root,root) %{_mandir}/man8/audispd.8.gz
+%attr(0644,root,root) %{_mandir}/man8/auditctl.8.gz
+%attr(0644,root,root) %{_mandir}/man8/auditd.8.gz
+%attr(0644,root,root) %{_mandir}/man8/aureport.8.gz
+%attr(0644,root,root) %{_mandir}/man8/ausearch.8.gz
+%attr(0644,root,root) %{_mandir}/man8/autrace.8.gz
+%attr(0644,root,root) %{_mandir}/man5/auditd.conf.5.gz
+%attr(0644,root,root) %{_mandir}/man5/audispd.conf.5.gz
%attr(750,root,root) /sbin/auditctl
%attr(750,root,root) /sbin/auditd
%attr(755,root,root) /sbin/ausearch
@@ -210,11 +261,17 @@ fi
%attr(640,root,root) /etc/audisp/plugins.d/af_unix.conf
%attr(640,root,root) /etc/audisp/plugins.d/syslog.conf
-##%files -n audispd-plugins
-##%defattr(-,root,root,-)
+%files -n audispd-plugins
+%defattr(-,root,root,-)
+%attr(0644,root,root) %{_mandir}/man8/audispd-zos-remote.8.gz
+%attr(0644,root,root) %{_mandir}/man5/zos-remote.conf.5.gz
##%attr(640,root,root) /etc/audisp/plugins.d/au-ids.conf
##%attr(640,root,root) /etc/audisp/plugins.d/remote.conf
+%config(noreplace) %attr(640,root,root) /etc/audisp/plugins.d/audispd-zos-remote.conf
+%config(noreplace) %attr(640,root,root) /etc/audisp/zos-remote.conf
##%attr(750,root,root) /sbin/audisp-ids
+%attr(750,root,root) /sbin/audispd-zos-remote
+%attr(0755,root,root) %{_datadir}/selinux/*/audispd-zos-remote.pp
%files -n system-config-audit -f system-config-audit.lang
%defattr(-,root,root,-)
diff -purN audit-1.6.2/configure.ac audit-1.6.2_zos-remote/configure.ac
--- audit-1.6.2/configure.ac 2007-09-12 14:26:41.000000000 -0300
+++ audit-1.6.2_zos-remote/configure.ac 2007-12-04 15:14:47.000000000 -0200
@@ -109,7 +109,7 @@ if test x$use_apparmor != xno ; then
AC_DEFINE(WITH_APPARMOR,1,[Define if you want to enable AppArmor events.])fi
AC_CONFIG_SUBDIRS([system-config-audit])
-AC_OUTPUT(Makefile lib/Makefile auparse/Makefile auparse/test/Makefile src/Makefile src/mt/Makefile swig/Makefile docs/Makefile init.d/Makefile audisp/Makefile audisp/plugins/Makefile audisp/plugins/builtins/Makefile audisp/plugins/ids/Makefile audisp/plugins/remote/Makefile bindings/Makefile bindings/python/Makefile)
+AC_OUTPUT(Makefile lib/Makefile auparse/Makefile auparse/test/Makefile src/Makefile src/mt/Makefile swig/Makefile docs/Makefile init.d/Makefile audisp/Makefile audisp/plugins/Makefile audisp/plugins/builtins/Makefile audisp/plugins/ids/Makefile audisp/plugins/remote/Makefile audisp/plugins/zos-remote/Makefile bindings/Makefile bindings/python/Makefile)
echo .
echo "
diff -purN audit-1.6.2/docs/Makefile.am audit-1.6.2_zos-remote/docs/Makefile.am
--- audit-1.6.2/docs/Makefile.am 2007-09-18 12:31:41.000000000 -0300
+++ audit-1.6.2_zos-remote/docs/Makefile.am 2007-12-04 12:56:13.000000000 -0200
@@ -46,5 +46,5 @@ auparse_node_compare.3 auparse_reset.3 a
aureport.8 ausearch.8 ausearch_add_item.3 ausearch_add_regex.3 \
ausearch_clear.3 ausearch_next_event.3 ausearch_set_stop.3 \
autrace.8 get_auditfail_action.3 set_aumessage_mode.3 \
-audispd.8 audispd.conf.5
+audispd.8 audispd.conf.5 audispd-zos-remote.8 zos-remote.conf.5
--
Klaus Heinrich Kiwi <klausk(a)linux.vnet.ibm.com>
IBM STG, Linux Technology Center
17 years
Re: [PATCH, v3 7/8] audispd-zos-remote plugin - manual pages
by Klaus Heinrich Kiwi
This patch brings the audispd-zos-remote(8) and zos-remote.conf(5)
manual pages.
Those also bring some information on how to configure an IBM z/OS server
running ITDS to enable Remote Auditing processing, as well as how to
configure the required @LINUX class.
Signed-off-by: Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
diff -purN audit-1.6.2/docs/audispd-zos-remote.8 audit-1.6.2_zos-remote/docs/audispd-zos-remote.8
--- audit-1.6.2/docs/audispd-zos-remote.8 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/docs/audispd-zos-remote.8 2007-12-04 14:44:22.000000000 -0200
@@ -0,0 +1,239 @@
+.\" Copyright (c) International Business Machines Corp., 2007
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+.\" the GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+.\" MA 02111-1307 USA
+.\"
+.\" Changelog:
+.\" 2007-10-06, created by Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
+.\"
+.TH AUDISP-RACF 8 "Oct 2007" "IBM" "System Administration Utilities"
+.SH NAME
+audispd-zos-remote \- z/OS Remote-services Audit dispatcher plugin
+.SH SYNOPSIS
+.B audispd-zos-remote [
+.I config-file
+.B ]
+.SH DESCRIPTION
+.BR audispd-zos-remote
+is a remote-auditing plugin for the Audit subsystem. It should be started by the
+.BR audispd(8)
+daemon and will forward all incoming audit events, as they happen, to a configured z/OS SMF (Service Management Facility) database, through an IBM Tivoli Directory Server (ITDS) set for Remote Audit service.
+See
+.B SMF MAPPING
+section below for more information about the resulting SMF record format.
+
+.BR audispd(8)
+must be configured to start the plugin. This is done by a configuration file usually located at
+.IR /etc/audisp/plugins.d/audispd-zos-remote.conf ,
+but multiple instances can be spawned by having multiple configuration files in
+.I /etc/audisp/plugins.d
+for the same plugin executable (see
+.BR audispd(8) ).
+
+Each instance needs a configuration file, located by default at
+.IR /etc/audisp/zos-remote.conf .
+Check
+.BR zos-remote.conf(5)
+for details about the plugin configuration.
+
+.SH OPTIONS
+.IP config-file
+Use an alternate configuration file instead of
+.IR /etc/audisp/zos-remote.conf .
+
+.SH SIGNALS
+.BR audispd-zos-remote
+reacts to SIGTERM and SIGHUP signals (according to the
+.BR audispd(8)
+specification):
+.TP
+.B SIGHUP
+Instructs the
+.B audispd-zos-remote
+plugin to re-read it's configuration and flush existing network connections.
+.TP
+.B SIGTERM
+Performs a clean exit.
+.B audispd-zos-remote
+will wait up to 10 seconds if there are queued events to be delivered, dropping any remaining queued events after that time.
+
+.SH IBM z/OS ITDS Server and RACF configuration
+In order to use this plugin, you must have an IBM z/OS v1R8 (or higher) server with IBM Tivoli Directory Server (ITDS) configured for Remote Audit service. For more detailed information about how to configure the z/OS server for Remote Auditing, refer to
+.B z/OS V1R8.0-9.0 Intergrated Security Services Enterprise Identity Mapping (EIM) Guide and Reference
+.RI ( http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/FRAMESET/EIMA1140/CC... ),
+chapter "2.0 - Working with remote services".
+
+.SS Enable ITDS to process Remote Audit requests
+To enable ITSD to process Remote Audit requests, the user ID associated with ITDS must be granted READ access to the IRR.AUDITX FACILITY Class profile (the profile used to protect the R_Auditx service). This user ID can usually be found in the STARTED Class profile for the ITDS started procedure. If the identity associated with ITDS is
+.IR ITDSUSER ,
+the administrator can configure RACF to grant Remote Auditing processing to ITDS with the following TSO commands:
+.TP
+.I TSO Commands: Grant ITDSUSER READ access to IRR.AUDITX FACILITY Class profile
+.nf
+rdefine FACILITY IRR.RAUDITX uacc(none)
+permit IRR.RAUDITX class(FACILITY) id(ITDSUSER) access(READ)
+.fi
+
+.SS Create/enable RACF user ID to perform Remote Audit requests
+A z/OS RACF user ID is needed by the plugin - Every Audit request performed by the plugin will use a RACF user ID, as configured in the plugin configuration (
+.BR zos-remote.conf(5) ).
+This user ID needs READ access to FACILITY Class resource IRR.LDAP.REMOTE.AUDIT. If the user ID is
+.IR BINDUSER ,
+the administrator can configure RACF to enable this user to perform Remote Auditing requests with the following TSO commands:
+.TP
+.I TSO Commands: Enable BINDUSER to perform Remote Audit requests
+.nf
+rdefine FACILITY IRR.LDAP.REMOTE.AUDIT uacc(none)
+permit IRR.LDAP.REMOTE.AUDIT class(FACILITY) id(BINDUSER) access(READ)
+.fi
+
+.SS Add @LINUX Class to RACF
+When performing remote auditing requests, the
+.B audispd-zos-remote
+plugin will use the special
+.B @LINUX
+.I CDT Class
+and the audit record type (eg.:
+.BR SYSCALL ,
+.BR AVC ,
+.BR PATH ...)
+as the
+.R CDT Resource Class
+for all events processed.
+To make sure events are logged, the RACF server must be configured with a Dynamic CDT Class named
+.B @LINUX
+with correct sizes and attributes. The following TSO commands can be used to add this class:
+.TP
+.I TSO Commands: Add @LINUX CDT Class
+.nf
+rdefine cdt @LINUX cdtinfo(posit(493) FIRST(alpha,national,numeric,special) OTHER(alpha,national,numeric,special) RACLIST(REQUIRED) case(asis) generic(allowed) defaultuacc(none) maxlength(246))
+setr classact(cdt)
+setr raclist(cdt)
+setr raclist(cdt) refresh
+setr classact(@LINUX)
+setr raclist(@LINUX)
+setr generic(@LINUX)
+.fi
+
+.SS Add profiles to the @LINUX Class
+Once the CDT Class has been defined, you can add profiles to it, specifying resources (wildcards allowed) to log or ignore. The following are examples:
+.TP
+.I TSO Commands: Log only AVC records (One generic and one discrete profile):
+.nf
+rdefine @LINUX * uacc(none) audit(none(read))
+rdefine @LINUX AVC uacc(none) audit(all(read))
+setr raclist(@LINUX) refresh
+.fi
+
+.TP
+.I TSO Commands: Log everything (One generic profile):
+.nf
+rdefine @LINUX * uacc(none) audit(all(read))
+setr raclist(@LINUX) refresh
+.fi
+
+.P
+Resources always match the single profile with the
+.I best
+match.
+
+There are many other ways to define logging in RACF. Please refer to the server documentation for more details.
+
+.SH SMF Mapping
+The ITDS Remote Audit service will cut SMF records of type 83 subtype 4 everytime it processes a request. This plugin will issue a remote audit request for every incoming Linux Audit record (meaning that one Linux record will map to one SMF record), and fill this type's records with the following:
+.SS Link Value
+The Linux event serial number, encoded in network-byte order hexadecimal representation. Records within the same Event share the same Link Value.
+.SS Violation
+Always zero (0) -
+.I False
+.SS Event Code
+Always two (2) -
+.I Authorization
+event
+.SS Event Qualifier
+Zero (0) -
+.IR Success ,
+if the event reported
+.B success=yes
+or
+.BR res=success ,
+Three (3) -
+.IR Fail ,
+if the event reported
+.B success=no
+or
+.BR res=failed ,
+or One (1) -
+.I Info
+otherwise.
+.SS Class
+Always
+.I @LINUX
+.SS Resource
+The Linux record type for the processed record. e.g.:
+.IR SYSCALL , AVC , PATH , CWD
+etc.
+.SS Log String
+Textual message bringing the RACF user ID used to perform the request, plus the Linux hostname and the record type for the first record in the processed event. e.g.:
+.I Remote audit request from RACFUSER. Linux (hostname.localdomain):USER_AUTH
+.SS Data Field List
+Also known as
+.IR relocates ,
+this list will bring all the field names and values in a
+.B fieldname=value
+format, as a type 114
+.RB ( "Appication specific Data" )
+relocate. The plug-in will try to interpret those fields (i.e.: use human-readable username
+.B root
+instead of numeric userid
+.BR 0 )
+whenever possible. Currently, this plugin will also add a relocate type 113
+.RB ( "Date And Time Security Event Occurred" )
+with the Event Timestamp in the format as returned by
+.BR ctime(3) .
+
+.SH ERRORS
+Errors and warnings are reported to syslog (under DAEMON facility). In situations where the event was submitted but the z/OS server returned an error condition, the logged message brings a name followed by a human-readable description. Below are some common errors conditions:
+
+.TP
+.B NOTREQ - No logging required
+Resource (audit record type) is not set to be logged in the RACF server - The @LINUX Class profile governing this audit record type is set to ignore. See
+.B IBM z/OS RACF Server configuration
+.TP
+.B UNDETERMINED - Undetermined result
+No profile found for specified resource. There is no @LINUX Class configured or no @LINUX Class profile associated with this audit record type. See
+.B IBM z/OS RACF Server configuration
+.TP
+.B UNAUTHORIZED - The user does not have authority the R_auditx service
+The user ID associated with the ITDS doesn't have READ access to the IRR.AUDITX FACILITY Class profile. See
+.B IBM z/OS RACF Server configuration
+.TP
+.B UNSUF_AUTH - The user has unsuficient authority for the requested function
+The RACF user ID used to perform Remote Audit requests (as configured in
+.BR zos-remote.conf(5) )
+don't have access to the IRR.LDAP.REMOTE.AUDIT FACILITY Class profile. See
+.B IBM z/OS RACF Server configuration
+
+.SH BUGS
+The plugin currently does remote auditing in a best-effort basis, and will dischard events in case the z/OS server cannot be contacted (network failures) or in any other case that event submission fails.
+
+.SH FILES
+/etc/audisp/plugins.d/audispd-zos-remote.conf
+/etc/audisp/zos-remote.conf
+.SH "SEE ALSO"
+.BR auditd (8),
+.BR zos-remote.conf (5).
+.SH AUTHOR
+Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
diff -purN audit-1.6.2/docs/zos-remote.conf.5 audit-1.6.2_zos-remote/docs/zos-remote.conf.5
--- audit-1.6.2/docs/zos-remote.conf.5 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/docs/zos-remote.conf.5 2007-12-04 14:50:54.000000000 -0200
@@ -0,0 +1,69 @@
+.\" Copyright (c) International Business Machines Corp., 2007
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+.\" the GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+.\" MA 02111-1307 USA
+.\"
+.\" Changelog:
+.\" 2007-10-06, created by Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
+.\"
+.TH ZOS\-REMOTE.CONF 8 "Oct 2007" "IBM" "System Administration Utilities"
+.SH NAME
+zos\-remote.conf \- the audisp-racf plugin configuration file
+.SH DESCRIPTION
+.B zos-remote.conf
+controls the configuration for the
+.BR audispd-zos-remote(8)
+Audit dispatcher plugin. The default location for this file is
+.IR /etc/audisp/zos-remote.conf ,
+however, a different file can be specified as the first argument to the
+.B audispd-zos-remote
+plugin. See
+.BR audispd-zos-remote(8)
+and
+.BR auditd(8) .
+The options available are as follows:
+.TP
+.I server
+This is the IBM z/OS ITDS server hostname or IP address
+.TP
+.I port
+The port number where ITDS is running on the z/OS server. Default is 389 (ldap port)
+.TP
+.I user
+The z/OS RACF user ID which the audispd-zos-remote plugin will use to perform Remote Audit requests. This user needs READ access to FACILITY Class resource IRR.LDAP.REMOTE.AUDIT (See
+.BR audispd-zos-remote(8) ).
+.TP
+.I password
+The password associated the the z/OS user ID configured above.
+.TP
+.I timeout
+The number in seconds that
+.B audispd-zos-remote
+plugin will wait before giving up in connection attemps and event submissions. The default value is 15
+.TP
+.I q_depth
+The
+.B audispd-zos-remote
+plugin will queue inputed events to the maximum of
+.I q_depth
+events while trying to submit those remotely. This can handle burst of events or in case of a slow network connection. However, the
+.B audispd-zos-remote
+plugin will drop events in case the queue is full. The default queue depth is 64 - Increase this value in case you are experiencing event drop due to full queue
+.RB ( audispd-zos-remote
+will log this to syslog).
+.SH "SEE ALSO"
+.BR audispd-zos-remote (8)
+.SH AUTHOR
+Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
--
Klaus Heinrich Kiwi <klausk(a)linux.vnet.ibm.com>
IBM STG, Linux Technology Center
17 years
Re: [PATCH, v3 6/8] audispd-zos-remote plugin - plugin main code
by Klaus Heinrich Kiwi
This patch implements the main body for the zos-remote plugin. It uses
the auparse_feed() interface to add a callback interface that's called
whenever a complete event is read from stdin.
The push_event() callback does the BER encoding and enqueues the encoded
event.
The 'submission_thread' then dequeues it and synchronously submits it to
the z/OS server (using the ldap interface).
SIGHUP re-reads the configuration file and forces a LDAP interface
reinitialization (forcing network connection flush). The submission
thread is stopped and restarted to avoid messing with the queue in an
invalid state. The queue is not touched between SIGHUPS.
Signed-off-by: Klaus Heinrich Kiwi <klausk(a)br.ibm.com>
diff -purN audit-1.6.2/audisp/plugins/zos-remote/zos-remote-plugin.c audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-plugin.c
--- audit-1.6.2/audisp/plugins/zos-remote/zos-remote-plugin.c 1969-12-31 21:00:00.000000000 -0300
+++ audit-1.6.2_zos-remote/audisp/plugins/zos-remote/zos-remote-plugin.c 2007-12-04 15:41:33.000000000 -0200
@@ -0,0 +1,558 @@
+/***************************************************************************
+* Copyright (C) 2007 International Business Machines Corp. *
+* All Rights Reserved. *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+* *
+* Authors: *
+* Klaus Heinrich Kiwi <klausk(a)br.ibm.com> *
+***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <limits.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+#include <lber.h>
+#include <netinet/in.h>
+#include "auparse.h"
+#include "zos-remote-log.h"
+#include "zos-remote-ldap.h"
+#include "zos-remote-config.h"
+#include "zos-remote-queue.h"
+
+/*
+ * Global vars
+ */
+volatile int stop = 0;
+volatile int hup = 0;
+volatile ZOS_REMOTE zos_remote_inst;
+static plugin_conf_t conf;
+static const char *def_config_file = "/etc/audisp/zos-remote.conf";
+static pthread_t submission_thread;
+pid_t mypid = 0;
+
+/*
+ * SIGTERM handler
+ */
+static void term_handler(int sig)
+{
+ log_info("Got Termination signal - shutting down plugin");
+ stop = 1;
+ nudge_queue();
+}
+
+/*
+ * SIGHUP handler - re-read config, reconnect to ITDS
+ */
+static void hup_handler(int sig)
+{
+ log_info("Got Hangup signal - flushing plugin configuration");
+ hup = 1;
+ nudge_queue();
+}
+
+/*
+ * SIGALRM handler - help force exit when terminating daemon
+ */
+static void alarm_handler(int sig)
+{
+ log_err("Timeout waiting for submission thread - Aborting (some events may have been dropped)");
+ pthread_cancel(submission_thread);
+}
+
+/*
+ * The submission thread
+ * It's job is to dequeue the events from the queue
+ * and sync submit them to ITDS
+ */
+static void *submission_thread_main(void *arg)
+{
+ int rc;
+
+ log_debug("Starting event submission thread");
+
+ rc = zos_remote_init(&zos_remote_inst, conf.server,
+ conf.port, conf.user,
+ conf.password,
+ conf.timeout);
+
+ if (rc != ICTX_SUCCESS) {
+ log_err("Error - Failed to initialize session to z/OS ITDS Server");
+ stop = 1;
+ return 0;
+ }
+
+ while (stop == 0) {
+ /* block until we have an event */
+ BerElement *ber = dequeue();
+
+ if (ber == NULL) {
+ if (hup) {
+ break;
+ }
+ continue;
+ }
+ debug_ber(ber);
+ rc = submit_request_s(&zos_remote_inst, ber);
+ if (rc == ICTX_E_FATAL) {
+ log_err("Error - Fatal error in event submission. Aborting");
+ stop = 1;
+ } else if (rc != ICTX_SUCCESS) {
+ log_warn("Warning - Event submission failure - event dropped");
+ }
+ else {
+ log_debug("Event submission success");
+ }
+ ber_free(ber, 1); /* also free BER buffer */
+ }
+ log_debug("Stopping event submission thread");
+ zos_remote_destroy(&zos_remote_inst);
+
+ return 0;
+}
+
+
+/*
+ * auparse library callback that's called when an event is ready
+ */
+void
+push_event(auparse_state_t * au, auparse_cb_event_t cb_event_type,
+ void *user_data)
+{
+ int rc;
+ BerElement *ber;
+ int qualifier;
+ char timestamp[26];
+ char linkValue[ZOS_REMOTE_LINK_VALUE_SIZE];
+ char logString[ZOS_REMOTE_LOGSTRING_SIZE];
+ unsigned long linkValue_tmp;
+
+ if (cb_event_type != AUPARSE_CB_EVENT_READY)
+ return;
+
+ const au_event_t *e = auparse_get_timestamp(au);
+ if (e == NULL)
+ return;
+ /*
+ * we have an event. Each record will result in a different 'Item'
+ * (refer ASN.1 definition in zos-remote-ldap.h)
+ */
+
+ /*
+ * Create a new BER element to encode the request
+ */
+ ber = ber_alloc_t(LBER_USE_DER);
+ if (ber == NULL) {
+ log_err("Error allocating memory for BER element");
+ goto fatal;
+ }
+
+ /*
+ * Collect some information to fill in every item
+ */
+ const char *node = auparse_get_node(au);
+ const char *orig_type = auparse_find_field(au, "type");
+ /* roll back event to get 'success' */
+ auparse_first_record(au);
+ const char *success = auparse_find_field(au, "success");
+ /* roll back event to get 'res' */
+ auparse_first_record(au);
+ const char *res = auparse_find_field(au, "res");
+
+ /* check if this event is a success or failure one */
+ if (success) {
+ if (strncmp(success, "0", 1) == 0 ||
+ strncmp(success, "no", 2) == 0)
+ qualifier = ZOS_REMOTE_QUALIF_FAIL;
+ else
+ qualifier = ZOS_REMOTE_QUALIF_SUCCESS;
+ } else if (res) {
+ if (strncmp(res, "0", 1) == 0
+ || strncmp(res, "failed", 6) == 0)
+ qualifier = ZOS_REMOTE_QUALIF_FAIL;
+ else
+ qualifier = ZOS_REMOTE_QUALIF_SUCCESS;
+ } else
+ qualifier = ZOS_REMOTE_QUALIF_INFO;
+
+ /* get timestamp text */
+ ctime_r(&e->sec, timestamp);
+ timestamp[24] = '\0'; /* strip \n' */
+
+ /* prepare linkValue which will be used for every item */
+ linkValue_tmp = htonl(e->serial); /* padronize to use network
+ * byte order
+ */
+ memset(&linkValue, 0, ZOS_REMOTE_LINK_VALUE_SIZE);
+ memcpy(&linkValue, &linkValue_tmp, sizeof(unsigned long));
+
+ /*
+ * Prepare the logString with some meaningful text
+ * We assume the first record type found is the
+ * 'originating' audit record
+ */
+ sprintf(logString, "Linux (%s): type: %s", node, orig_type);
+
+ /*
+ * Start writing to BER element.
+ * There's only one field (version) out of the item sequence.
+ * Also open item sequence
+ */
+ rc = ber_printf(ber, "{i{", ICTX_REQUESTVER);
+ if (rc < 0)
+ goto skip_event;
+
+ /*
+ * Roll back to first record and iterate through all records
+ */
+ auparse_first_record(au);
+ do {
+ const char *type = auparse_find_field(au, "type");
+ if (type == NULL)
+ goto skip_event;
+
+ log_debug("got record: %s", auparse_get_record_text(au));
+
+ /*
+ * First field is item Version, same as global version
+ */
+ rc = ber_printf(ber, "{i", ICTX_REQUESTVER);
+
+ /*
+ * Second field is the itemTag
+ * use our internal event counter, increasing it
+ */
+ rc |= ber_printf(ber, "i", conf.counter++);
+
+ /*
+ * Third field is the linkValue
+ * using ber_put_ostring since it is not null-terminated
+ */
+ rc |= ber_put_ostring(ber, linkValue,
+ ZOS_REMOTE_LINK_VALUE_SIZE,
+ LBER_OCTETSTRING);
+ /*
+ * Fourth field is the violation
+ * Don't have anything better yet to put here
+ */
+ rc |= ber_printf(ber, "b", 0);
+
+ /*
+ * Fifth field is the event.
+ * FIXME: this might be the place to switch on the
+ * audit record type and map to a more meaningful
+ * SMF type 83, subtype 4 event here
+ */
+ rc |= ber_printf(ber, "i", ZOS_REMOTE_EVENT_AUTHORIZATION);
+
+ /*
+ * Sixth field is the qualifier. We map 'success' or
+ * 'res' to this field
+ */
+ rc |= ber_printf(ber, "i", qualifier);
+
+ /*
+ * Seventh field is the Class
+ * always use '@LINUX' for this version
+ * max size ZOS_REMOTE_CLASS_SIZE
+ */
+ rc |= ber_printf(ber, "t", ASN1_IA5STRING_TAG);
+ rc |= ber_printf(ber, "s", "@LINUX");
+
+ /*
+ * Eighth field is the resource
+ * use the record type (name) as the resource
+ * max size ZOS_REMOTE_RESOURCE_SIZE
+ */
+ rc |= ber_printf(ber, "t", ASN1_IA5STRING_TAG);
+ rc |= ber_printf(ber, "s", type);
+
+ /*
+ * Nineth field is the LogString
+ * we try to put something meaningful here
+ * we also start the relocations sequence
+ */
+ rc |= ber_printf(ber, "t", ASN1_IA5STRING_TAG);
+ rc |= ber_printf(ber, "s{", logString);
+
+ /*
+ * Now we start adding the relocations.
+ * Let's add the timestamp as the first one
+ * so it's out of the field loop
+ */
+ rc |= ber_printf(ber, "{i", ZOS_REMOTE_RELOC_TIMESTAMP);
+ rc |= ber_printf(ber, "t", ASN1_IA5STRING_TAG);
+ rc |= ber_printf(ber, "s}", timestamp);
+
+ /*
+ * Check that encoding is going OK until now
+ */
+ if (rc < 0)
+ goto skip_event;
+
+ /*
+ * Now go to first field,
+ * and iterate through all fields
+ */
+ auparse_first_field(au);
+ do {
+ /*
+ * we set a maximum of 1024 chars for
+ * relocation data (field=value pairs)
+ * Hopefuly this wont overflow too often
+ */
+ char data[1024];
+ const char *name = auparse_get_field_name(au);
+ const char *value = auparse_interpret_field(au);
+ if (name == NULL || value == NULL)
+ goto skip_event;
+
+ /*
+ * First reloc field is the Relocation type
+ * We use 'OTHER' here since we don't have
+ * anything better
+ */
+ rc |= ber_printf(ber, "{i", ZOS_REMOTE_RELOC_OTHER);
+
+ /*
+ * Second field is the relocation data
+ * We use a 'name=value' pair here
+ * Use up to 1023 chars (one char left for '\0')
+ */
+ snprintf(data, 1023, "%s=%s", name, value);
+ rc |= ber_printf(ber, "t", ASN1_IA5STRING_TAG);
+ rc |= ber_printf(ber, "s}", data);
+
+ /*
+ * Check encoding status
+ */
+ if (rc < 0)
+ goto skip_event;
+ } while (auparse_next_field(au) > 0);
+
+ /*
+ * After adding all relocations we are done with
+ * this item - finalize relocs and item
+ */
+ rc |= ber_printf(ber, "}}");
+
+ /*
+ * Check if we are doing well with encoding
+ */
+ if (rc < 0)
+ goto skip_event;
+
+ } while (auparse_next_record(au) > 0);
+
+ /*
+ * We have all items in - finalize item sequence & request
+ */
+ rc |= ber_printf(ber, "}}");
+
+ /*
+ * Check if everything went alright with encoding
+ */
+ if (rc < 0)
+ goto skip_event;
+
+ /*
+ * finally, enqueue request and let the other
+ * thread process it
+ */
+ log_debug("Encoding done, enqueuing event");
+ enqueue(ber);
+
+ return;
+
+skip_event:
+ log_warn("Warning - error encoding request, skipping event");
+ ber_free(ber, 1); /* free it since we're not enqueuing it */
+ return;
+
+fatal:
+ log_err("Error - Fatal error while encoding request. Aborting");
+ stop = 1;
+}
+
+int main(int argc, char *argv[])
+{
+ int rc;
+ char *cpath;
+ char buf[1024];
+ struct sigaction sa;
+ sigset_t ss;
+ auparse_state_t *au;
+ ssize_t len;
+
+ mypid = getpid();
+
+ log_info("starting with pid=%d", mypid);
+
+ /*
+ * install signal handlers
+ */
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = term_handler;
+ sigaction(SIGTERM, &sa, NULL);
+ sa.sa_handler = hup_handler;
+ sigaction(SIGHUP, &sa, NULL);
+ sa.sa_handler = alarm_handler;
+ sigaction(SIGALRM, &sa, NULL);
+
+ /*
+ * the main program accepts a single (optional) argument:
+ * it's configuration file (this is NOT the plugin configuration
+ * usually located at /etc/audisp/plugin.d)
+ * We use the default (def_config_file) if no arguments are given
+ */
+ if (argc == 1) {
+ cpath = def_config_file;
+ log_warn("No configuration file specified - using default (%s)", cpath);
+ } else if (argc == 2) {
+ cpath = argv[1];
+ log_info("Using configuration file: %s", cpath);
+ } else {
+ log_err("Error - invalid number of parameters passed. Aborting");
+ return 1;
+ }
+
+ /* initialize record counter */
+ conf.counter = 1;
+
+ /* initialize configuration with default values */
+ plugin_clear_config(&conf);
+
+ /* initialize the submission queue */
+ if (init_queue(conf.q_depth) != 0) {
+ log_err("Error - Can't initialize event queue. Aborting");
+ return -1;
+ }
+ /* set stdin to O_NONBLOCK */
+ if (fcntl(0, F_SETFL, O_NONBLOCK) == -1) {
+ log_err("Error - Can't set input to Non-blocking mode: %s. Aborting",
+ strerror(errno));
+ return -1;
+ }
+
+ do {
+
+ hup = 0; /* don't flush unless hup == 1 */
+
+ /*
+ * initialization is done in 4 steps:
+ */
+
+ /*
+ * load configuration and
+ * increase queue depth if needed
+ */
+ rc = plugin_load_config(&conf, cpath);
+ if (rc != 0) {
+ log_err("Error - Can't load configuration. Aborting");
+ return -1;
+ }
+ increase_queue_depth(conf.q_depth); /* 1 */
+
+ /* initialize auparse */
+ au = auparse_init(AUSOURCE_FEED, 0); /* 2 */
+
+ /*
+ * Block signals for everyone,
+ * Initialize submission thread, and
+ * Unblock signals for this thread
+ */
+ sigfillset(&ss);
+ pthread_sigmask(SIG_BLOCK, &ss, NULL);
+ pthread_create(&submission_thread, NULL,
+ submission_thread_main, NULL);
+ pthread_sigmask(SIG_UNBLOCK, &ss, NULL); /* 3 */
+
+ /* add our event consumer callback */
+ auparse_add_callback(au, push_event, NULL, NULL); /* 4 */
+
+ /* main loop */
+ while (hup == 0 && stop == 0) {
+ fd_set rfds;
+ struct timeval tv;
+
+ FD_ZERO(&rfds);
+ FD_SET(0, &rfds);
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+ rc = select(1, &rfds, NULL, NULL, &tv);
+ if (rc == -1) {
+ if (errno == EINTR) {
+ log_debug("Select call interrupted");
+ continue;
+ }
+ else {
+ log_err("Error - Fatal error while monitoring input: %s. Aborting",
+ strerror(errno));
+ stop = 1;
+ }
+ }
+ else if (rc) {
+ len = read(0, buf, 1024);
+ if (len > 0)
+ /* let our callback know of the new data */
+ auparse_feed(au, buf, len);
+ else if (len == 0) {
+ log_debug("End of input - Exiting");
+ stop = 1;
+ }
+ else {
+ /* ignore interrupted call or empty pipe */
+ if (errno != EINTR && errno != EAGAIN) {
+ log_err("Error - Fatal error while reading input: %s. Aborting",
+ strerror(errno));
+ stop = 1;
+ }
+ else {
+ log_debug("Ignoring read interruption: %s",
+ strerror(errno));
+ }
+ }
+ }
+ }
+ /* flush everything, in order */
+ auparse_flush_feed(au); /* 4 */
+ alarm(10); /* 10 seconds to clear the queue */
+ pthread_join(submission_thread, NULL); /* 3 */
+ alarm(0); /* cancel any pending alarm */
+ auparse_destroy(au); /* 2 */
+ plugin_free_config(&conf); /* 1 */
+ }
+ while (hup && stop == 0);
+
+ /* destroy queue before leaving */
+ destroy_queue();
+
+ log_info("Exiting");
+
+ return 0;
+}
--
Klaus Heinrich Kiwi <klausk(a)linux.vnet.ibm.com>
IBM STG, Linux Technology Center
17 years