debuggers.hg

view tools/python/xen/xm/addlabel.py @ 16559:5255eac35270

Implement legacy XML-RPC interface for ACM commands.

This patch implements a (non Xen-API) legacy XML-RPC interface for the
ACM commands and funnels the calls into code introduced by the Xen-API
support for ACM security management. Since some of the functionality
has changed, also the xm applications have changed. In particular the
following old commands have been removed along with some tools the
have become obsolete now:

- loadpolicy (included in: setpolicy)
- makepolicy (included in: setpolicy)
- cfgbootpolicy (included in: setpolicy)

and the following commands been introduced:

- setpolicy
- getpolicy
- resetpolicy

All tools have been adapted to work in Xen-API and legacy XML-RPC
mode. Both modes support the same functionality.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Dec 05 09:44:20 2007 +0000 (2007-12-05)
parents ceb195042ca7
children 94c6501c4ffe
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2006 International Business Machines Corp.
16 # Author: Reiner Sailer <sailer@us.ibm.com>
17 # Author: Bryan D. Payne <bdpayne@us.ibm.com>
18 #============================================================================
20 """Labeling a domain configuration file or a resource.
21 """
22 import os
23 import sys
25 import xen.util.xsm.xsm as security
26 from xen.xm.opts import OptionError
27 from xen.util import xsconstants
28 from xen.xm import main as xm_main
29 from xen.xm.main import server
31 def help():
32 return """
33 Format: xm addlabel <label> dom <configfile> [<policy>]
34 xm addlabel <label> mgt <domain name> [<policy type>:<policy>]
35 xm addlabel <label> res <resource> [[<policy type>:]<policy>]
36 xm addlabel <label> vif-<idx> <domain name> [<policy type>:<policy>]
38 This program adds an acm_label entry into the 'configfile'
39 for a domain, allows to label a xend-managed domain, resources
40 of the VIF of a mangaged domain (requires xm to be used in
41 Xen-API mode).
43 For xend-managed domains, the 'mgt' parameter should be used and
44 the 'xm' tool must have been configured to use the xen-npi for
45 communication with xen. If a policy is provided as last parameter,
46 its type must also be given. Currently only one type of policy is
47 supported and identified as 'ACM'. An example for a valid string
48 is 'ACM:xm-test'. """
51 def validate_config_file(configfile):
52 """Performs a simple sanity check on the configuration file passed on
53 the command line. We basically just want to make sure that it's
54 not a domain image file so we check for a few configuration values
55 and then we are satisfied. Returned 1 on success, otherwise 0.
56 """
57 # read in the config file
58 globs = {}
59 locs = {}
60 try:
61 execfile(configfile, globs, locs)
62 except:
63 print "Invalid configuration file."
64 return 0
66 # sanity check on the data from the file
67 count = 0
68 required = ['kernel', 'memory', 'name']
69 for (k, v) in locs.items():
70 if k in required:
71 count += 1
72 if count != 3:
73 print "Invalid configuration file."
74 return 0
75 else:
76 return 1
79 def add_resource_label(label, resource, policyref, policy_type):
80 """Adds a resource label to the global resource label file.
81 """
83 if xm_main.serverType != xm_main.SERVER_XEN_API:
84 old = server.xend.security.get_resource_label(resource)
85 if len(old) == 0:
86 try:
87 rc = server.xend.security.set_resource_label(resource,
88 policy_type,
89 policyref,
90 label)
91 except Exception, e:
92 raise
93 if rc != xsconstants.XSERR_SUCCESS:
94 security.err("An error occurred labeling the resource: %s" % \
95 xsconstants.xserr2string(-rc))
96 else:
97 old = security.format_resource_label(old)
98 security.err("'%s' is already labeled with '%s'." % \
99 (resource,old))
100 else:
101 res = [ policy_type, policyref, label ]
102 res_xapi = security.format_resource_label(res)
103 old = server.xenapi.XSPolicy.get_resource_label(resource)
104 if old == "":
105 try:
106 server.xenapi.XSPolicy.set_resource_label(resource,
107 res_xapi,
108 "")
109 except Exception, e:
110 raise security.XSMError("Could not label this resource: %s" %
111 str(e))
112 else:
113 raise security.XSMError("'%s' is already labeled with '%s'" %
114 (resource,old))
116 def add_domain_label(label, configfile, policyref):
117 # sanity checks: make sure this label can be instantiated later on
118 ssidref = security.label2ssidref(label, policyref, 'dom')
120 new_label = "access_control = ['policy=%s,label=%s']\n" % \
121 (policyref, label)
122 if not os.path.isfile(configfile):
123 security.err("Configuration file \'" + configfile + "\' not found.")
124 config_fd = open(configfile, "ra+")
125 for line in config_fd:
126 if not security.access_control_re.match(line):
127 continue
128 config_fd.close()
129 security.err("Config file \'" + configfile + "\' is already labeled.")
130 config_fd.write(new_label)
131 config_fd.close()
133 def add_domain_label_xapi(label, domainname, policyref, policy_type):
134 sec_lab = "%s:%s:%s" % (policy_type, policyref, label)
135 if xm_main.serverType != xm_main.SERVER_XEN_API:
136 old_seclab = server.xend.security.get_domain_label(domainname)
137 if old_seclab[0] == '\'':
138 old_seclab = old_seclab[1:]
139 results = server.xend.security.set_domain_label(domainname,
140 sec_lab,
141 old_seclab)
142 rc, ssidref = results
143 if rc == xsconstants.XSERR_SUCCESS:
144 if ssidref != 0:
145 print "Successfully set the label of domain '%s' to '%s'.\n" \
146 % (domainname,label)
147 else:
148 print "Successfully set the label of the dormant domain " \
149 "'%s' to '%s'." % (domainname,label)
150 else:
151 msg = xsconstants.xserr2string(-rc)
152 raise security.XSMError("An error occurred relabeling "
153 "the domain: %s" % msg)
154 else:
155 uuids = server.xenapi.VM.get_by_name_label(domainname)
156 if len(uuids) == 0:
157 raise OptionError('A VM with that name does not exist.')
158 if len(uuids) != 1:
159 raise OptionError('There are multiple domains with the same name.')
160 uuid = uuids[0]
161 try:
162 old_lab = server.xenapi.VM.get_security_label(uuid)
163 rc = server.xenapi.VM.set_security_label(uuid, sec_lab, old_lab)
164 except Exception, e:
165 raise security.XSMError("Could not label the domain: %s" % e)
166 if int(rc) < 0:
167 raise OptionError('Could not label domain.')
168 else:
169 ssidref = int(rc)
170 if ssidref != 0:
171 print "Successfully set the label of domain '%s' to '%s'.\n" \
172 % (domainname,label)
173 else:
174 print "Successfully set the label of the dormant domain " \
175 "'%s' to '%s'." % (domainname,label)
177 def add_vif_label(label, vmname, idx, policyref, policy_type):
178 if xm_main.serverType != xm_main.SERVER_XEN_API:
179 raise OptionError('Need to be configure for using xen-api.')
180 vm_refs = server.xenapi.VM.get_by_name_label(vmname)
181 if len(vm_refs) == 0:
182 raise OptionError('A VM with the name %s does not exist.' %
183 vmname)
184 vif_refs = server.xenapi.VM.get_VIFs(vm_refs[0])
185 if len(vif_refs) <= idx:
186 raise OptionError("Bad VIF index.")
187 vif_ref = server.xenapi.VIF.get_by_uuid(vif_refs[idx])
188 if not vif_ref:
189 print "Internal error: VIF does not exist."
190 sec_lab = "%s:%s:%s" % (policy_type, policyref, label)
191 try:
192 old_lab = server.xenapi.VIF.get_security_label(vif_ref)
193 rc = server.xenapi.VIF.set_security_label(vif_ref,
194 sec_lab, old_lab)
195 if int(rc) != 0:
196 print "Could not label the VIF."
197 else:
198 print "Successfully labeled the VIF."
199 except Exception, e:
200 print "Could not label the VIF: %s" % str(e)
203 def main(argv):
204 policyref = None
205 policy_type = ""
206 if len(argv) not in (4, 5):
207 raise OptionError('Needs either 2 or 3 arguments')
209 label = argv[1]
211 if len(argv) == 5:
212 policyref = argv[4]
213 elif security.on():
214 policyref = security.active_policy
215 policy_type = xsconstants.ACM_POLICY_ID
216 else:
217 raise OptionError("No active policy. Must specify policy on the "
218 "command line.")
220 if argv[2].lower() == "dom":
221 configfile = argv[3]
222 if configfile[0] != '/':
223 for prefix in [os.path.realpath(os.path.curdir), "/etc/xen"]:
224 configfile = prefix + "/" + configfile
225 if os.path.isfile(configfile):
226 break
227 if not validate_config_file(configfile):
228 raise OptionError('Invalid config file')
229 else:
230 add_domain_label(label, configfile, policyref)
231 elif argv[2].lower() == "mgt":
232 domain = argv[3]
233 if policy_type == "":
234 tmp = policyref.split(":")
235 if len(tmp) != 2:
236 raise OptionError("Policy name in wrong format.")
237 policy_type, policyref = tmp
238 add_domain_label_xapi(label, domain, policyref, policy_type)
239 elif argv[2].lower() == "res":
240 resource = argv[3]
241 if policy_type == "":
242 tmp = policyref.split(":")
243 if len(tmp) == 1:
244 policy_type = xsconstants.ACM_POLICY_ID
245 elif len(tmp) == 2:
246 policy_type, policyref = tmp
247 else:
248 raise OptionError("Policy name in wrong format.")
249 add_resource_label(label, resource, policyref, policy_type)
250 elif argv[2].lower().startswith("vif-"):
251 try:
252 idx = int(argv[2][4:])
253 if idx < 0:
254 raise
255 except:
256 raise OptionError("Bad VIF device index.")
257 vmname = argv[3]
258 if policy_type == "":
259 tmp = policyref.split(":")
260 if len(tmp) != 2:
261 raise OptionError("Policy name in wrong format.")
262 policy_type, policyref = tmp
263 add_vif_label(label, vmname, idx, policyref, policy_type)
264 else:
265 raise OptionError('Need to specify either "dom", "mgt" or "res" as '
266 'object to add label to.')
268 if __name__ == '__main__':
269 try:
270 main(sys.argv)
271 except Exception, e:
272 sys.stderr.write('Error: %s\n' % str(e))
273 sys.exit(-1)