~ubuntu-branches/ubuntu/hardy/checkpolicy/hardy

« back to all changes in this revision

Viewing changes to genpolusers.c

  • Committer: Bazaar Package Importer
  • Author(s): Manoj Srivastava
  • Date: 2005-06-27 14:42:10 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050627144210-so2wgrysi6glkqkt
Tags: 1.24-1
* New upstream release
      * Updated version for release.
      * Merged cleanup patch from Dan Walsh.
      * Added sepol_ prefix to Flask types to avoid namespace
        collision with libselinux.
      * Merged identifier fix from Joshua Brindle (Tresys).
      * Merged hierarchical type/role patch from Tresys Technology.
      * Merged MLS fixes from Darrel Goeddel of TCS.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * genpolusers old-policy new-users new-policy
3
 
 *
4
 
 * Given an existing binary policy configuration and a new source users 
5
 
 * configuration (post-processed), generate a new binary policy 
6
 
 * configuration that is identical to the old one except that it has
7
 
 * the new user declarations.  User declarations from the old binary
8
 
 * policy are replaced if they also exist in the new source users 
9
 
 * configuration or removed otherwise.  Special exceptions are made
10
 
 * for system_u and user_u, which can be replaced but not removed as
11
 
 * a safety against reloading a user configuration generated from 
12
 
 * passwd information that would not include these special SELinux users.
13
 
 * This needs to be generalized in some manner.  New users may also be
14
 
 * added by including them in the new source users configuration.
15
 
 */ 
16
 
 
17
 
#include <getopt.h>
18
 
#include <unistd.h>
19
 
#include <sys/types.h>
20
 
#include <sys/stat.h>
21
 
#include <fcntl.h>
22
 
#include <stdio.h>
23
 
#include <stdlib.h>
24
 
#include <errno.h>
25
 
#include <sys/mman.h>
26
 
#include <sepol/policydb.h>
27
 
#include <sepol/services.h>
28
 
#include <sepol/conditional.h>
29
 
#include "queue.h"
30
 
#include "checkpolicy.h"
31
 
 
32
 
extern policydb_t *policydbp;
33
 
extern queue_t id_queue;
34
 
extern unsigned int policydb_errors;
35
 
 
36
 
extern FILE *yyin;
37
 
extern int yyparse(void);
38
 
extern void yyrestart(FILE *);
39
 
 
40
 
void usage(char *progname)
41
 
{
42
 
        printf("usage:  %s old-policy new-users new-policy\n", progname);
43
 
        exit(1);
44
 
}
45
 
 
46
 
/* Select users for removal based on whether they were defined in the
47
 
   new source users configuration. */
48
 
static int select_user(hashtab_key_t key, hashtab_datum_t datum, void *datap)
49
 
{
50
 
        char *name = key;
51
 
        user_datum_t *usrdatum = datum;
52
 
        
53
 
        if (!usrdatum->defined) {
54
 
                /* XXX Hack:  Don't accidentally remove SELinux-only users. */
55
 
                if (!strcmp(name, "system_u") || !strcmp(name, "user_u")) {
56
 
                        printf("Warning!  %s not defined, but not removing.\n", name);
57
 
                        return 0;
58
 
                }
59
 
                printf("Removing user %s\n", name);
60
 
                return 1;
61
 
        }
62
 
        return 0;
63
 
}
64
 
 
65
 
static struct ebitmap free_users;
66
 
 
67
 
/* Kill the user entries selected by select_user, and
68
 
   record that their slots are free. */
69
 
void kill_user(hashtab_key_t key, hashtab_datum_t datum, void *p)
70
 
{
71
 
        user_datum_t *usrdatum;
72
 
        struct policydb *pol = p;
73
 
 
74
 
        if (key)
75
 
                free(key);
76
 
 
77
 
        usrdatum = (user_datum_t *) datum;
78
 
        ebitmap_set_bit(&free_users, usrdatum->value - 1, 1);
79
 
 
80
 
        ebitmap_destroy(&usrdatum->roles);
81
 
        free(datum);
82
 
        pol->p_users.nprim--;
83
 
}
84
 
 
85
 
/* Fold user values down to avoid holes generated by removal.
86
 
   As the SID table is remapped by the kernel upon a policy reload,
87
 
   this is safe for existing SIDs.  But it could be a problem for
88
 
   constraints if they refer to the particular user.  */
89
 
int remap_users(hashtab_key_t key, hashtab_datum_t datum, void *p)
90
 
{
91
 
        user_datum_t *usrdatum = datum;
92
 
        struct policydb *pol = p;
93
 
        int i;
94
 
 
95
 
        if (usrdatum->value > pol->p_users.nprim) {
96
 
                for (i = ebitmap_startbit(&free_users); i < ebitmap_length(&free_users); i++) {
97
 
                        if (ebitmap_get_bit(&free_users, i)) {
98
 
                                printf("Remapping user %s (%u -> %u)\n", key, usrdatum->value, i+1);
99
 
                                usrdatum->value = i+1;
100
 
                                ebitmap_set_bit(&free_users, i, 0);
101
 
                                return 0;
102
 
                        }
103
 
                }
104
 
        }
105
 
        return 0;
106
 
}
107
 
 
108
 
int main(int argc, char **argv)
109
 
{
110
 
        policydb_t policydb;
111
 
        struct policy_file pf;
112
 
        struct stat sb;
113
 
        FILE *outfp;
114
 
        int fd, rc;
115
 
        void *map;
116
 
 
117
 
        if (argc != 4) 
118
 
                usage(argv[0]);
119
 
 
120
 
        fd = open(argv[1], O_RDONLY);
121
 
        if (fd < 0) {
122
 
                fprintf(stderr, "Can't open '%s':  %s\n",
123
 
                        argv[1], strerror(errno));
124
 
                exit(1);
125
 
        }
126
 
        if (fstat(fd, &sb) < 0) {
127
 
                fprintf(stderr, "Can't stat '%s':  %s\n",
128
 
                        argv[1], strerror(errno));
129
 
                exit(1);
130
 
        }
131
 
        map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
132
 
        if (map == MAP_FAILED) {
133
 
                fprintf(stderr, "Can't map '%s':  %s\n",
134
 
                        argv[1], strerror(errno));
135
 
                exit(1);
136
 
        }
137
 
        pf.type = PF_USE_MEMORY;
138
 
        pf.data = map;
139
 
        pf.len = sb.st_size;
140
 
        if (policydb_read(&policydb,&pf, 0)) {
141
 
                fprintf(stderr, "Can't read binary policy from '%s':  %s\n",
142
 
                        argv[1], strerror(errno));
143
 
                exit(1);
144
 
        }
145
 
        close(fd);
146
 
 
147
 
        /* Preserve the policy version of the original policy
148
 
           for the new policy. */
149
 
        sepol_set_policyvers(policydb.policyvers);
150
 
 
151
 
        yyin = fopen(argv[2], "r");
152
 
        if (!yyin) {
153
 
                fprintf(stderr, "%s:  unable to open %s\n", argv[0], 
154
 
                        argv[2]);
155
 
                exit(1);
156
 
        }
157
 
        id_queue = queue_create();
158
 
        if (!id_queue) {
159
 
                fprintf(stderr, "%s:  out of memory\n", argv[0]);
160
 
                exit(1);
161
 
        }
162
 
        policydbp = &policydb;
163
 
        policydb_errors = 0;
164
 
        if (yyparse() || policydb_errors) {
165
 
                fprintf(stderr, "%s:  error(s) encountered while parsing configuration\n", argv[0]);
166
 
                exit(1);
167
 
        }
168
 
        queue_destroy(id_queue);
169
 
 
170
 
        if (policydb_errors) 
171
 
                exit(1);
172
 
 
173
 
        hashtab_map_remove_on_error(policydb.p_users.table, select_user, kill_user, &policydb);
174
 
        hashtab_map(policydb.p_users.table, remap_users, &policydb);
175
 
 
176
 
        outfp = fopen(argv[3], "w");
177
 
        if (!outfp) {
178
 
                perror(argv[3]);
179
 
                exit(1);
180
 
        }
181
 
        pf.type = PF_USE_STDIO;
182
 
        pf.fp = outfp;
183
 
        rc = policydb_write(&policydb, &pf);
184
 
        if (rc) {
185
 
                fprintf(stderr, "%s:  error writing %s\n",
186
 
                        argv[0], argv[3]);
187
 
                exit(1);
188
 
        }
189
 
        fclose(outfp);
190
 
        exit(0);
191
 
}