diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2006-10-20 09:32:16 +0100 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2006-10-20 09:32:16 +0100 |
commit | a75c9af600f0f92d882477dc33c8a5fbe225d37c (patch) | |
tree | efbcdbf3ea8e9aac5b74d574201e0b24ab2e90e8 | |
parent | b039222b0b5e53e8b402a58a9165a7e9ff4f27ff (diff) | |
download | xen-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.1 | 4 | ||||
-rw-r--r-- | tools/python/xen/util/security.py | 1 | ||||
-rw-r--r-- | tools/python/xen/xm/cfgbootpolicy.py | 132 |
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) - |