1 #include <unistd.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <getopt.h> 5 #include <errno.h> 6 #include <string.h> 7 #include <limits.h> 8 #include <sys/types.h> 9 #include <sys/stat.h> 10 #include <sys/errno.h> 11 #include <selinux/selinux.h> 12 #include <limits.h> 13 #include <stdlib.h> 14 15 static void usage(const char *progname) 16 { 17 fprintf(stderr, 18 "usage: %s [-N] [-n] [-f file_contexts] [ -P policy_root_path ] [-p prefix] [-Vq] path...\n", 19 progname); 20 exit(1); 21 } 22 23 static int printmatchpathcon(const char *path, int header, int mode) 24 { 25 char *buf; 26 int rc = matchpathcon(path, mode, &buf); 27 if (rc < 0) { 28 if (errno == ENOENT) { 29 buf=strdup("<<none>>"); 30 } else { 31 fprintf(stderr, "matchpathcon(%s) failed: %s\n", path, 32 strerror(errno)); 33 return 1; 34 } 35 } 36 if (header) 37 printf("%s\t%s\n", path, buf); 38 else 39 printf("%s\n", buf); 40 41 freecon(buf); 42 return 0; 43 } 44 45 static mode_t string_to_mode(char *s) 46 { 47 switch (s[0]) { 48 case 'b': 49 return S_IFBLK; 50 case 'c': 51 return S_IFCHR; 52 case 'd': 53 return S_IFDIR; 54 case 'p': 55 return S_IFIFO; 56 case 'l': 57 return S_IFLNK; 58 case 's': 59 return S_IFSOCK; 60 case 'f': 61 return S_IFREG; 62 default: 63 return -1; 64 }; 65 return -1; 66 } 67 68 int main(int argc, char **argv) 69 { 70 int i, init = 0, force_mode = 0; 71 int header = 1, opt; 72 int verify = 0; 73 int notrans = 0; 74 int error = 0; 75 int quiet = 0; 76 77 if (argc < 2) 78 usage(argv[0]); 79 80 while ((opt = getopt(argc, argv, "m:Nnf:P:p:Vq")) > 0) { 81 switch (opt) { 82 case 'n': 83 header = 0; 84 break; 85 case 'm': 86 force_mode = string_to_mode(optarg); 87 if (force_mode < 0) { 88 fprintf(stderr, "%s: mode %s is invalid\n", argv[0], optarg); 89 exit(1); 90 } 91 break; 92 case 'V': 93 verify = 1; 94 break; 95 case 'N': 96 notrans = 1; 97 set_matchpathcon_flags(MATCHPATHCON_NOTRANS); 98 break; 99 case 'f': 100 if (init) { 101 fprintf(stderr, 102 "%s: -f and -p are exclusive\n", 103 argv[0]); 104 exit(1); 105 } 106 init = 1; 107 if (matchpathcon_init(optarg)) { 108 fprintf(stderr, 109 "Error while processing %s: %s\n", 110 optarg, 111 errno ? strerror(errno) : "invalid"); 112 exit(1); 113 } 114 break; 115 case 'P': 116 if (selinux_set_policy_root(optarg) < 0 ) { 117 fprintf(stderr, 118 "Error setting policy root %s: %s\n", 119 optarg, 120 errno ? strerror(errno) : "invalid"); 121 exit(1); 122 } 123 break; 124 case 'p': 125 if (init) { 126 fprintf(stderr, 127 "%s: -f and -p are exclusive\n", 128 argv[0]); 129 exit(1); 130 } 131 init = 1; 132 if (matchpathcon_init_prefix(NULL, optarg)) { 133 fprintf(stderr, 134 "Error while processing %s: %s\n", 135 optarg, 136 errno ? strerror(errno) : "invalid"); 137 exit(1); 138 } 139 break; 140 case 'q': 141 quiet = 1; 142 break; 143 default: 144 usage(argv[0]); 145 } 146 } 147 for (i = optind; i < argc; i++) { 148 int rc, mode = 0; 149 struct stat buf; 150 char *path = argv[i]; 151 int len = strlen(path); 152 if (len > 1 && path[len - 1 ] == '/') 153 path[len - 1 ] = '\0'; 154 155 if (lstat(path, &buf) == 0) 156 mode = buf.st_mode; 157 if (force_mode) 158 mode = force_mode; 159 160 if (verify) { 161 rc = selinux_file_context_verify(path, mode); 162 163 if (quiet) { 164 if (rc == 1) 165 continue; 166 else 167 exit(1); 168 } 169 170 if (rc == -1) { 171 printf("%s error: %s\n", path, strerror(errno)); 172 exit(1); 173 } else if (rc == 1) { 174 printf("%s verified.\n", path); 175 } else { 176 char * con; 177 error = 1; 178 if (notrans) 179 rc = lgetfilecon_raw(path, &con); 180 else 181 rc = lgetfilecon(path, &con); 182 183 if (rc >= 0) { 184 printf("%s has context %s, should be ", 185 path, con); 186 printmatchpathcon(path, 0, mode); 187 freecon(con); 188 } else { 189 printf 190 ("actual context unknown: %s, should be ", 191 strerror(errno)); 192 printmatchpathcon(path, 0, mode); 193 } 194 } 195 } else { 196 error |= printmatchpathcon(path, header, mode); 197 } 198 } 199 matchpathcon_fini(); 200 return error; 201 } 202