static void
init_auditd (NMAuditManager *self)
{
	NMAuditManagerPrivate *priv = NM_AUDIT_MANAGER_GET_PRIVATE (self);
	NMConfigData *data = nm_config_get_data (priv->config);

	if (nm_config_data_get_value_boolean (data, NM_CONFIG_KEYFILE_GROUP_LOGGING,
	                                      NM_CONFIG_KEYFILE_KEY_AUDIT,
	                                      NM_CONFIG_DEFAULT_LOGGING_AUDIT)) {
		if (priv->auditd_fd < 0) {
			priv->auditd_fd = audit_open ();
			if (priv->auditd_fd < 0) {
				nm_log_err (LOGD_CORE, "failed to open auditd socket: %s",
				            strerror (errno));
			} else
				nm_log_dbg (LOGD_CORE, "audit socket created");
		}
	} else {
		if (priv->auditd_fd >= 0) {
			audit_close (priv->auditd_fd);
			priv->auditd_fd = -1;
			nm_log_dbg (LOGD_CORE, "audit socket closed");
		}
	}
}
Exemple #2
0
static void maybe_audit_mass_relabel(int mass_relabel __attribute__((unused)),
				     int mass_relabel_errs __attribute__((unused)))
{
#else
static void maybe_audit_mass_relabel(int mass_relabel, int mass_relabel_errs)
{
	int audit_fd = -1;
	int rc = 0;

	if (!mass_relabel)		/* only audit a forced full relabel */
		return;

	audit_fd = audit_open();

	if (audit_fd < 0) {
		fprintf(stderr, "Error connecting to audit system.\n");
		exit(-1);
	}

	rc = audit_log_user_message(audit_fd, AUDIT_FS_RELABEL,
				    "op=mass relabel", NULL, NULL, NULL, !mass_relabel_errs);
	if (rc <= 0) {
		fprintf(stderr, "Error sending audit message: %s.\n",
			strerror(errno));
		/* exit(-1); -- don't exit atm. as fix for eff_cap isn't in most kernels */
	}
	audit_close(audit_fd);
#endif
}
Exemple #3
0
/**
 * Close the libaudit fd.
 */
void
bus_audit_shutdown (void)
{
#ifdef HAVE_LIBAUDIT
  audit_close (audit_fd);
#endif /* HAVE_LIBAUDIT */
}
static bool audit_mainloop()
{
    int fd = audit_open();
    if (fd < 0) {
        LOGE("Failed to open audit socket: %s", strerror(errno));
        return false;
    }

    auto close_fd = finally([&]{
        audit_close(fd);
    });

    if (audit_setup(fd, static_cast<uint32_t>(getpid())) < 0) {
        return false;
    }

    while (true) {
        struct audit_message reply;
        reply.nlh.nlmsg_type = 0;
        reply.nlh.nlmsg_len = 0;
        reply.data[0] = '\0';

        if (audit_get_reply(fd, &reply, GET_REPLY_BLOCKING, 0) < 0) {
            LOGE("Failed to get reply from audit socket: %s", strerror(errno));
            return false;
        }

        LOGV("type=%d %.*s",
             reply.nlh.nlmsg_type, reply.nlh.nlmsg_len, reply.data);
    }

    // unreachable
}
static int _audit_log(int type, const char *uname, int rc)
{
    int audit_fd;

    audit_fd = audit_open();
    if (audit_fd < 0) {
        /* You get these error codes only when the kernel doesn't have
         * audit compiled in. */
        if (errno == EINVAL || errno == EPROTONOSUPPORT ||
                errno == EAFNOSUPPORT)
            return PAM_SUCCESS;

        helper_log_err(LOG_CRIT, "audit_open() failed: %m");
        return PAM_AUTH_ERR;
    }

    rc = audit_log_acct_message(audit_fd, type, NULL, "PAM:unix_chkpwd",
                                uname, -1, NULL, NULL, NULL, rc == PAM_SUCCESS);
    if (rc == -EPERM && geteuid() != 0) {
        rc = 0;
    }

    audit_close(audit_fd);

    return rc < 0 ? PAM_AUTH_ERR : PAM_SUCCESS;
}
Exemple #6
0
/* Clean up the AVC before exiting.  */
void
nscd_avc_destroy (void)
{
  avc_destroy ();
#ifdef HAVE_LIBAUDIT
  audit_close (audit_fd);
#endif
}
Exemple #7
0
static void context_clear(Context *c) {
        assert(c);

        c->bus = sd_bus_flush_close_unref(c->bus);
#if HAVE_AUDIT
        if (c->audit_fd >= 0)
                audit_close(c->audit_fd);
        c->audit_fd = -1;
#endif
}
int LogAudit::getLogSocket() {
    int fd = audit_open();
    if (fd < 0) {
        return fd;
    }
    if (audit_setup(fd, getpid()) < 0) {
        audit_close(fd);
        fd = -1;
    }
    return fd;
}
Exemple #9
0
/*
 * A clean exit means : 
 * 1) we log that we are going down
 * 2) deregister with kernel
 * 3) close the netlink socket
 */
static void clean_exit(void)
{
	audit_msg(LOG_INFO, "The audit daemon is exiting.");
	if (fd >= 0) {
		audit_set_pid(fd, 0, WAIT_NO);
		audit_close(fd);
	}
	if (pidfile)
		unlink(pidfile);
	closelog();
}
static void
dispose (GObject *object)
{
#if HAVE_LIBAUDIT
	NMAuditManager *self = NM_AUDIT_MANAGER (object);
	NMAuditManagerPrivate *priv = NM_AUDIT_MANAGER_GET_PRIVATE (self);

	if (priv->config) {
		g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, self);
		g_clear_object (&priv->config);
	}

	 if (priv->auditd_fd >= 0) {
		audit_close (priv->auditd_fd);
		priv->auditd_fd = -1;
	}
#endif

	G_OBJECT_CLASS (nm_audit_manager_parent_class)->dispose (object);
}
Exemple #11
0
/*
 * This function interprets the reply and prints it to stdout. It returns
 * 0 if no more should be read and 1 to indicate that more messages of this
 * type may need to be read. 
 */
int audit_print_reply(struct audit_reply *rep, int fd)
{
	_audit_elf = 0; 

	switch (rep->type) {
		case NLMSG_NOOP:
			return 1;
		case NLMSG_DONE:
			// Close the socket so kernel can do other things
			audit_close(fd);
			if (printed == 0)
				printf("No rules\n");
			else {
				lnode *n;
				list_first(&l);
				n = l.cur;
				while (n) {
					print_rule(n->r);
					n = list_next(&l);
				}
				list_clear(&l);
			}
			break;
		case NLMSG_ERROR: 
		        printf("NLMSG_ERROR %d (%s)\n",
				-rep->error->error, 
				strerror(-rep->error->error));
			printed = 1;
			break;
		case AUDIT_GET:
			if (interpret)
				printf("enabled %s\nfailure %s\n",
					get_enable(rep->status->enabled),
					get_failure(rep->status->failure));
			else
				printf("enabled %u\nfailure %u\n",
				rep->status->enabled, rep->status->failure);
			printf("pid %u\nrate_limit %u\nbacklog_limit %u\n"
				"lost %u\nbacklog %u\n",
			rep->status->pid, rep->status->rate_limit,
			rep->status->backlog_limit, rep->status->lost,
			rep->status->backlog);
#if HAVE_DECL_AUDIT_VERSION_BACKLOG_WAIT_TIME
			printf("backlog_wait_time %u\n",
				rep->status->backlog_wait_time);
#endif
			printed = 1;
			break;
#if HAVE_DECL_AUDIT_FEATURE_VERSION
		case AUDIT_GET_FEATURE:
			{
			uint32_t mask = AUDIT_FEATURE_TO_MASK(AUDIT_FEATURE_LOGINUID_IMMUTABLE);
			if (rep->features->mask & mask)
				printf("loginuid_immutable %u %s\n",
					!!(rep->features->features & mask),
					rep->features->lock & mask ? "locked" :
					"unlocked");
			}
			printed = 1;
			break;
#endif
		case AUDIT_LIST_RULES:
			list_requested = 0;
			if (key_match(rep->ruledata))
				 list_append(&l, rep->ruledata,
					sizeof(struct audit_rule_data) +
					rep->ruledata->buflen);
			printed = 1;
			return 1;
		default:
			printf("Unknown: type=%d, len=%d\n", rep->type, 
				rep->nlh->nlmsg_len);
			printed = 1;
			break;
	}
	return 0;
}
Exemple #12
0
/*
 * This function is called after setopt to handle the return code.
 * On entry, status = 0 means just get the reply. Greater than 0 means we
 * are adding or deleting a rule or watch. -1 means an error occurred.
 * -2 means everything is OK and no reply needed. Even if there's an 
 * error, we need to call this routine to close up the audit fd.
 * The return code from this function is 0 success and -1 error.
 */
static int handle_request(int status)
{
	if (status == 0) {
		if (_audit_syscalladded) {
			fprintf(stderr, "Error - no list specified\n");
			return -1;
		}
		get_reply();
	} else if (status == -2)
		status = 0;  // report success 
	else if (status > 0) {
		int rc;
		if (add != AUDIT_FILTER_UNSET) {
			// if !task add syscall any if not specified
			if ((add & AUDIT_FILTER_MASK) != AUDIT_FILTER_TASK && 
					_audit_syscalladded != 1) {
					audit_rule_syscallbyname_data(
							rule_new, "all");
			}
			set_aumessage_mode(MSG_QUIET, DBG_NO);
			rc = audit_add_rule_data(fd, rule_new, add, action);
			set_aumessage_mode(MSG_STDERR, DBG_NO);
			/* Retry for legacy kernels */
			if (rc < 0) {
				if (errno == EINVAL &&
				rule_new->fields[0] == AUDIT_DIR) {
					rule_new->fields[0] = AUDIT_WATCH;
					rc = audit_add_rule_data(fd, rule_new,
							add, action);
				} else {
					fprintf(stderr,
				"Error sending add rule data request (%s)\n",
					errno == EEXIST ?
					"Rule exists" : strerror(-rc));
				}
			}
		}
		else if (del != AUDIT_FILTER_UNSET) {
			if ((del & AUDIT_FILTER_MASK) != AUDIT_FILTER_TASK && 
					_audit_syscalladded != 1) {
					audit_rule_syscallbyname_data(
							rule_new, "all");
			}
			set_aumessage_mode(MSG_QUIET, DBG_NO);
			rc = audit_delete_rule_data(fd, rule_new,
								 del, action);
			set_aumessage_mode(MSG_STDERR, DBG_NO);
			/* Retry for legacy kernels */
			if (rc < 0) {
				if (errno == EINVAL &&
					rule_new->fields[0] == AUDIT_DIR) {
					rule_new->fields[0] = AUDIT_WATCH;
					rc = audit_delete_rule_data(fd,rule_new,
								del, action);
				} else {
					fprintf(stderr,
			       "Error sending delete rule data request (%s)\n",
					errno == EEXIST ?
					"Rule exists" : strerror(-rc));
				}
			}
		} else {
        		usage();
	    		audit_close(fd);
			exit(1);
	    	}
		if (rc <= 0) 
			status = -1;
		else
			status = 0;
	} else 
		status = -1;

	audit_close(fd);
	fd = -1;
	return status;
}
Exemple #13
0
static void do_auditd(int fd) {
    struct audit_reply rep;
    sigset_t sigs;
    struct sigaction sa;
    struct pollfd pds = {
        .events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLMSG,
        .revents = 0,
        .fd = fd,
    };

    if (audit_set_pid(fd, getpid(), WAIT_YES) < 0)
        return;

    if (audit_set_enabled(fd, 1) < 0)
        return;

    memset(&sa, '\0', sizeof (sa));
    sa.sa_handler = sig_done;
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGHUP, &sa, NULL);

    sigfillset(&sigs);
    sigdelset(&sigs, SIGTERM);
    sigdelset(&sigs, SIGINT);
    sigdelset(&sigs, SIGHUP);

    while (1) {
        struct timespec timeout = { -1, -1 };
        int retval;

        memset(&rep, 0, sizeof(rep));

        do {
            retval = ppoll(&pds, 1, &timeout, &sigs);
        } while (retval == -1 && errno == EINTR && !done);

        if (done)
            break;

        if (audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0) > 0) {
            /* we don't actually want to do anything here. */
            ;
        }
    }
    return;
}
#endif /* USESELINUX */

int audit_daemonize(void) {
#ifdef USESELINUX
    int fd;
#ifndef STANDALONE 
    int i;
    pid_t child;

    if ((child = fork()) > 0)
        return 0;

    for (i = 0; i < getdtablesize(); i++)
        close(i);

    signal(SIGTTOU, SIG_IGN);
    signal(SIGTTIN, SIG_IGN);
    signal(SIGTSTP, SIG_IGN);

    if ((fd = open("/proc/self/oom_adj", O_RDWR)) >= 0) {
        i = write(fd, "-17", 3);
        close(fd);
    }

#endif /* !defined(STANDALONE) */
    fd = audit_open();
    do_auditd(fd);
    audit_close(fd);
#endif /* USESELINUX */
    exit(0);
}
Exemple #14
0
int main(int argc, char *argv[]) {
        int r;
        DBusError error;
        Context c;

        dbus_error_init(&error);

        zero(c);
#ifdef HAVE_AUDIT
        c.audit_fd = -1;
#endif

        if (getppid() != 1) {
                log_error("This program should be invoked by init only.");
                return EXIT_FAILURE;
        }

        if (argc != 2) {
                log_error("This program requires one argument.");
                return EXIT_FAILURE;
        }

        log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
        log_parse_environment();
        log_open();

#ifdef HAVE_AUDIT
        if ((c.audit_fd = audit_open()) < 0)
                log_error("Failed to connect to audit log: %m");
#endif

        if (bus_connect(DBUS_BUS_SYSTEM, &c.bus, NULL, &error) < 0) {
                log_error("Failed to get D-Bus connection: %s", bus_error_message(&error));
                r = -EIO;
                goto finish;
        }

        log_debug("systemd-update-utmp running as pid %lu", (unsigned long) getpid());

        if (streq(argv[1], "reboot"))
                r = on_reboot(&c);
        else if (streq(argv[1], "shutdown"))
                r = on_shutdown(&c);
        else if (streq(argv[1], "runlevel"))
                r = on_runlevel(&c);
        else {
                log_error("Unknown command %s", argv[1]);
                r = -EINVAL;
        }

        log_debug("systemd-update-utmp stopped as pid %lu", (unsigned long) getpid());

finish:
#ifdef HAVE_AUDIT
        if (c.audit_fd >= 0)
                audit_close(c.audit_fd);
#endif

        if (c.bus) {
                dbus_connection_flush(c.bus);
                dbus_connection_close(c.bus);
                dbus_connection_unref(c.bus);
        }

        dbus_error_free(&error);
        dbus_shutdown();

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}