Exemplo n.º 1
0
 def generate(self, cli_object):
     if cli_object.username is None:
         print "You must provide a username for postgres_md5 hashes!"
         return "Postgres_md5 Hashes require a username"
     generatedhash = postgres_md5.encrypt(cli_object.plaintext,
                                          user=cli_object.username)
     return generatedhash
Exemplo n.º 2
0
def user_alter(cursor, module, user, password, role_attr_flags, encrypted,
               expires, no_password_changes):
    """Change user password and/or attributes. Return True if changed, False otherwise."""
    changed = False

    # Note: role_attr_flags escaped by parse_role_attrs and encrypted is a literal
    if user == 'PUBLIC':
        if password is not None:
            module.fail_json(msg="cannot change the password for PUBLIC user")
        elif role_attr_flags != '':
            module.fail_json(
                msg="cannot change the role_attr_flags for PUBLIC user")
        else:
            return False

    # Handle passwords.
    if not no_password_changes and (password is not None
                                    or role_attr_flags != ''):
        # Select password and all flag-like columns in order to verify changes.
        query_password_data = dict(password=password, expires=expires)
        select = "SELECT * FROM pg_authid where rolname=%(user)s"
        cursor.execute(select, {"user": user})
        # Grab current role attributes.
        current_role_attrs = cursor.fetchone()

        # Do we actually need to do anything?
        pwchanging = False
        if password is not None:
            if encrypted:
                if password.startswith('md5'):
                    if password != current_role_attrs['rolpassword']:
                        pwchanging = True
                else:
                    try:
                        from passlib.hash import postgres_md5 as pm
                        if pm.encrypt(
                                password,
                                user) != current_role_attrs['rolpassword']:
                            pwchanging = True
                    except ImportError:
                        # Cannot check if passlib is not installed, so assume password is different
                        pwchanging = True
            else:
                if password != current_role_attrs['rolpassword']:
                    pwchanging = True

        role_attr_flags_changing = False
        if role_attr_flags:
            role_attr_flags_dict = {}
            for r in role_attr_flags.split(' '):
                if r.startswith('NO'):
                    role_attr_flags_dict[r.replace('NO', '', 1)] = False
                else:
                    role_attr_flags_dict[r] = True

            for role_attr_name, role_attr_value in role_attr_flags_dict.items(
            ):
                if current_role_attrs[PRIV_TO_AUTHID_COLUMN[
                        role_attr_name]] != role_attr_value:
                    role_attr_flags_changing = True

        expires_changing = (expires is not None and expires
                            == current_roles_attrs['rol_valid_until'])

        if not pwchanging and not role_attr_flags_changing and not expires_changing:
            return False

        alter = [
            'ALTER USER %(user)s' % {
                "user": pg_quote_identifier(user, 'role')
            }
        ]
        if pwchanging:
            alter.append("WITH %(crypt)s" % {"crypt": encrypted})
            alter.append("PASSWORD %(password)s")
            alter.append(role_attr_flags)
        elif role_attr_flags:
            alter.append('WITH %s' % role_attr_flags)
        if expires is not None:
            alter.append("VALID UNTIL %(expires)s")

        try:
            cursor.execute(' '.join(alter), query_password_data)
        except psycopg2.InternalError, e:
            if e.pgcode == '25006':
                # Handle errors due to read-only transactions indicated by pgcode 25006
                # ERROR:  cannot execute ALTER ROLE in a read-only transaction
                changed = False
                module.fail_json(msg=e.pgerror)
                return changed
            else:
                raise psycopg2.InternalError, e

        # Grab new role attributes.
        cursor.execute(select, {"user": user})
        new_role_attrs = cursor.fetchone()

        # Detect any differences between current_ and new_role_attrs.
        for i in range(len(current_role_attrs)):
            if current_role_attrs[i] != new_role_attrs[i]:
                changed = True
Exemplo n.º 3
0
 def digest(self):
     ''' Removes the "md5" prefix '''
     return unhexlify(postgres_md5.encrypt(self._data[:64], user=self._user)[3:])
Exemplo n.º 4
0
def user_alter(cursor, module, user, password, role_attr_flags, encrypted, expires, no_password_changes):
    """Change user password and/or attributes. Return True if changed, False otherwise."""
    changed = False

    # Note: role_attr_flags escaped by parse_role_attrs and encrypted is a literal
    if user == 'PUBLIC':
        if password is not None:
            module.fail_json(msg="cannot change the password for PUBLIC user")
        elif role_attr_flags != '':
            module.fail_json(msg="cannot change the role_attr_flags for PUBLIC user")
        else:
            return False

    # Handle passwords.
    if not no_password_changes and (password is not None or role_attr_flags != ''):
        # Select password and all flag-like columns in order to verify changes.
        query_password_data = dict(password=password, expires=expires)
        select = "SELECT * FROM pg_authid where rolname=%(user)s"
        cursor.execute(select, {"user": user})
        # Grab current role attributes.
        current_role_attrs = cursor.fetchone()

        # Do we actually need to do anything?
        pwchanging = False
        if password is not None:
            if encrypted:
                if password.startswith('md5'):
                    if password != current_role_attrs['rolpassword']:
                        pwchanging = True
                else:
                    try:
                        from passlib.hash import postgres_md5 as pm
                        if pm.encrypt(password, user) != current_role_attrs['rolpassword']:
                            pwchanging = True
                    except ImportError:
                        # Cannot check if passlib is not installed, so assume password is different
                        pwchanging = True
            else:
                if password != current_role_attrs['rolpassword']:
                    pwchanging = True

        role_attr_flags_changing = False
        if role_attr_flags:
            role_attr_flags_dict = {}
            for r in role_attr_flags.split(' '):
                if r.startswith('NO'):
                    role_attr_flags_dict[r.replace('NO', '', 1)] = False
                else:
                    role_attr_flags_dict[r] = True

            for role_attr_name, role_attr_value in role_attr_flags_dict.items():
                if current_role_attrs[PRIV_TO_AUTHID_COLUMN[role_attr_name]] != role_attr_value:
                    role_attr_flags_changing = True

        expires_changing = (expires is not None and expires == current_roles_attrs['rol_valid_until'])

        if not pwchanging and not role_attr_flags_changing and not expires_changing:
            return False

        alter = ['ALTER USER %(user)s' % {"user": pg_quote_identifier(user, 'role')}]
        if pwchanging:
            alter.append("WITH %(crypt)s" % {"crypt": encrypted})
            alter.append("PASSWORD %(password)s")
            alter.append(role_attr_flags)
        elif role_attr_flags:
            alter.append('WITH %s' % role_attr_flags)
        if expires is not None:
            alter.append("VALID UNTIL %(expires)s")

        try:
            cursor.execute(' '.join(alter), query_password_data)
        except psycopg2.InternalError:
            e = get_exception()
            if e.pgcode == '25006':
                # Handle errors due to read-only transactions indicated by pgcode 25006
                # ERROR:  cannot execute ALTER ROLE in a read-only transaction
                changed = False
                module.fail_json(msg=e.pgerror)
                return changed
            else:
                raise psycopg2.InternalError(e)

        # Grab new role attributes.
        cursor.execute(select, {"user": user})
        new_role_attrs = cursor.fetchone()

        # Detect any differences between current_ and new_role_attrs.
        for i in range(len(current_role_attrs)):
            if current_role_attrs[i] != new_role_attrs[i]:
                changed = True

    return changed
Exemplo n.º 5
0
 def digest(self):
     ''' Removes the "md5" prefix '''
     return postgres_md5.encrypt(self._data[:64],
                                 user=self._user)[3:].decode('hex')
Exemplo n.º 6
0
 def generate(self, cli_object):
     if cli_object.username is None:
         print "You must provide a username for postgres_md5 hashes!"
         return "Postgres_md5 Hashes require a username"
     generatedhash = postgres_md5.encrypt(cli_object.plaintext, user=cli_object.username)    
     return generatedhash