PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 Re : PL/pgSQL » Suppression de tous les rôles pour un utilisateur » 19/03/2021 18:45:12

rjuju a écrit :

Si je comprends bien il vous suffirait d'exécuter cette requête :

SELECT
    'REVOKE ' || quote_ident(b.rolname) || ' FROM ' || quote_ident(r.rolname)
FROM pg_catalog.pg_roles r
LEFT JOIN pg_catalog.pg_auth_members m ON m.member = r.oid
LEFT JOIN pg_catalog.pg_roles b ON b.oid = m.roleid
WHERE r.rolname = :'p1'
AND b.rolname LIKE 'TEST%' \gexec

Cf https://docs.postgresql.fr/13/app-psql.html pour le fonctionnement de \gexec.

Quoi dire de plus? C'est parfait, merci Julien

Bon week-end

#2 Re : PL/pgSQL » Suppression de tous les rôles pour un utilisateur » 19/03/2021 16:10:38

Bonjour rjuju
Un problème de connaissance et de pratique ;-)
J'essaie de récupérer la liste des rôles d'un utilisateur  (que j'arrive à faire avec la requête ci-dessus) et de les révoquer un à un à cet utilisateur.
J'essaie de chercher sur google la manière de faire (cursor, loop...) mais pas évident.
voilà voilà

#3 Re : PL/pgSQL » Suppression de tous les rôles pour un utilisateur » 19/03/2021 13:01:16

Après quelques recherches, j'imagine que je dois utiliser un cursor avec un fetch...

#4 PL/pgSQL » Suppression de tous les rôles pour un utilisateur » 19/03/2021 11:53:41

Christof25
Réponses : 5

Bonjour

J'aimerai une requête qui permet de supprimer tous les rôles commençant par TEST qu'un utilisateur peut avoir.

J'ai déjà cela comme requête, si cela peut vous aider :

psql -U $USER-d $BASE-f $UNXEXSQL/deleteRole.sql -v p1=toto

  user   |    role
---------+------------
   toto  | {TESTadmin}
(1 row)

Voici le contenu de la requête.

SELECT COUNT(*) = 1 AS user_exist FROM pg_user WHERE usename = :'p1' \gset

\if :user_exist

\gset
SELECT
      r.rolname as user,
      ARRAY(SELECT b.rolname
        FROM pg_catalog.pg_auth_members m
        LEFT JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)
        WHERE m.member = r.oid) as role
FROM pg_catalog.pg_roles r
WHERE  r.rolname = :'p1'
ORDER BY 1;
\else
\echo Warning ! User :p1 not exist on database
\endif

Merci d'avance

#5 Re : PL/pgSQL » requête SQL User + lock + role » 02/03/2021 10:01:31

rjuju a écrit :

Vous avez un \gset en trop à priori, de plus

WHERE  r.rolname = ':p1'

est erroné, il faut utiliser

WHERE  r.rolname = :'p1'

Merci beaucoup!

#6 Re : PL/pgSQL » requête SQL User + lock + role » 01/03/2021 15:21:50

Re salut à tous

dernière sollicitation car y a un truc qui m'échappe avec ma requête quand je ne veux avoir qu'un seul utilisateur passé en paramètre...
J'ai essayé avec cela :

SELECT COUNT(*) = 1 AS user_exist FROM pg_user WHERE usename = :'p1' \gset

\if :user_exist

\gset
SELECT
      CONCAT('PUM_RECUP:',r.rolname) as user,
      CASE WHEN r.rolcanlogin then 'non' else 'oui' end as LOCK,
      ARRAY(SELECT b.rolname
        FROM pg_catalog.pg_auth_members m
        LEFT JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)
        WHERE m.member = r.oid) as role
FROM pg_catalog.pg_roles r
WHERE  r.rolname ~ '^":p1"$'
ORDER BY 1;
\else
\echo Warning ! User :p1 not exist on database
\endif

Ça me sort 0 ligne....

J'ai aussé essayé avec cela dans la clause WHERE

WHERE  r.rolname = ':p1'

une idée?

Merci

#7 Re : PL/pgSQL » requête SQL User + lock + role » 17/02/2021 10:47:10

rjuju a écrit :

Remplacez le ARRAY(...) par des LEFT JOIN.

Je ne comprends pas....

#8 Re : PL/pgSQL » requête SQL User + lock + role » 17/02/2021 10:38:15

Je pense que les jointures déclarées dans la requêtes excluent d'office les utilisateurs sans rôle, c'est pour cela que je n'arrive pas à les afficher.
j'ai peut-être une idée. Dans le select sur les 3 colonnes à afficher, je vais inclure un ARRAY de la sorte :

SELECT
      r.rolname as user,
      CASE WHEN r.rolcanlogin then 'no' else 'yes' end as LOCK,
      ARRAY(SELECT b.rolname
        FROM pg_catalog.pg_auth_members m
        JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)
        WHERE m.member = r.oid) as role
FROM pg_catalog.pg_roles r
WHERE  r.rolname ~ '^[a-zA-Z0-9]{2}[0-9]{5}$'
ORDER BY 1;

J'obtiens cela :

  user   | lock |    role
---------+------+------------
 cv11111 | no   | {}
 e222222 | no   | {}
 e333333 | no   | {}
 e444444 | no   | {}
 e555555 | no   | {}
 e666666 | no   | {}
 u246802 | no   | {roleadmin}

Comment savez-vous s'il est possible de supprimer les {} du résultat?

#9 Re : PL/pgSQL » requête SQL User + lock + role » 17/02/2021 09:23:11

Merci dverite
En effet, pour Postgre, tout est mélangé entre utilisateur et rôle....
Dans mon cas, chaque utilisateur n'aura qu'un seul rôle. C'est pour cela que j'ai enlevé string_agg
Merci pour la clause Where.
Je vais continuer à plancher dessus.

#10 Re : PL/pgSQL » requête SQL User + lock + role » 16/02/2021 12:24:08

Ah, j'y suis presque ....

SELECT regexp_match(r2.rolname,'^[a-zA-Z0-9]{2}[0-9]{5}$') as user, CASE WHEN r.rolcanlogin then 'no' else 'yes' end as lock, r.rolname
FROM pg_catalog.pg_roles r
LEFT JOIN pg_catalog.pg_auth_members m ON (m.roleid = r.oid)
LEFT JOIN pg_catalog.pg_roles r2 ON m.member = r2.oid
where r.rolname is null or r.rolname like 'role%'
ORDER BY 2;

Je n'ai toujours pas les utilisateurs sans rôle....

   user    | lock | rolname
-----------+------+----------
 {u246802} | no   | roleadmin
           | no   | rolewrite
           | no   | roleread
(3 rows)

#11 Re : PL/pgSQL » requête SQL User + lock + role » 16/02/2021 12:02:32

Merci Julien.
J'ai repris ton sql pour y apporter quelques optimisations :

SELECT regexp_match(r2.rolname,'^[a-zA-Z0-9]{2}[0-9]{5}$') as user, CASE WHEN r.rolcanlogin then 'no' else 'yes' end as lock, r.rolname
FROM pg_catalog.pg_roles r
JOIN pg_catalog.pg_auth_members m ON m.roleid = r.oid
JOIN pg_catalog.pg_roles r2 ON m.member = r2.oid
ORDER BY 2;

Résultat :

   user    | lock |       rolname
-----------+------+----------------------
 {u246802} | no   | roleadmin
           | yes  | pg_stat_scan_tables
           | yes  | pg_read_all_stats
           | yes  | pg_read_all_settings
           | yes  | readaccess
(5 rows)

Par contre, il me manque des utilisateurs, ceux notamment qui n'ont pas de rôle.
Si je fais :

sql -U $USER-d $BASE-c "\du"

Il m'affiche ceux qu'il me manque, à savoir :

                                     List of roles
 Role name  |                         Attributes                         |  Member of
------------+------------------------------------------------------------+--------------
 cv11111    | Superuser, Create role, Create DB                         +| {}
            | Password valid until infinity                              |
 e222222    | Superuser, Create role, Create DB                         +| {}
            | Password valid until infinity                              |
 e333333    | Superuser, Create role, Create DB                         +| {}
            | Password valid until infinity                              |
 e444444    | Superuser, Create role, Create DB                         +| {}
            | Password valid until infinity                              |
 e555555    | Superuser, Create role, Create DB                         +| {}
            | Password valid until infinity                              |
 e666666    | Superuser, Create role, Create DB                         +| {}
            | Password valid until infinity                              |

Comment les inclure dans ma requête?

Merci

#12 PL/pgSQL » requête SQL User + lock + role » 15/02/2021 17:56:05

Christof25
Réponses : 15

Bonjour

J'essaie d'obtenir une liste d'utilisateur de la manière suivante :

  username  |  lock  |         role
------------+--------+---------------------
 e123456    |   no   | 
 e987654    |   yes  | 
 u246802    |   no   | roleadmin

J'aimerai savoir pour chacun si ce dernier est locké ou pas et de connaître son rôle s'il en a un.
Pour le statut 'lock', c'est la valeur rolcanlogin dans pg_roles. Mais comment afficher yes pour f et no pour t?

J'ai un début de requête :

SELECT r.rolname as username,r1.rolname as "role"
FROM pg_catalog.pg_roles r JOIN pg_catalog.pg_auth_members m
ON (m.member = r.oid)
JOIN pg_roles r1 ON (m.roleid=r1.oid)
ORDER BY 1
;

Mais loin d'être complète...
Pourriez-vous m'aider à la construire entièrement, svp?

Merci de votre écoute/aide.

#14 Re : Sécurité » Client Postgre » 11/02/2021 08:23:24

Merci, je vais tester et je vous redis.
Pour le client, je m'en doutais également. Mais c'est mieux que rien ;-)
Bonne journée

#15 Sécurité » Client Postgre » 10/02/2021 17:40:19

Christof25
Réponses : 5

Bonjour

Dans les logs Postgre, est-il possible de connaître le nom du client utilisé pour se connecter à une base à distance? Exemple : sqldev ou Dbeaver
Je sais qu'on peut avoir l'@IP mais on aimerait en savoir plus sur le mode de connexion.

Merci

#16 Re : PL/pgSQL » Select .... très sélectif » 08/02/2021 17:24:14

Re
Un ami m'a aidé entre temps.
Voilà ce que je cherchais ;-)

SELECT regexp_match(r.rolname,'^[a-zA-Z0-9]{2}[0-9]{5}$') as username,r1.rolname as "role"
FROM pg_catalog.pg_roles r LEFT JOIN pg_catalog.pg_auth_members m
ON (m.member = r.oid)
LEFT JOIN pg_roles r1 ON (m.roleid=r1.oid) where r1.rolname is null
ORDER BY 1
;

#17 Re : PL/pgSQL » Select .... très sélectif » 08/02/2021 16:24:44

Je pensais l'avoir fait depuis le début de ce post...
Mais il est vrai que de refaire un point n'est pas inutile ;-)

A la base, je cherchais des utilisateurs ayant un rôle spécifique (commençant par role...) :

SELECT regexp_match(r.rolname,'^[a-zA-Z]{1}[a-zA-Z0-9]{3}[0-9]{3}$') as username,r1.rolname as "role"
FROM pg_catalog.pg_roles r JOIN pg_catalog.pg_auth_members m
ON (m.member = r.oid)
JOIN pg_roles r1 ON (m.roleid=r1.oid)
WHERE r1.rolname like 'role%'
ORDER BY 1
;

Résultat :

 username  |   role
-----------+----------
 {u999999} | roleadmin

Maintenant, je recherche uniquement des utilisateurs SANS AUCUN rôle.
pour tester, j'ai recréé mon utilisateur u999999 sans rôle et j'essaie de l'extraire dans une liste

 username  
-----------
 {u999999}

Faut-il reprendre la 1ère requête pour la modifier ou la réécrire totalement?
Et comment...
Merci de votre aide

#18 Re : PL/pgSQL » Select .... très sélectif » 08/02/2021 16:06:13

frost242 a écrit :

Normalement, en transformant les JOIN en LEFT JOIN ? Avec la jointure interne (soit JOIN ou INNER JOIN si on aime taper sur son clavier), on ne fait ressortir que les lignes qui correspondent strictement à la jointure, donc pour lesquels il y a une entrée dans pg_auth_members.


A tout hasard, avez-vous un utilitaire pour construire vos requêtes? Depuis ce matin, je n'arrive pas au résultat désiré....

J'ai bien tenté cela :

SELECT regexp_match(r.rolname,'^[u]{1}[a-zA-Z0-9]{3}[0-9]{2}[3]{1}$') as username,r1.rolname as "role"
FROM pg_catalog.pg_roles r JOIN pg_catalog.pg_auth_members m
ON (m.member = r.oid)
JOIN pg_roles r1 ON (r1.oid is null)
ORDER BY 1
;

Je galère...

#19 Re : PL/pgSQL » Select .... très sélectif » 08/02/2021 11:23:27

Bonjour
J'ai un autre besoin.
A partir de cette même requête, je recherche maintenant tous les utilisateurs n'ayant aucun rôle.
Le but est de sécuriser un maximum ma base pour différencier les besoins de chacun et de les locker en cas de doute.

SELECT regexp_match(r.rolname,'^[a-zA-Z]{1}[a-zA-Z0-9]{3}[0-9]{3}$') as username,r1.rolname as "role"
FROM pg_catalog.pg_roles r JOIN pg_catalog.pg_auth_members m
ON (m.member = r.oid)
JOIN pg_roles r1 ON (m.roleid=r1.oid)
WHERE r1.rolname is null
ORDER BY 1;

Mon compte devrait sortir :

psql -U $USER -d $BASE -c "\du* u999999";
            List of roles
 Role name | Attributes | Member of
-----------+------------+------------
 u999999   |            | {}

Merci

#20 Re : PL/pgSQL » Select .... très sélectif » 05/02/2021 18:37:40

Yes, merci, c'est ce qu'il me fallait.

Cela marche bien :

SELECT regexp_match(r.rolname,'^[a-zA-Z]{1}[a-zA-Z0-9]{3}[0-9]{3}$') as username,r1.rolname as "role"
FROM pg_catalog.pg_roles r JOIN pg_catalog.pg_auth_members m
ON (m.member = r.oid)
JOIN pg_roles r1 ON (m.roleid=r1.oid)
WHERE r1.rolname like 'role%'
ORDER BY 1
;

J'obtiens cela :

 psql -U $USER-d $BASE -f ListUser.sql
 username  |   role
-----------+----------
 {u999999} | roleadmin
(1 row)

Mais si je change mon filtre (les 3 dernières positions doivent être des lettres), cela me ressort quand même un enregistrement.... Normalement, cela doit être à zéro...

SELECT regexp_match(r.rolname,'^[a-zA-Z]{1}[a-zA-Z0-9]{3}[a-zA-Z]{3}$') as username,r1.rolname as "role"

J'obtiens une ligne à moitié vide alors que cela doit être à zéro...

 username |   role
----------+----------
          | roleadmin
(1 row)

Il manque un truc?

#21 PL/pgSQL » Select .... très sélectif » 05/02/2021 17:30:55

Christof25
Réponses : 10

Bonjour

Dans cette requête, j'extrais les utilisateurs dont le rôle commence par role (roleadmin, roleread et rolewrite dans mon cas)

SELECT r.rolname as username,r1.rolname as "role"
FROM pg_catalog.pg_roles r JOIN pg_catalog.pg_auth_members m
ON (m.member = r.oid)
JOIN pg_roles r1 ON (m.roleid=r1.oid)
WHERE r1.rolname like 'role%'
ORDER BY 1

Mais dans la liste, j'aimerais ne garder que ceux dont le matricule ne commence par une lettre, les 3 positions peuvent des chiffres ou lettres et les 3 dernières ne sont que des chiffres.
Sous Oracle, j'avais cela comme expression :

(REGEXP_LIKE(USERNAME,'^[a-zA-Z]{1}[a-zA-Z0-9]{3}[0-9]{3}$');

Sauriez-vous comment l'intégrer dans ma requête?

Merci

#22 Re : PL/pgSQL » Formatage résultat » 05/02/2021 10:34:12

Parfait!!! merci beaucoup Gleu
Bonne journée

#23 PL/pgSQL » Formatage résultat » 05/02/2021 10:28:22

Christof25
Réponses : 3

Bonjour

J'ai une requête qui liste les rôles créés par mes soins.

psql -t  -U $USER -d $BASE -f listRole.sql
 roleadmin
 rolewrite
 roleread

Cependant, j'ai besoin en début de chaque ligne, d'insérer un champ textuel pour un traitement futur.
Le résultat désiré serait alors :

psql -t  -U $USER -d $BASE -f listRole.sql
 ROLE:roleadmin
 ROLE:rolewrite
 ROLE:roleread

Comment y parvenir en modifiant ma requête ci-dessous?

SELECT rolname FROM pg_roles WHERE rolname like 'role%';

En attendant une réponse, je cherche de mon côté dans https://docs.postgresql.fr/9.3/sql.html

Merci

#25 PL/pgSQL » instruction code erreur » 03/02/2021 19:15:56

Christof25
Réponses : 2

Bonjour

Dans mon SQL, si une condition n'est pas vérifiée, j'aimerai retourner un code de retour spécifique.
J'ai tenté de mettre RETURN mais cela ne passe pas dans mon cas :

SELECT COUNT(*) = 0 AS user_not_exist FROM pg_user WHERE usename = :'p1' \gset

\if :user_not_exist

SELECT CASE
    WHEN :'p2' = 'indus' THEN 'roleadmin'
    ELSE 'roleread'
END AS profil
\gset
CREATE USER :p1 NOCREATEDB IN GROUP :"profil";
\echo Creation user :p1 done!
\else
\echo 'Warning ! User :p1 already exist on database
RETURN '99';
\endif

Si l'utilisateur existe déjà, je le saurais avec un CR à 99.

Mais j'ai l'erreur suivante :

psql:/users2/eba00/exploit/sql/eba_0pum_createUser.sql:14: ERROR:  syntax error at or near "RETURN"
LINE 1: RETURN '99';
        ^

Idem avec un \ devant

Merci

Pied de page des forums

Propulsé par FluxBB