ia64/xen-unstable

view tools/security/secpol_tool.c @ 6538:84ee014ebd41

Merge xen-vtx-unstable.hg
author adsharma@los-vmm.sc.intel.com
date Wed Aug 17 12:34:38 2005 -0800 (2005-08-17)
parents 23979fb12c49 f507ca15ae00
children 99914b54f7bf
line source
1 /****************************************************************
2 * secpol_tool.c
3 *
4 * Copyright (C) 2005 IBM Corporation
5 *
6 * Authors:
7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Stefan Berger <stefanb@watson.ibm.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation, version 2 of the
13 * License.
14 *
15 * sHype policy management tool. This code runs in a domain and
16 * manages the Xen security policy by interacting with the
17 * Xen access control module via a /proc/xen/privcmd proc-ioctl,
18 * which is translated into a acm_op hypercall into Xen.
19 *
20 * indent -i4 -kr -nut
21 */
24 #include <unistd.h>
25 #include <stdio.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <sys/mman.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <stdlib.h>
32 #include <sys/ioctl.h>
33 #include <string.h>
34 #include <stdint.h>
35 #include <netinet/in.h>
37 typedef uint8_t u8;
38 typedef uint16_t u16;
39 typedef uint32_t u32;
40 typedef uint64_t u64;
41 typedef int8_t s8;
42 typedef int16_t s16;
43 typedef int32_t s32;
44 typedef int64_t s64;
46 #include <xen/acm.h>
47 #include <xen/acm_ops.h>
48 #include <xen/linux/privcmd.h>
50 #define PERROR(_m, _a...) \
51 fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
52 errno, strerror(errno))
54 static inline int do_policycmd(int xc_handle, unsigned int cmd,
55 unsigned long data)
56 {
57 return ioctl(xc_handle, cmd, data);
58 }
60 static inline int do_xen_hypercall(int xc_handle,
61 privcmd_hypercall_t * hypercall)
62 {
63 return do_policycmd(xc_handle,
64 IOCTL_PRIVCMD_HYPERCALL,
65 (unsigned long) hypercall);
66 }
68 static inline int do_acm_op(int xc_handle, acm_op_t * op)
69 {
70 int ret = -1;
71 privcmd_hypercall_t hypercall;
73 op->interface_version = ACM_INTERFACE_VERSION;
75 hypercall.op = __HYPERVISOR_acm_op;
76 hypercall.arg[0] = (unsigned long) op;
78 if (mlock(op, sizeof(*op)) != 0)
79 {
80 PERROR("Could not lock memory for Xen policy hypercall");
81 goto out1;
82 }
84 if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0)
85 {
86 if (errno == EACCES)
87 fprintf(stderr, "ACM operation failed -- need to"
88 " rebuild the user-space tool set?\n");
89 goto out2;
90 }
92 out2:(void) munlock(op, sizeof(*op));
93 out1:return ret;
94 }
96 /*************************** DUMPS *******************************/
98 void acm_dump_chinesewall_buffer(void *buf, int buflen)
99 {
101 struct acm_chwall_policy_buffer *cwbuf =
102 (struct acm_chwall_policy_buffer *) buf;
103 domaintype_t *ssids, *conflicts, *running_types, *conflict_aggregate;
104 int i, j;
107 if (htonl(cwbuf->policy_code) != ACM_CHINESE_WALL_POLICY)
108 {
109 printf("CHINESE WALL POLICY CODE not found ERROR!!\n");
110 return;
111 }
112 printf("\n\nChinese Wall policy:\n");
113 printf("====================\n");
114 printf("Policy version= %x.\n", ntohl(cwbuf->policy_version));
115 printf("Max Types = %x.\n", ntohl(cwbuf->chwall_max_types));
116 printf("Max Ssidrefs = %x.\n", ntohl(cwbuf->chwall_max_ssidrefs));
117 printf("Max ConfSets = %x.\n", ntohl(cwbuf->chwall_max_conflictsets));
118 printf("Ssidrefs Off = %x.\n", ntohl(cwbuf->chwall_ssid_offset));
119 printf("Conflicts Off = %x.\n",
120 ntohl(cwbuf->chwall_conflict_sets_offset));
121 printf("Runing T. Off = %x.\n",
122 ntohl(cwbuf->chwall_running_types_offset));
123 printf("C. Agg. Off = %x.\n",
124 ntohl(cwbuf->chwall_conflict_aggregate_offset));
125 printf("\nSSID To CHWALL-Type matrix:\n");
127 ssids = (domaintype_t *) (buf + ntohl(cwbuf->chwall_ssid_offset));
128 for (i = 0; i < ntohl(cwbuf->chwall_max_ssidrefs); i++)
129 {
130 printf("\n ssidref%2x: ", i);
131 for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
132 printf("%02x ",
133 ntohs(ssids[i * ntohl(cwbuf->chwall_max_types) + j]));
134 }
135 printf("\n\nConfict Sets:\n");
136 conflicts =
137 (domaintype_t *) (buf + ntohl(cwbuf->chwall_conflict_sets_offset));
138 for (i = 0; i < ntohl(cwbuf->chwall_max_conflictsets); i++)
139 {
140 printf("\n c-set%2x: ", i);
141 for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
142 printf("%02x ",
143 ntohs(conflicts
144 [i * ntohl(cwbuf->chwall_max_types) + j]));
145 }
146 printf("\n");
148 printf("\nRunning\nTypes: ");
149 if (ntohl(cwbuf->chwall_running_types_offset))
150 {
151 running_types =
152 (domaintype_t *) (buf +
153 ntohl(cwbuf->chwall_running_types_offset));
154 for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++)
155 {
156 printf("%02x ", ntohs(running_types[i]));
157 }
158 printf("\n");
159 } else {
160 printf("Not Reported!\n");
161 }
162 printf("\nConflict\nAggregate Set: ");
163 if (ntohl(cwbuf->chwall_conflict_aggregate_offset))
164 {
165 conflict_aggregate =
166 (domaintype_t *) (buf +
167 ntohl(cwbuf->chwall_conflict_aggregate_offset));
168 for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++)
169 {
170 printf("%02x ", ntohs(conflict_aggregate[i]));
171 }
172 printf("\n\n");
173 } else {
174 printf("Not Reported!\n");
175 }
176 }
178 void acm_dump_ste_buffer(void *buf, int buflen)
179 {
181 struct acm_ste_policy_buffer *stebuf =
182 (struct acm_ste_policy_buffer *) buf;
183 domaintype_t *ssids;
184 int i, j;
187 if (ntohl(stebuf->policy_code) != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
188 printf("SIMPLE TYPE ENFORCEMENT POLICY CODE not found ERROR!!\n");
189 return;
190 }
191 printf("\nSimple Type Enforcement policy:\n");
192 printf("===============================\n");
193 printf("Policy version= %x.\n", ntohl(stebuf->policy_version));
194 printf("Max Types = %x.\n", ntohl(stebuf->ste_max_types));
195 printf("Max Ssidrefs = %x.\n", ntohl(stebuf->ste_max_ssidrefs));
196 printf("Ssidrefs Off = %x.\n", ntohl(stebuf->ste_ssid_offset));
197 printf("\nSSID To STE-Type matrix:\n");
199 ssids = (domaintype_t *) (buf + ntohl(stebuf->ste_ssid_offset));
200 for (i = 0; i < ntohl(stebuf->ste_max_ssidrefs); i++)
201 {
202 printf("\n ssidref%2x: ", i);
203 for (j = 0; j < ntohl(stebuf->ste_max_types); j++)
204 printf("%02x ", ntohs(ssids[i * ntohl(stebuf->ste_max_types) + j]));
205 }
206 printf("\n\n");
207 }
209 void acm_dump_policy_buffer(void *buf, int buflen)
210 {
211 struct acm_policy_buffer *pol = (struct acm_policy_buffer *) buf;
213 printf("\nPolicy dump:\n");
214 printf("============\n");
215 printf("PolicyVer = %x.\n", ntohl(pol->policy_version));
216 printf("Magic = %x.\n", ntohl(pol->magic));
217 printf("Len = %x.\n", ntohl(pol->len));
218 printf("Primary = %s (c=%x, off=%x).\n",
219 ACM_POLICY_NAME(ntohl(pol->primary_policy_code)),
220 ntohl(pol->primary_policy_code),
221 ntohl(pol->primary_buffer_offset));
222 printf("Secondary = %s (c=%x, off=%x).\n",
223 ACM_POLICY_NAME(ntohl(pol->secondary_policy_code)),
224 ntohl(pol->secondary_policy_code),
225 ntohl(pol->secondary_buffer_offset));
226 switch (ntohl(pol->primary_policy_code))
227 {
228 case ACM_CHINESE_WALL_POLICY:
229 acm_dump_chinesewall_buffer(buf +
230 ntohl(pol->primary_buffer_offset),
231 ntohl(pol->len) -
232 ntohl(pol->primary_buffer_offset));
233 break;
235 case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
236 acm_dump_ste_buffer(buf + ntohl(pol->primary_buffer_offset),
237 ntohl(pol->len) -
238 ntohl(pol->primary_buffer_offset));
239 break;
241 case ACM_NULL_POLICY:
242 printf("Primary policy is NULL Policy (n/a).\n");
243 break;
245 default:
246 printf("UNKNOWN POLICY!\n");
247 }
249 switch (ntohl(pol->secondary_policy_code))
250 {
251 case ACM_CHINESE_WALL_POLICY:
252 acm_dump_chinesewall_buffer(buf +
253 ntohl(pol->secondary_buffer_offset),
254 ntohl(pol->len) -
255 ntohl(pol->secondary_buffer_offset));
256 break;
258 case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
259 acm_dump_ste_buffer(buf + ntohl(pol->secondary_buffer_offset),
260 ntohl(pol->len) -
261 ntohl(pol->secondary_buffer_offset));
262 break;
264 case ACM_NULL_POLICY:
265 printf("Secondary policy is NULL Policy (n/a).\n");
266 break;
268 default:
269 printf("UNKNOWN POLICY!\n");
270 }
271 }
273 /*************************** set policy ****************************/
275 int acm_domain_set_chwallpolicy(void *bufstart, int buflen)
276 {
277 #define CWALL_MAX_SSIDREFS 6
278 #define CWALL_MAX_TYPES 10
279 #define CWALL_MAX_CONFLICTSETS 2
281 struct acm_chwall_policy_buffer *chwall_bin_pol =
282 (struct acm_chwall_policy_buffer *) bufstart;
283 domaintype_t *ssidrefs, *conflicts;
284 int ret = 0;
285 int j;
287 chwall_bin_pol->chwall_max_types = htonl(CWALL_MAX_TYPES);
288 chwall_bin_pol->chwall_max_ssidrefs = htonl(CWALL_MAX_SSIDREFS);
289 chwall_bin_pol->policy_code = htonl(ACM_CHINESE_WALL_POLICY);
290 chwall_bin_pol->policy_version = htonl(ACM_CHWALL_VERSION);
291 chwall_bin_pol->chwall_ssid_offset =
292 htonl(sizeof(struct acm_chwall_policy_buffer));
293 chwall_bin_pol->chwall_max_conflictsets =
294 htonl(CWALL_MAX_CONFLICTSETS);
295 chwall_bin_pol->chwall_conflict_sets_offset =
296 htonl(ntohl(chwall_bin_pol->chwall_ssid_offset) +
297 sizeof(domaintype_t) * CWALL_MAX_SSIDREFS * CWALL_MAX_TYPES);
298 chwall_bin_pol->chwall_running_types_offset = 0; /* not set */
299 chwall_bin_pol->chwall_conflict_aggregate_offset = 0; /* not set */
300 ret += sizeof(struct acm_chwall_policy_buffer);
301 /* now push example ssids into the buffer (max_ssidrefs x max_types entries) */
302 /* check buffer size */
303 if ((buflen - ret) <
304 (CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t)))
305 return -1; /* not enough space */
307 ssidrefs = (domaintype_t *) (bufstart +
308 ntohl(chwall_bin_pol->chwall_ssid_offset));
309 memset(ssidrefs, 0,
310 CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t));
312 /* now set type j-1 for ssidref i+1 */
313 for (j = 0; j <= CWALL_MAX_SSIDREFS; j++)
314 if ((0 < j) && (j <= CWALL_MAX_TYPES))
315 ssidrefs[j * CWALL_MAX_TYPES + j - 1] = htons(1);
317 ret += CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t);
318 if ((buflen - ret) <
319 (CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES * sizeof(domaintype_t)))
320 return -1; /* not enough space */
322 /* now the chinese wall policy conflict sets */
323 conflicts = (domaintype_t *) (bufstart +
324 ntohl(chwall_bin_pol->
325 chwall_conflict_sets_offset));
326 memset((void *) conflicts, 0,
327 CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES *
328 sizeof(domaintype_t));
329 /* just 1 conflict set [0]={2,3}, [1]={1,5,6} */
330 if (CWALL_MAX_TYPES > 3)
331 {
332 conflicts[2] = htons(1);
333 conflicts[3] = htons(1); /* {2,3} */
334 conflicts[CWALL_MAX_TYPES + 1] = htons(1);
335 conflicts[CWALL_MAX_TYPES + 5] = htons(1);
336 conflicts[CWALL_MAX_TYPES + 6] = htons(1); /* {0,5,6} */
337 }
338 ret += sizeof(domaintype_t) * CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES;
339 return ret;
340 }
342 int acm_domain_set_stepolicy(void *bufstart, int buflen)
343 {
344 #define STE_MAX_SSIDREFS 6
345 #define STE_MAX_TYPES 5
347 struct acm_ste_policy_buffer *ste_bin_pol =
348 (struct acm_ste_policy_buffer *) bufstart;
349 domaintype_t *ssidrefs;
350 int j, ret = 0;
352 ste_bin_pol->ste_max_types = htonl(STE_MAX_TYPES);
353 ste_bin_pol->ste_max_ssidrefs = htonl(STE_MAX_SSIDREFS);
354 ste_bin_pol->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
355 ste_bin_pol->policy_version = htonl(ACM_STE_VERSION);
356 ste_bin_pol->ste_ssid_offset =
357 htonl(sizeof(struct acm_ste_policy_buffer));
358 ret += sizeof(struct acm_ste_policy_buffer);
359 /* check buffer size */
360 if ((buflen - ret) <
361 (STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t)))
362 return -1; /* not enough space */
364 ssidrefs =
365 (domaintype_t *) (bufstart + ntohl(ste_bin_pol->ste_ssid_offset));
366 memset(ssidrefs, 0,
367 STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t));
368 /* all types 1 for ssidref 1 */
369 for (j = 0; j < STE_MAX_TYPES; j++)
370 ssidrefs[1 * STE_MAX_TYPES + j] = htons(1);
371 /* now set type j-1 for ssidref j */
372 for (j = 0; j < STE_MAX_SSIDREFS; j++)
373 if ((0 < j) && (j <= STE_MAX_TYPES))
374 ssidrefs[j * STE_MAX_TYPES + j - 1] = htons(1);
375 ret += STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t);
376 return ret;
377 }
379 #define MAX_PUSH_BUFFER 16384
380 u8 push_buffer[MAX_PUSH_BUFFER];
382 int acm_domain_setpolicy(int xc_handle)
383 {
384 int ret;
385 struct acm_policy_buffer *bin_pol;
386 acm_op_t op;
388 /* future: read policy from file and set it */
389 bin_pol = (struct acm_policy_buffer *) push_buffer;
390 bin_pol->policy_version = htonl(ACM_POLICY_VERSION);
391 bin_pol->magic = htonl(ACM_MAGIC);
392 bin_pol->primary_policy_code = htonl(ACM_CHINESE_WALL_POLICY);
393 bin_pol->secondary_policy_code =
394 htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
396 bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
397 bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
398 ret =
399 acm_domain_set_chwallpolicy(push_buffer +
400 ntohl(bin_pol->primary_buffer_offset),
401 MAX_PUSH_BUFFER -
402 ntohl(bin_pol->primary_buffer_offset));
403 if (ret < 0)
404 {
405 printf("ERROR creating chwallpolicy buffer.\n");
406 return -1;
407 }
408 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
409 bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
410 ret = acm_domain_set_stepolicy(push_buffer +
411 ntohl(bin_pol->secondary_buffer_offset),
412 MAX_PUSH_BUFFER -
413 ntohl(bin_pol->secondary_buffer_offset));
414 if (ret < 0)
415 {
416 printf("ERROR creating chwallpolicy buffer.\n");
417 return -1;
418 }
419 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
421 /* dump it and then push it down into xen/acm */
422 acm_dump_policy_buffer(push_buffer, ntohl(bin_pol->len));
424 op.cmd = ACM_SETPOLICY;
425 op.interface_version = ACM_INTERFACE_VERSION;
426 op.u.setpolicy.pushcache = (void *) push_buffer;
427 op.u.setpolicy.pushcache_size = ntohl(bin_pol->len);
428 ret = do_acm_op(xc_handle, &op);
430 if (ret)
431 printf("ERROR setting policy. Use 'xm dmesg' to see details.\n");
432 else
433 printf("Successfully changed policy.\n");
435 return ret;
436 }
438 /******************************* get policy ******************************/
440 #define PULL_CACHE_SIZE 8192
441 u8 pull_buffer[PULL_CACHE_SIZE];
442 int acm_domain_getpolicy(int xc_handle)
443 {
444 acm_op_t op;
445 int ret;
447 memset(pull_buffer, 0x00, sizeof(pull_buffer));
448 op.cmd = ACM_GETPOLICY;
449 op.interface_version = ACM_INTERFACE_VERSION;
450 op.u.getpolicy.pullcache = (void *) pull_buffer;
451 op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
452 ret = do_acm_op(xc_handle, &op);
453 /* dump policy */
454 acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
455 return ret;
456 }
458 /************************ load binary policy ******************************/
460 int acm_domain_loadpolicy(int xc_handle, const char *filename)
461 {
462 struct stat mystat;
463 int ret, fd;
464 off_t len;
465 u8 *buffer;
467 if ((ret = stat(filename, &mystat)))
468 {
469 printf("File %s not found.\n", filename);
470 goto out;
471 }
473 len = mystat.st_size;
474 if ((buffer = malloc(len)) == NULL)
475 {
476 ret = -ENOMEM;
477 goto out;
478 }
479 if ((fd = open(filename, O_RDONLY)) <= 0)
480 {
481 ret = -ENOENT;
482 printf("File %s not found.\n", filename);
483 goto free_out;
484 }
485 if (len == read(fd, buffer, len))
486 {
487 acm_op_t op;
488 /* dump it and then push it down into xen/acm */
489 acm_dump_policy_buffer(buffer, len);
490 op.cmd = ACM_SETPOLICY;
491 op.interface_version = ACM_INTERFACE_VERSION;
492 op.u.setpolicy.pushcache = (void *) buffer;
493 op.u.setpolicy.pushcache_size = len;
494 ret = do_acm_op(xc_handle, &op);
496 if (ret)
497 printf
498 ("ERROR setting policy. Use 'xm dmesg' to see details.\n");
499 else
500 printf("Successfully changed policy.\n");
502 } else {
503 ret = -1;
504 }
505 close(fd);
506 free_out:
507 free(buffer);
508 out:
509 return ret;
510 }
512 /************************ dump hook statistics ******************************/
513 void dump_ste_stats(struct acm_ste_stats_buffer *ste_stats)
514 {
515 printf("STE-Policy Security Hook Statistics:\n");
516 printf("ste: event_channel eval_count = %d\n",
517 ntohl(ste_stats->ec_eval_count));
518 printf("ste: event_channel denied_count = %d\n",
519 ntohl(ste_stats->ec_denied_count));
520 printf("ste: event_channel cache_hit_count = %d\n",
521 ntohl(ste_stats->ec_cachehit_count));
522 printf("ste:\n");
523 printf("ste: grant_table eval_count = %d\n",
524 ntohl(ste_stats->gt_eval_count));
525 printf("ste: grant_table denied_count = %d\n",
526 ntohl(ste_stats->gt_denied_count));
527 printf("ste: grant_table cache_hit_count = %d\n",
528 ntohl(ste_stats->gt_cachehit_count));
529 }
531 #define PULL_STATS_SIZE 8192
532 int acm_domain_dumpstats(int xc_handle)
533 {
534 u8 stats_buffer[PULL_STATS_SIZE];
535 acm_op_t op;
536 int ret;
537 struct acm_stats_buffer *stats;
539 memset(stats_buffer, 0x00, sizeof(stats_buffer));
540 op.cmd = ACM_DUMPSTATS;
541 op.interface_version = ACM_INTERFACE_VERSION;
542 op.u.dumpstats.pullcache = (void *) stats_buffer;
543 op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
544 ret = do_acm_op(xc_handle, &op);
546 if (ret < 0)
547 {
548 printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n");
549 return ret;
550 }
551 stats = (struct acm_stats_buffer *) stats_buffer;
553 printf("\nPolicy dump:\n");
554 printf("============\n");
555 printf("Magic = %x.\n", ntohl(stats->magic));
556 printf("Len = %x.\n", ntohl(stats->len));
558 switch (ntohl(stats->primary_policy_code))
559 {
560 case ACM_NULL_POLICY:
561 printf("NULL Policy: No statistics apply.\n");
562 break;
564 case ACM_CHINESE_WALL_POLICY:
565 printf("Chinese Wall Policy: No statistics apply.\n");
566 break;
568 case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
569 dump_ste_stats((struct acm_ste_stats_buffer *) (stats_buffer +
570 ntohl(stats->
571 primary_stats_offset)));
572 break;
574 default:
575 printf("UNKNOWN PRIMARY POLICY ERROR!\n");
576 }
578 switch (ntohl(stats->secondary_policy_code))
579 {
580 case ACM_NULL_POLICY:
581 printf("NULL Policy: No statistics apply.\n");
582 break;
584 case ACM_CHINESE_WALL_POLICY:
585 printf("Chinese Wall Policy: No statistics apply.\n");
586 break;
588 case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
589 dump_ste_stats((struct acm_ste_stats_buffer *) (stats_buffer +
590 ntohl(stats->
591 secondary_stats_offset)));
592 break;
594 default:
595 printf("UNKNOWN SECONDARY POLICY ERROR!\n");
596 }
597 return ret;
598 }
600 /***************************** main **************************************/
602 void usage(char *progname)
603 {
604 printf("Use: %s \n"
605 "\t setpolicy\n"
606 "\t getpolicy\n"
607 "\t dumpstats\n"
608 "\t loadpolicy <binary policy file>\n", progname);
609 exit(-1);
610 }
612 int main(int argc, char **argv)
613 {
615 int acm_cmd_fd, ret = 0;
617 if (argc < 2)
618 usage(argv[0]);
620 if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0)
621 {
622 printf("ERROR: Could not open xen privcmd device!\n");
623 exit(-1);
624 }
626 if (!strcmp(argv[1], "setpolicy"))
627 {
628 if (argc != 2)
629 usage(argv[0]);
630 ret = acm_domain_setpolicy(acm_cmd_fd);
631 } else if (!strcmp(argv[1], "getpolicy")) {
632 if (argc != 2)
633 usage(argv[0]);
634 ret = acm_domain_getpolicy(acm_cmd_fd);
635 } else if (!strcmp(argv[1], "loadpolicy")) {
636 if (argc != 3)
637 usage(argv[0]);
638 ret = acm_domain_loadpolicy(acm_cmd_fd, argv[2]);
639 } else if (!strcmp(argv[1], "dumpstats")) {
640 if (argc != 2)
641 usage(argv[0]);
642 ret = acm_domain_dumpstats(acm_cmd_fd);
643 } else
644 usage(argv[0]);
646 close(acm_cmd_fd);
647 return ret;
648 }