def add_config_file_line(config_file, line, sudo_password): """Add line to config file (see above for detailed description). This is just a wrapper over _add_config_file_line(). Unless we are running as root, we need to spawn a subprocess and run it under sudo """ if processutils.is_running_as_root(): _add_config_file_line(config_file, line) else: processutils.run_sudo_program([sys.executable, __file__, config_file, line], sudo_password, logger)
def run(self, password_file, username, password, apache_config): class LogProxy: """We need to wrap the logger and capture any action events, as those may contain the password. """ def __init__(self, logger): #Set attribute. self._logger = logger def __getattr__(self, attrib): if attrib == "action": return self.action else: return getattr(self._logger, attrib) def action(self, msg): pass htpasswd_exe = apache_config.htpasswd_exe action._check_file_exists(htpasswd_exe, self) if os.path.exists(password_file): cmd = [htpasswd_exe, "-b", password_file, username, password] else: cmd = [htpasswd_exe, "-b", "-c", password_file, username, password] if self.ctx._get_sudo_password(self)==None or iuprocess.is_running_as_root(): self.ctx.logger.action("%s <password>" % " ".join(cmd[0:-1])) rc = iuprocess.run_and_log_program(cmd, {}, LogProxy(self.ctx.logger)) if rc != 0: raise UserError(errors[ERR_APACHE_HTPASSWD], msg_args={"exe": htpasswd_exe, "file": password_file, "id":self.ctx.props.id}, developer_msg="return code was %d" % rc) else: try: logger.action("sudo %s <password>" % " ".join(cmd[0:-1])) iuprocess.run_sudo_program(cmd, self.ctx._get_sudo_password(self), LogProxy(self.ctx.logger)) except Exception, e: exc_info = sys.exc_info() logger.exception("exception in htpasswd: %s, resource %s" % (e.__repr__(), ctx.props.id)) raise convert_exc_to_user_error(exc_info, errors[ERR_APACHE_HTPASSWD], msg_args={"exe": htpasswd_exe, "file": password_file, "id":self.ctx.props.id}, developer_msg="exception" % e.__repr__())
def generate_pw_file_if_necessary( engage_file_layout, deployment_home, parsed_install_solution, library, installer_supplied_pw_key_list=None, master_password_file=None, read_master_pw_from_stdin=False, suppress_master_password_file=False, generate_random_passwords=False, dry_run=False, ): """Do the password database setup. """ # helper functions def get_master_password(ask_only_once=False): return _get_master_password( deployment_home, master_password_file, read_master_pw_from_stdin, ask_only_once=ask_only_once, dry_run=dry_run, ) def get_new_pw_db(): return pw_repository.PasswordRepository(get_master_password()) # Get some file locations from the engage_file_layout object efl = engage_file_layout preprocessed_resource_def_file = efl.get_preprocessed_resource_file() pw_file = efl.get_password_database_file() pw_salt = efl.get_password_salt_file() # First, load the resource definitions and instances with open(preprocessed_resource_def_file, "rb") as f: g = rdef.create_resource_graph(json.load(f)) # read the existing password db if it exists if os.path.exists(pw_file): assert os.path.exists(pw_salt), "Password file present, but no password salt file at %s" % pw_salt load_from_file = pw_repository.PasswordRepository.load_from_file pw_db = load_from_file(pw_file, pw_salt, get_master_password(ask_only_once=True)) orig_pw_db = copy.copy(pw_db) else: pw_db = None orig_pw_db = None # obtain passwords referenced in the installer_config.json file, if any if installer_supplied_pw_key_list != None and len(installer_supplied_pw_key_list) > 0: if pw_db == None: pw_db = get_new_pw_db() for (pw_key, pw_desc) in installer_supplied_pw_key_list: # we only ask if the pw is not already present if not pw_db.has_key(pw_key): pw_db.add_key( pw_key, _prompt_for_password(pw_desc, pw_key, generate_random=generate_random_passwords, dry_run=dry_run), ) # Go through the install script. Check to see if there are any resources # that require root access. Also, see what passwords are missing, # and prompt for those. requires_root_access = False always_requires_pw_file = False for inst_md in parsed_install_solution: if inst_md.package != None: continue # new-style packages cannot have this password mess entry = library.get_entry(inst_md) if entry == None: raise Exception("Unable to find resource library entry for resource %s" % inst_md.key.__repr__()) # See if the resource requires root access. If the resource says it # needs root access, we also check if it is already installed (according # to the installed property on the resource metadta). If it is already # installed and isn't a service, we don't need root access. if entry.requires_root_access() and ( (not inst_md.is_installed()) or hasattr(entry.get_manager_class(), "start") ): logger.debug("Resource %s requires root access." % inst_md.id) requires_root_access = True if entry.always_requires_password_file(): always_requires_pw_file = True r = g.get_resource(inst_md.key) pw_props = r.get_password_properties() if len(pw_props) == 0: continue # no passwords on this resource if pw_db == None: pw_db = get_new_pw_db() # we lazily create the pw db for (prop, default_val) in pw_props.items(): if inst_md.config_port.has_key(prop): pw_key = inst_md.config_port[prop] elif default_val != None: pw_key = default_val else: raise Exception( "Resource instance %s (type %s) is missing a value for password property %s" % (inst["id"], inst["key"], prop) ) if not pw_db.has_key(pw_key): pw_db.add_key( pw_key, _prompt_for_password( "Password for %s, property %s" % (inst_md.id, prop), pw_key, generate_random=generate_random_passwords, dry_run=dry_run, ), ) # see if we need the sudo password. If so, ask for it and add to # password database if requires_root_access: if procutils.is_running_as_root(): logger.debug("Root access required, but no sudo password is required as we are running as root") elif procutils.SUDO_PASSWORD_REQUIRED == False: logger.debug("Root access required, but no sudo password is required for this user") else: logger.debug("Root access required, asking for sudo password") if pw_db == None: pw_db = get_new_pw_db() _add_sudo_password_to_repository(pw_db, dry_run=dry_run) # In some cases, a resource may want to ensure that there always is a # password file. if always_requires_pw_file and pw_db == None: pw_db = get_new_pw_db() # write out the password database, if it changed if pw_db and (orig_pw_db == None or orig_pw_db.data != pw_db.data): logger.info("Writing password file to %s" % pw_file) if not dry_run: pw_db.save_to_file(pw_file, pw_salt) if pw_db and (not suppress_master_password_file) and deployment_home: # write out the master password to the default file if it was not already # there. master_pwfile = _default_master_pwfile(deployment_home) if (not os.path.exists(master_pwfile)) or _read_pwfile(master_pwfile) != pw_db.user_key: with open(master_pwfile, "w") as f: f.write(pw_db.user_key) os.chmod(master_pwfile, 0600) if pw_db == None: logger.info("No password database required") return pw_db