1 #include <getopt.h>
2 
3 #include "attribute.h"
4 
attribute_usage()5 void attribute_usage() {
6     fprintf(stderr, "\tattribute [-l|--list] [-r|--reverse] <name>\n");
7 }
8 
retrieve_mapping(policydb_t * policydb,struct type_datum * dat,char * name,int reverse)9 static void retrieve_mapping(policydb_t *policydb, struct type_datum *dat, char *name, int reverse) {
10     struct ebitmap_node *n;
11     unsigned int bit;
12 
13     if (reverse) {
14         ebitmap_for_each_bit(&policydb->type_attr_map[dat->s.value - 1], n, bit) {
15             if (!ebitmap_node_get_bit(n, bit))
16                 continue;
17             if (!strcmp(policydb->p_type_val_to_name[bit], name))
18                 continue;
19             printf("%s\n", policydb->p_type_val_to_name[bit]);
20         }
21     } else {
22         ebitmap_for_each_bit(&policydb->attr_type_map[dat->s.value - 1], n, bit) {
23             if (!ebitmap_node_get_bit(n, bit))
24                 continue;
25             printf("%s\n", policydb->p_type_val_to_name[bit]);
26         }
27     }
28 }
29 
list_attribute(policydb_t * policydb,char * name,int reverse)30 static int list_attribute(policydb_t *policydb, char *name, int reverse)
31 {
32     struct type_datum *dat;
33 
34     dat = hashtab_search(policydb->p_types.table, name);
35     if (!dat) {
36         fprintf(stderr, "%s is not defined in this policy.\n", name);
37         return -1;
38     }
39 
40     if (reverse) {
41         if (dat->flavor != TYPE_TYPE) {
42             fprintf(stderr, "%s is an attribute not a type in this policy.\n", name);
43             return -1;
44         }
45     } else {
46         if (dat->flavor != TYPE_ATTRIB) {
47             fprintf(stderr, "%s is a type not an attribute in this policy.\n", name);
48             return -1;
49         }
50     }
51     retrieve_mapping(policydb, dat, name, reverse);
52 
53     return 0;
54 }
55 
print_attr(hashtab_key_t k,hashtab_datum_t d,void * args)56 static int print_attr(__attribute__ ((unused)) hashtab_key_t k,
57                       hashtab_datum_t d, void *args) {
58     struct type_datum *dat = (struct type_datum *)d;
59     policydb_t *pdb = (policydb_t *)args;
60     if (!dat) {
61         fprintf(stderr, "type encountered without datum!\n");
62         return -1;
63     }
64     if (dat->flavor == TYPE_ATTRIB) {
65         printf("%s\n", pdb->p_type_val_to_name[dat->s.value - 1]);
66     }
67     return 0;
68 }
69 
list_all_attributes(policydb_t * policydb)70 static int list_all_attributes(policydb_t *policydb) {
71     return hashtab_map(policydb->p_types.table, print_attr, policydb);
72 }
73 
attribute_func(int argc,char ** argv,policydb_t * policydb)74 int attribute_func (int argc, char **argv, policydb_t *policydb) {
75     int rc = -1;
76     int list = 0;
77     int reverse = 0;
78     char ch;
79 
80     struct option attribute_options[] = {
81         {"list", no_argument, NULL, 'l'},
82         {"reverse", no_argument, NULL, 'r'},
83         {NULL, 0, NULL, 0}
84     };
85 
86     while ((ch = getopt_long(argc, argv, "lr", attribute_options, NULL)) != -1) {
87         switch (ch) {
88         case 'l':
89             list = 1;
90             break;
91         case 'r':
92             reverse = 1;
93             break;
94         default:
95             USAGE_ERROR = true;
96             goto out;
97         }
98     }
99 
100     if ((argc != 2 && !(reverse && argc == 3)) || (list && reverse)) {
101         USAGE_ERROR = true;
102         goto out;
103     }
104     if (list)
105         rc = list_all_attributes(policydb);
106     else
107         rc = list_attribute(policydb, argv[optind], reverse);
108  out:
109     return rc;
110 }
111