Import the Xend portion of xen-unstable changeset

11839:328606e0705f0341bebda14cdd17962e463868e8.

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>
This commit is contained in:
Ewan Mellor committed 2006-10-20 09:32:16 +01:00
1 parent f652cfbe00
commit a81b06e66a
2 files changed
+70 -63

No files matched your search

+1
View File
@@ -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"
+69 -63
View File
@@ -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)
#temp file might be destroyed when closing it, first copy ...
#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 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)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.