root / acl.c @ 2d72c572
History | View | Annotate | Download (4.4 kB)
1 | 76655d6d | aliguori | /*
|
---|---|---|---|
2 | 76655d6d | aliguori | * QEMU access control list management
|
3 | 76655d6d | aliguori | *
|
4 | 76655d6d | aliguori | * Copyright (C) 2009 Red Hat, Inc
|
5 | 76655d6d | aliguori | *
|
6 | 76655d6d | aliguori | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 | 76655d6d | aliguori | * of this software and associated documentation files (the "Software"), to deal
|
8 | 76655d6d | aliguori | * in the Software without restriction, including without limitation the rights
|
9 | 76655d6d | aliguori | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 | 76655d6d | aliguori | * copies of the Software, and to permit persons to whom the Software is
|
11 | 76655d6d | aliguori | * furnished to do so, subject to the following conditions:
|
12 | 76655d6d | aliguori | *
|
13 | 76655d6d | aliguori | * The above copyright notice and this permission notice shall be included in
|
14 | 76655d6d | aliguori | * all copies or substantial portions of the Software.
|
15 | 76655d6d | aliguori | *
|
16 | 76655d6d | aliguori | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 | 76655d6d | aliguori | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 | 76655d6d | aliguori | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
19 | 76655d6d | aliguori | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 | 76655d6d | aliguori | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 | 76655d6d | aliguori | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 | 76655d6d | aliguori | * THE SOFTWARE.
|
23 | 76655d6d | aliguori | */
|
24 | 76655d6d | aliguori | |
25 | 76655d6d | aliguori | |
26 | 76655d6d | aliguori | #include "qemu-common.h" |
27 | 76655d6d | aliguori | #include "sysemu.h" |
28 | 76655d6d | aliguori | #include "acl.h" |
29 | 76655d6d | aliguori | |
30 | 76655d6d | aliguori | #ifdef HAVE_FNMATCH_H
|
31 | 76655d6d | aliguori | #include <fnmatch.h> |
32 | 76655d6d | aliguori | #endif
|
33 | 76655d6d | aliguori | |
34 | 76655d6d | aliguori | |
35 | 76655d6d | aliguori | static unsigned int nacls = 0; |
36 | 76655d6d | aliguori | static qemu_acl **acls = NULL; |
37 | 76655d6d | aliguori | |
38 | 76655d6d | aliguori | |
39 | 76655d6d | aliguori | |
40 | 76655d6d | aliguori | qemu_acl *qemu_acl_find(const char *aclname) |
41 | 76655d6d | aliguori | { |
42 | 76655d6d | aliguori | int i;
|
43 | 76655d6d | aliguori | for (i = 0 ; i < nacls ; i++) { |
44 | 28a76be8 | aliguori | if (strcmp(acls[i]->aclname, aclname) == 0) |
45 | 28a76be8 | aliguori | return acls[i];
|
46 | 76655d6d | aliguori | } |
47 | 76655d6d | aliguori | |
48 | 76655d6d | aliguori | return NULL; |
49 | 76655d6d | aliguori | } |
50 | 76655d6d | aliguori | |
51 | 76655d6d | aliguori | qemu_acl *qemu_acl_init(const char *aclname) |
52 | 76655d6d | aliguori | { |
53 | 76655d6d | aliguori | qemu_acl *acl; |
54 | 76655d6d | aliguori | |
55 | 76655d6d | aliguori | acl = qemu_acl_find(aclname); |
56 | 76655d6d | aliguori | if (acl)
|
57 | 28a76be8 | aliguori | return acl;
|
58 | 76655d6d | aliguori | |
59 | 76655d6d | aliguori | acl = qemu_malloc(sizeof(*acl));
|
60 | 76655d6d | aliguori | acl->aclname = qemu_strdup(aclname); |
61 | 76655d6d | aliguori | /* Deny by default, so there is no window of "open
|
62 | 76655d6d | aliguori | * access" between QEMU starting, and the user setting
|
63 | 76655d6d | aliguori | * up ACLs in the monitor */
|
64 | 76655d6d | aliguori | acl->defaultDeny = 1;
|
65 | 76655d6d | aliguori | |
66 | 76655d6d | aliguori | acl->nentries = 0;
|
67 | 76655d6d | aliguori | TAILQ_INIT(&acl->entries); |
68 | 76655d6d | aliguori | |
69 | 76655d6d | aliguori | acls = qemu_realloc(acls, sizeof(*acls) * (nacls +1)); |
70 | 76655d6d | aliguori | acls[nacls] = acl; |
71 | 76655d6d | aliguori | nacls++; |
72 | 76655d6d | aliguori | |
73 | 76655d6d | aliguori | return acl;
|
74 | 76655d6d | aliguori | } |
75 | 76655d6d | aliguori | |
76 | 76655d6d | aliguori | int qemu_acl_party_is_allowed(qemu_acl *acl,
|
77 | 28a76be8 | aliguori | const char *party) |
78 | 76655d6d | aliguori | { |
79 | 76655d6d | aliguori | qemu_acl_entry *entry; |
80 | 76655d6d | aliguori | |
81 | 76655d6d | aliguori | TAILQ_FOREACH(entry, &acl->entries, next) { |
82 | 76655d6d | aliguori | #ifdef HAVE_FNMATCH_H
|
83 | 28a76be8 | aliguori | if (fnmatch(entry->match, party, 0) == 0) |
84 | 28a76be8 | aliguori | return entry->deny ? 0 : 1; |
85 | 76655d6d | aliguori | #else
|
86 | 28a76be8 | aliguori | /* No fnmatch, so fallback to exact string matching
|
87 | 28a76be8 | aliguori | * instead of allowing wildcards */
|
88 | 28a76be8 | aliguori | if (strcmp(entry->match, party) == 0) |
89 | 28a76be8 | aliguori | return entry->deny ? 0 : 1; |
90 | 76655d6d | aliguori | #endif
|
91 | 76655d6d | aliguori | } |
92 | 76655d6d | aliguori | |
93 | 76655d6d | aliguori | return acl->defaultDeny ? 0 : 1; |
94 | 76655d6d | aliguori | } |
95 | 76655d6d | aliguori | |
96 | 76655d6d | aliguori | |
97 | 76655d6d | aliguori | void qemu_acl_reset(qemu_acl *acl)
|
98 | 76655d6d | aliguori | { |
99 | 76655d6d | aliguori | qemu_acl_entry *entry; |
100 | 76655d6d | aliguori | |
101 | 76655d6d | aliguori | /* Put back to deny by default, so there is no window
|
102 | 76655d6d | aliguori | * of "open access" while the user re-initializes the
|
103 | 76655d6d | aliguori | * access control list */
|
104 | 76655d6d | aliguori | acl->defaultDeny = 1;
|
105 | 76655d6d | aliguori | TAILQ_FOREACH(entry, &acl->entries, next) { |
106 | 28a76be8 | aliguori | TAILQ_REMOVE(&acl->entries, entry, next); |
107 | 28a76be8 | aliguori | free(entry->match); |
108 | 28a76be8 | aliguori | free(entry); |
109 | 76655d6d | aliguori | } |
110 | 76655d6d | aliguori | acl->nentries = 0;
|
111 | 76655d6d | aliguori | } |
112 | 76655d6d | aliguori | |
113 | 76655d6d | aliguori | |
114 | 76655d6d | aliguori | int qemu_acl_append(qemu_acl *acl,
|
115 | 28a76be8 | aliguori | int deny,
|
116 | 28a76be8 | aliguori | const char *match) |
117 | 76655d6d | aliguori | { |
118 | 76655d6d | aliguori | qemu_acl_entry *entry; |
119 | 76655d6d | aliguori | |
120 | 76655d6d | aliguori | entry = qemu_malloc(sizeof(*entry));
|
121 | 76655d6d | aliguori | entry->match = qemu_strdup(match); |
122 | 76655d6d | aliguori | entry->deny = deny; |
123 | 76655d6d | aliguori | |
124 | 76655d6d | aliguori | TAILQ_INSERT_TAIL(&acl->entries, entry, next); |
125 | 76655d6d | aliguori | acl->nentries++; |
126 | 76655d6d | aliguori | |
127 | 76655d6d | aliguori | return acl->nentries;
|
128 | 76655d6d | aliguori | } |
129 | 76655d6d | aliguori | |
130 | 76655d6d | aliguori | |
131 | 76655d6d | aliguori | int qemu_acl_insert(qemu_acl *acl,
|
132 | 28a76be8 | aliguori | int deny,
|
133 | 28a76be8 | aliguori | const char *match, |
134 | 28a76be8 | aliguori | int index)
|
135 | 76655d6d | aliguori | { |
136 | 76655d6d | aliguori | qemu_acl_entry *entry; |
137 | 76655d6d | aliguori | qemu_acl_entry *tmp; |
138 | 76655d6d | aliguori | int i = 0; |
139 | 76655d6d | aliguori | |
140 | 76655d6d | aliguori | if (index <= 0) |
141 | 28a76be8 | aliguori | return -1; |
142 | 76655d6d | aliguori | if (index >= acl->nentries)
|
143 | 28a76be8 | aliguori | return qemu_acl_append(acl, deny, match);
|
144 | 76655d6d | aliguori | |
145 | 76655d6d | aliguori | |
146 | 76655d6d | aliguori | entry = qemu_malloc(sizeof(*entry));
|
147 | 76655d6d | aliguori | entry->match = qemu_strdup(match); |
148 | 76655d6d | aliguori | entry->deny = deny; |
149 | 76655d6d | aliguori | |
150 | 76655d6d | aliguori | TAILQ_FOREACH(tmp, &acl->entries, next) { |
151 | 28a76be8 | aliguori | i++; |
152 | 28a76be8 | aliguori | if (i == index) {
|
153 | 28a76be8 | aliguori | TAILQ_INSERT_BEFORE(tmp, entry, next); |
154 | 28a76be8 | aliguori | acl->nentries++; |
155 | 28a76be8 | aliguori | break;
|
156 | 28a76be8 | aliguori | } |
157 | 76655d6d | aliguori | } |
158 | 76655d6d | aliguori | |
159 | 76655d6d | aliguori | return i;
|
160 | 76655d6d | aliguori | } |
161 | 76655d6d | aliguori | |
162 | 76655d6d | aliguori | int qemu_acl_remove(qemu_acl *acl,
|
163 | 28a76be8 | aliguori | const char *match) |
164 | 76655d6d | aliguori | { |
165 | 76655d6d | aliguori | qemu_acl_entry *entry; |
166 | 76655d6d | aliguori | int i = 0; |
167 | 76655d6d | aliguori | |
168 | 76655d6d | aliguori | TAILQ_FOREACH(entry, &acl->entries, next) { |
169 | 28a76be8 | aliguori | i++; |
170 | 28a76be8 | aliguori | if (strcmp(entry->match, match) == 0) { |
171 | 28a76be8 | aliguori | TAILQ_REMOVE(&acl->entries, entry, next); |
172 | 28a76be8 | aliguori | return i;
|
173 | 28a76be8 | aliguori | } |
174 | 76655d6d | aliguori | } |
175 | 76655d6d | aliguori | return -1; |
176 | 76655d6d | aliguori | } |
177 | 76655d6d | aliguori | |
178 | 76655d6d | aliguori | |
179 | 76655d6d | aliguori | /*
|
180 | 76655d6d | aliguori | * Local variables:
|
181 | 76655d6d | aliguori | * c-indent-level: 4
|
182 | 76655d6d | aliguori | * c-basic-offset: 4
|
183 | 76655d6d | aliguori | * tab-width: 8
|
184 | 76655d6d | aliguori | * End:
|
185 | 76655d6d | aliguori | */ |