~ubuntu-branches/ubuntu/edgy/checkpolicy/edgy

« back to all changes in this revision

Viewing changes to test/dismod.c

  • Committer: Bazaar Package Importer
  • Author(s): Manoj Srivastava
  • Date: 2005-09-30 14:41:04 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20050930144104-mxvxypbz4tdsf2r0
Tags: 1.27.4-1
New upstream CVS point release, required for the latest SELinux policy
package. Various bug fixes, and retooled for  the new avtab format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* Authors: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
 
3
 *
 
4
 * Copyright (C) 2003,2004,2005 Tresys Technology, LLC
 
5
 *      This program is free software; you can redistribute it and/or modify
 
6
 *      it under the terms of the GNU General Public License as published by
 
7
 *      the Free Software Foundation, version 2.
 
8
 */
 
9
 
 
10
/* 
 
11
 * dismod.c
 
12
 *
 
13
 * Test program to the contents of a binary policy in text
 
14
 * form.
 
15
 *
 
16
 *      dismod binary_mod_file
 
17
 */
 
18
 
 
19
#include <getopt.h>
 
20
#include <assert.h>
 
21
#include <sys/stat.h>
 
22
#include <sys/types.h>
 
23
#include <sys/mman.h>
 
24
#include <errno.h>
 
25
#include <stdio.h>
 
26
#include <fcntl.h>
 
27
#include <stdlib.h>
 
28
#include <unistd.h>
 
29
 
 
30
#include <sepol/policydb.h>
 
31
#include <sepol/services.h>
 
32
#include <sepol/conditional.h>
 
33
#include <sepol/flask.h>
 
34
#include <sepol/link.h>
 
35
#include <sepol/module.h>
 
36
 
 
37
#include <byteswap.h>
 
38
#include <endian.h>
 
39
 
 
40
#if __BYTE_ORDER == __LITTLE_ENDIAN
 
41
#define le32_to_cpu(x) (x)
 
42
#else
 
43
#define le32_to_cpu(x) bswap_32(x)
 
44
#endif
 
45
 
 
46
static policydb_t policydb;
 
47
extern unsigned int ss_initialized;
 
48
 
 
49
int policyvers = MOD_POLICYDB_VERSION_BASE;
 
50
 
 
51
static const char *symbol_labels[9] = {
 
52
    "commons",
 
53
    "classes", "roles  ", "types  ", "users  ", "bools  ",
 
54
    "levels ", "cats   ", "attribs"
 
55
};
 
56
 
 
57
void usage(char *progname)
 
58
{
 
59
        printf("usage:  %s binary_pol_file\n\n", progname);
 
60
        exit(1);
 
61
}
 
62
 
 
63
/* borrowed from checkpolicy.c */
 
64
static int find_perm(hashtab_key_t key, hashtab_datum_t datum, void *p)
 
65
{
 
66
        unsigned int *valuep;
 
67
        perm_datum_t *perdatum;
 
68
 
 
69
        valuep = (unsigned int *) p;
 
70
        perdatum = (perm_datum_t *) datum;
 
71
 
 
72
        if (*valuep == perdatum->value)
 
73
                return (int) key;
 
74
 
 
75
        return 0;
 
76
}
 
77
 
 
78
static void render_access_mask(uint32_t mask, uint32_t class, policydb_t *p, FILE *fp)
 
79
{
 
80
        unsigned int i;
 
81
        class_datum_t *cladatum;
 
82
        char *perm;
 
83
        cladatum = p->class_val_to_struct[class - 1];
 
84
        fprintf(fp, "{");
 
85
        for (i = 1; i <= sizeof(mask) * 8; i++) {
 
86
                if (mask & (1 << (i - 1))) {
 
87
                        perm = (char *) hashtab_map(cladatum->permissions.table,
 
88
                                  find_perm, &i);
 
89
 
 
90
                        if (!perm && cladatum->comdatum) {
 
91
                                perm = (char *) hashtab_map(cladatum->comdatum->permissions.table,
 
92
                                  find_perm, &i);
 
93
                        }
 
94
                        if (perm)
 
95
                                fprintf(fp, " %s", perm);
 
96
                }
 
97
        }
 
98
        fprintf(fp, " }");
 
99
}
 
100
 
 
101
static void render_access_bitmap(ebitmap_t *map, uint32_t class, policydb_t *p, FILE *fp)
 
102
{
 
103
        unsigned int i;
 
104
        uint32_t perm_value;
 
105
        class_datum_t *cladatum;
 
106
        char *perm;
 
107
        cladatum = p->class_val_to_struct[class - 1];
 
108
        fprintf(fp, "{");
 
109
        for (i = ebitmap_startbit(map); i < ebitmap_length(map); i++) {
 
110
                if (ebitmap_get_bit(map, i)) {
 
111
                        perm_value = i + 1;
 
112
                        perm = (char *) hashtab_map(cladatum->permissions.table,
 
113
                                  find_perm, &perm_value);
 
114
 
 
115
                        if (!perm && cladatum->comdatum) {
 
116
                                perm = (char *) hashtab_map(cladatum->comdatum->permissions.table,
 
117
                                  find_perm, &perm_value);
 
118
                        }
 
119
                        if (perm)
 
120
                                fprintf(fp, " %s", perm);
 
121
                }
 
122
        }
 
123
        fprintf(fp, " }");
 
124
}
 
125
 
 
126
static void display_id(policydb_t *p, FILE *fp, uint32_t symbol_type, uint32_t symbol_value, char *prefix) {
 
127
        char *id = p->sym_val_to_name[symbol_type][symbol_value];
 
128
        scope_datum_t *scope = (scope_datum_t *) hashtab_search(p->scope[symbol_type].table, id);
 
129
        assert(scope != NULL);
 
130
        if (scope->scope == SCOPE_REQ) {
 
131
                fprintf(fp, " [%s%s]", prefix, id);
 
132
        }
 
133
        else {
 
134
                fprintf(fp, " %s%s", prefix, id);
 
135
        }
 
136
}
 
137
 
 
138
int display_type_set(type_set_t *set, uint32_t flags, policydb_t *policy, FILE *fp)
 
139
{
 
140
        int i, num_types;
 
141
 
 
142
        if (set->flags & TYPE_STAR) {
 
143
                fprintf(fp, " * ");
 
144
                return 0;
 
145
        } else if (set->flags & TYPE_COMP) {
 
146
                fprintf(fp, " ~");
 
147
        }
 
148
 
 
149
        num_types = 0;
 
150
        if (flags & RULE_SELF) {
 
151
                num_types++;
 
152
        }
 
153
 
 
154
        for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types); i++) {
 
155
                if (!ebitmap_get_bit(&set->types, i))
 
156
                        continue;
 
157
                num_types++;
 
158
                if (num_types > 1)
 
159
                        break;
 
160
        }
 
161
 
 
162
        if (num_types <= 1) {
 
163
                for (i = ebitmap_startbit(&set->negset); i < ebitmap_length(&set->negset); i++) {
 
164
                        if (!ebitmap_get_bit(&set->negset, i))
 
165
                                continue;
 
166
                        num_types++;
 
167
                        if (num_types > 1)
 
168
                                break;
 
169
                }
 
170
        }
 
171
 
 
172
        if (num_types > 1)
 
173
                fprintf(fp, "{");
 
174
 
 
175
        for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types); i++) {
 
176
                if (!ebitmap_get_bit(&set->types, i))
 
177
                        continue;
 
178
                display_id(policy, fp, SYM_TYPES, i, "");
 
179
        }
 
180
 
 
181
 
 
182
        for (i = ebitmap_startbit(&set->negset); i < ebitmap_length(&set->negset); i++) {
 
183
                if (!ebitmap_get_bit(&set->negset, i))
 
184
                        continue;
 
185
                display_id(policy, fp, SYM_TYPES, i, "-");
 
186
        }
 
187
 
 
188
 
 
189
        if (flags & RULE_SELF) {
 
190
                fprintf(fp, " self");
 
191
        }
 
192
 
 
193
 
 
194
        if (num_types > 1)
 
195
                fprintf(fp, " }");
 
196
 
 
197
 
 
198
        return 0;
 
199
}
 
200
 
 
201
int display_mod_role_set(role_set_t *roles, policydb_t *p, FILE *fp)
 
202
{
 
203
        int i, num = 0;
 
204
 
 
205
        if (roles->flags & ROLE_STAR) {
 
206
                fprintf(fp, " * ");
 
207
                return 0;
 
208
        } else if (roles->flags & ROLE_COMP) {
 
209
                fprintf(fp, " ~");
 
210
        }
 
211
 
 
212
        for (i = ebitmap_startbit(&roles->roles); i < ebitmap_length(&roles->roles); i++) {
 
213
                if (!ebitmap_get_bit(&roles->roles, i))
 
214
                        continue;
 
215
                num++;
 
216
                if (num > 1) {
 
217
                        fprintf(fp, "{");
 
218
                        break;
 
219
                }
 
220
        }
 
221
 
 
222
        for (i = ebitmap_startbit(&roles->roles); i < ebitmap_length(&roles->roles); i++) {
 
223
                if (ebitmap_get_bit(&roles->roles, i))
 
224
                        display_id(p, fp, SYM_ROLES, i, "");
 
225
        }
 
226
 
 
227
        if (num > 1)
 
228
                fprintf(fp, " }");
 
229
 
 
230
        return 0;
 
231
 
 
232
}
 
233
 
 
234
                        
 
235
/* 'what' values for this function */
 
236
#define RENDER_UNCONDITIONAL    0x0001  /* render all regardless of enabled state */
 
237
#define RENDER_ENABLED          0x0002
 
238
#define RENDER_DISABLED         0x0004
 
239
#define RENDER_CONDITIONAL      (RENDER_ENABLED|RENDER_DISABLED)
 
240
 
 
241
int display_avrule(avrule_t *avrule, uint32_t what, policydb_t *policy, FILE *fp)
 
242
{
 
243
        class_perm_node_t *cur;
 
244
        int num_classes;
 
245
 
 
246
        if (avrule == NULL) {
 
247
                fprintf(fp, "  <empty>\n");
 
248
                return 0;
 
249
        }
 
250
        if( avrule->specified & AVRULE_AV) {
 
251
                if(avrule->specified & AVRULE_ALLOWED) {
 
252
                        fprintf(fp, "  allow");                 
 
253
                }
 
254
                if(avrule->specified & AVRULE_AUDITALLOW) {
 
255
                        fprintf(fp, "  auditallow ");
 
256
                }
 
257
                if(avrule->specified & AVRULE_DONTAUDIT) {
 
258
                        fprintf(fp, "  dontaudit");
 
259
                }
 
260
        } else if( avrule->specified & AVRULE_TYPE){
 
261
                if(avrule->specified & AVRULE_TRANSITION) {
 
262
                        fprintf(fp, "  type_transition");
 
263
                }
 
264
                if(avrule->specified & AVRULE_MEMBER) {
 
265
                        fprintf(fp, "  type_member");
 
266
                }
 
267
                if(avrule->specified & AVRULE_CHANGE) {
 
268
                        fprintf(fp, "  type_change");
 
269
                }
 
270
        } else if (avrule->specified & AVRULE_NEVERALLOW) {
 
271
                fprintf(fp, "  neverallow");
 
272
        } else {
 
273
                fprintf(fp, "     ERROR: no valid rule type specified\n");
 
274
                return -1;
 
275
        }
 
276
 
 
277
        if (display_type_set(&avrule->stypes, 0, policy, fp))
 
278
                return -1;
 
279
 
 
280
        if (display_type_set(&avrule->ttypes, avrule->flags, policy, fp))
 
281
                return -1;
 
282
 
 
283
        fprintf(fp, " :");
 
284
        cur = avrule->perms;
 
285
        num_classes = 0;
 
286
        while (cur) {
 
287
                num_classes++;
 
288
                if (num_classes > 1)
 
289
                        break;
 
290
                cur = cur->next;
 
291
        }
 
292
        
 
293
        if (num_classes > 1)
 
294
                fprintf(fp, " {");
 
295
 
 
296
        cur = avrule->perms;
 
297
        while (cur) {
 
298
                display_id(policy, fp, SYM_CLASSES, cur->class - 1, "");
 
299
                cur = cur->next;
 
300
        }
 
301
 
 
302
        if (num_classes > 1)
 
303
                fprintf(fp, " }");
 
304
        fprintf(fp, " ");
 
305
 
 
306
        if( avrule->specified & AVRULE_AV) {
 
307
                render_access_mask(avrule->perms->data, avrule->perms->class, policy, fp);
 
308
        } else if ( avrule->specified & AVRULE_TYPE) {
 
309
                display_id(policy, fp, SYM_TYPES, avrule->perms->data - 1, "");
 
310
        }
 
311
 
 
312
        fprintf(fp, ";\n");
 
313
 
 
314
        return 0;
 
315
}
 
316
 
 
317
int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
 
318
{
 
319
        type_datum_t *type;
 
320
        FILE *fp;
 
321
        int i, first_attrib = 1;
 
322
 
 
323
        type = (type_datum_t *)datum;
 
324
        fp = (FILE *)data;
 
325
 
 
326
        if (type->primary) {
 
327
                display_id(&policydb, fp, SYM_TYPES, type->value - 1, "");
 
328
                fprintf(fp, " [%d]: ", type->value);
 
329
        }
 
330
        else {
 
331
                /* as that aliases have no value of their own and that
 
332
                 * they can never be required by a module, use this
 
333
                 * alternative way of displaying a name */
 
334
                fprintf(fp, " %s [%d]: ", (char *) key, type->value);
 
335
        }
 
336
        if (type->isattr) {
 
337
                fprintf(fp, "attribute for types");
 
338
                for (i = ebitmap_startbit(&type->types); i < ebitmap_length(&type->types); i++) {
 
339
                        if (!ebitmap_get_bit(&type->types, i))
 
340
                                continue;
 
341
                        if (first_attrib) {
 
342
                                first_attrib = 0;
 
343
                        }
 
344
                        else {
 
345
                                fprintf(fp, ",");
 
346
                        }
 
347
                        display_id(&policydb, fp, SYM_TYPES, i, "");
 
348
                }
 
349
        } else if (type->primary) {
 
350
                fprintf(fp, "type");
 
351
        } else {
 
352
                fprintf(fp, "alias for type");
 
353
                display_id(&policydb, fp, SYM_TYPES, type->value - 1, "");
 
354
        }
 
355
        fprintf(fp, "\n");
 
356
 
 
357
        return 0;
 
358
}
 
359
 
 
360
int display_types(policydb_t *p, FILE *fp)
 
361
{
 
362
        if (hashtab_map(p->p_types.table, display_type_callback, fp))
 
363
        return -1;
 
364
        return 0;
 
365
}
 
366
 
 
367
int display_users(policydb_t *p, FILE *fp)
 
368
{
 
369
        int i, j;
 
370
        ebitmap_t *bitmap;
 
371
        for (i = 0; i < p->p_users.nprim; i++) {
 
372
                display_id(p, fp, SYM_USERS, i, "");
 
373
                fprintf(fp, ":");
 
374
                bitmap = &(p->user_val_to_struct[i]->roles.roles);
 
375
                for (j = ebitmap_startbit(bitmap); j < ebitmap_length(bitmap); j++) {
 
376
                        if (ebitmap_get_bit (bitmap, j)) {
 
377
                                display_id(p, fp, SYM_ROLES, j, "");
 
378
                        }
 
379
                }
 
380
                fprintf (fp, "\n");
 
381
        }
 
382
        return 0;
 
383
}
 
384
 
 
385
int display_bools(policydb_t *p, FILE *fp)
 
386
{
 
387
        int i;
 
388
 
 
389
        for (i = 0; i < p->p_bools.nprim; i++) {
 
390
                display_id(p, fp, SYM_BOOLS, i, "");
 
391
                fprintf(fp, " : %d\n", p->bool_val_to_struct[i]->state);
 
392
        }
 
393
        return 0;
 
394
}
 
395
 
 
396
void display_expr(policydb_t *p, cond_expr_t *exp, FILE *fp)
 
397
{
 
398
 
 
399
        cond_expr_t *cur;
 
400
        for (cur = exp; cur != NULL; cur = cur->next) {
 
401
                switch (cur->expr_type) {
 
402
                case COND_BOOL:
 
403
                        fprintf(fp, "%s ", p->p_bool_val_to_name[cur->bool - 1]);
 
404
                        break;
 
405
                case COND_NOT:
 
406
                        fprintf(fp, "! ");
 
407
                        break;
 
408
                case COND_OR:
 
409
                        fprintf(fp, "|| ");
 
410
                        break;
 
411
                case COND_AND:
 
412
                        fprintf(fp, "&& ");
 
413
                        break;
 
414
                case COND_XOR:
 
415
                        fprintf(fp, "^ ");
 
416
                        break;
 
417
                case COND_EQ:
 
418
                        fprintf(fp, "== ");
 
419
                        break;
 
420
                case COND_NEQ:
 
421
                        fprintf(fp, "!= ");
 
422
                        break;
 
423
                default:
 
424
                        fprintf(fp, "error!");
 
425
                        break;
 
426
                }
 
427
        }
 
428
}
 
429
 
 
430
void display_policycon(policydb_t *p, FILE *fp)
 
431
{
 
432
#if 0
 
433
        int i;
 
434
        ocontext_t *cur;
 
435
        char *name;
 
436
 
 
437
        for (i = 0; i < POLICYCON_NUM; i++) {
 
438
                fprintf(fp, "%s:", symbol_labels[i]);
 
439
                for(cur = p->policycon[i].head; cur != NULL; cur = cur->next) {
 
440
                        if (*(cur->u.name) == '\0') {
 
441
                                name = "{default}";
 
442
                        }
 
443
                        else {
 
444
                                name = cur->u.name;
 
445
                        }
 
446
                        fprintf(fp, "\n%16s - %s:%s:%s", name, p->p_user_val_to_name[cur->context[0].user -1],
 
447
                                p->p_role_val_to_name[cur->context[0].role -1],
 
448
                                p->p_type_val_to_name[cur->context[0].type -1]);
 
449
                }
 
450
                fprintf(fp, "\n");
 
451
        }
 
452
#endif
 
453
}
 
454
 
 
455
void display_initial_sids(policydb_t *p, FILE *fp)
 
456
{
 
457
        ocontext_t *cur;
 
458
        char *user, *role, *type;
 
459
 
 
460
        fprintf (fp, "Initial SIDs:\n");
 
461
        for (cur = p->ocontexts [OCON_ISID]; cur != NULL; cur = cur->next) {
 
462
                user = p->p_user_val_to_name [cur->context [0].user - 1];
 
463
                role = p->p_role_val_to_name [cur->context [0].role - 1];
 
464
                type = p->p_type_val_to_name [cur->context [0].type - 1];
 
465
                fprintf(fp, "\t%s: sid %d, context %s:%s:%s\n",
 
466
                        cur->u.name, cur->sid [0], user, role, type);
 
467
        }
 
468
#if 0
 
469
        fprintf (fp, "Policy Initial SIDs:\n");
 
470
        for (cur = p->ocontexts [OCON_POLICYISID]; cur != NULL; cur = cur->next) {
 
471
                user = p->p_user_val_to_name [cur->context [0].user - 1];
 
472
                role = p->p_role_val_to_name [cur->context [0].role - 1];
 
473
                type = p->p_type_val_to_name [cur->context [0].type - 1];
 
474
                fprintf(fp, "\t%s: sid %d, context %s:%s:%s\n",
 
475
                        cur->u.name, cur->sid [0], user, role, type);
 
476
        }
 
477
#endif
 
478
}
 
479
 
 
480
void display_role_trans(role_trans_rule_t *tr, policydb_t *p, FILE *fp)
 
481
{
 
482
        for (; tr; tr = tr->next) {
 
483
                fprintf(fp, "role transition ");
 
484
                display_mod_role_set(&tr->roles, p, fp);
 
485
                display_type_set(&tr->types, 0, p, fp);
 
486
                display_id(p, fp, SYM_ROLES, tr->new_role - 1, " :");
 
487
                fprintf(fp, "\n");
 
488
        }
 
489
}
 
490
 
 
491
void display_role_allow(role_allow_rule_t *ra, policydb_t *p, FILE *fp)
 
492
{
 
493
        for (; ra; ra = ra->next) {
 
494
                fprintf(fp, "role allow ");
 
495
                display_mod_role_set(&ra->roles, p, fp);
 
496
                display_mod_role_set(&ra->new_roles, p, fp);
 
497
                fprintf(fp, "\n");
 
498
        }
 
499
}
 
500
 
 
501
int role_display_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
 
502
{
 
503
        char *id;
 
504
        role_datum_t *role;
 
505
        FILE *fp;
 
506
        
 
507
        id = key;
 
508
        role = (role_datum_t*)datum;
 
509
        fp = (FILE*)data;
 
510
 
 
511
        fprintf(fp, "role:");
 
512
        display_id(&policydb, fp, SYM_ROLES, role->value - 1, "");
 
513
        fprintf(fp, " types: ");
 
514
        display_type_set(&role->types, 0, &policydb, fp);
 
515
        fprintf(fp, "\n");
 
516
        
 
517
        return 0;
 
518
}
 
519
 
 
520
 
 
521
static int display_scope_index(scope_index_t *indices, policydb_t *p, FILE *out_fp) {
 
522
        int i;
 
523
        for (i = 0; i < SYM_NUM; i++) {
 
524
                int any_found = 0, j;
 
525
                fprintf(out_fp, "%s:", symbol_labels[i]);
 
526
                for (j = ebitmap_startbit(&indices->scope[i]);
 
527
                     j < ebitmap_length(&indices->scope[i]);
 
528
                     j++) {
 
529
                        if (ebitmap_get_bit(&indices->scope[i], j)) {
 
530
                                any_found = 1;
 
531
                                fprintf(out_fp, " %s", p->sym_val_to_name[i][j]);
 
532
                                if (i == SYM_CLASSES) {
 
533
                                        if (j < indices->class_perms_len) {
 
534
                                                render_access_bitmap(indices->class_perms_map + j, j + 1, p, out_fp);
 
535
                                        }
 
536
                                        else {
 
537
                                                fprintf(out_fp, "<no perms known>");
 
538
                                        }
 
539
                                }
 
540
                        }
 
541
                }
 
542
                if (!any_found) {
 
543
                        fprintf(out_fp, " <empty>");
 
544
                }
 
545
                fprintf(out_fp, "\n");
 
546
        }
 
547
        return 0;
 
548
}
 
549
 
 
550
 
 
551
#if 0
 
552
int display_cond_expressions(policydb_t *p, FILE *fp)
 
553
{
 
554
        cond_node_t *cur;
 
555
        cond_av_list_t *av_cur;
 
556
        for (cur = p->cond_list; cur != NULL; cur = cur->next) {
 
557
                fprintf(fp, "expression: ");
 
558
                display_expr(p, cur->expr, fp);
 
559
                fprintf(fp, "current state: %d\n", cur->cur_state);
 
560
                fprintf(fp, "True list:\n");
 
561
                for (av_cur = cur->true_list; av_cur != NULL; av_cur = av_cur->next) {
 
562
                        fprintf(fp, "\t");
 
563
                        render_av_rule(&av_cur->node->key, &av_cur->node->datum,
 
564
                                       RENDER_CONDITIONAL, p, fp);
 
565
                }
 
566
                fprintf(fp, "False list:\n");
 
567
                for (av_cur = cur->false_list; av_cur != NULL; av_cur = av_cur->next) {
 
568
                        fprintf(fp, "\t");
 
569
                        render_av_rule(&av_cur->node->key, &av_cur->node->datum,
 
570
                                       RENDER_CONDITIONAL, p, fp);
 
571
                }
 
572
        }
 
573
        return 0;
 
574
}
 
575
 
 
576
int change_bool(char *name, int state, policydb_t *p, FILE *fp)
 
577
{
 
578
        cond_bool_datum_t *bool;
 
579
 
 
580
        bool = hashtab_search(p->p_bools.table, name);
 
581
        if (bool == NULL) {
 
582
                fprintf(fp, "Could not find bool %s\n", name);
 
583
                return -1;
 
584
        }
 
585
        bool->state = state;
 
586
        evaluate_conds(p);
 
587
        return 0;
 
588
}
 
589
#endif
 
590
 
 
591
int display_avdecl(avrule_decl_t *decl, int field, uint32_t what, policydb_t *policy, FILE *out_fp) {
 
592
        fprintf(out_fp, "decl %u:%s\n", decl->decl_id, (decl->enabled ? " [enabled]" : ""));
 
593
        switch (field) {
 
594
        case 0: {
 
595
                cond_list_t *cond = decl->cond_list;
 
596
                avrule_t *avrule;
 
597
                while (cond) {
 
598
                        fprintf(out_fp, "expression: ");
 
599
                        display_expr(&policydb, cond->expr, out_fp);
 
600
                        fprintf(out_fp, "current state: %d\n", cond->cur_state);
 
601
                        fprintf(out_fp, "True list:\n");
 
602
                        avrule = cond->avtrue_list;
 
603
                        while (avrule) {
 
604
                                display_avrule(avrule, RENDER_UNCONDITIONAL, &policydb, out_fp);
 
605
                                avrule = avrule->next;
 
606
                        }
 
607
                        fprintf(out_fp, "False list:\n");
 
608
                        avrule = cond->avfalse_list;
 
609
                        while (avrule) {
 
610
                                display_avrule(avrule, RENDER_UNCONDITIONAL, &policydb, out_fp);
 
611
                                avrule = avrule->next;
 
612
                        }
 
613
                        cond = cond->next;
 
614
                }
 
615
                break;
 
616
        }
 
617
        case 1: {
 
618
                avrule_t *avrule = decl->avrules;
 
619
                if (avrule == NULL) {
 
620
                        fprintf(out_fp, "  <empty>\n");
 
621
                }
 
622
                while (avrule != NULL) {
 
623
                        if (display_avrule(avrule, what, policy, out_fp)) {
 
624
                                return -1;
 
625
                        }
 
626
                        avrule = avrule->next;
 
627
                }
 
628
                break;
 
629
        }
 
630
        case 2: {  /* role_type_node */
 
631
                break;
 
632
        }
 
633
        case 3: {
 
634
                display_role_trans(decl->role_tr_rules, policy, out_fp);
 
635
                break;
 
636
        }
 
637
        case 4: {
 
638
                display_role_allow(decl->role_allow_rules, policy, out_fp);
 
639
                break;
 
640
        }
 
641
        case 5: {
 
642
                if (display_scope_index(&decl->required, policy, out_fp)) {
 
643
                        return -1;
 
644
                }
 
645
                break;
 
646
        }
 
647
        case 6: {
 
648
                if (display_scope_index(&decl->declared, policy, out_fp)) {
 
649
                        return -1;
 
650
                }
 
651
                break;
 
652
        }
 
653
        default: {
 
654
                assert(0);
 
655
        }
 
656
        }
 
657
        return 0;  /* should never get here */
 
658
}
 
659
 
 
660
int display_avblock(int field, uint32_t what, policydb_t *policy, FILE *out_fp) {
 
661
        avrule_block_t *block = policydb.global;
 
662
        while (block != NULL) {
 
663
                fprintf(out_fp, "--- begin avrule block ---\n");
 
664
                avrule_decl_t *decl = block->branch_list;
 
665
                while (decl != NULL) {
 
666
                        if (display_avdecl(decl, field, what, policy, out_fp)) {
 
667
                                return -1;
 
668
                        }
 
669
                        decl = decl->next;
 
670
                }
 
671
                block = block->next;
 
672
        }
 
673
        return 0;
 
674
}
 
675
 
 
676
static int read_policy(char *filename, policydb_t *policy) {
 
677
        FILE *in_fp;
 
678
        struct policy_file f;
 
679
        int retval;
 
680
        uint32_t buf[1];
 
681
 
 
682
        if ((in_fp = fopen(filename, "rb")) == NULL) {
 
683
                fprintf(stderr, "Can't open '%s':  %s\n",
 
684
                        filename, strerror(errno));
 
685
                exit(1);
 
686
        }
 
687
        f.type = PF_USE_STDIO;
 
688
        f.fp = in_fp;
 
689
 
 
690
        /* peek at the first byte.  if they are indicative of a
 
691
           package use the package reader, otherwise use the normal
 
692
           policy reader */
 
693
        if (fread(buf, sizeof(uint32_t), 1, in_fp) != 1) {
 
694
                fprintf(stderr, "Could not read from policy.\n");
 
695
                exit(1);
 
696
        }
 
697
        rewind(in_fp);
 
698
        if (le32_to_cpu(buf[0]) == SEPOL_MODULE_PACKAGE_MAGIC) {
 
699
                sepol_module_package_t package;
 
700
                package.policy = policy;
 
701
                package.file_contexts = NULL;
 
702
                retval = sepol_module_package_read(&package, &f, 1);
 
703
                free(package.file_contexts);
 
704
        }
 
705
        else {
 
706
                retval = policydb_read(policy, &f, 1);
 
707
        }
 
708
        fclose(in_fp);
 
709
        return retval;
 
710
}
 
711
 
 
712
static void link_module(policydb_t *base, FILE *out_fp) {
 
713
        char module_name[80] = {0};
 
714
        char error_buf[128] = {0};
 
715
        int ret;
 
716
        policydb_t module, *mods = &module;
 
717
        
 
718
        if (base->policy_type != POLICY_BASE) {
 
719
                printf("Can only link if initial file was a base policy.\n");
 
720
                return;
 
721
        }
 
722
        printf("\nModule filename: ");
 
723
        fgets(module_name, sizeof(module_name), stdin);
 
724
        module_name[strlen(module_name)-1] = '\0';  /* remove LF */
 
725
        if (module_name[0] == '\0') {
 
726
                return;
 
727
        }
 
728
        
 
729
        /* read the binary policy */
 
730
        fprintf(out_fp, "Reading module...\n");
 
731
        if (read_policy(module_name, mods)) {
 
732
                fprintf(stderr, "%s:  error(s) encountered while loading policy\n", module_name);
 
733
                exit(1);
 
734
        }
 
735
        if (module.policy_type != POLICY_MOD) {
 
736
                fprintf(stderr, "This file is not a loadable policy module.\n");
 
737
                exit(1);
 
738
        }
 
739
        if (policydb_index_classes(&module) ||
 
740
            policydb_index_others(&module, 0)) {
 
741
                fprintf(stderr, "Could not index module.\n");
 
742
                exit(1);
 
743
        }
 
744
        ret = link_modules(base, &mods, 1, 0, error_buf, sizeof(error_buf));
 
745
        if (ret != 0) {
 
746
                printf("Link failed (error %d): %s\n", ret, error_buf);
 
747
                printf("(You will probably need to restart dismod.)\n");
 
748
        }
 
749
        policydb_destroy(&module);
 
750
        return;
 
751
}
 
752
 
 
753
int menu() {
 
754
        printf("\nSelect a command:\n");
 
755
        printf("1)  display unconditional AVTAB\n");
 
756
        printf("2)  display conditional AVTAB\n");
 
757
        printf("3)  display users\n");
 
758
        printf("4)  display bools\n");
 
759
        printf("5)  display roles\n");
 
760
        printf("6)  display types, attributes, and aliases\n");
 
761
        printf("7)  display role transitions\n");
 
762
        printf("8)  display role allows\n");
 
763
        printf("9)  Display policycon\n");
 
764
        printf("0)  Display initial SIDs\n");
 
765
        printf("\n");
 
766
        printf("a)  Display avrule requirements\n");
 
767
        printf("b)  Display avrule declarations\n");
 
768
        printf("l)  Link in a module\n");
 
769
        printf("\n");
 
770
        printf("f)  set output file\n");
 
771
        printf("m)  display menu\n");
 
772
        printf("q)  quit\n");
 
773
        return 0;
 
774
}
 
775
 
 
776
 
 
777
int main(int argc, char **argv)
 
778
{
 
779
        FILE *out_fp = stdout;
 
780
        char ans[81], OutfileName[121];
 
781
 
 
782
        if(argc != 2) 
 
783
                usage(argv[0]);
 
784
 
 
785
        /* read the binary policy */
 
786
        fprintf(out_fp, "Reading policy...\n");
 
787
        if (read_policy(argv[1], &policydb)) {
 
788
                fprintf(stderr, "%s:  error(s) encountered while loading policy\n", argv[0]);
 
789
                exit(1);
 
790
        }
 
791
 
 
792
        if (policydb.policy_type != POLICY_BASE &&
 
793
            policydb.policy_type != POLICY_MOD) {
 
794
                fprintf(stderr, "This file is neither a base nor loadable policy module.\n");
 
795
                exit(1);
 
796
        }
 
797
 
 
798
        if (policydb_index_classes(&policydb)) {
 
799
                fprintf(stderr, "Error indexing classes\n");
 
800
                exit(1);
 
801
        }
 
802
 
 
803
        if (policydb_index_others(&policydb, 1)) {
 
804
                fprintf(stderr, "Error indexing others\n");
 
805
                exit(1);
 
806
        }
 
807
 
 
808
        if (policydb.policy_type == POLICY_BASE) {
 
809
                printf("Binary base policy file loaded.\n\n");
 
810
        }
 
811
        else {
 
812
                printf("Binary policy module file loaded.\n");
 
813
                printf("Module name: %s\n", policydb.name);
 
814
                printf("Module version: %s\n", policydb.version);
 
815
                printf("\n");
 
816
        }
 
817
 
 
818
        menu();
 
819
        for(;;) {
 
820
                printf("\nCommand (\'m\' for menu):  ");
 
821
                fgets(ans, sizeof(ans), stdin); 
 
822
                switch(ans[0]) {
 
823
                        
 
824
                case '1': {
 
825
                        fprintf(out_fp, "unconditional avtab:\n");
 
826
                        display_avblock(1, RENDER_UNCONDITIONAL, &policydb, out_fp);
 
827
                        break;
 
828
                }
 
829
                case '2':
 
830
                        fprintf(out_fp, "conditional avtab:\n");
 
831
                        display_avblock(0, RENDER_UNCONDITIONAL, &policydb, out_fp);
 
832
                        break;
 
833
                case '3':
 
834
                        display_users(&policydb, out_fp);
 
835
                        break;
 
836
                case '4':
 
837
                        display_bools(&policydb, out_fp);
 
838
                        break;
 
839
                case '5':
 
840
                        if (hashtab_map(policydb.p_roles.table, role_display_callback, out_fp))
 
841
                                exit(1);
 
842
                        break;
 
843
                case '6':
 
844
                        if (display_types(&policydb, out_fp)) {
 
845
                                fprintf(stderr, "Error displaying types\n");
 
846
                                exit(1);
 
847
                        }
 
848
                        break;
 
849
                case '7':
 
850
                        fprintf(out_fp, "role transitions:\n");
 
851
                        display_avblock(3, 0, &policydb, out_fp);
 
852
                        break;
 
853
                case '8':
 
854
                        fprintf(out_fp, "role allows:\n");
 
855
                        display_avblock(4, 0, &policydb, out_fp);
 
856
                        break;
 
857
                case '9':
 
858
                        display_policycon(&policydb, out_fp);
 
859
                        break;
 
860
                case '0':
 
861
                        display_initial_sids(&policydb, out_fp);
 
862
                        break;
 
863
                case 'a':
 
864
                        fprintf(out_fp, "avrule block requirements:\n");
 
865
                        display_avblock(5, 0, &policydb, out_fp);
 
866
                        break;
 
867
                case 'b':
 
868
                        fprintf(out_fp, "avrule block declarations:\n");
 
869
                        display_avblock(6, 0, &policydb, out_fp);
 
870
                        break;
 
871
                case 'f':
 
872
                        printf("\nFilename for output (<CR> for screen output): ");
 
873
                        fgets(OutfileName, sizeof(OutfileName), stdin); 
 
874
                        OutfileName[strlen(OutfileName)-1] = '\0'; /* fix_string (remove LF) */
 
875
                        if (strlen(OutfileName) == 0) 
 
876
                                out_fp = stdout;
 
877
                        else if ((out_fp = fopen(OutfileName, "w")) == NULL) {
 
878
                                fprintf (stderr, "Cannot open output file %s\n", OutfileName);
 
879
                                out_fp = stdout;
 
880
                        }
 
881
                        if (out_fp != stdout) 
 
882
                                printf("\nOutput to file: %s\n", OutfileName);
 
883
                        break;
 
884
                case 'l':
 
885
                        link_module(&policydb, out_fp);
 
886
                        break;
 
887
                case 'q':
 
888
                        policydb_destroy(&policydb);
 
889
                        exit(0);
 
890
                        break;
 
891
                case 'm':
 
892
                        menu();
 
893
                        break;
 
894
                default:
 
895
                        printf("\nInvalid choice\n");
 
896
                        menu();
 
897
                        break;
 
898
                
 
899
                }
 
900
        }
 
901
        exit(EXIT_SUCCESS);
 
902
}
 
903
 
 
904