| #include <unistd.h> |
| #include <sys/types.h> |
| #include <fcntl.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <errno.h> |
| #include <string.h> |
| #include <ctype.h> |
| #include <selinux/selinux.h> |
| #include <selinux/get_context_list.h> |
| |
| static __attribute__ ((__noreturn__)) void usage(const char *name, const char *detail, int rc) |
| { |
| fprintf(stderr, "usage: %s [-l level] [-s service] user [fromcon]\n", name); |
| if (detail) |
| fprintf(stderr, "%s: %s\n", name, detail); |
| exit(rc); |
| } |
| |
| int main(int argc, char **argv) |
| { |
| char * usercon = NULL, *cur_context = NULL; |
| char *user = NULL, *level = NULL, *role=NULL, *seuser=NULL, *dlevel=NULL; |
| char *service = NULL; |
| int ret, opt; |
| int verbose = 0; |
| |
| while ((opt = getopt(argc, argv, "l:r:s:v")) > 0) { |
| switch (opt) { |
| case 'l': |
| level = strdup(optarg); |
| break; |
| case 'r': |
| role = strdup(optarg); |
| break; |
| case 's': |
| service = strdup(optarg); |
| break; |
| case 'v': |
| verbose = 1; |
| break; |
| default: |
| usage(argv[0], "invalid option", 1); |
| } |
| } |
| |
| if (((argc - optind) < 1) || ((argc - optind) > 2)) |
| usage(argv[0], "invalid number of arguments", 2); |
| |
| /* If selinux isn't available, bail out. */ |
| if (!is_selinux_enabled()) { |
| fprintf(stderr, |
| "%s may be used only on a SELinux kernel.\n", argv[0]); |
| return 1; |
| } |
| |
| user = argv[optind]; |
| |
| /* If a context wasn't passed, use the current context. */ |
| if (((argc - optind) < 2)) { |
| if (getcon(&cur_context) < 0) { |
| fprintf(stderr, "Couldn't get current context.\n"); |
| return 2; |
| } |
| } else |
| cur_context = argv[optind + 1]; |
| |
| if ((ret = getseuser(user, service, &seuser, &dlevel)) == 0) { |
| if (! level) level=dlevel; |
| if (role != NULL && role[0]) |
| ret=get_default_context_with_rolelevel(seuser, role, level,cur_context,&usercon); |
| else |
| ret=get_default_context_with_level(seuser, level, cur_context,&usercon); |
| } |
| if (ret < 0) |
| perror(argv[0]); |
| else { |
| if (verbose) { |
| printf("%s: %s from %s %s %s %s -> %s\n", argv[0], user, cur_context, seuser, role, level, usercon); |
| } else { |
| printf("%s\n", usercon); |
| } |
| } |
| |
| free(role); |
| free(seuser); |
| if (level != dlevel) free(level); |
| free(dlevel); |
| free(usercon); |
| |
| return ret >= 0; |
| } |