aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/audit/lib/audit_logging.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/audit/lib/audit_logging.c')
-rw-r--r--framework/src/audit/lib/audit_logging.c746
1 files changed, 0 insertions, 746 deletions
diff --git a/framework/src/audit/lib/audit_logging.c b/framework/src/audit/lib/audit_logging.c
deleted file mode 100644
index c9461061..00000000
--- a/framework/src/audit/lib/audit_logging.c
+++ /dev/null
@@ -1,746 +0,0 @@
-/* audit_logging.c --
- * Copyright 2005-2008,2010,2011,2013 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Authors:
- * Steve Grubb <sgrubb@redhat.com>
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <netinet/in.h> // inet6 addrlen
-#include <netdb.h> // gethostbyname
-#include <arpa/inet.h> // inet_ntop
-#include <utmp.h>
-#include <limits.h> // PATH_MAX
-
-#include "libaudit.h"
-#include "private.h"
-
-#define TTY_PATH 32
-#define MAX_USER (UT_NAMESIZE * 2) + 8
-
-// NOTE: The kernel fills in pid, uid, and loginuid of sender. Therefore,
-// these routines do not need to send them.
-
-/*
- * resolve's the hostname - caller must pass a INET6_ADDRSTRLEN byte buffer
- * Returns string w/ numerical address, or "?" on failure
- */
-static void _resolve_addr(char buf[], const char *host)
-{
- struct addrinfo *ai;
- struct addrinfo hints;
- int e;
-
- buf[0] = '?';
- buf[1] = 0;
- /* Short circuit this lookup if NULL, or empty */
- if (host == NULL || *host == 0)
- return;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_ADDRCONFIG;
- hints.ai_socktype = SOCK_STREAM;
-
- e = getaddrinfo(host, NULL, &hints, &ai);
- if (e != 0) {
- audit_msg(LOG_ERR,
- "resolve_addr: cannot resolve hostname %s (%s)",
- host, gai_strerror(e));
- return;
- }
- // What to do if more than 1 addr?
- inet_ntop(ai->ai_family, ai->ai_family == AF_INET ?
- (void *) &((struct sockaddr_in *)ai->ai_addr)->sin_addr :
- (void *) &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr,
- buf, INET6_ADDRSTRLEN);
- freeaddrinfo(ai);
-}
-
-/*
- * This function checks a string to see if it needs encoding. It
- * return 1 if needed and 0 if not
- */
-int audit_value_needs_encoding(const char *str, unsigned int size)
-{
- unsigned int i;
-
- if (str == NULL)
- return 0;
-
- for (i=0; i<size; i++) {
- // we don't test for > 0x7f because str[] is signed.
- if (str[i] == '"' || str[i] < 0x21 || str[i] == 0x7F)
- return 1;
- }
- return 0;
-}
-
-/*
- * This function does encoding of "untrusted" names just like the kernel
- */
-char *audit_encode_value(char *final, const char *buf, unsigned int size)
-{
- unsigned int i;
- char *ptr = final;
- const char *hex = "0123456789ABCDEF";
-
- if (final == NULL)
- return NULL;
-
- if (buf == NULL) {
- *final = 0;
- return final;
- }
-
- for (i=0; i<size; i++) {
- *ptr++ = hex[(buf[i] & 0xF0)>>4]; /* Upper nibble */
- *ptr++ = hex[buf[i] & 0x0F]; /* Lower nibble */
- }
- *ptr = 0;
- return final;
-}
-
-char *audit_encode_nv_string(const char *name, const char *value,
- unsigned int vlen)
-{
- char *str;
-
- if (vlen == 0 && value)
- vlen = strlen(value);
-
- if (value && audit_value_needs_encoding(value, vlen)) {
- char *tmp = malloc(2*vlen + 1);
- if (tmp) {
- audit_encode_value(tmp, value, vlen);
- if (asprintf(&str, "%s=%s", name, tmp) < 0)
- str = NULL;
- free(tmp);
- } else
- str = NULL;
- } else
- if (asprintf(&str, "%s=\"%s\"", name, value ? value : "?") < 0)
- str = NULL;
- return str;
-}
-
-/*
- * Get the executable's name
- */
-static char *_get_exename(char *exename, int size)
-{
- int res;
- char tmp[PATH_MAX+1];
-
- /* get the name of the current executable */
- if ((res = readlink("/proc/self/exe", tmp, PATH_MAX)) == -1) {
- strcpy(exename, "\"?\"");
- audit_msg(LOG_ERR, "get_exename: cannot determine executable");
- } else {
- tmp[res] = '\0';
- if (audit_value_needs_encoding(tmp, res))
- return audit_encode_value(exename, tmp, res);
- snprintf(exename, size, "\"%s\"", tmp);
- }
- return exename;
-}
-
-/*
- * Get the command line name
- * NOTE: at the moment, this only escapes what the user sent
- */
-static char *_get_commname(const char *comm, char *commname, unsigned int size)
-{
- unsigned int len;
-
- if (comm == NULL) {
- strcpy(commname, "\"?\"");
- return commname;
- }
-
- len = strlen(comm);
- if (audit_value_needs_encoding(comm, len))
- audit_encode_value(commname, comm, len);
- else
- snprintf(commname, size, "\"%s\"", comm);
-
- return commname;
-}
-
-static int check_ttyname(const char *ttyn)
-{
- struct stat statbuf;
-
- if (lstat(ttyn, &statbuf)
- || !S_ISCHR(statbuf.st_mode)
- || (statbuf.st_nlink > 1 && strncmp(ttyn, "/dev/", 5))) {
- audit_msg(LOG_ERR, "FATAL: bad tty %s", ttyn);
- return 1;
- }
- return 0;
-}
-
-static const char *_get_tty(char *tname, int size)
-{
- int rc, i, found = 0;
-
- for (i=0; i<3 && !found; i++) {
- rc = ttyname_r(i, tname, size);
- if (rc == 0 && tname[0] != '\0')
- found = 1;
- }
-
- if (!found)
- return NULL;
-
- if (check_ttyname(tname))
- return NULL;
-
- if (strncmp(tname, "/dev/", 5) == 0)
- return &tname[5];
-
- return tname;
-}
-
-/*
- * This function will log a message to the audit system using a predefined
- * message format. This function should be used by all console apps that do
- * not manipulate accounts or groups.
- *
- * audit_fd - The fd returned by audit_open
- * type - type of message, ex: AUDIT_USER, AUDIT_USYS_CONFIG, AUDIT_USER_LOGIN
- * message - the message being sent
- * hostname - the hostname if known
- * addr - The network address of the user
- * tty - The tty of the user
- * result - 1 is "success" and 0 is "failed"
- *
- * It returns the sequence number which is > 0 on success or <= 0 on error.
- */
-int audit_log_user_message(int audit_fd, int type, const char *message,
- const char *hostname, const char *addr, const char *tty, int result)
-{
- char buf[MAX_AUDIT_MESSAGE_LENGTH];
- char addrbuf[INET6_ADDRSTRLEN];
- static char exename[PATH_MAX*2]="";
- char ttyname[TTY_PATH];
- const char *success;
- int ret;
-
- if (audit_fd < 0)
- return 0;
-
- if (result)
- success = "success";
- else
- success = "failed";
-
- /* If hostname is empty string, make it NULL ptr */
- if (hostname && *hostname == 0)
- hostname = NULL;
- addrbuf[0] = 0;
- if (addr == NULL || strlen(addr) == 0)
- _resolve_addr(addrbuf, hostname);
- else
- strncat(addrbuf, addr, sizeof(addrbuf)-1);
-
- if (exename[0] == 0)
- _get_exename(exename, sizeof(exename));
- if (tty == NULL)
- tty = _get_tty(ttyname, TTY_PATH);
- else if (*tty == 0)
- tty = NULL;
-
- snprintf(buf, sizeof(buf),
- "%s exe=%s hostname=%s addr=%s terminal=%s res=%s",
- message, exename,
- hostname ? hostname : "?",
- addrbuf,
- tty ? tty : "?",
- success
- );
-
- errno = 0;
- ret = audit_send_user_message( audit_fd, type, HIDE_IT, buf );
- if ((ret < 1) && errno == 0)
- errno = ret;
- return ret;
-}
-
-/*
- * This function will log a message to the audit system using a predefined
- * message format. This function should be used by all console apps that do
- * not manipulate accounts or groups and are executing a script. An example
- * would be python or crond wanting to say what they are executing.
- *
- * audit_fd - The fd returned by audit_open
- * type - type of message, ex: AUDIT_USER, AUDIT_USYS_CONFIG, AUDIT_USER_LOGIN
- * message - the message being sent
- * comm - the program command line name
- * hostname - the hostname if known
- * addr - The network address of the user
- * tty - The tty of the user
- * result - 1 is "success" and 0 is "failed"
- *
- * It returns the sequence number which is > 0 on success or <= 0 on error.
- */
-int audit_log_user_comm_message(int audit_fd, int type, const char *message,
- const char *comm, const char *hostname, const char *addr,
- const char *tty, int result)
-{
- char buf[MAX_AUDIT_MESSAGE_LENGTH];
- char addrbuf[INET6_ADDRSTRLEN];
- static char exename[PATH_MAX*2]="";
- char commname[PATH_MAX*2];
- char ttyname[TTY_PATH];
- const char *success;
- int ret;
-
- if (audit_fd < 0)
- return 0;
-
- if (result)
- success = "success";
- else
- success = "failed";
-
- /* If hostname is empty string, make it NULL ptr */
- if (hostname && *hostname == 0)
- hostname = NULL;
- addrbuf[0] = 0;
- if (addr == NULL || strlen(addr) == 0)
- _resolve_addr(addrbuf, hostname);
- else
- strncat(addrbuf, addr, sizeof(addrbuf)-1);
- if (exename[0] == 0)
- _get_exename(exename, sizeof(exename));
- if (tty == NULL)
- tty = _get_tty(ttyname, TTY_PATH);
- else if (*tty == 0)
- tty = NULL;
-
- _get_commname(comm, commname, sizeof(commname));
-
- snprintf(buf, sizeof(buf),
- "%s comm=%s exe=%s hostname=%s addr=%s terminal=%s res=%s",
- message, commname, exename,
- hostname ? hostname : "?",
- addrbuf,
- tty ? tty : "?",
- success
- );
-
- errno = 0;
- ret = audit_send_user_message( audit_fd, type, HIDE_IT, buf );
- if ((ret < 1) && errno == 0)
- errno = ret;
- return ret;
-}
-
-
-/*
- * This function will log a message to the audit system using a predefined
- * message format. It should be used for all account manipulation operations.
- * Parameter usage is as follows:
- *
- * audit_fd - The fd returned by audit_open
- * type - type of message: AUDIT_USER_CHAUTHTOK for changing any account
- * attributes.
- * pgname - program's name
- * op - operation. "adding user", "changing finger info", "deleting group"
- * name - user's account or group name. If not available use NULL.
- * id - uid or gid that the operation is being performed on. This is used
- * only when user is NULL.
- * host - The hostname if known
- * addr - The network address of the user
- * tty - The tty of the user
- * result - 1 is "success" and 0 is "failed"
- *
- * It returns the sequence number which is > 0 on success or <= 0 on error.
- */
-int audit_log_acct_message(int audit_fd, int type, const char *pgname,
- const char *op, const char *name, unsigned int id,
- const char *host, const char *addr, const char *tty, int result)
-{
- const char *success;
- char buf[MAX_AUDIT_MESSAGE_LENGTH];
- char addrbuf[INET6_ADDRSTRLEN];
- static char exename[PATH_MAX*2] = "";
- char ttyname[TTY_PATH];
- int ret;
-
- if (audit_fd < 0)
- return 0;
-
- if (result)
- success = "success";
- else
- success = "failed";
-
- /* If hostname is empty string, make it NULL ptr */
- if (host && *host == 0)
- host = NULL;
- addrbuf[0] = 0;
- if (addr == NULL || strlen(addr) == 0)
- _resolve_addr(addrbuf, host);
- else
- strncat(addrbuf, addr, sizeof(addrbuf)-1);
-
- if (pgname == NULL) {
- if (exename[0] == 0)
- _get_exename(exename, sizeof(exename));
- } else if (pgname[0] != '"')
- snprintf(exename, sizeof(exename), "\"%s\"", pgname);
- else
- snprintf(exename, sizeof(exename), "%s", pgname);
-
- if (tty == NULL)
- tty = _get_tty(ttyname, TTY_PATH);
- else if (*tty == 0)
- tty = NULL;
-
- if (name && id == -1) {
- char user[MAX_USER];
- const char *format;
- size_t len;
-
- user[0] = 0;
- strncat(user, name, MAX_USER-1);
- len = strnlen(user, UT_NAMESIZE);
- user[len] = 0;
- if (audit_value_needs_encoding(name, len)) {
- audit_encode_value(user, name, len);
- format =
- "op=%s acct=%s exe=%s hostname=%s addr=%s terminal=%s res=%s";
- } else
- format =
- "op=%s acct=\"%s\" exe=%s hostname=%s addr=%s terminal=%s res=%s";
-
- snprintf(buf, sizeof(buf), format,
- op, user, exename,
- host ? host : "?",
- addrbuf,
- tty ? tty : "?",
- success
- );
- } else
- snprintf(buf, sizeof(buf),
- "op=%s id=%u exe=%s hostname=%s addr=%s terminal=%s res=%s",
- op, id, exename,
- host ? host : "?",
- addrbuf,
- tty ? tty : "?",
- success
- );
-
- errno = 0;
- ret = audit_send_user_message(audit_fd, type, REAL_ERR, buf);
- if ((ret < 1) && errno == 0)
- errno = ret;
- return ret;
-}
-
-/*
- * This function will log a message to the audit system using a predefined
- * message format. This function should be used by all apps that are SE Linux
- * object managers.
- *
- * audit_fd - The fd returned by audit_open
- * type - type of message, ex: AUDIT_USER, AUDIT_USYS_CONFIG, AUDIT_USER_LOGIN
- * message - the message being sent
- * hostname - the hostname if known
- * addr - The network address of the user
- * tty - The tty of the user
- * uid - The auid of the person related to the avc message
- *
- * It returns the sequence number which is > 0 on success or <= 0 on error.
- */
-int audit_log_user_avc_message(int audit_fd, int type, const char *message,
- const char *hostname, const char *addr, const char *tty, uid_t uid)
-{
- char buf[MAX_AUDIT_MESSAGE_LENGTH];
- char addrbuf[INET6_ADDRSTRLEN];
- static char exename[PATH_MAX*2] = "";
- char ttyname[TTY_PATH];
- int retval;
-
- if (audit_fd < 0)
- return 0;
-
- /* If hostname is empty string, make it NULL ptr */
- if (hostname && *hostname == 0)
- hostname = NULL;
- addrbuf[0] = 0;
- if (addr == NULL || strlen(addr) == 0)
- _resolve_addr(addrbuf, hostname);
- else
- strncat(addrbuf, addr, sizeof(addrbuf)-1);
- if (exename[0] == 0)
- _get_exename(exename, sizeof(exename));
- if (tty == NULL)
- tty = _get_tty(ttyname, TTY_PATH);
- else if (*tty == 0)
- tty = NULL;
-
- snprintf(buf, sizeof(buf),
- "%s exe=%s sauid=%d hostname=%s addr=%s terminal=%s",
- message, exename, uid,
- hostname ? hostname : "?",
- addrbuf,
- tty ? tty : "?"
- );
-
- errno = 0;
- retval = audit_send_user_message( audit_fd, type, REAL_ERR, buf );
- if (retval == -EPERM && getuid() != 0) {
- syslog(LOG_ERR, "Can't send to audit system: %s %s",
- audit_msg_type_to_name(type), buf);
- return 0;
- }
- if ((retval < 1) && errno == 0)
- errno = retval;
- return retval;
-}
-
-/*
- * This function will log a message to the audit system using a predefined
- * message format. It should be used for all SE linux user and role
- * manipulation operations.
- * Parameter usage is as follows:
- *
- * type - type of message: AUDIT_ROLE_ASSIGN/REMOVE for changing any SE Linux
- * user or role attributes.
- * pgname - program's name
- * op - operation. "adding-user", "adding-role", "deleting-user", "deleting-role"
- * name - user's account. If not available use NULL.
- * id - uid that the operation is being performed on. This is used
- * only when name is NULL.
- * new_seuser - the new seuser that the login user is getting
- * new_role - the new_role that the login user is getting
- * new_range - the new mls range that the login user is getting
- * old_seuser - the old seuser that the login usr had
- * old_role - the old role that the login user had
- * old_range - the old mls range that the login usr had
- * host - The hostname if known
- * addr - The network address of the user
- * tty - The tty of the user
- * result - 1 is "success" and 0 is "failed"
- *
- * It returns the sequence number which is > 0 on success or <= 0 on error.
- */
-int audit_log_semanage_message(int audit_fd, int type, const char *pgname,
- const char *op, const char *name, unsigned int id,
- const char *new_seuser, const char *new_role, const char *new_range,
- const char *old_seuser, const char *old_role, const char *old_range,
- const char *host, const char *addr,
- const char *tty, int result)
-{
- const char *success;
- char buf[MAX_AUDIT_MESSAGE_LENGTH];
- char addrbuf[INET6_ADDRSTRLEN];
- static char exename[PATH_MAX*2] = "";
- char ttyname[TTY_PATH];
- int ret;
-
- if (audit_fd < 0)
- return 0;
-
- if (result)
- success = "success";
- else
- success = "failed";
-
- /* If hostname is empty string, make it NULL ptr */
- if (host && *host == 0)
- host = NULL;
- addrbuf[0] = 0;
- if (addr == NULL || strlen(addr) == 0)
- _resolve_addr(addrbuf, host);
- else
- strncat(addrbuf, addr, sizeof(addrbuf)-1);
-
- if (pgname == NULL || strlen(pgname) == 0) {
- if (exename[0] == 0)
- _get_exename(exename, sizeof(exename));
- pgname = exename;
- }
- if (tty == NULL || strlen(tty) == 0)
- tty = _get_tty(ttyname, TTY_PATH);
- else if (*tty == 0)
- tty = NULL;
-
- if (name && strlen(name) > 0) {
- size_t len;
- const char *format;
- char user[MAX_USER];
-
- user[0] = 0;
- strncat(user, name, MAX_USER-1);
- len = strnlen(user, UT_NAMESIZE);
- user[len] = 0;
- if (audit_value_needs_encoding(name, len)) {
- audit_encode_value(user, name, len);
- format = "op=%s acct=%s old-seuser=%s old-role=%s old-range=%s new-seuser=%s new-role=%s new-range=%s exe=%s hostname=%s addr=%s terminal=%s res=%s";
- } else
- format = "op=%s acct=\"%s\" old-seuser=%s old-role=%s old-range=%s new-seuser=%s new-role=%s new-range=%s exe=%s hostname=%s addr=%s terminal=%s res=%s";
- snprintf(buf, sizeof(buf), format, op, user,
- old_seuser && strlen(old_seuser) ? old_seuser : "?",
- old_role && strlen(old_role) ? old_role : "?",
- old_range && strlen(old_range) ? old_range : "?",
- new_seuser && strlen(new_seuser) ? new_seuser : "?",
- new_role && strlen(new_role) ? new_role : "?",
- new_range && strlen(new_range) ? new_range : "?",
- pgname,
- host && strlen(host) ? host : "?",
- addrbuf,
- tty && strlen(tty) ? tty : "?",
- success
- );
- } else
- snprintf(buf, sizeof(buf),
- "op=%s id=%u old-seuser=%s old-role=%s old-range=%s new-seuser=%s new-role=%s new-range=%s exe=%s hostname=%s addr=%s terminal=%s res=%s",
- op, id,
- old_seuser && strlen(old_seuser) ? old_seuser : "?",
- old_role && strlen(old_role) ? old_role : "?",
- old_range && strlen(old_range) ? old_range : "?",
- new_seuser && strlen(new_seuser) ? new_seuser : "?",
- new_role && strlen(new_role) ? new_role : "?",
- new_range && strlen(new_range) ? new_range : "?",
- pgname,
- host && strlen(host) ? host : "?",
- addrbuf,
- tty && strlen(tty) ? tty : "?",
- success
- );
-
- errno = 0;
- ret = audit_send_user_message(audit_fd, type, REAL_ERR, buf);
- if ((ret < 1) && errno == 0)
- errno = ret;
- return ret;
-}
-
-/*
- * This function will log a message to the audit system using a predefined
- * message format. This function should be used by all console apps that do
- * not manipulate accounts or groups.
- *
- * audit_fd - The fd returned by audit_open
- * type - type of message, ex: AUDIT_USER_CMD
- * command - the command line being logged
- * tty - The tty of the user
- * result - 1 is "success" and 0 is "failed"
- *
- * It returns the sequence number which is > 0 on success or <= 0 on error.
- */
-int audit_log_user_command(int audit_fd, int type, const char *command,
- const char *tty, int result)
-{
- char *p;
- char buf[MAX_AUDIT_MESSAGE_LENGTH];
- char commname[PATH_MAX*2];
- char cwdname[PATH_MAX*2];
- char ttyname[TTY_PATH];
- char format[64];
- const char *success;
- char *cmd;
- int ret, cwdenc=0, cmdenc=0;
- unsigned int len;
-
- if (audit_fd < 0)
- return 0;
-
- if (result)
- success = "success";
- else
- success = "failed";
-
- if (tty == NULL)
- tty = _get_tty(ttyname, TTY_PATH);
- else if (*tty == 0)
- tty = NULL;
-
- /* Trim leading spaces */
- while (*command == ' ')
- command++;
-
- cmd = strdup(command);
- if (cmd == NULL)
- return -1;
-
- // We borrow the commname buffer
- if (getcwd(commname, PATH_MAX) == NULL)
- strcpy(commname, "?");
- len = strlen(commname);
- if (audit_value_needs_encoding(commname, len)) {
- audit_encode_value(cwdname, commname, len);
- cwdenc = 1;
- } else
- strcpy(cwdname, commname);
-
- len = strlen(cmd);
- // Trim the trailing carriage return and spaces
- while (len && (cmd[len-1] == 0x0A || cmd[len-1] == ' ')) {
- cmd[len-1] = 0;
- len--;
- }
-
- if (len >= PATH_MAX) {
- cmd[PATH_MAX] = 0;
- len = PATH_MAX-1;
- }
- if (audit_value_needs_encoding(cmd, len)) {
- audit_encode_value(commname, cmd, len);
- cmdenc = 1;
- }
- if (cmdenc == 0)
- strcpy(commname, cmd);
- free(cmd);
-
- // Make the format string
- if (cwdenc)
- p=stpcpy(format, "cwd=%s ");
- else
- p=stpcpy(format, "cwd=\"%s\" ");
-
- if (cmdenc)
- p = stpcpy(p, "cmd=%s ");
- else
- p = stpcpy(p, "cmd=\"%s\" ");
-
- strcpy(p, "terminal=%s res=%s");
-
- // now use the format string to make the event
- snprintf(buf, sizeof(buf), format,
- cwdname, commname,
- tty ? tty : "?",
- success
- );
-
- errno = 0;
- ret = audit_send_user_message( audit_fd, type, HIDE_IT, buf );
- if ((ret < 1) && errno == 0)
- errno = ret;
- return ret;
-}
-