16cd6a6acSopenharmony_ci#include <errno.h> 26cd6a6acSopenharmony_ci#include <stdio.h> 36cd6a6acSopenharmony_ci#include <stdlib.h> 46cd6a6acSopenharmony_ci#include <string.h> 56cd6a6acSopenharmony_ci 66cd6a6acSopenharmony_ci#include <sepol/policydb/services.h> 76cd6a6acSopenharmony_ci#include <sepol/sepol.h> 86cd6a6acSopenharmony_ci 96cd6a6acSopenharmony_ci 106cd6a6acSopenharmony_ciint main(int argc, char *argv[]) 116cd6a6acSopenharmony_ci{ 126cd6a6acSopenharmony_ci FILE *fp; 136cd6a6acSopenharmony_ci sepol_security_id_t ssid, tsid; 146cd6a6acSopenharmony_ci sepol_security_class_t tclass; 156cd6a6acSopenharmony_ci const char *permlist; 166cd6a6acSopenharmony_ci sepol_access_vector_t av; 176cd6a6acSopenharmony_ci struct sepol_av_decision avd; 186cd6a6acSopenharmony_ci unsigned int reason; 196cd6a6acSopenharmony_ci char *reason_buf; 206cd6a6acSopenharmony_ci int i; 216cd6a6acSopenharmony_ci 226cd6a6acSopenharmony_ci if (argc != 6) { 236cd6a6acSopenharmony_ci printf("usage: %s policy source_context target_context class permission[,permission2[,...]]\n", argv[0]); 246cd6a6acSopenharmony_ci return 1; 256cd6a6acSopenharmony_ci } 266cd6a6acSopenharmony_ci 276cd6a6acSopenharmony_ci fp = fopen(argv[1], "r"); 286cd6a6acSopenharmony_ci if (!fp) { 296cd6a6acSopenharmony_ci fprintf(stderr, "Can't open policy %s: %s\n", argv[1], strerror(errno)); 306cd6a6acSopenharmony_ci return 1; 316cd6a6acSopenharmony_ci } 326cd6a6acSopenharmony_ci if (sepol_set_policydb_from_file(fp) < 0) { 336cd6a6acSopenharmony_ci fprintf(stderr, "Error while processing policy %s: %s\n", argv[1], strerror(errno)); 346cd6a6acSopenharmony_ci fclose(fp); 356cd6a6acSopenharmony_ci return 1; 366cd6a6acSopenharmony_ci } 376cd6a6acSopenharmony_ci fclose(fp); 386cd6a6acSopenharmony_ci 396cd6a6acSopenharmony_ci if (sepol_context_to_sid(argv[2], strlen(argv[2]), &ssid) < 0) { 406cd6a6acSopenharmony_ci fprintf(stderr, "Invalid source context %s\n", argv[2]); 416cd6a6acSopenharmony_ci return 1; 426cd6a6acSopenharmony_ci } 436cd6a6acSopenharmony_ci 446cd6a6acSopenharmony_ci if (sepol_context_to_sid(argv[3], strlen(argv[3]), &tsid) < 0) { 456cd6a6acSopenharmony_ci fprintf(stderr, "Invalid target context %s\n", argv[3]); 466cd6a6acSopenharmony_ci return 1; 476cd6a6acSopenharmony_ci } 486cd6a6acSopenharmony_ci 496cd6a6acSopenharmony_ci if (sepol_string_to_security_class(argv[4], &tclass) < 0) { 506cd6a6acSopenharmony_ci fprintf(stderr, "Invalid security class %s\n", argv[4]); 516cd6a6acSopenharmony_ci return 1; 526cd6a6acSopenharmony_ci } 536cd6a6acSopenharmony_ci 546cd6a6acSopenharmony_ci permlist = argv[5]; 556cd6a6acSopenharmony_ci do { 566cd6a6acSopenharmony_ci char *tmp = NULL; 576cd6a6acSopenharmony_ci const char *perm; 586cd6a6acSopenharmony_ci const char *delim = strchr(permlist, ','); 596cd6a6acSopenharmony_ci 606cd6a6acSopenharmony_ci if (delim) { 616cd6a6acSopenharmony_ci tmp = strndup(permlist, delim - permlist); 626cd6a6acSopenharmony_ci if (!tmp) { 636cd6a6acSopenharmony_ci fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno)); 646cd6a6acSopenharmony_ci return 1; 656cd6a6acSopenharmony_ci } 666cd6a6acSopenharmony_ci } 676cd6a6acSopenharmony_ci 686cd6a6acSopenharmony_ci perm = tmp ? tmp : permlist; 696cd6a6acSopenharmony_ci 706cd6a6acSopenharmony_ci if (sepol_string_to_av_perm(tclass, perm, &av) < 0) { 716cd6a6acSopenharmony_ci fprintf(stderr, "Invalid permission %s for security class %s: %s\n", perm, argv[4], strerror(errno)); 726cd6a6acSopenharmony_ci free(tmp); 736cd6a6acSopenharmony_ci return 1; 746cd6a6acSopenharmony_ci } 756cd6a6acSopenharmony_ci 766cd6a6acSopenharmony_ci free(tmp); 776cd6a6acSopenharmony_ci 786cd6a6acSopenharmony_ci permlist = strchr(permlist, ','); 796cd6a6acSopenharmony_ci } while (permlist++); 806cd6a6acSopenharmony_ci 816cd6a6acSopenharmony_ci if (av == 0) { 826cd6a6acSopenharmony_ci fprintf(stderr, "Empty permission set computed from %s\n", argv[5]); 836cd6a6acSopenharmony_ci return 1; 846cd6a6acSopenharmony_ci } 856cd6a6acSopenharmony_ci 866cd6a6acSopenharmony_ci if (sepol_compute_av_reason_buffer(ssid, tsid, tclass, av, &avd, &reason, &reason_buf, 0) < 0) { 876cd6a6acSopenharmony_ci fprintf(stderr, "Failed to compute av decision: %s\n", strerror(errno)); 886cd6a6acSopenharmony_ci return 1; 896cd6a6acSopenharmony_ci } 906cd6a6acSopenharmony_ci 916cd6a6acSopenharmony_ci if ((avd.allowed & av) == av) { 926cd6a6acSopenharmony_ci printf("requested permission %s allowed\n", argv[5]); 936cd6a6acSopenharmony_ci free(reason_buf); 946cd6a6acSopenharmony_ci return 0; 956cd6a6acSopenharmony_ci } 966cd6a6acSopenharmony_ci 976cd6a6acSopenharmony_ci printf("requested permission %s denied by ", argv[5]); 986cd6a6acSopenharmony_ci i = 0; 996cd6a6acSopenharmony_ci if (reason & SEPOL_COMPUTEAV_TE) { 1006cd6a6acSopenharmony_ci printf("te-rule"); 1016cd6a6acSopenharmony_ci i++; 1026cd6a6acSopenharmony_ci } 1036cd6a6acSopenharmony_ci if (reason & SEPOL_COMPUTEAV_CONS) { 1046cd6a6acSopenharmony_ci if (i > 0) 1056cd6a6acSopenharmony_ci printf(", "); 1066cd6a6acSopenharmony_ci printf("constraint"); 1076cd6a6acSopenharmony_ci i++; 1086cd6a6acSopenharmony_ci } 1096cd6a6acSopenharmony_ci if (reason & SEPOL_COMPUTEAV_RBAC) { 1106cd6a6acSopenharmony_ci if (i > 0) 1116cd6a6acSopenharmony_ci printf(", "); 1126cd6a6acSopenharmony_ci printf("role-transition"); 1136cd6a6acSopenharmony_ci i++; 1146cd6a6acSopenharmony_ci } 1156cd6a6acSopenharmony_ci if (reason & SEPOL_COMPUTEAV_BOUNDS) { 1166cd6a6acSopenharmony_ci if (i > 0) 1176cd6a6acSopenharmony_ci printf(", "); 1186cd6a6acSopenharmony_ci printf("type-bound"); 1196cd6a6acSopenharmony_ci //i++; 1206cd6a6acSopenharmony_ci } 1216cd6a6acSopenharmony_ci 1226cd6a6acSopenharmony_ci if ((reason & SEPOL_COMPUTEAV_CONS) && reason_buf) 1236cd6a6acSopenharmony_ci printf("; reason:\n%s", reason_buf); 1246cd6a6acSopenharmony_ci 1256cd6a6acSopenharmony_ci free(reason_buf); 1266cd6a6acSopenharmony_ci 1276cd6a6acSopenharmony_ci printf("\n"); 1286cd6a6acSopenharmony_ci 1296cd6a6acSopenharmony_ci return 7; 1306cd6a6acSopenharmony_ci} 131