ia64/xen-unstable

view xen/acm/acm_policy.c @ 5860:d63b100b327a

Fix restart/poweroff properly. From aq.
author kaf24@firebug.cl.cam.ac.uk
date Tue Jul 26 10:09:06 2005 +0000 (2005-07-26)
parents ecb17ef5a587
children b53a65034532 1efe6f4163ee d18f732c0a5f 361d31028129
line source
1 /****************************************************************
2 * acm_policy.c
3 *
4 * Copyright (C) 2005 IBM Corporation
5 *
6 * Author:
7 * Reiner Sailer <sailer@watson.ibm.com>
8 *
9 * Contributions:
10 * Stefan Berger <stefanb@watson.ibm.com>
11 * support for network-byte-order binary policies
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2 of the
16 * License.
17 *
18 * sHype access control policy management for Xen.
19 * This interface allows policy tools in authorized
20 * domains to interact with the Xen access control module
21 *
22 */
24 #include <xen/config.h>
25 #include <xen/errno.h>
26 #include <xen/types.h>
27 #include <xen/lib.h>
28 #include <xen/delay.h>
29 #include <xen/sched.h>
30 #include <public/policy_ops.h>
31 #include <acm/acm_core.h>
32 #include <acm/acm_hooks.h>
33 #include <acm/acm_endian.h>
35 int
36 acm_set_policy(void *buf, u16 buf_size, u16 policy, int isuserbuffer)
37 {
38 u8 *policy_buffer = NULL;
39 struct acm_policy_buffer *pol;
41 if (policy != ACM_USE_SECURITY_POLICY) {
42 printk("%s: Loading incompatible policy (running: %s).\n", __func__,
43 ACM_POLICY_NAME(ACM_USE_SECURITY_POLICY));
44 return -EFAULT;
45 }
46 /* now check correct buffer sizes for policy combinations */
47 if (policy == ACM_NULL_POLICY) {
48 printkd("%s: NULL Policy, no policy needed.\n", __func__);
49 goto out;
50 }
51 if (buf_size < sizeof(struct acm_policy_buffer))
52 return -EFAULT;
53 /* 1. copy buffer from domain */
54 if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
55 goto error_free;
56 if (isuserbuffer) {
57 if (copy_from_user(policy_buffer, buf, buf_size)) {
58 printk("%s: Error copying!\n",__func__);
59 goto error_free;
60 }
61 } else {
62 memcpy(policy_buffer, buf, buf_size);
63 }
64 /* 2. some sanity checking */
65 pol = (struct acm_policy_buffer *)policy_buffer;
67 if ((ntohl(pol->magic) != ACM_MAGIC) ||
68 (ntohs(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) ||
69 (ntohs(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code) ||
70 (ntohl(pol->policyversion) != POLICY_INTERFACE_VERSION)) {
71 printkd("%s: Wrong policy magics!\n", __func__);
72 goto error_free;
73 }
74 if (buf_size != ntohl(pol->len)) {
75 printk("%s: ERROR in buf size.\n", __func__);
76 goto error_free;
77 }
79 /* get bin_policy lock and rewrite policy (release old one) */
80 write_lock(&acm_bin_pol_rwlock);
82 /* 3. now get/set primary policy data */
83 if (acm_primary_ops->set_binary_policy(buf + ntohs(pol->primary_buffer_offset),
84 ntohs(pol->secondary_buffer_offset) -
85 ntohs(pol->primary_buffer_offset))) {
86 goto error_lock_free;
87 }
88 /* 4. now get/set secondary policy data */
89 if (acm_secondary_ops->set_binary_policy(buf + ntohs(pol->secondary_buffer_offset),
90 ntohl(pol->len) -
91 ntohs(pol->secondary_buffer_offset))) {
92 goto error_lock_free;
93 }
94 write_unlock(&acm_bin_pol_rwlock);
95 out:
96 printk("%s: Done .\n", __func__);
97 if (policy_buffer != NULL)
98 xfree(policy_buffer);
99 return ACM_OK;
101 error_lock_free:
102 write_unlock(&acm_bin_pol_rwlock);
103 error_free:
104 printk("%s: Error setting policy.\n", __func__);
105 if (policy_buffer != NULL)
106 xfree(policy_buffer);
107 return -ENOMEM;
108 }
110 int
111 acm_get_policy(void *buf, u16 buf_size)
112 {
113 u8 *policy_buffer;
114 int ret;
115 struct acm_policy_buffer *bin_pol;
117 if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
118 return -ENOMEM;
120 read_lock(&acm_bin_pol_rwlock);
121 /* future: read policy from file and set it */
122 bin_pol = (struct acm_policy_buffer *)policy_buffer;
123 bin_pol->magic = htonl(ACM_MAGIC);
124 bin_pol->policyversion = htonl(POLICY_INTERFACE_VERSION);
125 bin_pol->primary_policy_code = htons(acm_bin_pol.primary_policy_code);
126 bin_pol->secondary_policy_code = htons(acm_bin_pol.secondary_policy_code);
128 bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
129 bin_pol->primary_buffer_offset = htons(ntohl(bin_pol->len));
130 bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len));
132 ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohs(bin_pol->primary_buffer_offset),
133 buf_size - ntohs(bin_pol->primary_buffer_offset));
134 if (ret < 0) {
135 printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
136 read_unlock(&acm_bin_pol_rwlock);
137 return -1;
138 }
139 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
140 bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len));
142 ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohs(bin_pol->secondary_buffer_offset),
143 buf_size - ntohs(bin_pol->secondary_buffer_offset));
144 if (ret < 0) {
145 printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
146 read_unlock(&acm_bin_pol_rwlock);
147 return -1;
148 }
149 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
150 read_unlock(&acm_bin_pol_rwlock);
151 if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
152 return -EFAULT;
153 xfree(policy_buffer);
154 return ACM_OK;
155 }
157 int
158 acm_dump_statistics(void *buf, u16 buf_size)
159 {
160 /* send stats to user space */
161 u8 *stats_buffer;
162 int len1, len2;
163 struct acm_stats_buffer acm_stats;
165 if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL)
166 return -ENOMEM;
168 read_lock(&acm_bin_pol_rwlock);
170 len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer),
171 buf_size - sizeof(struct acm_stats_buffer));
172 if (len1 < 0)
173 goto error_lock_free;
175 len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1,
176 buf_size - sizeof(struct acm_stats_buffer) - len1);
177 if (len2 < 0)
178 goto error_lock_free;
180 acm_stats.magic = htonl(ACM_MAGIC);
181 acm_stats.policyversion = htonl(POLICY_INTERFACE_VERSION);
182 acm_stats.primary_policy_code = htons(acm_bin_pol.primary_policy_code);
183 acm_stats.secondary_policy_code = htons(acm_bin_pol.secondary_policy_code);
184 acm_stats.primary_stats_offset = htons(sizeof(struct acm_stats_buffer));
185 acm_stats.secondary_stats_offset = htons(sizeof(struct acm_stats_buffer) + len1);
186 acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2);
187 memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
189 if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2))
190 goto error_lock_free;
192 read_unlock(&acm_bin_pol_rwlock);
193 xfree(stats_buffer);
194 return ACM_OK;
196 error_lock_free:
197 read_unlock(&acm_bin_pol_rwlock);
198 xfree(stats_buffer);
199 return -EFAULT;
200 }
202 /*eof*/