AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 56096
Accepted
Neil McGuigan
Neil McGuigan
Asked: 2014-01-04 14:07:29 +0800 CST2014-01-04 14:07:29 +0800 CST 2014-01-04 14:07:29 +0800 CST

Como obter todas as funções das quais um usuário é membro (incluindo funções herdadas)?

  • 772

Digamos que eu tenha dois grupos de banco de dados Postgresql, "autores" e "editores", e dois usuários, "maxwell" e "ernest".

create role authors;

create role editors;

create user maxwell;

create user ernest;

grant authors to editors; --editors can do what authors can do

grant editors to maxwell; --maxwell is an editor

grant authors to ernest; --ernest is an author

Eu gostaria de escrever uma função performante que retornasse uma lista dos papéis (de preferência seus oid's) aos quais o maxwell pertence, algo assim:

create or replace function get_all_roles() returns oid[] ...

Deve retornar os oids para maxwell, autores e editores (mas não ernest).

Mas não tenho certeza de como fazê-lo quando há herança.

postgresql users
  • 6 6 respostas
  • 93333 Views

6 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2014-01-04T14:42:31+08:002014-01-04T14:42:31+08:00

    Você pode consultar o catálogo do sistema com uma consulta recursiva , em particular pg_auth_members:

    WITH RECURSIVE cte AS (
       SELECT oid FROM pg_roles WHERE rolname = 'maxwell'
    
       UNION ALL
       SELECT m.roleid
       FROM   cte
       JOIN   pg_auth_members m ON m.member = cte.oid
       )
    SELECT oid, oid::regrole::text AS rolename FROM cte;  -- oid & name
    

    O manual sobre o tipo de identificador de conversão para objeto regrole.

    BTW 1: INHERITé o comportamento padrão CREATE ROLEe não precisa ser explicado.

    BTW 2: dependências circulares não são possíveis. O Postgres não permite isso. Então não temos que verificar isso.

    • 44
  2. Daniel Vérité
    2015-07-23T16:59:30+08:002015-07-23T16:59:30+08:00

    Esta é uma versão simplificada da resposta de Craig Ringer que um não superusuário pode usar diretamente:

     SELECT oid, rolname FROM pg_roles WHERE
       pg_has_role( 'maxwell', oid, 'member');
    

    pg_rolesé essencialmente uma visão pg_authidacessível ao público, pois não revela senhas, ao contrário do pg_authid. A base oidé mesmo exportada para a vista. Quando não precisa de senhas, não faz sentido criar a função dedicada de propriedade do superusuário.

    • 25
  3. Craig Ringer
    2014-01-04T16:11:43+08:002014-01-04T16:11:43+08:00

    Versão curta:

    SELECT a.oid 
    FROM pg_authid a 
    WHERE pg_has_role('maxwell', a.oid, 'member');
    

    Aqui usamos uma versão de pg_has_roleque leva um nome de função como assunto e função oid para testar a associação , passando membero modo para que testamos associações herdadas.

    A vantagem de usar pg_has_roleé que ele usa os caches internos de informações de função do PostgreSQL para atender rapidamente às consultas de associação.

    Você pode querer envolver isso em uma SECURITY DEFINERfunção, pois pg_authidtem acesso restrito. Algo como:

    CREATE OR REPLACE FUNCTION user_role_memberships(text)
    RETURNS SETOF oid
    LANGUAGE sql
    SECURITY DEFINER
    SET search_path = pg_catalog, pg_temp
    AS $$
    SELECT a.oid 
    FROM pg_authid a 
    WHERE pg_has_role($1, a.oid, 'member');
    $$;
    
    REVOKE EXECUTE ON FUNCTION user_role_memberships(text) FROM public;
    
    GRANT EXECUTE ON FUNCTION user_role_memberships(text) TO ...whoever...;
    

    Você pode usar pg_get_userbyid(oid)para obter o nome da função do oid sem a necessidade de consultar pg_authid:

    SELECT a.oid AS member_oid, pg_get_userbyid(oid) AS member_name
    FROM pg_authid a 
    WHERE pg_has_role('maxwell', a.oid, 'member');
    
    • 21
  4. Alexis.Rolland
    2019-02-24T23:17:44+08:002019-02-24T23:17:44+08:00

    Aqui está a minha opinião sobre isso. Funciona para um usuário específico ou para todos os usuários.

    select a.oid as user_role_id
    , a.rolname as user_role_name
    , b.roleid as other_role_id
    , c.rolname as other_role_name
    from pg_roles a
    inner join pg_auth_members b on a.oid=b.member
    inner join pg_roles c on b.roleid=c.oid 
    where a.rolname = 'user_1'
    
    • 5
  5. SureShotUK
    2019-02-06T07:21:33+08:002019-02-06T07:21:33+08:00

    Eu acredito que isso vai fazer isso

    SELECT 
        oid 
    FROM 
        pg_roles 
    WHERE 
        oid IN (SELECT 
                    roleid 
                FROM 
                    pg_auth_members 
                WHERE 
                    member=(SELECT oid FROM pg_roles WHERE rolname='maxwell'));
    

    Se você preferir obter os nomes das funções, substitua o primeiro oidpor rolname.

    • 1
  6. Mihail Gershkovich
    2019-07-03T14:19:01+08:002019-07-03T14:19:01+08:00

    se você quiser saber todas as funções da sua função atualmente ativa:

    CREATE OR REPLACE VIEW public.my_roles
    AS WITH RECURSIVE cte AS (
             SELECT pg_roles.oid,
                pg_roles.rolname
               FROM pg_roles
              WHERE pg_roles.rolname = CURRENT_USER
            UNION ALL
             SELECT m.roleid,
                pgr.rolname
               FROM cte cte_1
                 JOIN pg_auth_members m ON m.member = cte_1.oid
                 JOIN pg_roles pgr ON pgr.oid = m.roleid
            )
     SELECT array_agg(cte.rolname) AS my_roles
       FROM cte;
    
    • 1

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve