| #include <unistd.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <libgen.h> |
| #include <errno.h> |
| #include <selinux/selinux.h> |
| #include <syslog.h> |
| #include <pwd.h> |
| #include <string.h> |
| |
| /* Attempt to rollback the transaction. No need to check error |
| codes since this is rolling back something that blew up. */ |
| static __attribute__ ((__noreturn__)) void rollback(int argc, char **argv) |
| { |
| int i; |
| |
| for (i = 1; i < argc; i++) |
| security_set_boolean(argv[i], |
| security_get_boolean_active(argv[i])); |
| exit(1); |
| } |
| |
| int main(int argc, char **argv) |
| { |
| |
| int rc, i, commit = 0; |
| |
| if (is_selinux_enabled() <= 0) { |
| fprintf(stderr, "%s: SELinux is disabled\n", argv[0]); |
| return 1; |
| } |
| |
| if (argc < 2) { |
| printf("Usage: %s boolname1 [boolname2 ...]\n", |
| basename(argv[0])); |
| return 1; |
| } |
| |
| for (i = 1; i < argc; i++) { |
| printf("%s: ", argv[i]); |
| rc = security_get_boolean_active(argv[i]); |
| switch (rc) { |
| case 1: |
| if (security_set_boolean(argv[i], 0) >= 0) { |
| printf("inactive\n"); |
| commit++; |
| } else { |
| printf("%s - rolling back all changes\n", |
| strerror(errno)); |
| rollback(i, argv); |
| } |
| break; |
| case 0: |
| if (security_set_boolean(argv[i], 1) >= 0) { |
| printf("active\n"); |
| commit++; |
| } else { |
| printf("%s - rolling back all changes\n", |
| strerror(errno)); |
| rollback(i, argv); |
| } |
| break; |
| default: |
| if (errno == ENOENT) |
| printf |
| ("Boolean does not exist - rolling back all changes.\n"); |
| else |
| printf("%s - rolling back all changes.\n", |
| strerror(errno)); |
| rollback(i, argv); |
| break; /* Not reached. */ |
| } |
| } |
| |
| if (commit > 0) { |
| if (security_commit_booleans() < 0) { |
| printf("Commit failed. (%s) No change to booleans.\n", |
| strerror(errno)); |
| } else { |
| /* syslog all the changes */ |
| struct passwd *pwd = getpwuid(getuid()); |
| for (i = 1; i < argc; i++) { |
| if (pwd && pwd->pw_name) |
| syslog(LOG_NOTICE, |
| "The %s policy boolean was toggled by %s", |
| argv[i], pwd->pw_name); |
| else |
| syslog(LOG_NOTICE, |
| "The %s policy boolean was toggled by uid:%u", |
| argv[i], getuid()); |
| |
| } |
| return 0; |
| } |
| } |
| return 1; |
| } |