ia64/xen-unstable

view xen/common/acm_ops.c @ 9706:3c05406f5e0a

In some cases, say for instance for some bizzare reason
the tree was checked out of CVS, which doens't neccessarily
store file permissions, mkbuildtree may not be executable.
So run them explicitly via bash.

Signed-Off-By: Horms <horms@verge.net.au>
author kaf24@firebug.cl.cam.ac.uk
date Thu Apr 13 11:24:00 2006 +0100 (2006-04-13)
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 */