ia64/xen-unstable

changeset 12190:f3be4922cc8b

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>
author Ewan Mellor <ewan@xensource.com>
date Fri Oct 20 09:32:16 2006 +0100 (2006-10-20)
parents cc6f0a3596fc
children 4441715c9a67
files tools/python/xen/util/security.py tools/python/xen/xm/cfgbootpolicy.py
line diff
     1.1 --- a/tools/python/xen/util/security.py	Sat Oct 28 17:58:00 2006 +0100
     1.2 +++ b/tools/python/xen/util/security.py	Fri Oct 20 09:32:16 2006 +0100
     1.3 @@ -31,6 +31,7 @@ from xen.util import dictio
     1.4  policy_dir_prefix = "/etc/xen/acm-security/policies"
     1.5  res_label_filename = policy_dir_prefix + "/resource_labels"
     1.6  boot_filename = "/boot/grub/menu.lst"
     1.7 +altboot_filename = "/boot/grub/grub.conf"
     1.8  xensec_xml2bin = "/usr/sbin/xensec_xml2bin"
     1.9  xensec_tool = "/usr/sbin/xensec_tool"
    1.10  
     2.1 --- a/tools/python/xen/xm/cfgbootpolicy.py	Sat Oct 28 17:58:00 2006 +0100
     2.2 +++ b/tools/python/xen/xm/cfgbootpolicy.py	Fri Oct 20 09:32:16 2006 +0100
     2.3 @@ -14,6 +14,7 @@
     2.4  #============================================================================
     2.5  # Copyright (C) 2006 International Business Machines Corp.
     2.6  # Author: Reiner Sailer <sailer@us.ibm.com>
     2.7 +# Contributions: Stefan Berger <stefanb@us.ibm.com>
     2.8  #============================================================================
     2.9  """Configuring a security policy into the boot configuration
    2.10  """
    2.11 @@ -24,67 +25,60 @@ import tempfile
    2.12  import os, stat
    2.13  import shutil
    2.14  import string
    2.15 -from xen.util.security import ACMError, err
    2.16 -from xen.util.security import policy_dir_prefix, boot_filename, xen_title_re
    2.17 -from xen.util.security import any_title_re, xen_kernel_re, kernel_ver_re, any_module_re
    2.18 +import re
    2.19 +from xen.util.security import err
    2.20 +from xen.util.security import policy_dir_prefix, xen_title_re
    2.21 +from xen.util.security import boot_filename, altboot_filename
    2.22 +from xen.util.security import any_title_re, xen_kernel_re, any_module_re
    2.23  from xen.util.security import empty_line_re, binary_name_re, policy_name_re
    2.24  from xen.xm.opts import OptionError
    2.25  
    2.26  def help():
    2.27      return """
    2.28 -    Adds a 'module' line to the Xen grub.conf entry
    2.29 -    so that xen boots into a specific access control
    2.30 -    policy. If kernelversion is not given, then this
    2.31 -    script tries to determine it by looking for a grub
    2.32 -    entry with a line kernel xen.* If there are multiple
    2.33 -    Xen entries, then it must be called with an explicit
    2.34 -    version (it will fail otherwise).\n"""
    2.35 -
    2.36 -def determine_kernelversion(user_specified):
    2.37 -    within_xen_title = 0
    2.38 -    within_xen_entry = 0
    2.39 -    version_list = []
    2.40 -    guess_version = None
    2.41 +    Adds a 'module' line to the Xen grub configuration file entry
    2.42 +    so that Xen boots with a specific access control policy. If
    2.43 +    kernelversion is not given, then this script tries to determine
    2.44 +    it by looking for a title starting with \"XEN\". If there are
    2.45 +    multiple entries matching, then it must be called with the unique
    2.46 +    beginning of the title's name.\n"""
    2.47  
    2.48 -    grub_fd = open(boot_filename)
    2.49 -    for line in grub_fd:
    2.50 -        if xen_title_re.match(line):
    2.51 -            within_xen_title = 1
    2.52 -        elif within_xen_title and xen_kernel_re.match(line):
    2.53 -            within_xen_entry = 1
    2.54 -        elif within_xen_title and within_xen_entry and kernel_ver_re.match(line):
    2.55 -            for i in line.split():
    2.56 -                if (i.find("vmlinuz-") >= 0):
    2.57 -                    # skip start until "vmlinuz-"
    2.58 -                    guess_version = i[i.find("vmlinuz-") + len("vmlinuz-"):]
    2.59 -                    if user_specified:
    2.60 -                        if (guess_version == user_specified):
    2.61 -                            version_list.append(guess_version)
    2.62 -                    else:
    2.63 -                        version_list.append(guess_version)
    2.64 -        elif len(line.split()) > 0:
    2.65 -            if line.split()[0] == "title":
    2.66 -                within_xen_title = 0
    2.67 -                within_xen_entry = 0
    2.68 -    if len(version_list) > 1:
    2.69 -        err("Cannot decide between entries for kernels %s" % version_list)
    2.70 -    elif len(version_list) == 0:
    2.71 -        err("Cannot find a boot entry candidate (please create a Xen boot entry first).")
    2.72 +def strip_title(line):
    2.73 +    """
    2.74 +    strips whitespace left and right and cuts 'title'
    2.75 +    """
    2.76 +    s_title = string.strip(line)
    2.77 +    pos = string.index(s_title, "title")
    2.78 +    if pos >= 0:
    2.79 +        return s_title[pos+6:]
    2.80      else:
    2.81 -        return version_list[0]
    2.82 +        return s_title
    2.83  
    2.84  
    2.85 -
    2.86 -def insert_policy(boot_file, kernel_version, policy_name):
    2.87 +def insert_policy(boot_file, alt_boot_file, user_title, policy_name):
    2.88      """
    2.89      inserts policy binary file as last line of the grub entry
    2.90      matching the kernel_version version
    2.91      """
    2.92 +    if user_title:
    2.93 +        #replace "(" by "\(" and ")" by "\)" for matching
    2.94 +        user_title = string.replace(user_title, "(", "\(")
    2.95 +        user_title = string.replace(user_title, ")", "\)")
    2.96 +        user_title_re = re.compile("\s*title\s+.*%s" \
    2.97 +                                   % user_title, re.IGNORECASE)
    2.98 +    else:
    2.99 +        user_title_re = xen_title_re
   2.100 +
   2.101      within_xen_title = 0
   2.102      within_xen_entry = 0
   2.103      insert_at_end_of_entry = 0
   2.104      path_prefix = ''
   2.105 +    this_title = ''
   2.106 +    extended_titles = []
   2.107      (tmp_fd, tmp_grub) = tempfile.mkstemp()
   2.108 +    #First check whether menu.lst exists
   2.109 +    if not os.path.isfile(boot_file):
   2.110 +        #take alternate boot file (grub.conf) instead
   2.111 +        boot_file = alt_boot_file
   2.112      #follow symlink since menue.lst might be linked to grub.conf
   2.113      if stat.S_ISLNK(os.lstat(boot_file)[stat.ST_MODE]):
   2.114          new_name = os.readlink(boot_file)
   2.115 @@ -95,30 +89,33 @@ def insert_policy(boot_file, kernel_vers
   2.116              path[len(path)-1] = new_name
   2.117              boot_file = '/'.join(path)
   2.118          if not os.path.exists(boot_file):
   2.119 -            err("Boot file \'" + boot_file + "\' not found.")
   2.120 +            err("Boot file \'%s\' not found." % boot_file)
   2.121      grub_fd = open(boot_file)
   2.122      for line in grub_fd:
   2.123 -        if xen_title_re.match(line):
   2.124 +        if user_title_re.match(line):
   2.125 +            this_title = strip_title(line)
   2.126              within_xen_title = 1
   2.127          elif within_xen_title and xen_kernel_re.match(line):
   2.128 -            within_xen_entry = 1
   2.129 -        elif within_xen_title and within_xen_entry and kernel_ver_re.match(line):
   2.130 -            for i in line.split():
   2.131 -                if (i.find("vmlinuz-") >= 0):
   2.132 -                    if  kernel_version == i[i.find("vmlinuz-") + len("vmlinuz-"):]:
   2.133 -                        insert_at_end_of_entry = 1
   2.134 -                        path_prefix = i[0:i.find("vmlinuz-")]
   2.135 +            insert_at_end_of_entry = 1
   2.136 +            #use prefix from xen.gz path for policy
   2.137 +            path_prefix = line.split()[1]
   2.138 +            idx = path_prefix.rfind('/')
   2.139 +            if idx >= 0:
   2.140 +                path_prefix = path_prefix[0:idx+1]
   2.141 +            else:
   2.142 +                path_prefix = ''
   2.143          elif any_module_re.match(line) and insert_at_end_of_entry:
   2.144              if binary_name_re.match(line):
   2.145                  #delete existing policy module line
   2.146                  line=''
   2.147          elif any_title_re.match(line):
   2.148              within_xen_title = 0
   2.149 -            within_xen_entry = 0
   2.150  
   2.151 -        if (empty_line_re.match(line) or any_title_re.match(line)) and insert_at_end_of_entry:
   2.152 +        if (empty_line_re.match(line) or any_title_re.match(line)) and \
   2.153 +            insert_at_end_of_entry:
   2.154              #newline or new title: we insert the policy module line here
   2.155              os.write(tmp_fd, "\tmodule " + path_prefix + policy_name + ".bin\n")
   2.156 +            extended_titles.append(this_title)
   2.157              insert_at_end_of_entry = 0
   2.158          #write the line that was read (except potential existing policy entry)
   2.159          os.write(tmp_fd, line)
   2.160 @@ -126,27 +123,36 @@ def insert_policy(boot_file, kernel_vers
   2.161      if insert_at_end_of_entry:
   2.162          #last entry, no empty line at end of file
   2.163          os.write(tmp_fd, "\tmodule " + path_prefix + policy_name + ".bin\n")
   2.164 +        extended_titles.append(this_title)
   2.165  
   2.166 -    #temp file might be destroyed when closing it, first copy ...
   2.167 +    #if more than one entry was changed, abort
   2.168 +    if len(extended_titles) > 1:
   2.169 +        err("Following boot entries matched: %s. \nPlease specify "
   2.170 +            "unique part of the boot title." % extended_titles)
   2.171 +    if len(extended_titles) == 0:
   2.172 +        err("Boot entry not found. Please specify unique part "
   2.173 +            "of the boot title.")
   2.174 +
   2.175 +    #temp file might be destroyed when closing it, first copy it
   2.176      shutil.move(boot_file, boot_file+"_save")
   2.177      shutil.copyfile(tmp_grub, boot_file)
   2.178      os.close(tmp_fd)
   2.179 -    #temp file did not disappear on my system ...
   2.180 +    #sometimes the temp file does not disappear
   2.181      try:
   2.182          os.remove(tmp_grub)
   2.183      except:
   2.184          pass
   2.185 -
   2.186 +    return extended_titles[0]
   2.187  
   2.188  
   2.189  def main(argv):
   2.190      user_kver = None
   2.191 -    policy = None
   2.192 +    user_title = None
   2.193      if len(argv) == 2:
   2.194          policy = argv[1]
   2.195      elif len(argv) == 3:
   2.196          policy = argv[1]
   2.197 -        user_kver = argv[2]
   2.198 +        user_title = argv[2]
   2.199      else:
   2.200          raise OptionError('Invalid number of arguments')
   2.201      
   2.202 @@ -167,9 +173,10 @@ def main(argv):
   2.203      dst_binary_policy_file = "/boot/" + policy + ".bin"
   2.204      shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
   2.205      
   2.206 -    kernel_version = determine_kernelversion(user_kver)
   2.207 -    insert_policy(boot_filename, kernel_version, policy)
   2.208 -    print "Boot entry created and \'%s\' copied to /boot" % (policy + ".bin")
   2.209 +    entryname = insert_policy(boot_filename, altboot_filename,
   2.210 +                              user_title, policy)
   2.211 +    print "Boot entry '%s' extended and \'%s\' copied to /boot" \
   2.212 +          % (entryname, policy + ".bin")
   2.213  
   2.214  if __name__ == '__main__':
   2.215      try:
   2.216 @@ -177,4 +184,3 @@ if __name__ == '__main__':
   2.217      except Exception, e:
   2.218          sys.stderr.write('Error: ' + str(e) + '\n')    
   2.219          sys.exit(-1)
   2.220 -