ia64/xen-unstable

view tools/python/xen/xm/addlabel.py @ 17578:94c6501c4ffe

xend: Refactor security.on() call

I am refactoring the security.on() call to return the actual type of
the security module that is found to be enabled rather than just
returning True or False.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue May 06 10:05:52 2008 +0100 (2008-05-06)
parents 5255eac35270
children abada55aec43
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() == xsconstants.XS_POLICY_ACM:
214 policyref = security.active_policy
215 policy_type = xsconstants.ACM_POLICY_ID
216 else:
217 raise OptionError("ACM security is not enabled. You must specify "\
218 "the policy on the 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)