Example #1
0
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)
Example #2
0
    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__())
Example #3
0
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