ia64/xen-unstable

view xen/common/acm_ops.c @ 9776:72f9c751d3ea

Replace &foo[0] with foo where the latter seems cleaner
(which is usually, and particularly when its an argument
to one of the bitops functions).

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Apr 19 18:32:20 2006 +0100 (2006-04-19)
parents 4293d6760cef
children 4e1b8be54311
line source
1 /******************************************************************************
2 * acm_ops.c
3 *
4 * Copyright (C) 2005 IBM Corporation
5 *
6 * Author:
7 * Reiner Sailer <sailer@watson.ibm.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2 of the
12 * License.
13 *
14 * Process acm command requests from guest OS.
15 *
16 */
18 #include <xen/config.h>
19 #include <xen/types.h>
20 #include <xen/lib.h>
21 #include <xen/mm.h>
22 #include <public/acm.h>
23 #include <public/acm_ops.h>
24 #include <xen/sched.h>
25 #include <xen/event.h>
26 #include <xen/trace.h>
27 #include <xen/console.h>
28 #include <xen/guest_access.h>
29 #include <asm/shadow.h>
30 #include <public/sched_ctl.h>
31 #include <acm/acm_hooks.h>
33 #ifndef ACM_SECURITY
35 long do_acm_op(GUEST_HANDLE(acm_op_t) u_acm_op)
36 {
37 return -ENOSYS;
38 }
40 #else
42 enum acm_operation {
43 POLICY, /* access to policy interface (early drop) */
44 GETPOLICY, /* dump policy cache */
45 SETPOLICY, /* set policy cache (controls security) */
46 DUMPSTATS, /* dump policy statistics */
47 GETSSID, /* retrieve ssidref for domain id (decide inside authorized domains) */
48 GETDECISION /* retrieve ACM decision from authorized domains */
49 };
51 int acm_authorize_acm_ops(struct domain *d, enum acm_operation pops)
52 {
53 /* currently, policy management functions are restricted to privileged domains */
54 if (!IS_PRIV(d))
55 return -EPERM;
57 return 0;
58 }
60 long do_acm_op(GUEST_HANDLE(acm_op_t) u_acm_op)
61 {
62 long ret = 0;
63 struct acm_op curop, *op = &curop;
65 if (acm_authorize_acm_ops(current->domain, POLICY))
66 return -EPERM;
68 if (copy_from_guest(op, u_acm_op, 1))
69 return -EFAULT;
71 if (op->interface_version != ACM_INTERFACE_VERSION)
72 return -EACCES;
74 switch (op->cmd)
75 {
76 case ACM_SETPOLICY:
77 {
78 ret = acm_authorize_acm_ops(current->domain, SETPOLICY);
79 if (!ret)
80 ret = acm_set_policy(op->u.setpolicy.pushcache,
81 op->u.setpolicy.pushcache_size, 1);
82 }
83 break;
85 case ACM_GETPOLICY:
86 {
87 ret = acm_authorize_acm_ops(current->domain, GETPOLICY);
88 if (!ret)
89 ret = acm_get_policy(op->u.getpolicy.pullcache,
90 op->u.getpolicy.pullcache_size);
91 if (!ret)
92 copy_to_guest(u_acm_op, op, 1);
93 }
94 break;
96 case ACM_DUMPSTATS:
97 {
98 ret = acm_authorize_acm_ops(current->domain, DUMPSTATS);
99 if (!ret)
100 ret = acm_dump_statistics(op->u.dumpstats.pullcache,
101 op->u.dumpstats.pullcache_size);
102 if (!ret)
103 copy_to_guest(u_acm_op, op, 1);
104 }
105 break;
107 case ACM_GETSSID:
108 {
109 ssidref_t ssidref;
111 ret = acm_authorize_acm_ops(current->domain, GETSSID);
112 if (ret)
113 break;
115 if (op->u.getssid.get_ssid_by == SSIDREF)
116 ssidref = op->u.getssid.id.ssidref;
117 else if (op->u.getssid.get_ssid_by == DOMAINID)
118 {
119 struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid);
120 if (!subj)
121 {
122 ret = -ESRCH; /* domain not found */
123 break;
124 }
125 if (subj->ssid == NULL)
126 {
127 put_domain(subj);
128 ret = -ESRCH;
129 break;
130 }
131 ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
132 put_domain(subj);
133 }
134 else
135 {
136 ret = -ESRCH;
137 break;
138 }
139 ret = acm_get_ssid(ssidref,
140 op->u.getssid.ssidbuf,
141 op->u.getssid.ssidbuf_size);
142 if (!ret)
143 copy_to_guest(u_acm_op, op, 1);
144 }
145 break;
147 case ACM_GETDECISION:
148 {
149 ssidref_t ssidref1, ssidref2;
151 ret = acm_authorize_acm_ops(current->domain, GETDECISION);
152 if (ret)
153 break;
155 if (op->u.getdecision.get_decision_by1 == SSIDREF)
156 ssidref1 = op->u.getdecision.id1.ssidref;
157 else if (op->u.getdecision.get_decision_by1 == DOMAINID)
158 {
159 struct domain *subj = find_domain_by_id(op->u.getdecision.id1.domainid);
160 if (!subj)
161 {
162 ret = -ESRCH; /* domain not found */
163 break;
164 }
165 if (subj->ssid == NULL)
166 {
167 put_domain(subj);
168 ret = -ESRCH;
169 break;
170 }
171 ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
172 put_domain(subj);
173 }
174 else
175 {
176 ret = -ESRCH;
177 break;
178 }
179 if (op->u.getdecision.get_decision_by2 == SSIDREF)
180 ssidref2 = op->u.getdecision.id2.ssidref;
181 else if (op->u.getdecision.get_decision_by2 == DOMAINID)
182 {
183 struct domain *subj = find_domain_by_id(op->u.getdecision.id2.domainid);
184 if (!subj)
185 {
186 ret = -ESRCH; /* domain not found */
187 break;;
188 }
189 if (subj->ssid == NULL)
190 {
191 put_domain(subj);
192 ret = -ESRCH;
193 break;
194 }
195 ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
196 put_domain(subj);
197 }
198 else
199 {
200 ret = -ESRCH;
201 break;
202 }
203 ret = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook);
205 if (ret == ACM_ACCESS_PERMITTED)
206 {
207 op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED;
208 ret = 0;
209 }
210 else if (ret == ACM_ACCESS_DENIED)
211 {
212 op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
213 ret = 0;
214 }
215 else
216 ret = -ESRCH;
218 if (!ret)
219 copy_to_guest(u_acm_op, op, 1);
220 }
221 break;
223 default:
224 ret = -ESRCH;
225 }
227 return ret;
228 }
230 #endif
232 /*
233 * Local variables:
234 * mode: C
235 * c-set-style: "BSD"
236 * c-basic-offset: 4
237 * tab-width: 4
238 * indent-tabs-mode: nil
239 * End:
240 */