blob: 96a5a8c23656c2ded3274ad57edafe7b761d702c [file] [log] [blame]
Joshua Brindle13cd4c82008-08-19 15:30:36 -04001#include <unistd.h>
2#include <sys/types.h>
3#include <fcntl.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <errno.h>
7#include <string.h>
8#include <ctype.h>
9#include <selinux/selinux.h>
10#include <selinux/get_context_list.h>
11
William Robertse4f2bcc2016-11-01 14:23:10 -070012static __attribute__ ((__noreturn__)) void usage(const char *name, const char *detail, int rc)
Joshua Brindle13cd4c82008-08-19 15:30:36 -040013{
Eric Paris056f23c2012-06-21 15:44:45 -040014 fprintf(stderr, "usage: %s [-l level] [-s service] user [fromcon]\n", name);
Joshua Brindle13cd4c82008-08-19 15:30:36 -040015 if (detail)
16 fprintf(stderr, "%s: %s\n", name, detail);
17 exit(rc);
18}
19
20int main(int argc, char **argv)
21{
Stephen Smalley9eb9c932014-02-19 09:16:17 -050022 char * usercon = NULL, *cur_context = NULL;
Joshua Brindle13cd4c82008-08-19 15:30:36 -040023 char *user = NULL, *level = NULL, *role=NULL, *seuser=NULL, *dlevel=NULL;
Eric Paris056f23c2012-06-21 15:44:45 -040024 char *service = NULL;
Joshua Brindle13cd4c82008-08-19 15:30:36 -040025 int ret, opt;
Daniel J Walsh20eff2b2009-05-14 15:43:18 -040026 int verbose = 0;
Joshua Brindle13cd4c82008-08-19 15:30:36 -040027
Eric Paris056f23c2012-06-21 15:44:45 -040028 while ((opt = getopt(argc, argv, "l:r:s:v")) > 0) {
Joshua Brindle13cd4c82008-08-19 15:30:36 -040029 switch (opt) {
30 case 'l':
31 level = strdup(optarg);
32 break;
33 case 'r':
34 role = strdup(optarg);
35 break;
Eric Paris056f23c2012-06-21 15:44:45 -040036 case 's':
37 service = strdup(optarg);
38 break;
Daniel J Walsh20eff2b2009-05-14 15:43:18 -040039 case 'v':
40 verbose = 1;
41 break;
Joshua Brindle13cd4c82008-08-19 15:30:36 -040042 default:
43 usage(argv[0], "invalid option", 1);
44 }
45 }
46
47 if (((argc - optind) < 1) || ((argc - optind) > 2))
48 usage(argv[0], "invalid number of arguments", 2);
49
50 /* If selinux isn't available, bail out. */
51 if (!is_selinux_enabled()) {
52 fprintf(stderr,
53 "%s may be used only on a SELinux kernel.\n", argv[0]);
54 return 1;
55 }
56
57 user = argv[optind];
58
59 /* If a context wasn't passed, use the current context. */
60 if (((argc - optind) < 2)) {
61 if (getcon(&cur_context) < 0) {
62 fprintf(stderr, "Couldn't get current context.\n");
63 return 2;
64 }
65 } else
66 cur_context = argv[optind + 1];
67
Eric Paris056f23c2012-06-21 15:44:45 -040068 if ((ret = getseuser(user, service, &seuser, &dlevel)) == 0) {
Joshua Brindle13cd4c82008-08-19 15:30:36 -040069 if (! level) level=dlevel;
70 if (role != NULL && role[0])
71 ret=get_default_context_with_rolelevel(seuser, role, level,cur_context,&usercon);
72 else
73 ret=get_default_context_with_level(seuser, level, cur_context,&usercon);
74 }
75 if (ret < 0)
76 perror(argv[0]);
Daniel J Walsh20eff2b2009-05-14 15:43:18 -040077 else {
78 if (verbose) {
79 printf("%s: %s from %s %s %s %s -> %s\n", argv[0], user, cur_context, seuser, role, level, usercon);
80 } else {
Eric Paris056f23c2012-06-21 15:44:45 -040081 printf("%s\n", usercon);
Daniel J Walsh20eff2b2009-05-14 15:43:18 -040082 }
83 }
Joshua Brindle13cd4c82008-08-19 15:30:36 -040084
85 free(role);
86 free(seuser);
87 if (level != dlevel) free(level);
88 free(dlevel);
89 free(usercon);
90
Daniel J Walsh20eff2b2009-05-14 15:43:18 -040091 return ret >= 0;
Joshua Brindle13cd4c82008-08-19 15:30:36 -040092}