/* * This function builds: * - OUTPUT rule * - POSTROUTING rule * - PREROUTING rule * - ntk_mark_chain * and store rules for future deletion. * * Returns: * 0 * -1 * * If -1, any rule will be committed. */ int mark_init(int igw) { int res; iptc_handle_t t; char rule[MAX_RULE_SZ]; /*res=inet_aton(NTK_NET_STR,&inet_dst); if (!res) { error("Can not convert str to addr."); goto cannot_init; } res=inet_aton(NTK_NET_MASK_STR,&inet_dst_mask); if (!res) { error("Can not convert str to addr."); goto cannot_init; } */ res = table_init(MANGLE_TABLE, &t); if (res) { error(err_str); goto cannot_init; } res = ntk_mark_chain_init(&t); if (res) { error(err_str); error("Unable to create netfilter ntk_mark_chain."); goto cannot_init; } restore_output_rule_init(rule); res = insert_rule(rule, &t, CHAIN_OUTPUT, 0); if (res) { error(err_str); error("Unable to create netfilter restore-marking rule."); goto cannot_init; } ntk_forward_rule_init(rule); res = insert_rule(rule, &t, CHAIN_POSTROUTING, 0); if (res) { error(err_str); error("Unable to create netfilter forwarding rule."); goto cannot_init; } if (igw) { death_loop_rule = 1; igw_mark_rule_init(rule); res = insert_rule(rule, &t, CHAIN_PREROUTING, 0); if (res) { error(err_str); error("Unable to create netfilter igw death loop rule."); death_loop_rule = 0; goto cannot_init; } } else death_loop_rule = 0; res = commit_rules(&t); if (res) { error(err_str); error("Netfilter mangle table was not altered!"); goto cannot_init; } res = store_rules(); if (res) { error(err_str); error ("Rules storing failed: autocleaning netfilter on exit disable."); clean_on_exit = 0; } else clean_on_exit = 1; dump_rules(); debug(DBG_NORMAL, "Netfilter chain ntk_mark_chain created (mangle)."); debug(DBG_NORMAL, "Netfilter restoring rule created (mangle->output)."); debug(DBG_NORMAL, "Netfilter forwarding rule created (mangle->postrouting)."); if (igw) debug(DBG_NORMAL, "Netfilter death loop igw rule created."); debug(DBG_NORMAL, "mark_init(), netfilter mangle table initialized."); loginfo("Netfilter mangle table modified."); return 0; cannot_init: err_ret(ERR_MRKINI, -1); }
/* * Algorithm: * check that user is root * check to see if program exists * if so fork, child waits for parent * parent clears audit rules, loads audit all syscalls with child's pid * parent tells child to go & waits for sigchld * child exec's program * parent deletes rules after getting sigchld */ int main(int argc, char *argv[]) { int fd[2]; int pid,cmd=1; char buf[2]; if (argc < 2) { usage(); return 1; } if (strcmp(argv[cmd], "-h") == 0) { usage(); return 1; } if (strcmp(argv[cmd], "-r") == 0) { threat = 1; cmd++; } if (getuid() != 0) { fprintf(stderr, "You must be root to run this program.\n"); return 1; } if (access(argv[cmd], X_OK)) { if (errno == ENOENT) fprintf(stderr, "Error - can't find: %s\n", argv[cmd]); else fprintf(stderr, "Error checking %s (%s)\n", argv[cmd], strerror(errno)); return 1; } set_aumessage_mode(MSG_STDERR, DBG_NO); switch (count_rules()) { case -1: if (errno == ECONNREFUSED) fprintf(stderr, "The audit system is disabled\n"); else fprintf(stderr, "Error - can't get rule count.\n"); return 1; case 0: break; default: fprintf(stderr, "autrace cannot be run with rules loaded.\n" "Please delete all rules using 'auditctl -D' if you " "really wanted to\nrun this command.\n"); return 1; } if (pipe(fd) != 0) { fprintf(stderr, "Error creating pipe.\n"); return 1; } switch ((pid=fork())) { case -1: fprintf(stderr, "Error forking.\n"); return 1; case 0: /* Child */ close(fd[1]); printf("Waiting to execute: %s\n", argv[cmd]); while (read(fd[0], buf, 1) == -1 && errno == EINTR) /* blank */ ; close(fd[0]); execvp(argv[cmd], &argv[cmd]); fprintf(stderr, "Failed to exec %s\n", argv[cmd]); return 1; default: /* Parent */ close(fd[0]); fcntl(fd[1], F_SETFD, FD_CLOEXEC); { char field[16]; int audit_fd; audit_fd = audit_open(); if (audit_fd < 0) exit(1); snprintf(field, sizeof(field), "pid=%d", pid); if (insert_rule(audit_fd, field)) { kill(pid,SIGTERM); (void)delete_all_rules(audit_fd); exit(1); } snprintf(field, sizeof(field), "ppid=%d", pid); if (insert_rule(audit_fd, field)) { kill(pid,SIGTERM); (void)delete_all_rules(audit_fd); exit(1); } sleep(1); if (write(fd[1],"1", 1) != 1) { kill(pid,SIGTERM); (void)delete_all_rules(audit_fd); exit(1); } waitpid(pid, NULL, 0); close(fd[1]); puts("Cleaning up..."); (void)delete_all_rules(audit_fd); close(audit_fd); } printf("Trace complete. " "You can locate the records with " "\'ausearch -i -p %d\'\n", pid); break; } return 0; }