16cd6a6acSopenharmony_ci#include <unistd.h> 26cd6a6acSopenharmony_ci#include <sys/types.h> 36cd6a6acSopenharmony_ci#include <fcntl.h> 46cd6a6acSopenharmony_ci#include <stdio.h> 56cd6a6acSopenharmony_ci#include <stdlib.h> 66cd6a6acSopenharmony_ci#include <errno.h> 76cd6a6acSopenharmony_ci#include <string.h> 86cd6a6acSopenharmony_ci#include <ctype.h> 96cd6a6acSopenharmony_ci#include <selinux/selinux.h> 106cd6a6acSopenharmony_ci#include <selinux/get_context_list.h> 116cd6a6acSopenharmony_ci 126cd6a6acSopenharmony_cistatic __attribute__ ((__noreturn__)) void usage(const char *name, const char *detail, int rc) 136cd6a6acSopenharmony_ci{ 146cd6a6acSopenharmony_ci fprintf(stderr, "usage: %s [-l level] [-s service] user [fromcon]\n", name); 156cd6a6acSopenharmony_ci if (detail) 166cd6a6acSopenharmony_ci fprintf(stderr, "%s: %s\n", name, detail); 176cd6a6acSopenharmony_ci exit(rc); 186cd6a6acSopenharmony_ci} 196cd6a6acSopenharmony_ci 206cd6a6acSopenharmony_ciint main(int argc, char **argv) 216cd6a6acSopenharmony_ci{ 226cd6a6acSopenharmony_ci char * usercon = NULL, *cur_context = NULL; 236cd6a6acSopenharmony_ci char *user = NULL, *level = NULL, *role=NULL, *seuser=NULL, *dlevel=NULL; 246cd6a6acSopenharmony_ci char *service = NULL; 256cd6a6acSopenharmony_ci int ret, opt; 266cd6a6acSopenharmony_ci int verbose = 0; 276cd6a6acSopenharmony_ci 286cd6a6acSopenharmony_ci while ((opt = getopt(argc, argv, "l:r:s:v")) > 0) { 296cd6a6acSopenharmony_ci switch (opt) { 306cd6a6acSopenharmony_ci case 'l': 316cd6a6acSopenharmony_ci free(level); 326cd6a6acSopenharmony_ci level = strdup(optarg); 336cd6a6acSopenharmony_ci break; 346cd6a6acSopenharmony_ci case 'r': 356cd6a6acSopenharmony_ci free(role); 366cd6a6acSopenharmony_ci role = strdup(optarg); 376cd6a6acSopenharmony_ci break; 386cd6a6acSopenharmony_ci case 's': 396cd6a6acSopenharmony_ci free(service); 406cd6a6acSopenharmony_ci service = strdup(optarg); 416cd6a6acSopenharmony_ci break; 426cd6a6acSopenharmony_ci case 'v': 436cd6a6acSopenharmony_ci verbose = 1; 446cd6a6acSopenharmony_ci break; 456cd6a6acSopenharmony_ci default: 466cd6a6acSopenharmony_ci usage(argv[0], "invalid option", 1); 476cd6a6acSopenharmony_ci } 486cd6a6acSopenharmony_ci } 496cd6a6acSopenharmony_ci 506cd6a6acSopenharmony_ci if (((argc - optind) < 1) || ((argc - optind) > 2)) 516cd6a6acSopenharmony_ci usage(argv[0], "invalid number of arguments", 2); 526cd6a6acSopenharmony_ci 536cd6a6acSopenharmony_ci /* If selinux isn't available, bail out. */ 546cd6a6acSopenharmony_ci if (!is_selinux_enabled()) { 556cd6a6acSopenharmony_ci fprintf(stderr, 566cd6a6acSopenharmony_ci "%s may be used only on a SELinux kernel.\n", argv[0]); 576cd6a6acSopenharmony_ci return 1; 586cd6a6acSopenharmony_ci } 596cd6a6acSopenharmony_ci 606cd6a6acSopenharmony_ci user = argv[optind]; 616cd6a6acSopenharmony_ci 626cd6a6acSopenharmony_ci /* If a context wasn't passed, use the current context. */ 636cd6a6acSopenharmony_ci if (((argc - optind) < 2)) { 646cd6a6acSopenharmony_ci if (getcon(&cur_context) < 0) { 656cd6a6acSopenharmony_ci fprintf(stderr, "Couldn't get current context: %s\n", strerror(errno)); 666cd6a6acSopenharmony_ci return 2; 676cd6a6acSopenharmony_ci } 686cd6a6acSopenharmony_ci } else 696cd6a6acSopenharmony_ci cur_context = argv[optind + 1]; 706cd6a6acSopenharmony_ci 716cd6a6acSopenharmony_ci if (security_check_context(cur_context)) { 726cd6a6acSopenharmony_ci fprintf(stderr, "%s: invalid from context '%s'\n", argv[0], cur_context); 736cd6a6acSopenharmony_ci return 3; 746cd6a6acSopenharmony_ci } 756cd6a6acSopenharmony_ci 766cd6a6acSopenharmony_ci if ((ret = getseuser(user, service, &seuser, &dlevel)) == 0) { 776cd6a6acSopenharmony_ci if (! level) level=dlevel; 786cd6a6acSopenharmony_ci if (role != NULL && role[0]) 796cd6a6acSopenharmony_ci ret=get_default_context_with_rolelevel(seuser, role, level,cur_context,&usercon); 806cd6a6acSopenharmony_ci else 816cd6a6acSopenharmony_ci ret=get_default_context_with_level(seuser, level, cur_context,&usercon); 826cd6a6acSopenharmony_ci } 836cd6a6acSopenharmony_ci if (ret < 0) 846cd6a6acSopenharmony_ci perror(argv[0]); 856cd6a6acSopenharmony_ci else { 866cd6a6acSopenharmony_ci if (verbose) { 876cd6a6acSopenharmony_ci printf("%s: %s from %s %s %s %s -> %s\n", argv[0], user, cur_context, seuser, role, level, usercon); 886cd6a6acSopenharmony_ci } else { 896cd6a6acSopenharmony_ci printf("%s\n", usercon); 906cd6a6acSopenharmony_ci } 916cd6a6acSopenharmony_ci } 926cd6a6acSopenharmony_ci 936cd6a6acSopenharmony_ci free(role); 946cd6a6acSopenharmony_ci free(seuser); 956cd6a6acSopenharmony_ci if (level != dlevel) free(level); 966cd6a6acSopenharmony_ci free(dlevel); 976cd6a6acSopenharmony_ci free(usercon); 986cd6a6acSopenharmony_ci 996cd6a6acSopenharmony_ci return ret >= 0; 1006cd6a6acSopenharmony_ci} 101