aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-10-20 09:32:16 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-10-20 09:32:16 +0100
commita75c9af600f0f92d882477dc33c8a5fbe225d37c (patch)
treeefbcdbf3ea8e9aac5b74d574201e0b24ab2e90e8
parentb039222b0b5e53e8b402a58a9165a7e9ff4f27ff (diff)
downloadxen-a75c9af600f0f92d882477dc33c8a5fbe225d37c.tar.gz
xen-a75c9af600f0f92d882477dc33c8a5fbe225d37c.tar.bz2
xen-a75c9af600f0f92d882477dc33c8a5fbe225d37c.zip
Use the name of the title of the system to boot into (instead of the
kernel version) to determine where to make the entry into the grub configuration file. Signed-off-by: Reiner Sailer <sailer@us.ibm.com> Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
-rw-r--r--docs/man/xm.pod.14
-rw-r--r--tools/python/xen/util/security.py1
-rw-r--r--tools/python/xen/xm/cfgbootpolicy.py132
3 files changed, 72 insertions, 65 deletions
diff --git a/docs/man/xm.pod.1 b/docs/man/xm.pod.1
index e7dbbb90f6..b0ba7f8fb2 100644
--- a/docs/man/xm.pod.1
+++ b/docs/man/xm.pod.1
@@ -810,13 +810,13 @@ global policy root directory.
Loads the binary representation of the I<policy> into Xen. The binary
representation can be created with the B<makepolicy> subcommand.
-=item B<cfgbootpolicy> I<policy> [I<kernelversion>]
+=item B<cfgbootpolicy> I<policy> [I<boot title>]
Configures I<policy> as the boot policy for Xen. It copies the binary
policy representation into the /boot directory and adds a module line
specifying the binary policy to the /boot/grub/menu.lst file. If your
boot configuration includes multiple Xen boot titles, then use the
-I<kernelversion> parameter to select the proper title.
+I<boot title> parameter to specify a unique part of the proper title.
=item B<dumppolicy>
diff --git a/tools/python/xen/util/security.py b/tools/python/xen/util/security.py
index 0b23303e53..e617ddf894 100644
--- a/tools/python/xen/util/security.py
+++ b/tools/python/xen/util/security.py
@@ -31,6 +31,7 @@ from xen.util import dictio
policy_dir_prefix = "/etc/xen/acm-security/policies"
res_label_filename = policy_dir_prefix + "/resource_labels"
boot_filename = "/boot/grub/menu.lst"
+altboot_filename = "/boot/grub/grub.conf"
xensec_xml2bin = "/usr/sbin/xensec_xml2bin"
xensec_tool = "/usr/sbin/xensec_tool"
diff --git a/tools/python/xen/xm/cfgbootpolicy.py b/tools/python/xen/xm/cfgbootpolicy.py
index 5cb8e83793..c7043dfbc5 100644
--- a/tools/python/xen/xm/cfgbootpolicy.py
+++ b/tools/python/xen/xm/cfgbootpolicy.py
@@ -14,6 +14,7 @@
#============================================================================
# Copyright (C) 2006 International Business Machines Corp.
# Author: Reiner Sailer <sailer@us.ibm.com>
+# Contributions: Stefan Berger <stefanb@us.ibm.com>
#============================================================================
"""Configuring a security policy into the boot configuration
"""
@@ -24,67 +25,60 @@ import tempfile
import os, stat
import shutil
import string
-from xen.util.security import ACMError, err
-from xen.util.security import policy_dir_prefix, boot_filename, xen_title_re
-from xen.util.security import any_title_re, xen_kernel_re, kernel_ver_re, any_module_re
+import re
+from xen.util.security import err
+from xen.util.security import policy_dir_prefix, xen_title_re
+from xen.util.security import boot_filename, altboot_filename
+from xen.util.security import any_title_re, xen_kernel_re, any_module_re
from xen.util.security import empty_line_re, binary_name_re, policy_name_re
from xen.xm.opts import OptionError
def help():
return """
- Adds a 'module' line to the Xen grub.conf entry
- so that xen boots into a specific access control
- policy. If kernelversion is not given, then this
- script tries to determine it by looking for a grub
- entry with a line kernel xen.* If there are multiple
- Xen entries, then it must be called with an explicit
- version (it will fail otherwise).\n"""
+ Adds a 'module' line to the Xen grub configuration file entry
+ so that Xen boots with a specific access control policy. If
+ kernelversion is not given, then this script tries to determine
+ it by looking for a title starting with \"XEN\". If there are
+ multiple entries matching, then it must be called with the unique
+ beginning of the title's name.\n"""
-def determine_kernelversion(user_specified):
- within_xen_title = 0
- within_xen_entry = 0
- version_list = []
- guess_version = None
-
- grub_fd = open(boot_filename)
- for line in grub_fd:
- if xen_title_re.match(line):
- within_xen_title = 1
- elif within_xen_title and xen_kernel_re.match(line):
- within_xen_entry = 1
- elif within_xen_title and within_xen_entry and kernel_ver_re.match(line):
- for i in line.split():
- if (i.find("vmlinuz-") >= 0):
- # skip start until "vmlinuz-"
- guess_version = i[i.find("vmlinuz-") + len("vmlinuz-"):]
- if user_specified:
- if (guess_version == user_specified):
- version_list.append(guess_version)
- else:
- version_list.append(guess_version)
- elif len(line.split()) > 0:
- if line.split()[0] == "title":
- within_xen_title = 0
- within_xen_entry = 0
- if len(version_list) > 1:
- err("Cannot decide between entries for kernels %s" % version_list)
- elif len(version_list) == 0:
- err("Cannot find a boot entry candidate (please create a Xen boot entry first).")
+def strip_title(line):
+ """
+ strips whitespace left and right and cuts 'title'
+ """
+ s_title = string.strip(line)
+ pos = string.index(s_title, "title")
+ if pos >= 0:
+ return s_title[pos+6:]
else:
- return version_list[0]
-
+ return s_title
-def insert_policy(boot_file, kernel_version, policy_name):
+def insert_policy(boot_file, alt_boot_file, user_title, policy_name):
"""
inserts policy binary file as last line of the grub entry
matching the kernel_version version
"""
+ if user_title:
+ #replace "(" by "\(" and ")" by "\)" for matching
+ user_title = string.replace(user_title, "(", "\(")
+ user_title = string.replace(user_title, ")", "\)")
+ user_title_re = re.compile("\s*title\s+.*%s" \
+ % user_title, re.IGNORECASE)
+ else:
+ user_title_re = xen_title_re
+
within_xen_title = 0
within_xen_entry = 0
insert_at_end_of_entry = 0
path_prefix = ''
+ this_title = ''
+ extended_titles = []
(tmp_fd, tmp_grub) = tempfile.mkstemp()
+ #First check whether menu.lst exists
+ if not os.path.isfile(boot_file):
+ #take alternate boot file (grub.conf) instead
+ boot_file = alt_boot_file
#follow symlink since menue.lst might be linked to grub.conf
if stat.S_ISLNK(os.lstat(boot_file)[stat.ST_MODE]):
new_name = os.readlink(boot_file)
@@ -95,30 +89,33 @@ def insert_policy(boot_file, kernel_version, policy_name):
path[len(path)-1] = new_name
boot_file = '/'.join(path)
if not os.path.exists(boot_file):
- err("Boot file \'" + boot_file + "\' not found.")
+ err("Boot file \'%s\' not found." % boot_file)
grub_fd = open(boot_file)
for line in grub_fd:
- if xen_title_re.match(line):
+ if user_title_re.match(line):
+ this_title = strip_title(line)
within_xen_title = 1
elif within_xen_title and xen_kernel_re.match(line):
- within_xen_entry = 1
- elif within_xen_title and within_xen_entry and kernel_ver_re.match(line):
- for i in line.split():
- if (i.find("vmlinuz-") >= 0):
- if kernel_version == i[i.find("vmlinuz-") + len("vmlinuz-"):]:
- insert_at_end_of_entry = 1
- path_prefix = i[0:i.find("vmlinuz-")]
+ insert_at_end_of_entry = 1
+ #use prefix from xen.gz path for policy
+ path_prefix = line.split()[1]
+ idx = path_prefix.rfind('/')
+ if idx >= 0:
+ path_prefix = path_prefix[0:idx+1]
+ else:
+ path_prefix = ''
elif any_module_re.match(line) and insert_at_end_of_entry:
if binary_name_re.match(line):
#delete existing policy module line
line=''
elif any_title_re.match(line):
within_xen_title = 0
- within_xen_entry = 0
- if (empty_line_re.match(line) or any_title_re.match(line)) and insert_at_end_of_entry:
+ if (empty_line_re.match(line) or any_title_re.match(line)) and \
+ insert_at_end_of_entry:
#newline or new title: we insert the policy module line here
os.write(tmp_fd, "\tmodule " + path_prefix + policy_name + ".bin\n")
+ extended_titles.append(this_title)
insert_at_end_of_entry = 0
#write the line that was read (except potential existing policy entry)
os.write(tmp_fd, line)
@@ -126,27 +123,36 @@ def insert_policy(boot_file, kernel_version, policy_name):
if insert_at_end_of_entry:
#last entry, no empty line at end of file
os.write(tmp_fd, "\tmodule " + path_prefix + policy_name + ".bin\n")
+ extended_titles.append(this_title)
+
+ #if more than one entry was changed, abort
+ if len(extended_titles) > 1:
+ err("Following boot entries matched: %s. \nPlease specify "
+ "unique part of the boot title." % extended_titles)
+ if len(extended_titles) == 0:
+ err("Boot entry not found. Please specify unique part "
+ "of the boot title.")
- #temp file might be destroyed when closing it, first copy ...
+ #temp file might be destroyed when closing it, first copy it
shutil.move(boot_file, boot_file+"_save")
shutil.copyfile(tmp_grub, boot_file)
os.close(tmp_fd)
- #temp file did not disappear on my system ...
+ #sometimes the temp file does not disappear
try:
os.remove(tmp_grub)
except:
pass
-
+ return extended_titles[0]
def main(argv):
user_kver = None
- policy = None
+ user_title = None
if len(argv) == 2:
policy = argv[1]
elif len(argv) == 3:
policy = argv[1]
- user_kver = argv[2]
+ user_title = argv[2]
else:
raise OptionError('Invalid number of arguments')
@@ -167,9 +173,10 @@ def main(argv):
dst_binary_policy_file = "/boot/" + policy + ".bin"
shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
- kernel_version = determine_kernelversion(user_kver)
- insert_policy(boot_filename, kernel_version, policy)
- print "Boot entry created and \'%s\' copied to /boot" % (policy + ".bin")
+ entryname = insert_policy(boot_filename, altboot_filename,
+ user_title, policy)
+ print "Boot entry '%s' extended and \'%s\' copied to /boot" \
+ % (entryname, policy + ".bin")
if __name__ == '__main__':
try:
@@ -177,4 +184,3 @@ if __name__ == '__main__':
except Exception, e:
sys.stderr.write('Error: ' + str(e) + '\n')
sys.exit(-1)
-