A scriptable utility for setting auid

Matthew Booth
2007-02-20T21:29:25Z

[-- Attachment #1.1.1: Type: text/plain, Size: 932 bytes --]

I needed a way to exclude a very large class of audit traffic [1] in
RHEL 4. It occurred to me that if I could launch a process and give it
the auid of a dedicated user, I could easily filter it out along with
all child processes. With this in mind I wrote the attached simple
wrapper round the audit_setloginuid. It sets its own auid to whatever
you give it, then execs a command.

I'm assuming that this would be better achieved in RHEL 5 using selinux
context filtering. However, I hope to use this tool to achieve useful
auditing on an Oracle RAC node on RHEL 4.

Matt

[1] It turns out that Oracle CSSD, which maintains cluster membership,
is a somewhat retarded shell script. Amongst many other things, it execs
both bash and awk about 8 times per second.
--
Red Hat, Global Professional Services

M: +44 (0)7977 267231
GPG ID: D33C3490
GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490

[-- Attachment #1.1.2: ausetauid.c --]
[-- Type: text/x-csrc, Size: 1738 bytes --]

/*
* ausetauid: A utility to create a new process with a specified auid.
*
* ausetauid is a convenient wrapper round the audit_setloginuid function. It is
* called as:
*
* ausetauid <audit user> <command> [<arguments ...>]
*
* It sets its auid to the uid of <audit user>, then execs <command>, passing
* any arguments specified. The audit_setloginuid call results in a LOGIN audit
* record being created.
*
* Matthew Booth <mbooth@redhat.com> - 20/02/2007
*/

#include <pwd.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

#include <libaudit.h>

/* Function prototypes */
static void __attribute__((nonnull))
display_usage(const char * const exename);
static int __attribute__((nonnull))
set_audit_user(const char * const username);

int main(const int argc, char *const argv[])
{
int retval;

if(argc < 3) {
display_usage(argv[0]);
return 1;
}

retval = set_audit_user(argv[1]);
if(retval != 0) {
return retval;
}

execv(argv[2], argv + 2);

fprintf(stderr, "Failed to execute %s: %m\n", argv[2]);
return 1;
}

static void display_usage(const char * const exename)
{
fprintf(stderr, "Usage: %s <audit user> "
"<command> [<arguments ...>]\n", exename);
}

static int set_audit_user(const char * const username)
{
struct passwd *pwd = NULL;

pwd = getpwnam(username);
if(NULL == pwd) {
fprintf(stderr, "%s is not a valid username\n", username);
return 1;
}

if(audit_setloginuid(pwd->pw_uid) != 0) {
fprintf(stderr, "Failed to change audit login uid\n");
return 1;
}

return 0;
}

[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]