Kaynağa Gözat

AMBARI-2528. Setup-ldap with invalid master key allows LDAP reconfiguration. (swagle)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1499616 13f79535-47bb-0310-9956-ffa450edef68
Siddharth Wagle 12 yıl önce
ebeveyn
işleme
6550e1c409

+ 4 - 4
ambari-server/sbin/ambari-server

@@ -91,7 +91,7 @@ case "$1" in
         $PYTHON /usr/sbin/ambari-server.py $@
         $PYTHON /usr/sbin/ambari-server.py $@
         ;;
         ;;
   setup)
   setup)
-        echo -e "Initializing ..."
+        echo -e "Initializing..."
         initdb_res=`/sbin/service postgresql initdb 2>&1 > /dev/null`
         initdb_res=`/sbin/service postgresql initdb 2>&1 > /dev/null`
         initdb_res=`/sbin/service postgresql start 2>&1 > /dev/null`
         initdb_res=`/sbin/service postgresql start 2>&1 > /dev/null`
         initdb_res=`/sbin/service postgresql stop 2>&1 > /dev/null`
         initdb_res=`/sbin/service postgresql stop 2>&1 > /dev/null`
@@ -102,8 +102,8 @@ case "$1" in
         echo -e "Setting up LDAP properties..."
         echo -e "Setting up LDAP properties..."
         $PYTHON /usr/sbin/ambari-server.py $@
         $PYTHON /usr/sbin/ambari-server.py $@
         ;;
         ;;
-  resetmasterkey)
-        echo -e "Reseting master key for credential store"
+  encrypt-passwords)
+        echo -e "Setting up password encryption..."
         $PYTHON /usr/sbin/ambari-server.py $@
         $PYTHON /usr/sbin/ambari-server.py $@
         ;;
         ;;
   setup-https)
   setup-https)
@@ -111,7 +111,7 @@ case "$1" in
         $PYTHON /usr/sbin/ambari-server.py $@
         $PYTHON /usr/sbin/ambari-server.py $@
         ;;
         ;;
   *)
   *)
-        echo "Usage: /usr/sbin/ambari-server {start|stop|restart|setup|upgrade|status|upgradestack|setup-ldap|setup-https|resetmasterkey} [options]"
+        echo "Usage: /usr/sbin/ambari-server {start|stop|restart|setup|upgrade|status|upgradestack|setup-ldap|setup-https|encrypt-passwords} [options]"
         exit 1
         exit 1
 esac
 esac
 
 

+ 5 - 4
ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java

@@ -225,8 +225,8 @@ public class Configuration {
     ".key.ispersisted";
     ".key.ispersisted";
   public static final String MASTER_KEY_LOCATION = "security.master.key" +
   public static final String MASTER_KEY_LOCATION = "security.master.key" +
     ".location";
     ".location";
-  public static final String MASTER_KEY_ENV_PROP = "ambari.security.master" +
-    ".key";
+  public static final String MASTER_KEY_ENV_PROP =
+    "AMBARI_SECURITY_MASTER_KEY";
   public static final String MASTER_KEY_FILENAME_DEFAULT = "master";
   public static final String MASTER_KEY_FILENAME_DEFAULT = "master";
 
 
   private static final Logger LOG = LoggerFactory.getLogger(
   private static final Logger LOG = LoggerFactory.getLogger(
@@ -696,8 +696,9 @@ public class Configuration {
   }
   }
 
 
   public boolean isMasterKeyPersisted() {
   public boolean isMasterKeyPersisted() {
-    String isPersisted = properties.getProperty(MASTER_KEY_PERSISTED, "true");
-    return isPersisted.toLowerCase().equals("true");
+    String masterKeyLocation = getMasterKeyLocation();
+    File f = new File(masterKeyLocation);
+    return f.exists();
   }
   }
 
 
   public String getMasterKeyLocation() {
   public String getMasterKeyLocation() {

+ 204 - 143
ambari-server/src/main/python/ambari-server.py

@@ -40,6 +40,7 @@ import datetime
 import socket
 import socket
 import tempfile
 import tempfile
 import random
 import random
+import pwd
 
 
 # debug settings
 # debug settings
 VERBOSE = False
 VERBOSE = False
@@ -57,7 +58,7 @@ UPDATE_METAINFO_ACTION = "update-metainfo"
 STATUS_ACTION = "status"
 STATUS_ACTION = "status"
 SETUP_HTTPS_ACTION = "setup-https"
 SETUP_HTTPS_ACTION = "setup-https"
 LDAP_SETUP_ACTION = "setup-ldap"
 LDAP_SETUP_ACTION = "setup-ldap"
-RESET_MASTER_KEY_ACTION = "resetmasterkey"
+ENCRYPT_PASSWORDS_ACTION = "encrypt-passwords"
 
 
 # selinux commands
 # selinux commands
 GET_SE_LINUX_ST_CMD = "/usr/sbin/sestatus"
 GET_SE_LINUX_ST_CMD = "/usr/sbin/sestatus"
@@ -151,8 +152,9 @@ SECURITY_PROVIDER_KEY_CMD="{0}" + os.sep + "bin" + os.sep + "java -cp {1}" +\
 SECURITY_KEYS_DIR = "security.server.keys_dir"
 SECURITY_KEYS_DIR = "security.server.keys_dir"
 SECURITY_MASTER_KEY_LOCATION = "security.master.key.location"
 SECURITY_MASTER_KEY_LOCATION = "security.master.key.location"
 SECURITY_KEY_IS_PERSISTED = "security.master.key.ispersisted"
 SECURITY_KEY_IS_PERSISTED = "security.master.key.ispersisted"
-SECURITY_KEY_ENV_VAR_NAME = "ambari.security.master.key"
+SECURITY_KEY_ENV_VAR_NAME = "AMBARI_SECURITY_MASTER_KEY"
 SECURITY_MASTER_KEY_FILENAME = "master"
 SECURITY_MASTER_KEY_FILENAME = "master"
+SECURITY_IS_ENCRYPTION_ENABLED = "security.passwords.encryption.enabled"
 
 
 SSL_KEY_DIR = 'security.server.keys_dir'
 SSL_KEY_DIR = 'security.server.keys_dir'
 SSL_API_PORT = 'client.api.ssl.port'
 SSL_API_PORT = 'client.api.ssl.port'
@@ -575,11 +577,14 @@ def adjust_directory_permissions(ambari_user):
   cmd = RECURSIVE_RM_CMD.format(bootstrap_dir)
   cmd = RECURSIVE_RM_CMD.format(bootstrap_dir)
   run_os_command(cmd)
   run_os_command(cmd)
   os.mkdir(bootstrap_dir)
   os.mkdir(bootstrap_dir)
-  # Add master key if exists
+  # Add master key and credential store if exists
   keyLocation = get_master_key_location(properties)
   keyLocation = get_master_key_location(properties)
   masterKeyFile = search_file(SECURITY_MASTER_KEY_FILENAME, keyLocation)
   masterKeyFile = search_file(SECURITY_MASTER_KEY_FILENAME, keyLocation)
   if masterKeyFile:
   if masterKeyFile:
     NR_ADJUST_OWNERSHIP_LIST.append((masterKeyFile, "600", "{0}", "{0}", False))
     NR_ADJUST_OWNERSHIP_LIST.append((masterKeyFile, "600", "{0}", "{0}", False))
+  credStoreFile = get_credential_store_location(properties)
+  if os.path.exists(credStoreFile):
+    NR_ADJUST_OWNERSHIP_LIST.append((credStoreFile, "600", "{0}", "{0}", False))
   print "Adjusting ambari-server permissions and ownership..."
   print "Adjusting ambari-server permissions and ownership..."
   for pack in NR_ADJUST_OWNERSHIP_LIST:
   for pack in NR_ADJUST_OWNERSHIP_LIST:
     file = pack[0]
     file = pack[0]
@@ -842,6 +847,19 @@ def store_password_file(password, filename):
 
 
   return passFilePath
   return passFilePath
 
 
+def remove_password_file(filename):
+  conf_file = find_properties_file()
+  passFilePath = os.path.join(os.path.dirname(conf_file),
+    filename)
+
+  if os.path.exists(passFilePath):
+    try:
+      os.remove(passFilePath)
+    except Exception, e:
+      print_warning_msg('Unable to remove password file: ' + str(e))
+      return 1
+  pass
+  return 0
 
 
 def execute_db_script(args, file):
 def execute_db_script(args, file):
   #password access to ambari-server and mapred
   #password access to ambari-server and mapred
@@ -1070,13 +1088,7 @@ def prompt_db_properties(args):
         "followed by alphanumeric or _ or - characters",
         "followed by alphanumeric or _ or - characters",
         False
         False
       )
       )
-      (masterKey, isSecure, isPersisted) = setup_master_key()
-      (password, passwordAlias) = configure_database_password(isSecure,
-        masterKey, True)
-      args.database_password =  password
-      if passwordAlias:
-        setattr(args, 'database_password_alias', passwordAlias) # Store alias if present
-
+      args.database_password =  configure_database_password(True)
 
 
   print_info_msg('Using database options: {database},{host},{port},{schema},{user},{password}'.format(
   print_info_msg('Using database options: {database},{host},{port},{schema},{user},{password}'.format(
     database=args.database,
     database=args.database,
@@ -1095,6 +1107,12 @@ def store_remote_properties(args):
     print_error_msg ("Error getting ambari properties")
     print_error_msg ("Error getting ambari properties")
     return -1
     return -1
 
 
+  isSecure = properties.get_property(SECURITY_IS_ENCRYPTION_ENABLED)
+  if isSecure and isSecure.lower() == 'true':
+    isSecure = True
+  else:
+    isSecure = False
+
   properties.process_pair(PERSISTENCE_TYPE_PROPERTY, "remote")
   properties.process_pair(PERSISTENCE_TYPE_PROPERTY, "remote")
 
 
   properties.process_pair(JDBC_DATABASE_PROPERTY, args.database)
   properties.process_pair(JDBC_DATABASE_PROPERTY, args.database)
@@ -1114,8 +1132,9 @@ def store_remote_properties(args):
     connectionStringFormat = DATABASE_CONNECTION_STRINGS_ALT
     connectionStringFormat = DATABASE_CONNECTION_STRINGS_ALT
   properties.process_pair(JDBC_URL_PROPERTY, connectionStringFormat[DATABASE_INDEX].format(jdbc_hostname, args.database_port, args.database_name))
   properties.process_pair(JDBC_URL_PROPERTY, connectionStringFormat[DATABASE_INDEX].format(jdbc_hostname, args.database_port, args.database_name))
   properties.process_pair(JDBC_USER_NAME_PROPERTY, args.database_username)
   properties.process_pair(JDBC_USER_NAME_PROPERTY, args.database_username)
-  if hasattr(args, 'database_password_alias') and args.database_password_alias:
-    properties.process_pair(JDBC_PASSWORD_PROPERTY, args.database_password_alias)
+  if isSecure:
+    properties.process_pair(JDBC_PASSWORD_PROPERTY,
+          encrypt_password(JDBC_RCA_PASSWORD_ALIAS, args.database_password))
   else:
   else:
     properties.process_pair(JDBC_PASSWORD_PROPERTY,
     properties.process_pair(JDBC_PASSWORD_PROPERTY,
       store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
       store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
@@ -1123,9 +1142,9 @@ def store_remote_properties(args):
   properties.process_pair(JDBC_RCA_DRIVER_PROPERTY, DATABASE_DRIVER_NAMES[DATABASE_INDEX])
   properties.process_pair(JDBC_RCA_DRIVER_PROPERTY, DATABASE_DRIVER_NAMES[DATABASE_INDEX])
   properties.process_pair(JDBC_RCA_URL_PROPERTY, connectionStringFormat[DATABASE_INDEX].format(jdbc_hostname, args.database_port, args.database_name))
   properties.process_pair(JDBC_RCA_URL_PROPERTY, connectionStringFormat[DATABASE_INDEX].format(jdbc_hostname, args.database_port, args.database_name))
   properties.process_pair(JDBC_RCA_USER_NAME_PROPERTY, args.database_username)
   properties.process_pair(JDBC_RCA_USER_NAME_PROPERTY, args.database_username)
-  if hasattr(args, 'database_password_alias') and args.database_password_alias:
+  if isSecure:
     properties.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY,
     properties.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY,
-      args.database_password_alias)
+          encrypt_password(JDBC_RCA_PASSWORD_ALIAS, args.database_password))
   else:
   else:
     properties.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY,
     properties.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY,
       store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
       store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
@@ -1220,7 +1239,7 @@ def execute_remote_script(args, scriptPath):
   return -2, "Wrong database", "Wrong database"
   return -2, "Wrong database", "Wrong database"
 
 
 
 
-def configure_database_password(isSecure=False, masterKey=None, showDefault=True):
+def configure_database_password(showDefault=True):
   passwordDefault = PG_DEFAULT_PASSWORD
   passwordDefault = PG_DEFAULT_PASSWORD
   if showDefault:
   if showDefault:
     passwordPrompt = 'Enter Database Password [' + passwordDefault + ']: '
     passwordPrompt = 'Enter Database Password [' + passwordDefault + ']: '
@@ -1233,15 +1252,7 @@ def configure_database_password(isSecure=False, masterKey=None, showDefault=True
   password = read_password(passwordDefault, passwordPattern, passwordPrompt,
   password = read_password(passwordDefault, passwordPattern, passwordPrompt,
     passwordDescr)
     passwordDescr)
 
 
-  aliasStr = None
-  if isSecure:
-    retCode = save_passwd_for_alias(JDBC_RCA_PASSWORD_ALIAS, password, masterKey)
-    if retCode != 0:
-      print 'Failed to save secure LDAP password.'
-      return password, aliasStr
-    return password, get_alias_string(JDBC_RCA_PASSWORD_ALIAS)
-
-  return password, aliasStr
+  return password
 
 
 
 
 def configure_database_username_password(args):
 def configure_database_username_password(args):
@@ -1252,19 +1263,16 @@ def configure_database_username_password(args):
 
 
   username = properties[JDBC_USER_NAME_PROPERTY]
   username = properties[JDBC_USER_NAME_PROPERTY]
   passwordProp = properties[JDBC_PASSWORD_PROPERTY]
   passwordProp = properties[JDBC_PASSWORD_PROPERTY]
-  isPersisted = get_master_key_ispersisted(properties)
 
 
   if username and passwordProp:
   if username and passwordProp:
     print_info_msg("Database username + password already configured")
     print_info_msg("Database username + password already configured")
     args.database_username=username
     args.database_username=username
     if is_alias_string(passwordProp):
     if is_alias_string(passwordProp):
-      if isPersisted:
-        # No need to prompt for key
-        args.database_password = read_passwd_for_alias(JDBC_RCA_PASSWORD_ALIAS)
-      else:
-        (masterKey, isSecure, isPersisted) = setup_master_key()
-        args.database_password = read_passwd_for_alias(
-          JDBC_RCA_PASSWORD_ALIAS, masterKey)
+      args.database_password = decrypt_password_for_alias(JDBC_RCA_PASSWORD_ALIAS)
+    else:
+      if os.path.exists(passwordProp):
+        with open(passwordProp, 'r') as file:
+          args.database_password = file.read()
 
 
     return 1
     return 1
   else:
   else:
@@ -1290,9 +1298,10 @@ def store_local_properties(args):
   properties.removeOldProp(JDBC_DATABASE_PROPERTY)
   properties.removeOldProp(JDBC_DATABASE_PROPERTY)
   properties.process_pair(PERSISTENCE_TYPE_PROPERTY, "local")
   properties.process_pair(PERSISTENCE_TYPE_PROPERTY, "local")
   properties.process_pair(JDBC_USER_NAME_PROPERTY, args.database_username)
   properties.process_pair(JDBC_USER_NAME_PROPERTY, args.database_username)
-  if hasattr(args, 'database_password_alias') and args.database_password_alias:
+  isSecure = properties.get_property(SECURITY_IS_ENCRYPTION_ENABLED)
+  if isSecure and isSecure.lower() == 'true':
     properties.process_pair(JDBC_PASSWORD_PROPERTY,
     properties.process_pair(JDBC_PASSWORD_PROPERTY,
-      args.database_password_alias)
+      encrypt_password(JDBC_RCA_PASSWORD_ALIAS, args.database_password))
   else:
   else:
     properties.process_pair(JDBC_PASSWORD_PROPERTY,
     properties.process_pair(JDBC_PASSWORD_PROPERTY,
       store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
       store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
@@ -2040,23 +2049,20 @@ def start(args):
 
 
 
 
   properties = get_ambari_properties()
   properties = get_ambari_properties()
-  persist = get_master_key_ispersisted(properties)
+  isSecure = properties.get_property(SECURITY_IS_ENCRYPTION_ENABLED)
+  isSecure = True if isSecure and isSecure.lower() == 'true' else False
+  keyLocation = get_master_key_location(properties)
+  masterKeyFile = search_file(SECURITY_MASTER_KEY_FILENAME, keyLocation)
   environ = os.environ.copy()
   environ = os.environ.copy()
   # Need to handle master key not persisted scenario
   # Need to handle master key not persisted scenario
-  if persist is not None and not persist:
+  if isSecure and not masterKeyFile:
     prompt = False
     prompt = False
-    try:
-      masterKey = environ[SECURITY_KEY_ENV_VAR_NAME]
-    except KeyError:
-      masterKey = None
+    masterKey = environ.get(SECURITY_KEY_ENV_VAR_NAME)
 
 
     if masterKey is not None and masterKey != "":
     if masterKey is not None and masterKey != "":
       pass
       pass
     else:
     else:
-      try:
-        keyLocation = environ[SECURITY_MASTER_KEY_LOCATION]
-      except KeyError:
-        keyLocation = None
+      keyLocation = environ.get(SECURITY_MASTER_KEY_LOCATION)
 
 
       if keyLocation is not None:
       if keyLocation is not None:
         try:
         try:
@@ -2072,16 +2078,20 @@ def start(args):
 
 
     if prompt:
     if prompt:
       masterKey = get_validated_string_input("Please provide master key " +\
       masterKey = get_validated_string_input("Please provide master key " +\
-                    "for unlocking credential store: ", "", ".*", "", False)
+                  "for unlocking credential store: ", "", ".*", "", True, False)
       tempDir = tempfile.gettempdir()
       tempDir = tempfile.gettempdir()
       tempFilePath = tempDir + os.sep + "masterkey"
       tempFilePath = tempDir + os.sep + "masterkey"
       save_master_key(masterKey, tempFilePath, True)
       save_master_key(masterKey, tempFilePath, True)
-      os.chmod(tempFilePath, stat.S_IREAD | stat.S_IWRITE)
+      if ambari_user != current_user:
+        uid = pwd.getpwnam(ambari_user).pw_uid
+        gid = pwd.getpwnam(ambari_user).pw_gid
+        os.chown(tempFilePath, uid, gid)
+      else:
+        os.chmod(tempFilePath, stat.S_IREAD | stat.S_IWRITE)
 
 
       if tempFilePath is not None:
       if tempFilePath is not None:
         environ[SECURITY_MASTER_KEY_LOCATION] = tempFilePath
         environ[SECURITY_MASTER_KEY_LOCATION] = tempFilePath
 
 
-
   pidfile = PID_DIR + os.sep + PID_NAME
   pidfile = PID_DIR + os.sep + PID_NAME
   command_base = SERVER_START_CMD_DEBUG if (SERVER_DEBUG_MODE or SERVER_START_DEBUG) else SERVER_START_CMD
   command_base = SERVER_START_CMD_DEBUG if (SERVER_DEBUG_MODE or SERVER_START_DEBUG) else SERVER_START_CMD
   command = command_base.format(jdk_path, conf_dir, get_ambari_classpath(), pidfile)
   command = command_base.format(jdk_path, conf_dir, get_ambari_classpath(), pidfile)
@@ -2316,10 +2326,6 @@ def setup_ldap():
     raise FatalException(4, err)
     raise FatalException(4, err)
 
 
   properties = get_ambari_properties()
   properties = get_ambari_properties()
-
-  # Setup secure key
-  (masterKey, isSecure, isPersisted) = setup_master_key(False)
-
   # python2.x dict is not ordered
   # python2.x dict is not ordered
   ldap_property_list_reqd = ["authentication.ldap.primaryUrl",
   ldap_property_list_reqd = ["authentication.ldap.primaryUrl",
                         "authentication.ldap.secondaryUrl",
                         "authentication.ldap.secondaryUrl",
@@ -2342,7 +2348,7 @@ def setup_ldap():
 
 
   ldap_properties_map_reqd =\
   ldap_properties_map_reqd =\
   {
   {
-    ldap_property_list_reqd[0]:(LDAP_PRIMARY_URL_DEFAULT, "Primary URL* {0}: ".format(get_prompt_default(LDAP_PRIMARY_URL_DEFAULT)), False),\
+    ldap_property_list_reqd[0]:(LDAP_PRIMARY_URL_DEFAULT, "Primary URL* {{host:port}} {0}: ".format(get_prompt_default(LDAP_PRIMARY_URL_DEFAULT)), False),\
     ldap_property_list_reqd[1]:(LDAP_SECONDARY_URL_DEFAULT, "Secondary URL {0}: ".format(get_prompt_default(LDAP_SECONDARY_URL_DEFAULT)), True),\
     ldap_property_list_reqd[1]:(LDAP_SECONDARY_URL_DEFAULT, "Secondary URL {0}: ".format(get_prompt_default(LDAP_SECONDARY_URL_DEFAULT)), True),\
     ldap_property_list_reqd[2]:(LDAP_USE_SSL_DEFAULT, "Use SSL* [true/false] {0}: ".format(get_prompt_default(LDAP_USE_SSL_DEFAULT)), False),\
     ldap_property_list_reqd[2]:(LDAP_USE_SSL_DEFAULT, "Use SSL* [true/false] {0}: ".format(get_prompt_default(LDAP_USE_SSL_DEFAULT)), False),\
     ldap_property_list_reqd[3]:(LDAP_USER_ATT_DEFAULT, "User name attribute* {0}: ".format(get_prompt_default(LDAP_USER_ATT_DEFAULT)), False),\
     ldap_property_list_reqd[3]:(LDAP_USER_ATT_DEFAULT, "User name attribute* {0}: ".format(get_prompt_default(LDAP_USER_ATT_DEFAULT)), False),\
@@ -2351,10 +2357,11 @@ def setup_ldap():
   }
   }
 
 
   ldap_property_value_map = {}
   ldap_property_value_map = {}
-  for key in ldap_property_list_reqd:
+  for idx, key in enumerate(ldap_property_list_reqd):
+    pattern = ".*" if idx != 0 else "^(.*:[0-9]{1,5}$)"
     input = get_validated_string_input(ldap_properties_map_reqd[key][1],
     input = get_validated_string_input(ldap_properties_map_reqd[key][1],
-      ldap_properties_map_reqd[key][0], ".*", "", False,
-      ldap_properties_map_reqd[key][2])
+      ldap_properties_map_reqd[key][0], pattern,
+      "Invalid characters in the input!", False, ldap_properties_map_reqd[key][2])
     if input is not None and input != "":
     if input is not None and input != "":
       ldap_property_value_map[key] = input
       ldap_property_value_map[key] = input
 
 
@@ -2363,16 +2370,12 @@ def setup_ldap():
   password = None
   password = None
   # Ask for manager credentials only if bindAnonymously is false
   # Ask for manager credentials only if bindAnonymously is false
   if not anonymous:
   if not anonymous:
-    username = get_validated_string_input("Manager DN* {0}:".format(
-      get_prompt_default(LDAP_MGR_DN_DEFAULT)), LDAP_MGR_DN_DEFAULT, ".*", "", False, False)
+    username = get_validated_string_input("Manager DN* {0}: ".format(
+      get_prompt_default(LDAP_MGR_DN_DEFAULT)), LDAP_MGR_DN_DEFAULT, ".*",
+                "Invalid characters in the input!", False, False)
     ldap_property_value_map[LDAP_MGR_USERNAME_PROPERTY] = username
     ldap_property_value_map[LDAP_MGR_USERNAME_PROPERTY] = username
     password = configure_ldap_password()
     password = configure_ldap_password()
-    if isSecure:
-      ldap_property_value_map[LDAP_MGR_PASSWORD_PROPERTY] = get_alias_string(
-        LDAP_MGR_PASSWORD_ALIAS)
-    else:
-      ldap_property_value_map[LDAP_MGR_PASSWORD_PROPERTY] = password
-
+    ldap_property_value_map[LDAP_MGR_PASSWORD_PROPERTY] = password
 
 
   print '=' * 20
   print '=' * 20
   print 'Review Settings'
   print 'Review Settings'
@@ -2391,11 +2394,6 @@ def setup_ldap():
   save_settings = get_YN_input("Save settings [y/n] (y)? ", True)
   save_settings = get_YN_input("Save settings [y/n] (y)? ", True)
 
 
   if save_settings:
   if save_settings:
-    if isSecure and password:
-      retCode = save_passwd_for_alias(LDAP_MGR_PASSWORD_ALIAS, password, masterKey)
-      if retCode != 0:
-        print 'Failed to save secure LDAP password.'
-        return retCode
     ldap_property_value_map[CLIENT_SECURITY_KEY] = 'ldap'
     ldap_property_value_map[CLIENT_SECURITY_KEY] = 'ldap'
     # Persisting values
     # Persisting values
     update_properties(ldap_property_value_map)
     update_properties(ldap_property_value_map)
@@ -2405,13 +2403,6 @@ def setup_ldap():
   return 0
   return 0
 
 
 
 
-def reset_master_key():
-  if not is_root():
-    err = 'Ambari-server resetmasterkey should be run with ' \
-          'root-level privileges'
-    raise FatalException(4, err)
-  setup_master_key(resetKey=True)
-
 def read_master_key():
 def read_master_key():
   passwordPattern = ".*"
   passwordPattern = ".*"
   passwordDescr = "Invalid characters in password. Use only alphanumeric or "\
   passwordDescr = "Invalid characters in password. Use only alphanumeric or "\
@@ -2419,7 +2410,7 @@ def read_master_key():
   passwordDefault = ""
   passwordDefault = ""
 
 
   masterKey = get_validated_string_input(
   masterKey = get_validated_string_input(
-      "Please provide master key for the credential store: ",
+      "Please provide master key for locking the credential store: ",
       passwordDefault, passwordPattern, passwordDescr, True, True)
       passwordDefault, passwordPattern, passwordDescr, True, True)
 
 
   if not masterKey:
   if not masterKey:
@@ -2436,37 +2427,115 @@ def read_master_key():
   return masterKey
   return masterKey
 
 
 
 
-def setup_master_key(resetKey=False):
+def encrypt_password(alias, password):
   properties = get_ambari_properties()
   properties = get_ambari_properties()
-  # check configuration for location of master key
-  keyLocation = get_master_key_location(properties)
-  persist = get_master_key_ispersisted(properties)
-  masterKeyFile = search_file(SECURITY_MASTER_KEY_FILENAME, keyLocation)
+  if properties == -1:
+    raise FatalException(1, None)
 
 
-  if persist is not None:
-    if persist and masterKeyFile is not None and not resetKey:
-      return None, True, True       # setup is secure and key persisted
-    elif not persist and not resetKey:
+  isSecure = properties.get_property(SECURITY_IS_ENCRYPTION_ENABLED)
+  if isSecure and isSecure.lower() == 'true':
+    keyLocation = get_master_key_location(properties)
+    masterKeyFile = search_file(SECURITY_MASTER_KEY_FILENAME, keyLocation)
+    masterKey = None
+    if not masterKeyFile:
+      # Encryption enabled but no master key file found
       masterKey = get_validated_string_input("Please provide master key " +\
       masterKey = get_validated_string_input("Please provide master key " +\
-                    "for unlocking credential store: ", "", ".*", "", False, False)
-      return masterKey, True, False # return master key for saving passwords
+                "for unlocking credential store: ", "", ".*", "", False, False)
+
+    retCode = save_passwd_for_alias(alias, password, masterKey)
+    if retCode != 0:
+      print 'Failed to save secure password!'
+      return password
+    else:
+      return get_alias_string(alias)
+
+  return password
+
+def decrypt_password_for_alias(alias):
+  properties = get_ambari_properties()
+  if properties == -1:
+    raise FatalException(1, None)
+
+  isSecure = properties.get_property(SECURITY_IS_ENCRYPTION_ENABLED)
+  if isSecure and isSecure.lower() == 'true':
+    keyLocation = get_master_key_location(properties)
+    masterKeyFile = search_file(SECURITY_MASTER_KEY_FILENAME, keyLocation)
+    masterKey = None
+    if not masterKeyFile:
+      # Encryption enabled but no master key file found
+      masterKey = get_validated_string_input("Please provide master key " +\
+                "for unlocking credential store: ", "", ".*", "", False, False)
+
+    return read_passwd_for_alias(alias, masterKey)
   else:
   else:
-    if masterKeyFile is not None:
-      print_info_msg("Master key file exists. Updating property...")
-      update_properties({SECURITY_KEY_IS_PERSISTED : True})
-      return None, True, True
-
-  enable_ok = True
-  if not resetKey:
-    enable_ok = get_YN_input("Do you want encryption enabled for saving " +\
-                             "passwords [y/n] (n)? ", False)
-  if not enable_ok:
-    return None, False, None
-
-  key = None
-  if masterKeyFile is None or resetKey:
-    key = read_master_key()
+    return alias
+
+
+def setup_master_key():
+  if not is_root():
+    err = 'Ambari-server setup should be run with '\
+                     'root-level privileges'
+    raise FatalException(4, err)
+
+  properties = get_ambari_properties()
+  if properties == -1:
+    raise FatalException(1, "Failed to read properties file.")
+  # Check configuration for location of master key
+  keyLocation = get_master_key_location(properties)
+  masterKeyFile = search_file(SECURITY_MASTER_KEY_FILENAME, keyLocation)
+  isPersisted = True if masterKeyFile else False
+  isSecure = properties.get_property(SECURITY_IS_ENCRYPTION_ENABLED)
+  isSecure = True if isSecure and isSecure.lower() == 'true' else False
+  db_password = properties.get_property(JDBC_PASSWORD_PROPERTY)
+  # Read clear text password from from
+  if db_password and not is_alias_string(db_password) and os.path.isfile(db_password):
+    with open(db_password, 'r') as file:
+      db_password = file.read()
+      
+  ldap_password = properties.get_property(LDAP_MGR_PASSWORD_PROPERTY)
+  resetKey = False
+  masterKey = None
+
+  if isSecure:
+    resetKey = get_YN_input("Password encryption is enabled. Do you want to "
+                            "reset master key? [y/n] (n): ", False)
+
+  # For encrypting of only unencrypted passwords without resetting the key ask
+  # for master key if not persisted.
+  if isSecure and not isPersisted and not resetKey:
+    masterKey = get_validated_string_input('Please provide master key for '
+                  'the credential store: ', "", ".*", "", True, False)
+  pass
+
+  # Make sure both passwords are clear-text if master key is lost
+  if resetKey:
+    if not isPersisted:
+      masterKey = get_validated_string_input('Please provide original master '
+                  'key for the credential store. Press [Enter] to skip: ',
+                                             "", ".*", "", True, True)
+
+      if not masterKey:
+        err = '{0} is already encrypted. Please call {1} to store unencrypted' \
+              ' password and call "encrypt-passwords" again.'
+        if db_password and is_alias_string(db_password):
+          print err.format('Database password', '"' + SETUP_ACTION + '"')
+          return 1
+        if ldap_password and is_alias_string(ldap_password):
+          print err.format('LDAP manager password', '"' + LDAP_SETUP_ACTION + '"')
+          return 1
+      pass
+    pass
+  pass
 
 
+  # Read back any encrypted passwords
+  if db_password and is_alias_string(db_password):
+    db_password = read_passwd_for_alias(JDBC_RCA_PASSWORD_ALIAS, masterKey)
+  if ldap_password and is_alias_string(ldap_password):
+    ldap_password = read_passwd_for_alias(LDAP_MGR_PASSWORD_ALIAS, masterKey)
+
+  # Read master key, if non-secure or reset is true
+  if resetKey or not isSecure:
+    masterKey = read_master_key()
     persist = get_YN_input("Do you want to persist master key. If you choose "\
     persist = get_YN_input("Do you want to persist master key. If you choose "\
                            "not to persist, you need to provide the master "\
                            "not to persist, you need to provide the master "\
                            "key while starting the ambari server as an env "\
                            "key while starting the ambari server as an env "\
@@ -2474,42 +2543,44 @@ def setup_master_key(resetKey=False):
                            " or the start will prompt for the master key."
                            " or the start will prompt for the master key."
                            " Persist [y/n] (y)? ", True)
                            " Persist [y/n] (y)? ", True)
     if persist:
     if persist:
-      save_master_key(key, keyLocation + os.sep + SECURITY_MASTER_KEY_FILENAME,
-        persist)
-    elif not persist and masterKeyFile is not None:
+      save_master_key(masterKey, keyLocation + os.sep +
+                                 SECURITY_MASTER_KEY_FILENAME, persist)
+    elif not persist and masterKeyFile:
       try:
       try:
         os.remove(masterKeyFile)
         os.remove(masterKeyFile)
-        print_warning_msg("Master key exists although security " +\
-                          "is disabled. location: " + str(masterKeyFile))
+        print_info_msg("Deleting master key file at location: " + str(
+          masterKeyFile))
       except Exception, e:
       except Exception, e:
         print 'Could not remove master key file. %s' % e
         print 'Could not remove master key file. %s' % e
+    pass
+  pass
 
 
-  if persist is not None:
-    update_properties({SECURITY_KEY_IS_PERSISTED : persist})
-
-  if resetKey:
+  if resetKey and masterKey:
     # Blow up the credential store made with previous key
     # Blow up the credential store made with previous key
     store_file = get_credential_store_location(properties)
     store_file = get_credential_store_location(properties)
     if os.path.exists(store_file):
     if os.path.exists(store_file):
       os.remove(store_file)
       os.remove(store_file)
+  pass
 
 
-    # Encrypt the passwords with new key
-    db_password_alias = None
-    ldap_password_alias = None
-    try:
-      db_password_alias = properties[JDBC_PASSWORD_PROPERTY]
-      ldap_password_alias = properties[LDAP_MGR_PASSWORD_PROPERTY]
-    except (KeyError), e:
-      print_warning_msg("KeyError: " + str(e))
+  propertyMap = {SECURITY_IS_ENCRYPTION_ENABLED : 'true'}
+  # Encrypt only un-encrypted passwords
+  if db_password and not is_alias_string(db_password):
+    retCode = save_passwd_for_alias(JDBC_RCA_PASSWORD_ALIAS, db_password, masterKey)
+    propertyMap[JDBC_PASSWORD_PROPERTY] = get_alias_string(JDBC_RCA_PASSWORD_ALIAS)
+    if retCode != 0:
+      print 'Failed to save secure database password.'
+    else:
+      remove_password_file(JDBC_PASSWORD_FILENAME)
+  pass
 
 
-    if db_password_alias is not None and is_alias_string(db_password_alias):
-      configure_database_password(True, key, True)
+  if ldap_password and not is_alias_string(ldap_password):
+    retCode = save_passwd_for_alias(LDAP_MGR_PASSWORD_ALIAS, ldap_password, masterKey)
+    propertyMap[LDAP_MGR_PASSWORD_PROPERTY] = get_alias_string(LDAP_MGR_PASSWORD_ALIAS)
+    if retCode != 0:
+      print 'Failed to save secure LDAP password.'
+  pass
 
 
-    if ldap_password_alias is not None and is_alias_string(ldap_password_alias):
-      password = configure_ldap_password()
-      retCode = save_passwd_for_alias(LDAP_MGR_PASSWORD_ALIAS, password, key)
-      if retCode != 0:
-        print 'Saving secure ldap password failed. Exiting.'
+  update_properties(propertyMap)
 
 
   # Since files for store and master are created we need to ensure correct
   # Since files for store and master are created we need to ensure correct
   # permissions
   # permissions
@@ -2517,7 +2588,7 @@ def setup_master_key(resetKey=False):
   if ambari_user:
   if ambari_user:
     adjust_directory_permissions(ambari_user)
     adjust_directory_permissions(ambari_user)
 
 
-  return key, True, persist
+  return 0
 
 
 def get_credential_store_location(properties):
 def get_credential_store_location(properties):
   store_loc = properties[SECURITY_KEYS_DIR]
   store_loc = properties[SECURITY_KEYS_DIR]
@@ -2533,19 +2604,6 @@ def get_master_key_location(properties):
     keyLocation = properties[SECURITY_KEYS_DIR]
     keyLocation = properties[SECURITY_KEYS_DIR]
   return keyLocation
   return keyLocation
 
 
-def get_master_key_ispersisted(properties):
-  try:
-    isPersisted = properties[SECURITY_KEY_IS_PERSISTED]
-  except (KeyError), e:
-    return None
-
-  if isPersisted is not None and isPersisted != "":
-    return isPersisted == 'true' or isPersisted == 'TRUE' or\
-           isPersisted == 'True'
-
-  return None
-
-
 def is_alias_string(passwdStr):
 def is_alias_string(passwdStr):
   regex = re.compile("\$\{alias=[\w\.]+\}")
   regex = re.compile("\$\{alias=[\w\.]+\}")
   # Match implies string at beginning of word
   # Match implies string at beginning of word
@@ -2558,6 +2616,9 @@ def is_alias_string(passwdStr):
 def get_alias_string(alias):
 def get_alias_string(alias):
   return "${alias=" + alias + "}"
   return "${alias=" + alias + "}"
 
 
+def get_alias_from_alias_string(aliasStr):
+  return aliasStr[8:-1]
+
 def read_passwd_for_alias(alias, masterKey=""):
 def read_passwd_for_alias(alias, masterKey=""):
   if alias:
   if alias:
     jdk_path = find_jdk()
     jdk_path = find_jdk()
@@ -2634,7 +2695,7 @@ def save_master_key(master_key, key_location, persist=True):
 
 
 def configure_ldap_password():
 def configure_ldap_password():
   passwordDefault = ""
   passwordDefault = ""
-  passwordPrompt = 'Enter Manager Password*: '
+  passwordPrompt = 'Enter Manager Password* : '
   passwordPattern = ".*"
   passwordPattern = ".*"
   passwordDescr = "Invalid characters in password."
   passwordDescr = "Invalid characters in password."
 
 
@@ -2971,8 +3032,8 @@ def main():
       upgrade_stack(options, stack_id)
       upgrade_stack(options, stack_id)
     elif action == LDAP_SETUP_ACTION:
     elif action == LDAP_SETUP_ACTION:
       setup_ldap()
       setup_ldap()
-    elif action == RESET_MASTER_KEY_ACTION:
-      reset_master_key()
+    elif action == ENCRYPT_PASSWORDS_ACTION:
+      setup_master_key()
     elif action == UPDATE_METAINFO_ACTION:
     elif action == UPDATE_METAINFO_ACTION:
       update_metainfo(options)
       update_metainfo(options)
     elif action == SETUP_HTTPS_ACTION:
     elif action == SETUP_HTTPS_ACTION:

+ 166 - 150
ambari-server/src/test/python/TestAmbaryServer.py

@@ -27,6 +27,8 @@ import signal
 import stat
 import stat
 import datetime
 import datetime
 import operator
 import operator
+from pwd import getpwnam
+
 # We have to use this import HACK because the filename contains a dash
 # We have to use this import HACK because the filename contains a dash
 ambari_server = __import__('ambari-server')
 ambari_server = __import__('ambari-server')
 FatalException = ambari_server.FatalException
 FatalException = ambari_server.FatalException
@@ -608,17 +610,20 @@ class TestAmbariServer(TestCase):
     self.assertEquals(user, None)
     self.assertEquals(user, None)
 
 
 
 
+  @patch("os.path.exists")
   @patch.object(ambari_server, "set_file_permissions")
   @patch.object(ambari_server, "set_file_permissions")
   @patch.object(ambari_server, "run_os_command")
   @patch.object(ambari_server, "run_os_command")
   @patch.object(ambari_server, "get_ambari_properties")
   @patch.object(ambari_server, "get_ambari_properties")
   @patch.object(ambari_server, "get_value_from_properties")
   @patch.object(ambari_server, "get_value_from_properties")
   @patch("os.mkdir")
   @patch("os.mkdir")
-  def test_adjust_directory_permissions(self, mkdir_mock, get_value_from_properties_mock, get_ambari_properties_mock,
-                                        run_os_command_mock, set_file_permissions_mock):
+  def test_adjust_directory_permissions(self, mkdir_mock,
+            get_value_from_properties_mock, get_ambari_properties_mock,
+            run_os_command_mock, set_file_permissions_mock, exists_mock):
     # Testing boostrap dir wipe
     # Testing boostrap dir wipe
     properties_mock = MagicMock()
     properties_mock = MagicMock()
     get_value_from_properties_mock.return_value = "dummy_bootstrap_dir"
     get_value_from_properties_mock.return_value = "dummy_bootstrap_dir"
     ambari_server.adjust_directory_permissions("user")
     ambari_server.adjust_directory_permissions("user")
+    exists_mock.return_value = False
     self.assertEquals(run_os_command_mock.call_args_list[0][0][0], "rm -rf dummy_bootstrap_dir")
     self.assertEquals(run_os_command_mock.call_args_list[0][0][0], "rm -rf dummy_bootstrap_dir")
     self.assertTrue(mkdir_mock.called)
     self.assertTrue(mkdir_mock.called)
 
 
@@ -1673,7 +1678,9 @@ class TestAmbariServer(TestCase):
     self.assertEqual(None, rcode)
     self.assertEqual(None, rcode)
     self.assertTrue(setup_db_mock.called)
     self.assertTrue(setup_db_mock.called)
 
 
-
+  @patch("os.chown")
+  @patch("pwd.getpwnam")
+  @patch.object(ambari_server, 'get_master_key_location')
   @patch.object(ambari_server, 'save_master_key')
   @patch.object(ambari_server, 'save_master_key')
   @patch('os.chmod', autospec=True)
   @patch('os.chmod', autospec=True)
   @patch.object(ambari_server, 'get_validated_string_input')
   @patch.object(ambari_server, 'get_validated_string_input')
@@ -1700,15 +1707,22 @@ class TestAmbariServer(TestCase):
                  print_info_msg_mock, popenMock, openMock, pexistsMock,
                  print_info_msg_mock, popenMock, openMock, pexistsMock,
                  killMock, get_ambari_properties_mock, os_environ_mock,
                  killMock, get_ambari_properties_mock, os_environ_mock,
                  get_validated_string_input_method, os_chmod_method,
                  get_validated_string_input_method, os_chmod_method,
-                 save_master_key_method):
+                 save_master_key_method, get_master_key_location_method,
+                 getpwnam_mock, os_chown_mock):
     args = MagicMock()
     args = MagicMock()
 
 
     f = MagicMock()
     f = MagicMock()
     f.readline.return_value = 42
     f.readline.return_value = 42
     openMock.return_value = f
     openMock.return_value = f
-    get_ambari_properties_mock.return_value = \
-    {ambari_server.SECURITY_KEY_IS_PERSISTED : "True"}
 
 
+    p = get_ambari_properties_mock.return_value
+    p.get_property.return_value = 'False'
+    search_file_mock.return_value = None
+    pw = MagicMock()
+    pw.setattr('pw_uid', 0)
+    pw.setattr('pw_gid', 0)
+    getpwnam_mock.return_value = pw
+    os_chown_mock.return_value = None
     # Checking "server is running"
     # Checking "server is running"
     pexistsMock.return_value = True
     pexistsMock.return_value = True
     try:
     try:
@@ -1882,8 +1896,6 @@ class TestAmbariServer(TestCase):
 
 
     # Check environ master key is set
     # Check environ master key is set
     popenMock.reset_mock()
     popenMock.reset_mock()
-    get_ambari_properties_mock.return_value = \
-    {ambari_server.SECURITY_KEY_IS_PERSISTED : "False"}
     os_environ_mock.copy.return_value = {"a" : "b",
     os_environ_mock.copy.return_value = {"a" : "b",
         ambari_server.SECURITY_KEY_ENV_VAR_NAME : "masterkey"}
         ambari_server.SECURITY_KEY_ENV_VAR_NAME : "masterkey"}
     args.persistence_type="local"
     args.persistence_type="local"
@@ -1902,8 +1914,7 @@ class TestAmbariServer(TestCase):
     # Check environ master key is not set
     # Check environ master key is not set
     popenMock.reset_mock()
     popenMock.reset_mock()
     os_environ_mock.reset_mock()
     os_environ_mock.reset_mock()
-    get_ambari_properties_mock.return_value = \
-    {ambari_server.SECURITY_KEY_IS_PERSISTED : "False"}
+    p.get_property.return_value = 'True'
     os_environ_mock.copy.return_value = {"a" : "b"}
     os_environ_mock.copy.return_value = {"a" : "b"}
     args.persistence_type="local"
     args.persistence_type="local"
     read_ambari_user_mock.return_value = "root"
     read_ambari_user_mock.return_value = "root"
@@ -2766,13 +2777,12 @@ class TestAmbariServer(TestCase):
     self.assertEquals(args.persistence_type, "remote")
     self.assertEquals(args.persistence_type, "remote")
 
 
 
 
-  @patch.object(ambari_server, 'setup_master_key')
-  @patch.object(ambari_server, 'read_passwd_for_alias')
+  @patch.object(ambari_server, 'decrypt_password_for_alias')
   @patch.object(ambari_server, 'is_alias_string')
   @patch.object(ambari_server, 'is_alias_string')
   @patch.object(ambari_server, 'get_ambari_properties')
   @patch.object(ambari_server, 'get_ambari_properties')
   def test_configure_database_username_password_masterkey_persisted(self,
   def test_configure_database_username_password_masterkey_persisted(self,
           get_ambari_properties_method, is_alias_string_method,
           get_ambari_properties_method, is_alias_string_method,
-          read_passwd_for_alias_method, setup_master_key_method):
+          decrypt_password_for_alias_method):
 
 
     out = StringIO.StringIO()
     out = StringIO.StringIO()
     sys.stdout = out
     sys.stdout = out
@@ -2784,170 +2794,148 @@ class TestAmbariServer(TestCase):
     get_ambari_properties_method.return_value = configs
     get_ambari_properties_method.return_value = configs
 
 
     is_alias_string_method.return_value = True
     is_alias_string_method.return_value = True
-    read_passwd_for_alias_method.return_value = "falepasswd"
+    decrypt_password_for_alias_method.return_value = "falepasswd"
     args = MagicMock()
     args = MagicMock()
+    args.master_key = None
 
 
     ambari_server.configure_database_username_password(args)
     ambari_server.configure_database_username_password(args)
 
 
-    self.assertTrue(read_passwd_for_alias_method.called)
+    self.assertTrue(decrypt_password_for_alias_method.called)
     self.assertTrue(is_alias_string_method.called)
     self.assertTrue(is_alias_string_method.called)
     self.assertEquals("fakeuser", args.database_username)
     self.assertEquals("fakeuser", args.database_username)
     self.assertEquals("falepasswd", args.database_password)
     self.assertEquals("falepasswd", args.database_password)
 
 
-    configs[ambari_server.SECURITY_KEY_IS_PERSISTED] = "False"
-    get_ambari_properties_method.return_value = configs
-    args.reset_mock()
-    setup_master_key_method.return_value = (None, True, True)
-
-    ambari_server.configure_database_username_password(args)
-
-    self.assertTrue(setup_master_key_method.called)
-    read_passwd_for_alias_method.assert_called_with(
-        ambari_server.JDBC_RCA_PASSWORD_ALIAS, None)
-
     sys.stdout = sys.__stdout__
     sys.stdout = sys.__stdout__
 
 
 
 
-  @patch.object(ambari_server, 'save_passwd_for_alias')
   @patch.object(ambari_server, 'read_password')
   @patch.object(ambari_server, 'read_password')
-  def test_configure_database_password(self, read_password_method,
-                                       save_passwd_for_alias_method):
+  def test_configure_database_password(self, read_password_method):
 
 
     out = StringIO.StringIO()
     out = StringIO.StringIO()
     sys.stdout = out
     sys.stdout = out
 
 
     read_password_method.return_value = "fakepasswd"
     read_password_method.return_value = "fakepasswd"
-    save_passwd_for_alias_method.return_value = 0
 
 
-    result = ambari_server.configure_database_password(True, None, True)
-    self.assertTrue(save_passwd_for_alias_method.called)
+    result = ambari_server.configure_database_password(True)
     self.assertTrue(read_password_method.called)
     self.assertTrue(read_password_method.called)
-    save_passwd_for_alias_method.assert_called_with(ambari_server
-      .JDBC_RCA_PASSWORD_ALIAS, "fakepasswd", None)
-    self.assertEquals(("fakepasswd", ambari_server.get_alias_string(
-      ambari_server.JDBC_RCA_PASSWORD_ALIAS)), result)
+    self.assertEquals("fakepasswd", result)
 
 
-    save_passwd_for_alias_method.reset_mock()
-    result = ambari_server.configure_database_password(False, None, True)
-    self.assertFalse(save_passwd_for_alias_method.called)
-    self.assertEquals(("fakepasswd", None), result)
+    result = ambari_server.configure_database_password(True)
+    self.assertEquals("fakepasswd", result)
 
 
-    save_passwd_for_alias_method.reset_mock()
-    save_passwd_for_alias_method.return_value = -1
-    result = ambari_server.configure_database_password(True, None, True)
-    self.assertEquals(("fakepasswd", None), result)
+    result = ambari_server.configure_database_password(True)
+    self.assertEquals("fakepasswd", result)
 
 
     sys.stdout = sys.__stdout__
     sys.stdout = sys.__stdout__
 
 
 
 
-  @patch.object(ambari_server, 'read_ambari_user')
+  @patch.object(ambari_server, 'remove_password_file')
+  @patch.object(ambari_server, 'save_passwd_for_alias')
   @patch.object(ambari_server, 'read_master_key')
   @patch.object(ambari_server, 'read_master_key')
+  @patch.object(ambari_server, 'read_ambari_user')
+  @patch.object(ambari_server, 'get_master_key_location')
   @patch.object(ambari_server, 'update_properties')
   @patch.object(ambari_server, 'update_properties')
   @patch.object(ambari_server, 'save_master_key')
   @patch.object(ambari_server, 'save_master_key')
   @patch.object(ambari_server, 'get_YN_input')
   @patch.object(ambari_server, 'get_YN_input')
+  @patch.object(ambari_server, 'search_file')
   @patch.object(ambari_server, 'get_ambari_properties')
   @patch.object(ambari_server, 'get_ambari_properties')
-  def test_setup_master_key_persist(self, get_ambari_properties_method,
-            get_YN_input_method, save_master_key_method,
-            update_properties_method, read_master_key_method,
-            read_ambari_user_method):
+  @patch.object(ambari_server, 'is_root')
+  def test_setup_master_key_not_persist(self, is_root_method,
+              get_ambari_properties_method, search_file_message,
+              get_YN_input_method, save_master_key_method,
+              update_properties_method, get_master_key_location_method,
+              read_ambari_user_method, read_master_key_method,
+              save_passwd_for_alias_method, remove_password_file_method):
 
 
     out = StringIO.StringIO()
     out = StringIO.StringIO()
     sys.stdout = out
     sys.stdout = out
-    configs = { ambari_server.SECURITY_MASTER_KEY_LOCATION : "filepath",
-                ambari_server.SECURITY_KEYS_DIR : tempfile.gettempdir(),
-                ambari_server.SECURITY_KEY_IS_PERSISTED : None }
 
 
-    get_ambari_properties_method.return_value = configs
-    get_YN_input_method.return_value = True
+    is_root_method.return_value = True
+    p = get_ambari_properties_method.return_value
+    p.get_property.side_effect = [ None, "fakepasswd", "fakepasswd" ]
     read_master_key_method.return_value = "aaa"
     read_master_key_method.return_value = "aaa"
+    get_YN_input_method.return_value = False
     read_ambari_user_method.return_value = None
     read_ambari_user_method.return_value = None
-    save_master_key_method.return_value = None
-    update_properties_method.return_value = None
+    save_passwd_for_alias_method.return_value = 0
 
 
-    ambari_server.setup_master_key(False)
+    ambari_server.setup_master_key()
 
 
     self.assertTrue(get_YN_input_method.called)
     self.assertTrue(get_YN_input_method.called)
     self.assertTrue(read_master_key_method.called)
     self.assertTrue(read_master_key_method.called)
     self.assertTrue(read_ambari_user_method.called)
     self.assertTrue(read_ambari_user_method.called)
-    self.assertTrue(save_master_key_method.called)
     self.assertTrue(update_properties_method.called)
     self.assertTrue(update_properties_method.called)
+    self.assertFalse(save_master_key_method.called)
+    self.assertTrue(save_passwd_for_alias_method.called)
+    self.assertEquals(2, save_passwd_for_alias_method.call_count)
+    self.assertTrue(remove_password_file_method.called)
+
+    result_expected = {ambari_server.JDBC_PASSWORD_PROPERTY :
+        ambari_server.get_alias_string(ambari_server.JDBC_RCA_PASSWORD_ALIAS),
+        ambari_server.LDAP_MGR_PASSWORD_PROPERTY :
+        ambari_server.get_alias_string(ambari_server.LDAP_MGR_PASSWORD_ALIAS),
+        ambari_server.SECURITY_IS_ENCRYPTION_ENABLED : 'true'}
+
+    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
+    sorted_y = sorted(update_properties_method.call_args[0][0].iteritems(),
+                      key=operator.itemgetter(0))
+    self.assertEquals(sorted_x, sorted_y)
 
 
     sys.stdout = sys.__stdout__
     sys.stdout = sys.__stdout__
 
 
 
 
-  @patch.object(ambari_server, 'read_ambari_user')
   @patch.object(ambari_server, 'read_master_key')
   @patch.object(ambari_server, 'read_master_key')
+  @patch.object(ambari_server, 'read_ambari_user')
+  @patch.object(ambari_server, 'get_master_key_location')
   @patch.object(ambari_server, 'update_properties')
   @patch.object(ambari_server, 'update_properties')
   @patch.object(ambari_server, 'save_master_key')
   @patch.object(ambari_server, 'save_master_key')
   @patch.object(ambari_server, 'get_YN_input')
   @patch.object(ambari_server, 'get_YN_input')
+  @patch.object(ambari_server, 'search_file')
   @patch.object(ambari_server, 'get_ambari_properties')
   @patch.object(ambari_server, 'get_ambari_properties')
-  def test_setup_master_key_not_persist(self, get_ambari_properties_method,
+  @patch.object(ambari_server, 'is_root')
+  def test_setup_master_key_persist(self, is_root_method,
+              get_ambari_properties_method, search_file_message,
               get_YN_input_method, save_master_key_method,
               get_YN_input_method, save_master_key_method,
-              update_properties_method, read_master_key_method,
-              read_ambari_user_method):
+              update_properties_method, get_master_key_location_method,
+              read_ambari_user_method, read_master_key_method):
 
 
     out = StringIO.StringIO()
     out = StringIO.StringIO()
     sys.stdout = out
     sys.stdout = out
-    configs = { ambari_server.SECURITY_MASTER_KEY_LOCATION : "filepath",
-                ambari_server.SECURITY_KEYS_DIR : tempfile.gettempdir(),
-                ambari_server.SECURITY_KEY_IS_PERSISTED : None }
 
 
-    get_ambari_properties_method.return_value = configs
-    get_YN_input_method.side_effect = [True, False]
+    is_root_method.return_value = True
+    p = get_ambari_properties_method.return_value
+    p.get_property.side_effect = [ None, "fakepasswd", None ]
     read_master_key_method.return_value = "aaa"
     read_master_key_method.return_value = "aaa"
+    get_YN_input_method.side_effect = [True, False]
     read_ambari_user_method.return_value = None
     read_ambari_user_method.return_value = None
-    save_master_key_method.return_value = None
-    update_properties_method.return_value = None
 
 
-    ambari_server.setup_master_key(False)
+    ambari_server.setup_master_key()
 
 
     self.assertTrue(get_YN_input_method.called)
     self.assertTrue(get_YN_input_method.called)
     self.assertTrue(read_master_key_method.called)
     self.assertTrue(read_master_key_method.called)
     self.assertTrue(read_ambari_user_method.called)
     self.assertTrue(read_ambari_user_method.called)
     self.assertTrue(update_properties_method.called)
     self.assertTrue(update_properties_method.called)
-    self.assertFalse(save_master_key_method.called)
-
-    sys.stdout = sys.__stdout__
-
-
-  @patch.object(ambari_server, 'get_master_key_ispersisted')
-  @patch.object(ambari_server, 'update_properties')
-  @patch.object(ambari_server, 'save_master_key')
-  @patch.object(ambari_server, 'get_validated_string_input')
-  @patch.object(ambari_server, 'get_YN_input')
-  @patch.object(ambari_server, 'get_ambari_properties')
-  @patch.object(ambari_server, 'search_file')
-  def test_setup_master_key_already_persisted(self, search_file_message,
-            get_ambari_properties_method,
-            get_YN_input_method, get_validated_string_input_method,
-            save_master_key_method, update_properties_method,
-            get_master_key_ispersisted_method):
-
-    out = StringIO.StringIO()
-    sys.stdout = out
-    configs = { ambari_server.SECURITY_MASTER_KEY_LOCATION : "filepath",
-                ambari_server.SECURITY_KEYS_DIR : tempfile.gettempdir(),
-                ambari_server.SECURITY_KEY_IS_PERSISTED : "true" }
-
-    get_ambari_properties_method.return_value = configs
-    get_master_key_ispersisted_method.return_value = True
-    search_file_message.return_value = "filepath"
+    self.assertTrue(save_master_key_method.called)
 
 
-    ambari_server.setup_master_key(False)
+    result_expected = {ambari_server.JDBC_PASSWORD_PROPERTY:
+        ambari_server.get_alias_string(ambari_server.JDBC_RCA_PASSWORD_ALIAS),
+        ambari_server.SECURITY_IS_ENCRYPTION_ENABLED: 'true'}
 
 
-    self.assertFalse(save_master_key_method.called)
-    self.assertFalse(get_YN_input_method.called)
-    self.assertFalse(get_validated_string_input_method.called)
-    self.assertFalse(update_properties_method.called)
+    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
+    sorted_y = sorted(update_properties_method.call_args[0][0].iteritems(),
+                      key=operator.itemgetter(0))
+    self.assertEquals(sorted_x, sorted_y)
 
 
     sys.stdout = sys.__stdout__
     sys.stdout = sys.__stdout__
 
 
 
 
+  @patch.object(ambari_server, 'read_master_key')
+  @patch.object(ambari_server, 'remove_password_file')
+  @patch("os.path.exists")
+  @patch.object(ambari_server, 'read_ambari_user')
+  @patch.object(ambari_server, 'get_master_key_location')
+  @patch("ambari-server.Properties")
   @patch.object(ambari_server, 'save_passwd_for_alias')
   @patch.object(ambari_server, 'save_passwd_for_alias')
-  @patch.object(ambari_server, 'configure_ldap_password')
-  @patch.object(ambari_server, 'configure_database_password')
-  @patch.object(ambari_server, 'is_alias_string')
-  @patch.object(ambari_server, 'get_master_key_ispersisted')
+  @patch.object(ambari_server, 'read_passwd_for_alias')
   @patch.object(ambari_server, 'update_properties')
   @patch.object(ambari_server, 'update_properties')
   @patch.object(ambari_server, 'save_master_key')
   @patch.object(ambari_server, 'save_master_key')
   @patch.object(ambari_server, 'get_validated_string_input')
   @patch.object(ambari_server, 'get_validated_string_input')
@@ -2955,12 +2943,14 @@ class TestAmbariServer(TestCase):
   @patch.object(ambari_server, 'search_file')
   @patch.object(ambari_server, 'search_file')
   @patch.object(ambari_server, 'get_ambari_properties')
   @patch.object(ambari_server, 'get_ambari_properties')
   @patch.object(ambari_server, 'is_root')
   @patch.object(ambari_server, 'is_root')
-  def test_reset_master_key_persisted(self, is_root_method, get_ambari_properties_method,
-              search_file_message, get_YN_input_method,
-              get_validated_string_input_method, save_master_key_method,
-              update_properties_method, get_master_key_ispersisted_method,
-              is_alias_string_method, configure_database_password_method,
-              configure_ldap_password_method, save_passwd_for_alias_method):
+  def test_reset_master_key_persisted(self, is_root_method,
+              get_ambari_properties_method, search_file_message,
+              get_YN_input_method, get_validated_string_input_method,
+              save_master_key_method, update_properties_method,
+              read_passwd_for_alias_method, save_passwd_for_alias_method,
+              Properties_mock, get_master_key_location_method,
+              read_ambari_user_method, exists_mock,
+              remove_password_file_method, read_master_key_method):
 
 
     out = StringIO.StringIO()
     out = StringIO.StringIO()
     sys.stdout = out
     sys.stdout = out
@@ -2968,7 +2958,7 @@ class TestAmbariServer(TestCase):
     # Testing call under non-root
     # Testing call under non-root
     is_root_method.return_value = False
     is_root_method.return_value = False
     try:
     try:
-      ambari_server.reset_master_key()
+      ambari_server.setup_master_key()
       self.fail("Should throw exception")
       self.fail("Should throw exception")
     except FatalException as fe:
     except FatalException as fe:
       # Expected
       # Expected
@@ -2979,36 +2969,48 @@ class TestAmbariServer(TestCase):
     is_root_method.return_value = True
     is_root_method.return_value = True
 
 
     search_file_message.return_value = "filepath"
     search_file_message.return_value = "filepath"
-    configs = { ambari_server.SECURITY_MASTER_KEY_LOCATION : "filepath",
-                ambari_server.SECURITY_KEYS_DIR : tempfile.gettempdir(),
-                ambari_server.SECURITY_KEY_IS_PERSISTED : "true",
-                ambari_server.JDBC_PASSWORD_PROPERTY : "${alias=fakealias}",
-                ambari_server.LDAP_MGR_PASSWORD_PROPERTY : "${alias=fakealias}"}
+    read_ambari_user_method.return_value = None
+    p = get_ambari_properties_method.return_value
+    p.get_property.side_effect = [ 'true', '${alias=fakealias}',
+                                   '${alias=fakealias}' ]
 
 
-    get_ambari_properties_method.return_value = configs
-    get_master_key_ispersisted_method.return_value = True
-    get_validated_string_input_method.return_value = "aaa"
-    get_YN_input_method.return_value = True
-    is_alias_string_method.return_value = True
+    get_YN_input_method.side_effect = [ True, True ]
+    read_master_key_method.return_value = "aaa"
+    read_passwd_for_alias_method.return_value = "fakepassword"
+    save_passwd_for_alias_method.return_value = 0
+    exists_mock.return_value = False
 
 
-    ambari_server.reset_master_key()
+    ambari_server.setup_master_key()
 
 
     self.assertTrue(save_master_key_method.called)
     self.assertTrue(save_master_key_method.called)
     self.assertTrue(get_YN_input_method.called)
     self.assertTrue(get_YN_input_method.called)
-    self.assertTrue(get_validated_string_input_method.called)
+    self.assertTrue(read_master_key_method.called)
     self.assertTrue(update_properties_method.called)
     self.assertTrue(update_properties_method.called)
-    self.assertTrue(configure_database_password_method.called)
-    self.assertTrue(configure_ldap_password_method.called)
-    self.assertTrue(save_passwd_for_alias_method.called)
+    self.assertTrue(read_passwd_for_alias_method.called)
+    self.assertTrue(2, read_passwd_for_alias_method.call_count)
+    self.assertTrue(2, save_passwd_for_alias_method.call_count)
+
+    result_expected = {ambari_server.JDBC_PASSWORD_PROPERTY:
+        ambari_server.get_alias_string(ambari_server.JDBC_RCA_PASSWORD_ALIAS),
+        ambari_server.LDAP_MGR_PASSWORD_PROPERTY:
+        ambari_server.get_alias_string(ambari_server.LDAP_MGR_PASSWORD_ALIAS),
+        ambari_server.SECURITY_IS_ENCRYPTION_ENABLED: 'true'}
+
+    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
+    sorted_y = sorted(update_properties_method.call_args[0][0].iteritems(),
+                      key=operator.itemgetter(0))
+    self.assertEquals(sorted_x, sorted_y)
 
 
     sys.stdout = sys.__stdout__
     sys.stdout = sys.__stdout__
 
 
 
 
+  @patch.object(ambari_server, 'remove_password_file')
+  @patch("os.path.exists")
+  @patch.object(ambari_server, 'read_ambari_user')
+  @patch.object(ambari_server, 'get_master_key_location')
+  @patch("ambari-server.Properties")
   @patch.object(ambari_server, 'save_passwd_for_alias')
   @patch.object(ambari_server, 'save_passwd_for_alias')
-  @patch.object(ambari_server, 'configure_ldap_password')
-  @patch.object(ambari_server, 'configure_database_password')
-  @patch.object(ambari_server, 'is_alias_string')
-  @patch.object(ambari_server, 'get_master_key_ispersisted')
+  @patch.object(ambari_server, 'read_passwd_for_alias')
   @patch.object(ambari_server, 'update_properties')
   @patch.object(ambari_server, 'update_properties')
   @patch.object(ambari_server, 'save_master_key')
   @patch.object(ambari_server, 'save_master_key')
   @patch.object(ambari_server, 'get_validated_string_input')
   @patch.object(ambari_server, 'get_validated_string_input')
@@ -3016,39 +3018,53 @@ class TestAmbariServer(TestCase):
   @patch.object(ambari_server, 'search_file')
   @patch.object(ambari_server, 'search_file')
   @patch.object(ambari_server, 'get_ambari_properties')
   @patch.object(ambari_server, 'get_ambari_properties')
   @patch.object(ambari_server, 'is_root')
   @patch.object(ambari_server, 'is_root')
-  def test_reset_master_key_not_persisted(self, is_root_method, get_ambari_properties_method,
+  def test_reset_master_key_not_persisted(self, is_root_method,
+              get_ambari_properties_method,
               search_file_message, get_YN_input_method,
               search_file_message, get_YN_input_method,
               get_validated_string_input_method, save_master_key_method,
               get_validated_string_input_method, save_master_key_method,
-              update_properties_method, get_master_key_ispersisted_method,
-              is_alias_string_method, configure_database_password_method,
-              configure_ldap_password_method, save_passwd_for_alias_method):
+              update_properties_method, read_passwd_for_alias_method,
+              save_passwd_for_alias_method, Properties_mock,
+              get_master_key_location_method, read_ambari_user_method,
+              exists_mock, remove_password_file_method):
 
 
     out = StringIO.StringIO()
     out = StringIO.StringIO()
     sys.stdout = out
     sys.stdout = out
+
     is_root_method.return_value = True
     is_root_method.return_value = True
-    search_file_message.return_value = "filepath"
-    configs = { ambari_server.SECURITY_MASTER_KEY_LOCATION : "filepath",
-                ambari_server.SECURITY_KEYS_DIR : tempfile.gettempdir(),
-                ambari_server.SECURITY_KEY_IS_PERSISTED : "false",
-                ambari_server.JDBC_PASSWORD_PROPERTY : "${alias=fakealias}",
-                ambari_server.LDAP_MGR_PASSWORD_PROPERTY : "${alias=fakealias}"}
+    search_file_message.return_value = False
+    read_ambari_user_method.return_value = None
+    p = get_ambari_properties_method.return_value
+    p.get_property.side_effect = [ 'true', '${alias=fakealias}',
+                                   '${alias=fakealias}' ]
 
 
-    get_ambari_properties_method.return_value = configs
-    get_master_key_ispersisted_method.return_value = False
+    get_YN_input_method.side_effect = [ True, False ]
     get_validated_string_input_method.return_value = "aaa"
     get_validated_string_input_method.return_value = "aaa"
-    get_YN_input_method.return_value = False
-    is_alias_string_method.return_value = True
+    read_passwd_for_alias_method.return_value = "fakepassword"
+    save_passwd_for_alias_method.return_value = 0
+    exists_mock.return_value = False
 
 
-    ambari_server.reset_master_key()
+    ambari_server.setup_master_key()
 
 
     self.assertFalse(save_master_key_method.called)
     self.assertFalse(save_master_key_method.called)
     self.assertTrue(get_YN_input_method.called)
     self.assertTrue(get_YN_input_method.called)
     self.assertTrue(get_validated_string_input_method.called)
     self.assertTrue(get_validated_string_input_method.called)
     self.assertTrue(update_properties_method.called)
     self.assertTrue(update_properties_method.called)
-    self.assertTrue(configure_database_password_method.called)
-    self.assertTrue(configure_ldap_password_method.called)
+    self.assertTrue(read_passwd_for_alias_method.called)
+    self.assertTrue(2, read_passwd_for_alias_method.call_count)
+    self.assertTrue(2, save_passwd_for_alias_method.call_count)
     self.assertFalse(save_master_key_method.called)
     self.assertFalse(save_master_key_method.called)
 
 
+    result_expected = {ambari_server.JDBC_PASSWORD_PROPERTY:
+        ambari_server.get_alias_string(ambari_server.JDBC_RCA_PASSWORD_ALIAS),
+        ambari_server.LDAP_MGR_PASSWORD_PROPERTY:
+        ambari_server.get_alias_string(ambari_server.LDAP_MGR_PASSWORD_ALIAS),
+        ambari_server.SECURITY_IS_ENCRYPTION_ENABLED: 'true'}
+
+    sorted_x = sorted(result_expected.iteritems(), key=operator.itemgetter(0))
+    sorted_y = sorted(update_properties_method.call_args[0][0].iteritems(),
+                      key=operator.itemgetter(0))
+    self.assertEquals(sorted_x, sorted_y)
+
     sys.stdout = sys.__stdout__
     sys.stdout = sys.__stdout__
 
 
 
 
@@ -3117,7 +3133,7 @@ class TestAmbariServer(TestCase):
       "authentication.ldap.bindAnonymously" : "false",
       "authentication.ldap.bindAnonymously" : "false",
       "authentication.ldap.managerDn" : "test",
       "authentication.ldap.managerDn" : "test",
       "authentication.ldap.managerPassword" : \
       "authentication.ldap.managerPassword" : \
-        '${alias=ambari.ldap.manager.password}',
+       'password',
       "client.security" : "ldap"
       "client.security" : "ldap"
     }
     }