#include "audit-api.h"
-/* solaris default is 2048 */
-#define MAXMSG 2048
-
/* message queue size will be increased to this value
if not already bigger */
#define MSGMNB (2*1024*1024)
-static struct my_msgbuf {
+/* msgsnd requires a structure with the following layout. See manpage for
+ * msgsnd() for the details */
+struct my_msgbuf {
long mtype;
- char mtext[MAXMSG];
-} msgbuffer;
-
-static int mqid;
+ char mtext[OSI_AUDIT_MAXMSG];
+};
-static struct mqaudit_stats {
+struct mqaudit_stats {
long all;
long truncated;
long lost;
-} myauditstats;
-
-static int truncated;
+};
-static void
-send_msg(void)
-{
- /* +1 to send the trailing '\0' in the message too so the
- receiver doesn't need to bother with it */
- if (msgsnd(mqid, &msgbuffer, strlen(msgbuffer.mtext)+1, IPC_NOWAIT) == -1) {
- myauditstats.lost++;
- } else if (truncated) {
- myauditstats.truncated++;
- }
- myauditstats.all++;
- msgbuffer.mtext[0] = 0;
- truncated = 0;
-}
+struct sysvmq_context {
+ int mqid;
+ struct my_msgbuf msgbuffer;
+ struct mqaudit_stats myauditstats;
+};
static void
-append_msg(const char *format, ...)
+send_msg(void *rock, const char *message, int msglen, int truncated)
{
- va_list vaList;
- int size, printed;
+ struct sysvmq_context *ctx = rock;
- size = MAXMSG - strlen(msgbuffer.mtext);
+ if (msglen >= OSI_AUDIT_MAXMSG) {
+ truncated = 1;
+ msglen = OSI_AUDIT_MAXMSG - 1;
+ }
- va_start(vaList, format);
- printed = vsnprintf(&msgbuffer.mtext[strlen(msgbuffer.mtext)], size, format, vaList);
- va_end(vaList);
+ /* Copy the data into the msgsnd structure */
+ memcpy(&ctx->msgbuffer.mtext, message, msglen+1);
+ ctx->msgbuffer.mtext[msglen] = '\0';
- /* A return value of size or more means that the output was truncated.
- If an output error is encountered, a negative value is returned. */
- if (size <= printed || printed == -1) {
- truncated = 1;
+ /* Include the trailing zero in the msgsnd */
+ if (msgsnd(ctx->mqid, &ctx->msgbuffer, msglen+1, IPC_NOWAIT) == -1) {
+ ctx->myauditstats.lost++;
+ } else if (truncated) {
+ ctx->myauditstats.truncated++;
}
+ ctx->myauditstats.all++;
}
static int
-open_file(const char *fileName)
+open_file(void *rock, const char *fileName)
{
+ struct sysvmq_context *ctx = rock;
int tempfd;
struct msqid_ds msqdesc;
- msgbuffer.mtext[0] = 0;
- msgbuffer.mtype = 1;
+ ctx->msgbuffer.mtext[0] = 0;
+ ctx->msgbuffer.mtype = 1;
- truncated = 0;
- myauditstats.all = 0;
- myauditstats.lost = 0;
- myauditstats.truncated = 0;
+ ctx->myauditstats.all = 0;
+ ctx->myauditstats.lost = 0;
+ ctx->myauditstats.truncated = 0;
/* try to create file for ftok if it doesn't already exist */
tempfd = open(fileName, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if(tempfd != -1)
close(tempfd);
- mqid = msgget(ftok(fileName, 1), S_IRUSR | S_IWUSR | IPC_CREAT);
- if (mqid == -1) {
+ ctx->mqid = msgget(ftok(fileName, 1), S_IRUSR | S_IWUSR | IPC_CREAT);
+ if (ctx->mqid == -1) {
printf("Warning: auditlog message queue %s cannot be opened.\n", fileName);
return 1;
}
/* increase message queue size */
- msgctl(mqid, IPC_STAT, &msqdesc);
+ msgctl(ctx->mqid, IPC_STAT, &msqdesc);
if (msqdesc.msg_qbytes < MSGMNB) {
msqdesc.msg_qbytes = MSGMNB;
- msgctl(mqid, IPC_SET, &msqdesc);
+ msgctl(ctx->mqid, IPC_SET, &msqdesc);
}
return 0;
}
static void
-print_interface_stats(FILE *out)
+print_interface_stats(void *rock, FILE *out)
{
+ struct sysvmq_context *ctx = rock;
+
fprintf(out, "audit statistics: %ld messages total, %ld truncated, %ld lost\n",
- myauditstats.all, myauditstats.truncated, myauditstats.lost);
+ ctx->myauditstats.all, ctx->myauditstats.truncated, ctx->myauditstats.lost);
+}
+
+static void *
+create_interface(void)
+{
+ struct sysvmq_context *ctx;
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL) {
+ printf("error allocating memory\n");
+ return NULL;
+ }
+ return ctx;
+}
+
+static void
+close_interface(void **rock)
+{
+ struct sysvmq_context *ctx = *rock;
+ if (ctx == NULL)
+ return;
+
+ free(ctx);
+ *rock = NULL;
}
const struct osi_audit_ops audit_sysvmq_ops = {
&send_msg,
- &append_msg,
&open_file,
&print_interface_stats,
+ &create_interface,
+ &close_interface,
+ NULL, /* set_option */
+ NULL, /* open_interface */
};
#endif /* HAVE_SYS_IPC_H */