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] user [context]\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 **list, *cur_context = NULL; 236cd6a6acSopenharmony_ci char *user = NULL, *level = NULL; 246cd6a6acSopenharmony_ci int ret, i, opt; 256cd6a6acSopenharmony_ci 266cd6a6acSopenharmony_ci while ((opt = getopt(argc, argv, "l:")) > 0) { 276cd6a6acSopenharmony_ci switch (opt) { 286cd6a6acSopenharmony_ci case 'l': 296cd6a6acSopenharmony_ci free(level); 306cd6a6acSopenharmony_ci level = strdup(optarg); 316cd6a6acSopenharmony_ci if (!level) { 326cd6a6acSopenharmony_ci fprintf(stderr, "memory allocation failure: %d(%s)\n", 336cd6a6acSopenharmony_ci errno, strerror(errno)); 346cd6a6acSopenharmony_ci return 3; 356cd6a6acSopenharmony_ci } 366cd6a6acSopenharmony_ci break; 376cd6a6acSopenharmony_ci default: 386cd6a6acSopenharmony_ci usage(argv[0], "invalid option", 1); 396cd6a6acSopenharmony_ci } 406cd6a6acSopenharmony_ci } 416cd6a6acSopenharmony_ci 426cd6a6acSopenharmony_ci if (((argc - optind) < 1) || ((argc - optind) > 2)) 436cd6a6acSopenharmony_ci usage(argv[0], "invalid number of arguments", 2); 446cd6a6acSopenharmony_ci 456cd6a6acSopenharmony_ci /* If selinux isn't available, bail out. */ 466cd6a6acSopenharmony_ci if (!is_selinux_enabled()) { 476cd6a6acSopenharmony_ci fprintf(stderr, 486cd6a6acSopenharmony_ci "getconlist may be used only on a SELinux kernel.\n"); 496cd6a6acSopenharmony_ci free(level); 506cd6a6acSopenharmony_ci return 1; 516cd6a6acSopenharmony_ci } 526cd6a6acSopenharmony_ci 536cd6a6acSopenharmony_ci user = argv[optind]; 546cd6a6acSopenharmony_ci 556cd6a6acSopenharmony_ci /* If a context wasn't passed, use the current context. */ 566cd6a6acSopenharmony_ci if (((argc - optind) < 2)) { 576cd6a6acSopenharmony_ci if (getcon(&cur_context) < 0) { 586cd6a6acSopenharmony_ci fprintf(stderr, "Couldn't get current context: %s\n", strerror(errno)); 596cd6a6acSopenharmony_ci free(level); 606cd6a6acSopenharmony_ci return 2; 616cd6a6acSopenharmony_ci } 626cd6a6acSopenharmony_ci } else { 636cd6a6acSopenharmony_ci cur_context = argv[optind + 1]; 646cd6a6acSopenharmony_ci if (security_check_context(cur_context) != 0) { 656cd6a6acSopenharmony_ci fprintf(stderr, "Given context '%s' is invalid.\n", cur_context); 666cd6a6acSopenharmony_ci free(level); 676cd6a6acSopenharmony_ci return 3; 686cd6a6acSopenharmony_ci } 696cd6a6acSopenharmony_ci } 706cd6a6acSopenharmony_ci 716cd6a6acSopenharmony_ci /* Get the list and print it */ 726cd6a6acSopenharmony_ci if (level) 736cd6a6acSopenharmony_ci ret = 746cd6a6acSopenharmony_ci get_ordered_context_list_with_level(user, level, 756cd6a6acSopenharmony_ci cur_context, &list); 766cd6a6acSopenharmony_ci else 776cd6a6acSopenharmony_ci ret = get_ordered_context_list(user, cur_context, &list); 786cd6a6acSopenharmony_ci if (ret != -1) { 796cd6a6acSopenharmony_ci for (i = 0; list[i]; i++) 806cd6a6acSopenharmony_ci puts(list[i]); 816cd6a6acSopenharmony_ci freeconary(list); 826cd6a6acSopenharmony_ci } else { 836cd6a6acSopenharmony_ci fprintf(stderr, "get_ordered_context_list%s failure: %d(%s)\n", 846cd6a6acSopenharmony_ci level ? "_with_level" : "", errno, strerror(errno)); 856cd6a6acSopenharmony_ci free(level); 866cd6a6acSopenharmony_ci return 4; 876cd6a6acSopenharmony_ci } 886cd6a6acSopenharmony_ci 896cd6a6acSopenharmony_ci free(level); 906cd6a6acSopenharmony_ci 916cd6a6acSopenharmony_ci return 0; 926cd6a6acSopenharmony_ci} 93