I've been successfully using the audit package to trace programs that
fork by using the ptrace system call to add audit rules. As a result
of tracing ever more programs, I notice I have added three features to
my program that may be of use in the autrace program.
To trace a program that behaves like a server, I exercise the server,
and then send it a keyboard interrupt. If nothing special is done,
the tracing process terminates, but not the traced processes. To
handle this situation, I make the first child a process group leader
with:
if (setpgid(0, 0)) { /* Make child a process group leader */
perror("setpgid of child"); /* so that signals can be sent to */
return -1; /* the group */
}
The tracing process stores the pid of the first child in the group
variable, and then registers the following handler with SIGINT:
static void
signal_group(int signum)
{
if (group && kill(-group, signum))
perror("kill group");
if (signal(signum, SIG_DFL) == SIG_ERR)
fprintf(stderr, "Setting signal %d to its default failed\n", signum);
}
The group variable is set to zero whenever it is known no child is
running, such as when rules are being deleted.
For some of the programs I trace, it is important they not be run as
root. I have a -u username option, and before the first child
executes the traced program, I use the following code to make use of
the option's value.
static int
set_id(const char *username) /* Sets the group and user ID */
{ /* when given a user name. */
struct passwd *pent; /* Setuid and setgid bits are */
if (!username) /* ignored on the executable file */
return 0; /* containing the program being */
else if ((pent = getpwnam(username)) == NULL) { /* traced. */
fprintf(stderr, "Cannot find user `%s'\n", username);
return -1;
}
else if (setregid(pent->pw_gid, pent->pw_gid)) {
perror("setregid");
return -1;
}
else if (setreuid(pent->pw_uid, pent->pw_uid)) {
perror("setreuid");
return -1;
}
else
return 0;
}
Finally, when printing the command to retrieve the records associated
with the trace for process P, I would print
ausearch -i -p P > P.txt
rather than
'ausearch -i -p P'
I almost always want to place the output into a file, and when I
don't, it's easy to copy only part of the command. Also, the single
quotes force one to be more precise with the mouse than I like to be
when cutting and pasting within a terminal window.
If any or all of these suggestions seem useful, I am willing to
implement them in the autrace source file and send patches. On the
other hand, I tried to put enough detail into this message so you can
easily make the changes.
John