~ubuntu-branches/ubuntu/gutsy/checkpolicy/gutsy

« back to all changes in this revision

Viewing changes to write.c

  • Committer: Bazaar Package Importer
  • Author(s): Manoj Srivastava
  • Date: 2004-11-24 14:01:41 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041124140141-2w64gbhqynveunlv
Tags: 1.18-2
Update download location and copyright file, since the locations we
were pointing to are now forbidden (return a code 403).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */
3
 
 
4
 
/* Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
5
 
 *
6
 
 *      Added conditional policy language extensions
7
 
 *
8
 
 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
9
 
 *      This program is free software; you can redistribute it and/or modify
10
 
 *      it under the terms of the GNU General Public License as published by
11
 
 *      the Free Software Foundation, version 2.
12
 
 */
13
 
 
14
 
#include "ebitmap.h"
15
 
#include "avtab.h"
16
 
#include "mls.h"
17
 
#include "policydb.h"
18
 
#include "conditional.h"
19
 
 
20
 
int ebitmap_write(ebitmap_t * e, FILE * fp)
21
 
{
22
 
        ebitmap_node_t *n;
23
 
        __u32 buf[32], bit, count;
24
 
        __u64 map;
25
 
        size_t items;
26
 
 
27
 
        buf[0] = cpu_to_le32(MAPSIZE);
28
 
        buf[1] = cpu_to_le32(e->highbit);
29
 
 
30
 
        count = 0;
31
 
        for (n = e->node; n; n = n->next)
32
 
                count++;
33
 
        buf[2] = cpu_to_le32(count);
34
 
 
35
 
        items = fwrite(buf, sizeof(__u32), 3, fp);
36
 
        if (items != 3)
37
 
                return -1;
38
 
 
39
 
        for (n = e->node; n; n = n->next) {
40
 
                bit = cpu_to_le32(n->startbit);
41
 
                items = fwrite(&bit, sizeof(__u32), 1, fp);
42
 
                if (items != 1)
43
 
                        return -1;
44
 
                map = cpu_to_le64(n->map);
45
 
                items = fwrite(&map, sizeof(__u64), 1, fp);
46
 
                if (items != 1)
47
 
                        return -1;
48
 
 
49
 
        }
50
 
 
51
 
        return 0;
52
 
}
53
 
 
54
 
int avtab_write_item(avtab_ptr_t cur, FILE *fp)
55
 
{
56
 
        __u32 buf[32];
57
 
        size_t items, items2;
58
 
 
59
 
        items = 1;      /* item 0 is used for the item count */
60
 
        buf[items++] = cpu_to_le32(cur->key.source_type);
61
 
        buf[items++] = cpu_to_le32(cur->key.target_type);
62
 
        buf[items++] = cpu_to_le32(cur->key.target_class);
63
 
        buf[items++] = cpu_to_le32(cur->datum.specified);
64
 
        if (!(cur->datum.specified & (AVTAB_AV | AVTAB_TYPE))) {
65
 
                printf("security: avtab: null entry\n");
66
 
                return -1;
67
 
        }
68
 
        if ((cur->datum.specified & AVTAB_AV) &&
69
 
            (cur->datum.specified & AVTAB_TYPE)) {
70
 
                printf("security: avtab: entry has both access vectors and types\n");
71
 
                return -1;
72
 
        }
73
 
        if (cur->datum.specified & AVTAB_AV) {
74
 
                if (cur->datum.specified & AVTAB_ALLOWED)
75
 
                        buf[items++] = cpu_to_le32(avtab_allowed(&cur->datum));
76
 
                if (cur->datum.specified & AVTAB_AUDITDENY)
77
 
                        buf[items++] = cpu_to_le32(avtab_auditdeny(&cur->datum));
78
 
                if (cur->datum.specified & AVTAB_AUDITALLOW)
79
 
                        buf[items++] = cpu_to_le32(avtab_auditallow(&cur->datum));
80
 
        } else {
81
 
                if (cur->datum.specified & AVTAB_TRANSITION)
82
 
                        buf[items++] = cpu_to_le32(avtab_transition(&cur->datum));
83
 
                if (cur->datum.specified & AVTAB_CHANGE)
84
 
                        buf[items++] = cpu_to_le32(avtab_change(&cur->datum));
85
 
                if (cur->datum.specified & AVTAB_MEMBER)
86
 
                        buf[items++] = cpu_to_le32(avtab_member(&cur->datum));
87
 
        }
88
 
        buf[0] = cpu_to_le32(items - 1);
89
 
        
90
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
91
 
        if (items != items2)
92
 
                return -1;
93
 
        return 0;
94
 
}
95
 
 
96
 
int avtab_write(avtab_t * a, FILE * fp)
97
 
{
98
 
        int i;
99
 
        avtab_ptr_t cur;
100
 
        __u32 nel;
101
 
        size_t items;
102
 
 
103
 
        nel = cpu_to_le32(a->nel);
104
 
        items = fwrite(&nel, sizeof(__u32), 1, fp);
105
 
        if (items != 1)
106
 
                return -1;
107
 
 
108
 
        for (i = 0; i < AVTAB_SIZE; i++) {
109
 
                for (cur = a->htable[i]; cur; cur = cur->next) {
110
 
                        if (avtab_write_item(cur, fp))
111
 
                            return -1;
112
 
                }       
113
 
        }
114
 
 
115
 
        return 0;
116
 
}
117
 
 
118
 
#ifdef CONFIG_SECURITY_SELINUX_MLS
119
 
/*
120
 
 * Write a MLS level structure to a policydb binary 
121
 
 * representation file.
122
 
 */
123
 
int mls_write_level(mls_level_t * l,
124
 
                    FILE * fp)
125
 
{
126
 
        __u32 sens;
127
 
        size_t items;
128
 
 
129
 
        sens = cpu_to_le32(l->sens);
130
 
        items = fwrite(&sens, sizeof(__u32), 1, fp);
131
 
        if (items != 1)
132
 
                return -1;
133
 
 
134
 
        if (ebitmap_write(&l->cat, fp))
135
 
                return -1;
136
 
 
137
 
        return 0;
138
 
}
139
 
 
140
 
 
141
 
/*
142
 
 * Write a MLS range structure to a policydb binary 
143
 
 * representation file.
144
 
 */
145
 
static int mls_write_range_helper(mls_range_t * r,
146
 
                                  FILE * fp)
147
 
{
148
 
        __u32 buf[3];
149
 
        size_t items, items2;
150
 
        int rel;
151
 
 
152
 
        rel = mls_level_relation(r->level[1], r->level[0]);
153
 
 
154
 
        items = 1;              /* item 0 is used for the item count */
155
 
        buf[items++] = cpu_to_le32(r->level[0].sens);
156
 
        if (rel != MLS_RELATION_EQ)
157
 
                buf[items++] = cpu_to_le32(r->level[1].sens);
158
 
        buf[0] = cpu_to_le32(items - 1);
159
 
 
160
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
161
 
        if (items2 != items)
162
 
                return -1;
163
 
 
164
 
        if (ebitmap_write(&r->level[0].cat, fp))
165
 
                return -1;
166
 
        if (rel != MLS_RELATION_EQ)
167
 
                if (ebitmap_write(&r->level[1].cat, fp))
168
 
                        return -1;
169
 
 
170
 
        return 0;
171
 
}
172
 
 
173
 
int mls_write_range(context_struct_t * c,
174
 
                    FILE * fp)
175
 
{
176
 
        return mls_write_range_helper(&c->range, fp);
177
 
}
178
 
 
179
 
 
180
 
/*
181
 
 * Write a MLS perms structure to a policydb binary 
182
 
 * representation file.
183
 
 */
184
 
int mls_write_class(class_datum_t * cladatum,
185
 
                    FILE * fp)
186
 
{
187
 
        mls_perms_t *p = &cladatum->mlsperms;
188
 
        __u32 buf[32];
189
 
        size_t items, items2;
190
 
 
191
 
        items = 0;
192
 
        buf[items++] = cpu_to_le32(p->read);
193
 
        buf[items++] = cpu_to_le32(p->readby);
194
 
        buf[items++] = cpu_to_le32(p->write);
195
 
        buf[items++] = cpu_to_le32(p->writeby);
196
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
197
 
        if (items2 != items)
198
 
                return -1;
199
 
 
200
 
        return 0;
201
 
}
202
 
 
203
 
#define mls_write_perm(buf, items, perdatum) \
204
 
        buf[items++] = cpu_to_le32(perdatum->base_perms);
205
 
 
206
 
int mls_write_user(user_datum_t *usrdatum, FILE *fp)
207
 
{
208
 
        mls_range_list_t *r;
209
 
        __u32 nel;
210
 
        __u32 buf[32];
211
 
        int items;
212
 
 
213
 
        nel = 0;
214
 
        for (r = usrdatum->ranges; r; r = r->next)
215
 
                nel++;
216
 
        buf[0] = cpu_to_le32(nel);
217
 
        items = fwrite(buf, sizeof(__u32), 1, fp);
218
 
        if (items != 1)
219
 
                return -1;
220
 
        for (r = usrdatum->ranges; r; r = r->next) {
221
 
                if (mls_write_range_helper(&r->range, fp))
222
 
                        return -1;
223
 
        }
224
 
        return 0;
225
 
}
226
 
 
227
 
int mls_write_nlevels(policydb_t *p, FILE *fp)
228
 
{
229
 
        __u32 buf[32];
230
 
        size_t items;
231
 
 
232
 
        buf[0] = cpu_to_le32(p->nlevels);
233
 
        items = fwrite(buf, sizeof(__u32), 1, fp);
234
 
        if (items != 1)
235
 
                return -1;
236
 
        return 0;
237
 
}
238
 
 
239
 
int mls_write_trusted(policydb_t *p, FILE *fp)
240
 
{
241
 
        if (ebitmap_write(&p->trustedreaders, fp))
242
 
                return -1;
243
 
        if (ebitmap_write(&p->trustedwriters, fp))
244
 
                return -1;
245
 
        if (ebitmap_write(&p->trustedobjects, fp))
246
 
                return -1;
247
 
        return 0;
248
 
}
249
 
 
250
 
int sens_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
251
 
{
252
 
        level_datum_t *levdatum;
253
 
        __u32 buf[32];
254
 
        size_t items, items2, len;
255
 
        FILE *fp = p;
256
 
 
257
 
        levdatum = (level_datum_t *) datum;
258
 
 
259
 
        len = strlen(key);
260
 
        items = 0;
261
 
        buf[items++] = cpu_to_le32(len);
262
 
        buf[items++] = cpu_to_le32(levdatum->isalias);
263
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
264
 
        if (items != items2)
265
 
                return -1;
266
 
 
267
 
        items = fwrite(key, 1, len, fp);
268
 
        if (items != len)
269
 
                return -1;
270
 
 
271
 
        if (mls_write_level(levdatum->level, fp))
272
 
                return -1;
273
 
 
274
 
        return 0;
275
 
}
276
 
 
277
 
int cat_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
278
 
{
279
 
        cat_datum_t *catdatum;
280
 
        __u32 buf[32];
281
 
        size_t items, items2, len;
282
 
        FILE *fp = p;
283
 
 
284
 
 
285
 
        catdatum = (cat_datum_t *) datum;
286
 
 
287
 
        len = strlen(key);
288
 
        items = 0;
289
 
        buf[items++] = cpu_to_le32(len);
290
 
        buf[items++] = cpu_to_le32(catdatum->value);
291
 
        buf[items++] = cpu_to_le32(catdatum->isalias);
292
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
293
 
        if (items != items2)
294
 
                return -1;
295
 
 
296
 
        items = fwrite(key, 1, len, fp);
297
 
        if (items != len)
298
 
                return -1;
299
 
 
300
 
        return 0;
301
 
}
302
 
#else
303
 
#define mls_write_range(c, fp) 0
304
 
#define mls_write_class(c, fp) 0
305
 
#define mls_write_perm(buf, items, perdatum) 
306
 
#define mls_write_user(u, fp) 0
307
 
#define mls_write_nlevels(p, fp) 0
308
 
#define mls_write_trusted(p, fp) 0
309
 
#endif
310
 
 
311
 
 
312
 
int cond_write_bool(hashtab_key_t key, hashtab_datum_t datum, void *p)
313
 
{
314
 
        cond_bool_datum_t *booldatum;
315
 
        __u32 buf[3], len;
316
 
        int items, items2;
317
 
        FILE *fp = p;
318
 
 
319
 
        booldatum = (cond_bool_datum_t*)datum;
320
 
 
321
 
        len = strlen(key);
322
 
        items = 0;
323
 
        buf[items++] = cpu_to_le32(booldatum->value);
324
 
        buf[items++] = cpu_to_le32(booldatum->state);
325
 
        buf[items++] = cpu_to_le32(len);
326
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
327
 
        if (items != items2)
328
 
                return -1;
329
 
        items = fwrite(key, 1, len, fp);
330
 
        if (items != len)
331
 
                return -1;
332
 
        return 0;
333
 
}
334
 
 
335
 
/*
336
 
 * cond_write_cond_av_list doesn't write out the av_list nodes.
337
 
 * Instead it writes out the key/value pairs from the avtab. This
338
 
 * is necessary because there is no way to uniquely identifying rules
339
 
 * in the avtab so it is not possible to associate individual rules
340
 
 * in the avtab with a conditional without saving them as part of
341
 
 * the conditional. This means that the avtab with the conditional
342
 
 * rules will not be saved but will be rebuilt on policy load.
343
 
 */
344
 
int cond_write_av_list(cond_av_list_t *list, FILE *fp)
345
 
{
346
 
        __u32 buf[4];
347
 
        cond_av_list_t *cur_list;
348
 
        __u32 len, items;
349
 
 
350
 
        len = 0;
351
 
        for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
352
 
                if (cur_list->node->parse_context)
353
 
                        len++;
354
 
        }
355
 
        
356
 
        buf[0] = cpu_to_le32(len);
357
 
        items = fwrite(buf, sizeof(__u32), 1, fp);
358
 
        if (items != 1)
359
 
                return -1;
360
 
        if (items == 0)
361
 
                return 0;
362
 
 
363
 
        for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
364
 
                if (cur_list->node->parse_context)
365
 
                        if (avtab_write_item(cur_list->node, fp))
366
 
                                return -1;
367
 
        }
368
 
        return 0;
369
 
}
370
 
 
371
 
int cond_write_node(cond_node_t *node, FILE *fp)
372
 
{
373
 
        cond_expr_t *cur_expr;
374
 
        __u32 buf[2];
375
 
        __u32 items, items2, len;
376
 
 
377
 
        buf[0] = cpu_to_le32(node->cur_state);
378
 
        items = fwrite(buf, sizeof(__u32), 1, fp);
379
 
        if (items != 1)
380
 
                return -1;
381
 
 
382
 
        /* expr */
383
 
        len = 0;
384
 
        for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next)
385
 
                len++;
386
 
 
387
 
        buf[0] = cpu_to_le32(len);
388
 
        items = fwrite(buf, sizeof(__u32), 1, fp);
389
 
        if (items != 1)
390
 
                return -1;
391
 
 
392
 
        for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) {
393
 
                items = 0;
394
 
                buf[items++] = cpu_to_le32(cur_expr->expr_type);
395
 
                buf[items++] = cpu_to_le32(cur_expr->bool);
396
 
                items2 = fwrite(buf, sizeof(__u32), items, fp);
397
 
                if (items2 != items)
398
 
                        return -1;
399
 
        }
400
 
 
401
 
        if (cond_write_av_list(node->true_list, fp) != 0)
402
 
                return -1;
403
 
        if (cond_write_av_list(node->false_list, fp) != 0)
404
 
                return -1;
405
 
        
406
 
        return 0;
407
 
}
408
 
 
409
 
int cond_write_list(cond_list_t *list, void *p)
410
 
{
411
 
        FILE *fp = p;
412
 
        cond_node_t *cur;
413
 
        __u32 len, items;
414
 
        __u32 buf[1];
415
 
 
416
 
        len = 0;
417
 
        for (cur = list; cur != NULL; cur = cur->next)
418
 
                len++;
419
 
        buf[0] = cpu_to_le32(len);
420
 
        items = fwrite(buf, sizeof(__u32), 1, fp);
421
 
        if (items != 1)
422
 
                return -1;
423
 
 
424
 
        for (cur = list; cur != NULL; cur = cur->next) {
425
 
                if (cond_write_node(cur, p) != 0)
426
 
                        return -1;
427
 
        }
428
 
        return 0;
429
 
}
430
 
 
431
 
/*
432
 
 * Write a security context structure
433
 
 * to a policydb binary representation file.
434
 
 */
435
 
static int context_write(context_struct_t * c, FILE * fp)
436
 
{
437
 
        __u32 buf[32];
438
 
        size_t items, items2;
439
 
 
440
 
        items = 0;
441
 
        buf[items++] = cpu_to_le32(c->user);
442
 
        buf[items++] = cpu_to_le32(c->role);
443
 
        buf[items++] = cpu_to_le32(c->type);
444
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
445
 
        if (items2 != items)
446
 
                return -1;
447
 
        if (mls_write_range(c, fp))
448
 
                return -1;
449
 
 
450
 
        return 0;
451
 
}
452
 
 
453
 
 
454
 
/*
455
 
 * The following *_write functions are used to
456
 
 * write the symbol data to a policy database
457
 
 * binary representation file.
458
 
 */
459
 
 
460
 
static int perm_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
461
 
{
462
 
        perm_datum_t *perdatum;
463
 
        __u32 buf[32];
464
 
        size_t items, items2, len;
465
 
        FILE *fp = p;
466
 
 
467
 
        perdatum = (perm_datum_t *) datum;
468
 
 
469
 
        len = strlen(key);
470
 
        items = 0;
471
 
        buf[items++] = cpu_to_le32(len);
472
 
        buf[items++] = cpu_to_le32(perdatum->value);
473
 
        mls_write_perm(buf, items, perdatum);
474
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
475
 
        if (items != items2)
476
 
                return -1;
477
 
 
478
 
        items = fwrite(key, 1, len, fp);
479
 
        if (items != len)
480
 
                return -1;
481
 
 
482
 
        return 0;
483
 
}
484
 
 
485
 
 
486
 
static int common_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
487
 
{
488
 
        common_datum_t *comdatum;
489
 
        __u32 buf[32];
490
 
        size_t items, items2, len;
491
 
        FILE *fp = p;
492
 
 
493
 
        comdatum = (common_datum_t *) datum;
494
 
 
495
 
        len = strlen(key);
496
 
        items = 0;
497
 
        buf[items++] = cpu_to_le32(len);
498
 
        buf[items++] = cpu_to_le32(comdatum->value);
499
 
        buf[items++] = cpu_to_le32(comdatum->permissions.nprim);
500
 
        buf[items++] = cpu_to_le32(comdatum->permissions.table->nel);
501
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
502
 
        if (items != items2)
503
 
                return -1;
504
 
 
505
 
        items = fwrite(key, 1, len, fp);
506
 
        if (items != len)
507
 
                return -1;
508
 
 
509
 
        if (hashtab_map(comdatum->permissions.table, perm_write, fp))
510
 
                return -1;
511
 
 
512
 
        return 0;
513
 
}
514
 
 
515
 
 
516
 
static int class_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
517
 
{
518
 
        class_datum_t *cladatum;
519
 
        constraint_node_t *c;
520
 
        constraint_expr_t *e;
521
 
        __u32 buf[32], ncons, nexpr;
522
 
        size_t items, items2, len, len2;
523
 
        FILE *fp = p;
524
 
 
525
 
        cladatum = (class_datum_t *) datum;
526
 
 
527
 
        len = strlen(key);
528
 
        if (cladatum->comkey)
529
 
                len2 = strlen(cladatum->comkey);
530
 
        else
531
 
                len2 = 0;
532
 
 
533
 
        ncons = 0;
534
 
        for (c = cladatum->constraints; c; c = c->next) {
535
 
                ncons++;
536
 
        }
537
 
 
538
 
        items = 0;
539
 
        buf[items++] = cpu_to_le32(len);
540
 
        buf[items++] = cpu_to_le32(len2);
541
 
        buf[items++] = cpu_to_le32(cladatum->value);
542
 
        buf[items++] = cpu_to_le32(cladatum->permissions.nprim);
543
 
        if (cladatum->permissions.table) 
544
 
                buf[items++] = cpu_to_le32(cladatum->permissions.table->nel);
545
 
        else
546
 
                buf[items++] = 0;
547
 
        buf[items++] = cpu_to_le32(ncons);
548
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
549
 
        if (items != items2)
550
 
                return -1;
551
 
 
552
 
        items = fwrite(key, 1, len, fp);
553
 
        if (items != len)
554
 
                return -1;
555
 
 
556
 
        if (cladatum->comkey) {
557
 
                items = fwrite(cladatum->comkey, 1, len2, fp);
558
 
                if (items != len2)
559
 
                        return -1;
560
 
        }
561
 
        if (hashtab_map(cladatum->permissions.table, perm_write, fp))
562
 
                return -1;
563
 
 
564
 
        for (c = cladatum->constraints; c; c = c->next) {
565
 
                nexpr = 0;
566
 
                for (e = c->expr; e; e = e->next) {
567
 
                        nexpr++;
568
 
                }
569
 
                buf[0] = cpu_to_le32(c->permissions);
570
 
                buf[1] = cpu_to_le32(nexpr);
571
 
                items = fwrite(buf, sizeof(__u32), 2, fp);
572
 
                if (items != 2)
573
 
                        return -1;
574
 
                for (e = c->expr; e; e = e->next) {
575
 
                        items = 0;
576
 
                        buf[items++] = cpu_to_le32(e->expr_type);
577
 
                        buf[items++] = cpu_to_le32(e->attr);
578
 
                        buf[items++] = cpu_to_le32(e->op);
579
 
                        items2 = fwrite(buf, sizeof(__u32), items, fp);
580
 
                        if (items != items2)
581
 
                                return -1;
582
 
 
583
 
                        switch (e->expr_type) {
584
 
                        case CEXPR_NAMES:
585
 
                                if (ebitmap_write(&e->names, fp))
586
 
                                        return -1;
587
 
                                break;
588
 
                        default:
589
 
                                break;
590
 
                        }
591
 
                }
592
 
        }
593
 
 
594
 
        if (mls_write_class(cladatum, fp))
595
 
                return -1;
596
 
 
597
 
        return 0;
598
 
}
599
 
 
600
 
static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
601
 
{
602
 
        role_datum_t *role;
603
 
        __u32 buf[32];
604
 
        size_t items, items2, len;
605
 
        FILE *fp = p;
606
 
 
607
 
        role = (role_datum_t *) datum;
608
 
 
609
 
        len = strlen(key);
610
 
        items = 0;
611
 
        buf[items++] = cpu_to_le32(len);
612
 
        buf[items++] = cpu_to_le32(role->value);
613
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
614
 
        if (items != items2)
615
 
                return -1;
616
 
 
617
 
        items = fwrite(key, 1, len, fp);
618
 
        if (items != len)
619
 
                return -1;
620
 
 
621
 
        if (ebitmap_write(&role->dominates, fp))
622
 
                return -1;
623
 
 
624
 
        if (ebitmap_write(&role->types, fp))
625
 
                return -1;
626
 
 
627
 
        return 0;
628
 
}
629
 
 
630
 
static int type_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
631
 
{
632
 
        type_datum_t *typdatum;
633
 
        __u32 buf[32];
634
 
        size_t items, items2, len;
635
 
        FILE *fp = p;
636
 
 
637
 
        typdatum = (type_datum_t *) datum;
638
 
 
639
 
        len = strlen(key);
640
 
        items = 0;
641
 
        buf[items++] = cpu_to_le32(len);
642
 
        buf[items++] = cpu_to_le32(typdatum->value);
643
 
        buf[items++] = cpu_to_le32(typdatum->primary);
644
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
645
 
        if (items != items2)
646
 
                return -1;
647
 
 
648
 
        items = fwrite(key, 1, len, fp);
649
 
        if (items != len)
650
 
                return -1;
651
 
 
652
 
        return 0;
653
 
}
654
 
 
655
 
static int user_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
656
 
{
657
 
        user_datum_t *usrdatum;
658
 
        __u32 buf[32];
659
 
        size_t items, items2, len;
660
 
        FILE *fp = p;
661
 
 
662
 
 
663
 
        usrdatum = (user_datum_t *) datum;
664
 
 
665
 
        len = strlen(key);
666
 
        items = 0;
667
 
        buf[items++] = cpu_to_le32(len);
668
 
        buf[items++] = cpu_to_le32(usrdatum->value);
669
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
670
 
        if (items != items2)
671
 
                return -1;
672
 
 
673
 
        items = fwrite(key, 1, len, fp);
674
 
        if (items != len)
675
 
                return -1;
676
 
 
677
 
        if (ebitmap_write(&usrdatum->roles, fp))
678
 
                return -1;
679
 
 
680
 
        return mls_write_user(usrdatum, fp);
681
 
}
682
 
 
683
 
 
684
 
static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, void *datap) =
685
 
{
686
 
        common_write,
687
 
        class_write,
688
 
        role_write,
689
 
        type_write,
690
 
        user_write,
691
 
        mls_write_f
692
 
        cond_write_bool
693
 
};
694
 
 
695
 
 
696
 
/*
697
 
 * Write the configuration data in a policy database
698
 
 * structure to a policy database binary representation
699
 
 * file.
700
 
 */
701
 
int policydb_write(policydb_t * p, FILE * fp)
702
 
{
703
 
        struct role_allow *ra;
704
 
        struct role_trans *tr;
705
 
        ocontext_t *c;
706
 
        genfs_t *genfs;
707
 
        int i, j, num_syms;
708
 
        __u32 buf[32], config;
709
 
        size_t items, items2, len, nel;
710
 
        struct policydb_compat_info *info;
711
 
        char *policydb_str = POLICYDB_STRING;
712
 
 
713
 
        config = 0;
714
 
        mls_set_config(config);
715
 
 
716
 
        /* Write the magic number and string identifiers. */
717
 
        items = 0;
718
 
        buf[items++] = cpu_to_le32(POLICYDB_MAGIC);
719
 
        len = strlen(POLICYDB_STRING);
720
 
        buf[items++] = cpu_to_le32(len);
721
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
722
 
        if (items != items2)
723
 
                return -1;
724
 
        items = fwrite(policydb_str, 1, len, fp);
725
 
        if (items != len)
726
 
                return -1;
727
 
 
728
 
        /* Write the version, config, and table sizes. */
729
 
        items = 0;
730
 
        info = policydb_lookup_compat(policyvers);
731
 
        if (!info) {
732
 
                fprintf(stderr, "policydb_lookup_compat() failed for %d\n", policyvers);
733
 
                return -1;
734
 
        }
735
 
 
736
 
        buf[items++] = cpu_to_le32(policyvers);
737
 
        buf[items++] = cpu_to_le32(config);
738
 
        buf[items++] = cpu_to_le32(info->sym_num);
739
 
        buf[items++] = cpu_to_le32(info->ocon_num);
740
 
        
741
 
        items2 = fwrite(buf, sizeof(__u32), items, fp);
742
 
        if (items != items2)
743
 
                return -1;
744
 
 
745
 
        if (mls_write_nlevels(p, fp))
746
 
                return -1;
747
 
 
748
 
        num_syms = info->sym_num;
749
 
        for (i = 0; i < num_syms; i++) {
750
 
                buf[0] = cpu_to_le32(p->symtab[i].nprim);
751
 
                buf[1] = cpu_to_le32(p->symtab[i].table->nel);
752
 
                items = fwrite(buf, sizeof(__u32), 2, fp);
753
 
                if (items != 2)
754
 
                        return -1;
755
 
                if (hashtab_map(p->symtab[i].table, write_f[i], fp))
756
 
                        return -1;
757
 
        }
758
 
 
759
 
        if (avtab_write(&p->te_avtab, fp))
760
 
                return -1;
761
 
 
762
 
        if (policyvers < POLICYDB_VERSION_BOOL) {
763
 
                if (p->p_bools.nprim)
764
 
                        fprintf(stderr, "warning: discarding booleans and conditional rules\n");
765
 
 
766
 
        } else {
767
 
                if (cond_write_list(p->cond_list, fp))
768
 
                        return -1;
769
 
        }
770
 
 
771
 
        nel = 0;
772
 
        for (tr = p->role_tr; tr; tr = tr->next) 
773
 
                nel++;
774
 
        buf[0] = cpu_to_le32(nel);
775
 
        items = fwrite(buf, sizeof(__u32), 1, fp);
776
 
        if (items != 1)
777
 
                return -1;
778
 
        for (tr = p->role_tr; tr; tr = tr->next) {
779
 
                buf[0] = cpu_to_le32(tr->role);
780
 
                buf[1] = cpu_to_le32(tr->type);
781
 
                buf[2] = cpu_to_le32(tr->new_role);
782
 
                items = fwrite(buf, sizeof(__u32), 3, fp);
783
 
                if (items != 3)
784
 
                        return -1;              
785
 
        }
786
 
 
787
 
        nel = 0;
788
 
        for (ra = p->role_allow; ra; ra = ra->next) 
789
 
                nel++;
790
 
        buf[0] = cpu_to_le32(nel);
791
 
        items = fwrite(buf, sizeof(__u32), 1, fp);
792
 
        if (items != 1)
793
 
                return -1;
794
 
        for (ra = p->role_allow; ra; ra = ra->next) {
795
 
                buf[0] = cpu_to_le32(ra->role);
796
 
                buf[1] = cpu_to_le32(ra->new_role);
797
 
                items = fwrite(buf, sizeof(__u32), 2, fp);
798
 
                if (items != 2)
799
 
                        return -1;              
800
 
        }
801
 
 
802
 
        for (i = 0; i < info->ocon_num; i++) {
803
 
                nel = 0;
804
 
                for (c = p->ocontexts[i]; c; c = c->next)
805
 
                        nel++;
806
 
                buf[0] = cpu_to_le32(nel);
807
 
                items = fwrite(buf, sizeof(__u32), 1, fp);
808
 
                if (items != 1)
809
 
                        return -1;
810
 
                for (c = p->ocontexts[i]; c; c = c->next) {
811
 
                        switch (i) {
812
 
                        case OCON_ISID:
813
 
                                buf[0] = cpu_to_le32(c->sid[0]);
814
 
                                items = fwrite(buf, sizeof(__u32), 1, fp);
815
 
                                if (items != 1)
816
 
                                        return -1;
817
 
                                if (context_write(&c->context[0], fp))
818
 
                                        return -1;
819
 
                                break;
820
 
                        case OCON_FS:
821
 
                        case OCON_NETIF:
822
 
                                len = strlen(c->u.name);
823
 
                                buf[0] = cpu_to_le32(len);
824
 
                                items = fwrite(buf, sizeof(__u32), 1, fp);
825
 
                                if (items != 1)
826
 
                                        return -1;
827
 
                                items = fwrite(c->u.name, 1, len, fp);
828
 
                                if (items != len)
829
 
                                        return -1;
830
 
                                if (context_write(&c->context[0], fp))
831
 
                                        return -1;
832
 
                                if (context_write(&c->context[1], fp))
833
 
                                        return -1;
834
 
                                break;
835
 
                        case OCON_PORT:
836
 
                                buf[0] = c->u.port.protocol;
837
 
                                buf[1] = c->u.port.low_port;
838
 
                                buf[2] = c->u.port.high_port;
839
 
                                for (j = 0; j < 3; j++) {
840
 
                                        buf[j] = cpu_to_le32(buf[j]);
841
 
                                }
842
 
                                items = fwrite(buf, sizeof(__u32), 3, fp);
843
 
                                if (items != 3)
844
 
                                        return -1;
845
 
                                if (context_write(&c->context[0], fp))
846
 
                                        return -1;
847
 
                                break;
848
 
                        case OCON_NODE:
849
 
                                buf[0] = cpu_to_le32(c->u.node.addr);
850
 
                                buf[1] = cpu_to_le32(c->u.node.mask);
851
 
                                items = fwrite(buf, sizeof(__u32), 2, fp);
852
 
                                if (items != 2)
853
 
                                        return -1;
854
 
                                if (context_write(&c->context[0], fp))
855
 
                                        return -1;
856
 
                                break;
857
 
                        case OCON_FSUSE:
858
 
                                buf[0] = cpu_to_le32(c->v.behavior);
859
 
                                len = strlen(c->u.name);
860
 
                                buf[1] = cpu_to_le32(len);
861
 
                                items = fwrite(buf, sizeof(__u32), 2, fp);
862
 
                                if (items != 2)
863
 
                                        return -1;
864
 
                                items = fwrite(c->u.name, 1, len, fp);
865
 
                                if (items != len)
866
 
                                        return -1;
867
 
                                if (context_write(&c->context[0], fp))
868
 
                                        return -1;
869
 
                                break;
870
 
                        case OCON_NODE6:
871
 
                                for (j = 0; j < 4; j++)
872
 
                                        buf[j] = cpu_to_le32(c->u.node6.addr[j]);
873
 
                                for (j = 0; j < 4; j++)
874
 
                                        buf[j+4] = cpu_to_le32(c->u.node6.mask[j]);
875
 
                                items = fwrite(buf, sizeof(__u32), 8, fp);
876
 
                                if (items != 8)
877
 
                                        return -1;
878
 
                                if (context_write(&c->context[0], fp))
879
 
                                        return -1;
880
 
                                break;  
881
 
                        }
882
 
                }
883
 
        }
884
 
 
885
 
        nel = 0;
886
 
        for (genfs = p->genfs; genfs; genfs = genfs->next) 
887
 
                nel++;
888
 
        buf[0] = cpu_to_le32(nel);
889
 
        items = fwrite(buf, sizeof(__u32), 1, fp);
890
 
        if (items != 1)
891
 
                return -1;      
892
 
        for (genfs = p->genfs; genfs; genfs = genfs->next) {
893
 
                len = strlen(genfs->fstype);
894
 
                buf[0] = cpu_to_le32(len);
895
 
                items = fwrite(buf, sizeof(__u32), 1, fp);
896
 
                if (items != 1)
897
 
                        return -1;
898
 
                items = fwrite(genfs->fstype, 1, len, fp);
899
 
                if (items != len)
900
 
                        return -1;
901
 
                nel = 0;
902
 
                for (c = genfs->head; c; c = c->next)
903
 
                        nel++;
904
 
                buf[0] = cpu_to_le32(nel);
905
 
                items = fwrite(buf, sizeof(__u32), 1, fp);
906
 
                if (items != 1)
907
 
                        return -1;
908
 
                for (c = genfs->head; c; c = c->next) {
909
 
                        len = strlen(c->u.name);
910
 
                        buf[0] = cpu_to_le32(len);
911
 
                        items = fwrite(buf, sizeof(__u32), 1, fp);
912
 
                        if (items != 1)
913
 
                                return -1;
914
 
                        items = fwrite(c->u.name, 1, len, fp);
915
 
                        if (items != len)
916
 
                                return -1;
917
 
                        buf[0] = cpu_to_le32(c->v.sclass);
918
 
                        items = fwrite(buf, sizeof(__u32), 1, fp);
919
 
                        if (items != 1)
920
 
                                return -1;
921
 
                        if (context_write(&c->context[0], fp))
922
 
                                return -1;
923
 
                }
924
 
        }
925
 
 
926
 
        if (mls_write_trusted(p, fp))
927
 
                return -1;
928
 
 
929
 
        return 0;
930
 
}
931