ia64/xen-unstable

view tools/python/xen/xm/addlabel.py @ 18843:abada55aec43

xm: Relax the sanity check on guest configuration with XSM-ACM addlabel

The attached patch relaxes the sanity check on guest configuration
when assigning a acm label to the guest. This patch makes a guest
configuration accept a bootloader parameter. This is common for
paravirtualized guests to boot them by using pygrub.

Signed-off-by: INAKOSHI Hiroya <inakoshi.hiroya@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Nov 28 13:04:30 2008 +0000 (2008-11-28)
parents 94c6501c4ffe
children 23f9857f642f
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 # requiring 'memory,' 'name,' and ether 'kernel' or 'bootloader'
68 count = 0
69 required = ['kernel', 'bootloader', 'memory', 'name']
70 for (k, v) in locs.items():
71 if k in required:
72 count += 1
73 if count < len(required) - 1:
74 print "Invalid configuration file."
75 return 0
76 else:
77 return 1
80 def add_resource_label(label, resource, policyref, policy_type):
81 """Adds a resource label to the global resource label file.
82 """
84 if xm_main.serverType != xm_main.SERVER_XEN_API:
85 old = server.xend.security.get_resource_label(resource)
86 if len(old) == 0:
87 try:
88 rc = server.xend.security.set_resource_label(resource,
89 policy_type,
90 policyref,
91 label)
92 except Exception, e:
93 raise
94 if rc != xsconstants.XSERR_SUCCESS:
95 security.err("An error occurred labeling the resource: %s" % \
96 xsconstants.xserr2string(-rc))
97 else:
98 old = security.format_resource_label(old)
99 security.err("'%s' is already labeled with '%s'." % \
100 (resource,old))
101 else:
102 res = [ policy_type, policyref, label ]
103 res_xapi = security.format_resource_label(res)
104 old = server.xenapi.XSPolicy.get_resource_label(resource)
105 if old == "":
106 try:
107 server.xenapi.XSPolicy.set_resource_label(resource,
108 res_xapi,
109 "")
110 except Exception, e:
111 raise security.XSMError("Could not label this resource: %s" %
112 str(e))
113 else:
114 raise security.XSMError("'%s' is already labeled with '%s'" %
115 (resource,old))
117 def add_domain_label(label, configfile, policyref):
118 # sanity checks: make sure this label can be instantiated later on
119 ssidref = security.label2ssidref(label, policyref, 'dom')
121 new_label = "access_control = ['policy=%s,label=%s']\n" % \
122 (policyref, label)
123 if not os.path.isfile(configfile):
124 security.err("Configuration file \'" + configfile + "\' not found.")
125 config_fd = open(configfile, "ra+")
126 for line in config_fd:
127 if not security.access_control_re.match(line):
128 continue
129 config_fd.close()
130 security.err("Config file \'" + configfile + "\' is already labeled.")
131 config_fd.write(new_label)
132 config_fd.close()
134 def add_domain_label_xapi(label, domainname, policyref, policy_type):
135 sec_lab = "%s:%s:%s" % (policy_type, policyref, label)
136 if xm_main.serverType != xm_main.SERVER_XEN_API:
137 old_seclab = server.xend.security.get_domain_label(domainname)
138 if old_seclab[0] == '\'':
139 old_seclab = old_seclab[1:]
140 results = server.xend.security.set_domain_label(domainname,
141 sec_lab,
142 old_seclab)
143 rc, ssidref = results
144 if rc == xsconstants.XSERR_SUCCESS:
145 if ssidref != 0:
146 print "Successfully set the label of domain '%s' to '%s'.\n" \
147 % (domainname,label)
148 else:
149 print "Successfully set the label of the dormant domain " \
150 "'%s' to '%s'." % (domainname,label)
151 else:
152 msg = xsconstants.xserr2string(-rc)
153 raise security.XSMError("An error occurred relabeling "
154 "the domain: %s" % msg)
155 else:
156 uuids = server.xenapi.VM.get_by_name_label(domainname)
157 if len(uuids) == 0:
158 raise OptionError('A VM with that name does not exist.')
159 if len(uuids) != 1:
160 raise OptionError('There are multiple domains with the same name.')
161 uuid = uuids[0]
162 try:
163 old_lab = server.xenapi.VM.get_security_label(uuid)
164 rc = server.xenapi.VM.set_security_label(uuid, sec_lab, old_lab)
165 except Exception, e:
166 raise security.XSMError("Could not label the domain: %s" % e)
167 if int(rc) < 0:
168 raise OptionError('Could not label domain.')
169 else:
170 ssidref = int(rc)
171 if ssidref != 0:
172 print "Successfully set the label of domain '%s' to '%s'.\n" \
173 % (domainname,label)
174 else:
175 print "Successfully set the label of the dormant domain " \
176 "'%s' to '%s'." % (domainname,label)
178 def add_vif_label(label, vmname, idx, policyref, policy_type):
179 if xm_main.serverType != xm_main.SERVER_XEN_API:
180 raise OptionError('Need to be configure for using xen-api.')
181 vm_refs = server.xenapi.VM.get_by_name_label(vmname)
182 if len(vm_refs) == 0:
183 raise OptionError('A VM with the name %s does not exist.' %
184 vmname)
185 vif_refs = server.xenapi.VM.get_VIFs(vm_refs[0])
186 if len(vif_refs) <= idx:
187 raise OptionError("Bad VIF index.")
188 vif_ref = server.xenapi.VIF.get_by_uuid(vif_refs[idx])
189 if not vif_ref:
190 print "Internal error: VIF does not exist."
191 sec_lab = "%s:%s:%s" % (policy_type, policyref, label)
192 try:
193 old_lab = server.xenapi.VIF.get_security_label(vif_ref)
194 rc = server.xenapi.VIF.set_security_label(vif_ref,
195 sec_lab, old_lab)
196 if int(rc) != 0:
197 print "Could not label the VIF."
198 else:
199 print "Successfully labeled the VIF."
200 except Exception, e:
201 print "Could not label the VIF: %s" % str(e)
204 def main(argv):
205 policyref = None
206 policy_type = ""
207 if len(argv) not in (4, 5):
208 raise OptionError('Needs either 2 or 3 arguments')
210 label = argv[1]
212 if len(argv) == 5:
213 policyref = argv[4]
214 elif security.on() == xsconstants.XS_POLICY_ACM:
215 policyref = security.active_policy
216 policy_type = xsconstants.ACM_POLICY_ID
217 else:
218 raise OptionError("ACM security is not enabled. You must specify "\
219 "the policy on the command line.")
221 if argv[2].lower() == "dom":
222 configfile = argv[3]
223 if configfile[0] != '/':
224 for prefix in [os.path.realpath(os.path.curdir), "/etc/xen"]:
225 configfile = prefix + "/" + configfile
226 if os.path.isfile(configfile):
227 break
228 if not validate_config_file(configfile):
229 raise OptionError('Invalid config file')
230 else:
231 add_domain_label(label, configfile, policyref)
232 elif argv[2].lower() == "mgt":
233 domain = argv[3]
234 if policy_type == "":
235 tmp = policyref.split(":")
236 if len(tmp) != 2:
237 raise OptionError("Policy name in wrong format.")
238 policy_type, policyref = tmp
239 add_domain_label_xapi(label, domain, policyref, policy_type)
240 elif argv[2].lower() == "res":
241 resource = argv[3]
242 if policy_type == "":
243 tmp = policyref.split(":")
244 if len(tmp) == 1:
245 policy_type = xsconstants.ACM_POLICY_ID
246 elif len(tmp) == 2:
247 policy_type, policyref = tmp
248 else:
249 raise OptionError("Policy name in wrong format.")
250 add_resource_label(label, resource, policyref, policy_type)
251 elif argv[2].lower().startswith("vif-"):
252 try:
253 idx = int(argv[2][4:])
254 if idx < 0:
255 raise
256 except:
257 raise OptionError("Bad VIF device index.")
258 vmname = argv[3]
259 if policy_type == "":
260 tmp = policyref.split(":")
261 if len(tmp) != 2:
262 raise OptionError("Policy name in wrong format.")
263 policy_type, policyref = tmp
264 add_vif_label(label, vmname, idx, policyref, policy_type)
265 else:
266 raise OptionError('Need to specify either "dom", "mgt" or "res" as '
267 'object to add label to.')
269 if __name__ == '__main__':
270 try:
271 main(sys.argv)
272 except Exception, e:
273 sys.stderr.write('Error: %s\n' % str(e))
274 sys.exit(-1)