summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Kosek <mkosek@redhat.com>2011-11-03 11:08:26 +0100
committerMartin Kosek <mkosek@redhat.com>2011-11-03 21:47:50 +0100
commitc960e0a4b0f74afd55d88c8bb20cc532351ee728 (patch)
tree50b75bdd981b844d2d86d2b9cb508ae87188fae2
parentc10db54aeedad18e04a18d664687b147043b6bbd (diff)
downloadfreeipa-c960e0a4b0f74afd55d88c8bb20cc532351ee728.tar.gz
freeipa-c960e0a4b0f74afd55d88c8bb20cc532351ee728.tar.xz
freeipa-c960e0a4b0f74afd55d88c8bb20cc532351ee728.zip
Fix ipa-server-install answer cache
Current Answer Cache storing mechanism is not ideal for storing non-trivial Python types like arrays, custom classes, etc. RawConfigParser just translates values to string, which are not correctly decoded when the Answer Cache is parsed and restored in the installer. This patch replaces RawConfigParser with Python's standard pickle module, which is a recommended way for serialization in Python. https://fedorahosted.org/freeipa/ticket/2054
-rwxr-xr-xinstall/tools/ipa-server-install65
1 files changed, 26 insertions, 39 deletions
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 76d5f2f5a..3e00018be 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -36,7 +36,7 @@ import signal
import shutil
import glob
import traceback
-from ConfigParser import RawConfigParser
+import pickle
import random
import tempfile
import nss.error
@@ -313,45 +313,36 @@ ANSWER_CACHE = "/root/.ipa_cache"
def read_cache(dm_password):
"""
- Returns a dict of cached answers or None if no cache file exists.
+ Returns a dict of cached answers or empty dict if no cache file exists.
"""
if not ipautil.file_exists(ANSWER_CACHE):
return {}
top_dir = tempfile.mkdtemp("ipa")
+ fname = "%s/cache" % top_dir
try:
- clearfile = "%s/cache" % top_dir
- decrypt_file(ANSWER_CACHE, clearfile, dm_password, top_dir)
+ decrypt_file(ANSWER_CACHE, fname, dm_password, top_dir)
except Exception, e:
shutil.rmtree(top_dir)
- raise RuntimeError("Problem decrypting answer cache in %s, check your password." % ANSWER_CACHE)
+ raise Exception("Decryption of answer cache in %s failed, please check your password." % ANSWER_CACHE)
- optdict={}
- parser = RawConfigParser()
try:
- fp = open(clearfile, "r")
- parser.readfp(fp)
- optlist = parser.items('options')
- fp.close()
-
+ with open(fname, 'rb') as f:
+ try:
+ optdict = pickle.load(f)
+ except Exception, e:
+ raise Exception("Parse error in %s: %s" % (ANSWER_CACHE, str(e)))
except IOError, e:
- raise RuntimeError("Error reading cache file %s: %s" % (ANSWER_CACHE, str(e)))
+ raise Exception("Read error in %s: %s" % (ANSWER_CACHE, str(e)))
finally:
shutil.rmtree(top_dir)
- for opt in optlist:
- value = opt[1]
- if value.lower() in ['true', 'false']:
- value = value.lower() == 'true'
- if value == 'None':
- value = None
- optdict[opt[0]] = value
-
# These are the only ones that may be overridden
- if 'external_ca_file' in optdict:
- del optdict['external_ca_file']
- if 'external_cert_file' in optdict:
- del optdict['external_cert_file']
+ for opt in ('external_ca_file', 'external_cert_file'):
+ try:
+ del optdict[opt]
+ except KeyError:
+ pass
return optdict
@@ -359,21 +350,14 @@ def write_cache(options):
"""
Takes a dict as input and writes a cached file of answers
"""
-
- # convert the options instance into a dict
- optdict = eval(str(options))
- parser = RawConfigParser()
top_dir = tempfile.mkdtemp("ipa")
+ fname = "%s/cache" % top_dir
try:
- fp = open("%s/cache" % top_dir, "w")
- parser.add_section('options')
- for opt in optdict:
- parser.set('options', opt, optdict[opt])
- parser.write(fp)
- fp.close()
- ipautil.encrypt_file("%s/cache" % top_dir, ANSWER_CACHE, options.dm_password, top_dir);
+ with open(fname, 'wb') as f:
+ pickle.dump(options, f)
+ ipautil.encrypt_file(fname, ANSWER_CACHE, options['dm_password'], top_dir)
except IOError, e:
- raise RuntimeError("Unable to cache command-line options %s" % str(e))
+ raise Exception("Unable to cache command-line options %s" % str(e))
finally:
shutil.rmtree(top_dir)
@@ -647,7 +631,10 @@ def main():
dm_password = read_password("Directory Manager", confirm=False)
if dm_password is None:
sys.exit("\nDirectory Manager password required")
- options._update_loose(read_cache(dm_password))
+ try:
+ options._update_loose(read_cache(dm_password))
+ except Exception, e:
+ sys.exit("Cannot process the cache file: %s" % str(e))
if options.external_cert_file:
try:
@@ -975,7 +962,7 @@ def main():
options.unattended = True
options.forwarders = dns_forwarders
options.reverse_zone = reverse_zone
- write_cache(options)
+ write_cache(vars(options))
ca.configure_instance(host_name, dm_password, dm_password,
csr_file="/root/ipa.csr",
subject_base=options.subject)