, , Utilisez DRDA sur #IBMi

Dans ACS vous avez des exemples comme si dessous

Vous indiquer le nom de votre base de données distantes et vous exécuter votre requête sur le système distant.

derrière cette requête ce cache un protocole nommé DRDA , comme ODBC il permet de ce connecté à une base de donnée distante.

Nous allons voir comment le mettre en œuvre .

sur le système source
Vous devez créer une entrée pour la base de données

le plus simple c’est de passer par la commande WRBRDBDIRE , vous ajouterez une connexion IP à votre système distant.

Sur le système cible
Vous devez paramétrer le service par la commande CHGDDMTCPA , il faut avoir le même mode d’authentification que la base de données distante, par défaut user + mot de passe
vous devez démarrer le service STRTCPSVR *DDM

voila c’est tout
vous pouvez à partir de votre système source faire un connect SQL sur votre système cible si vous avez un mot de passe.

Si vous ne voulez pas renseigner de mot de passe comme dans les exemples ACS vous allez devoir utiliser sur votre système source les postes poste d’authentification serveur.
Pour les ajouter vous avez la commande ADDSVRAUTE, vous devrez également avoir mis la valeur système QRETSVRSEC à ‘1’ pour que vos mots de passe soit enregistrés

il est conseillé d’ajouter un poste générique, par exemple QDDMDRDASERVER en indiquant un user et un mot de passe du système cible !

il n’y a pas de commande WRKSRVAUTE mais vous pouvez en trouver une ici https://github.com/Plberthoin/PLB/tree/master/GTOOLS/

Exemple :

A partir de ce moment la mot de passe sera passé directement.

Vous pouvez facilement, par des services sql comparer 2 partitions (valeurs systèmes, fonctions , etc …)

Remarques

Les noms doivent être en majuscule
il est conseillé de mettre un programme d’exit de contrôle
Attention, vous pouvez vous connecter avec un utilisateur *disabled
Les fichier DDM sur IP s’appuient sur cette technologie

, , , Connaitre la bibliothèque du programme en cours

Vous voulez connaitre la bibliothèque d’un programme en cours d’exécution, pour ajouter cette bibliothèque par exemple, pour contextualiser un exit programme, un watcher, un trigger ou pour limiter un environnement prod, versus dev.
Le tout, sans harcoder une bibliothèque qui figera votre code et vos environnements.

Voici 2 exemples

En RPGLE

dcl-ds *N PSDS ;                  
  bibli_du_pgm CHAR(10) POS(81);  
  nom_du_pgm CHAR(10) POS(1);     
 End-ds ;                          
dcl-s present ind ;
// on tente d'ajouter la bibliothèque
 exec sql                                                                  
 call qcmdexc('Addlible ' concat :bibli_du_pgm concat ' *FIRST') ;         
if sqlcode = 0 ;
  present = *on ;
endif ;
// votre traitement ici
// on enlève si on a ajouté 
if present = *on ;
 exec sql                                                                  
 call qcmdexc('Rmvlible ' concat :bibli_du_pgm ) ;         
endif ;

En CLLE

PGM                                                    
            DCL        VAR(&DATA) TYPE(*CHAR) LEN(80)  
            DCL        VAR(&LIB) TYPE(*CHAR) LEN(10)   
            DCL        VAR(&PGM) TYPE(*CHAR) LEN(10)   
            DCL        VAR(&TEMOIN) TYPE(*LGL)
 /* Paramétrage de l'appel */                          
            CHGVAR     VAR(%BIN(&DATA  1 4)) VALUE(80) 
            CHGVAR     VAR(%BIN(&DATA  5 4)) VALUE(80) 
            CHGVAR     VAR(%BIN(&DATA  9 4)) VALUE( 0) 
            CHGVAR     VAR(%BIN(&DATA 13 4)) VALUE( 0) 
 /* Appel de la procédure */                           
            CALLPRC    PRC('_MATPGMNM') PARM(&DATA)    
 /* Extraction des informations  */                    
            chgvar &pgm %SST(&DATA 51 10)              
            chgvar &lib %SST(&DATA 19 10) 
/* ajout de la bibliothèque */
ADDLIBLE &LIB *FIRST
monmsg cpf2103 exec(do)
chgvar &temoin '1'
enddo 
/* Votre traitement ici */
/* on enlève si on a ajouté */
if cond(*not &temoin) then(do)
RMVLIBLE &LIB
enddo          
ENDPGM          

Remarque :

On a mis également le programme en cours dans les exemples

On a mis le code pour enlever la bibliothèque après le traitement, uniquement si c’est notre programme qui l’a ajouté.


En RPGLE si vous avez un fichier vous devrez déclarer votre fichier en USROPN et ouvrir le fichier par un OPEN, après avoir ajouté la bibliothèque

, CPF2225 sur CHGUSRPRF

Il est possible que vous receviez ce message sur un changement de profil ou sur une suppression (DLTUSRPRF ou CHGUSRPRF)

Ca signifie qu’un autre utilisateur verrouille l’AUT (Authorized User Table) par une autre commande liée à la sécurité.

Cette objet s’appelle QSYUPTBL de la bibliothèque QSYS et il est de Type *AUT.

le premier reflexe serait de faire :

==>

WRKOBJLCK OBJ(QSYS/QSYUPTBL)
OBJTYPE(*AUT)

Mais le type *AUT n’est pas supporté dans la commande (sniff !)

Vous devrez donc passer la commande suivante

==>CALL QTNDSPLS (‘QSYS/QSYUPTBL’ *AUT)

qui vous indiquera qui tient cette table :

Exemple

‘STATUS OF ALL JOBS FOR THE ABOVE SPACE LOCATION:        
                                                         
158965/PLB/QPADEV0001                         LSRD  HELD  

Vous devrez déterminer si c’est normal , sinon il faudra arrêter le travail fautif

Pour en savoir plus :

https://www.ibm.com/support/pages/cpf2225-received-running-security-commands

Remarque :

Vous n’avez pas intérêt à faire tourner 2 process de gestion de profil en même temps

, , Protéger APPEL / SYSTEME

Vous voulez protéger vos sessions 5250 de la possibilité de faire un Appel systéme

Vous devez mettre en place un programme d’exit (8 possibles)

QIBM_QWT_SYSREQPGMS

Vous devez ensuite indiquer sur chaque profil les programmes à utiliser

Schéma ci dessous

L’utilisateur quand il appuiera sur APP SYST le programme PGM1 sera appelé

Programme Exit ici le 1 , nom du programme APPSYS



**free
     //  programme QIBM_QWT_SYSREQPGMS contrôle d'accès à la touche
     //  ATTN REQUEST
     // l'utilisateur à ce programme de contrôle son profil il s'exécute
     //     et il n'a pas le droit
      ctl-opt
      DFTACTGRP(*NO) ;
  Dcl-Pi *N;
    Reponse            int(10);
  //                            1 ok
  //                            0 ko
    data               Char(128);
  End-Pi;
  //
    Reponse = 0;
    *inlr = *on ;
GDATA_QRPGLESRC_APPSYS.TXT
Affichage de GDATA_QRPGLESRC_APPSYS.TXT en cours...

Ce programme est simple , il interdit s’il est appelé

Pour ajouter ce programme :

ADDEXITPGM EXITPNT(QIBM_QWT_SYSREQPGMS)

FORMAT(SREQ0100)
PGMNBR(1)
PGM(Votrelib/APPSYS)
REPLACE(NO)

Dans ==>WRKREGINF pour contrôle

Programme de mise à jour des profils qui devront être concernés par le contrôle

**free
//     Programme exit pour protéger appel système
//     exit PGM   QIBM_QWT_SYSREQPGMS
//     Pour que ce programme ce déclenche il faut que vous
//     l'indiquiez au niveau du profil
//     8 programmes possibles ici le 1 correspond au PGMNBR(1)
//     vous devez utiliser l'API  QWTSETPX
ctl-opt
  DFTACTGRP(*NO) ;
// paramètre recu le profil à protéger
Dcl-Pi *N;
  P_user             char(10);
End-Pi;
// prototypage de l'API de mise à jour
Dcl-PR QWTSETPX ExtPgm( 'QWTSETPX');
  nbrent  int(10)     ;
  flags   char(32)    ;
  format  char(8)    ;
  user    char(10)   ;
  erreur  char(32)   ;
End-PR;
// Variables de travail
dcl-s wnbrent  int(10)     ;
dcl-s wflags   char(32)    ;
dcl-s wformat  char(8)    ;
dcl-s werreur  char(32)    ;
// constantes figuratives
dcl-s inact    char(04)  inz(x'00000000') ;
dcl-s actif    char(04)  inz(x'00000001') ;
// Appel du programme
  wformat = 'SREQ0100' ;
  wnbrent = x'00000004' ;
  %subst(wflags :1 : 4) = actif       ;   <<<<< ici
  %subst(wflags :5 : 4) = inact       ;
  %subst(wflags :9 : 4) = inact       ;
  %subst(wflags :13 : 4) = inact       ;
  %subst(wflags :17 : 4) = inact       ;
  %subst(wflags :21 : 4) = inact       ;
  %subst(wflags :25 : 4) = inact       ;
  %subst(wflags :29 : 4) = inact       ;
  QWTSETPX(wnbrent:wflags:wformat:p_user:werreur) ;
  *inlr = *on ;

Programme pour voir les programmes du profil

**free
//
// Lecture des informations sur les profils pour appel système
// sur exit pgm  QIBM_QWT_SYSREQPGMS
// Rappel 8 possibilités qui correspondent au PGMNBR de l'exit PGM
//
ctl-opt
  DFTACTGRP(*NO) ;
// paramétre le profil
Dcl-Pi *N;
  P_user             char(10);
End-Pi;
// API de lecture des postes
Dcl-PR QWTRTVPX ExtPgm( 'QWTRTVPX');
  rcvvar  char(40)     ;
  rcvlen  char(4)    ;
  format  char(8)    ;
  user    char(10)   ;
  erreur  char(32)   ;
End-PR;
// déclaration des variables de travail
dcl-s wrcvlen  char(4) inz(x'00000028') ;
dcl-s wrcvvar char(40) inz(' ')  ;
dcl-s wformat  char(8)    ;
dcl-s werreur  char(32)    ;
dcl-s wflags   char(32)    ;
dcl-s wnbpos   int(10)     ;
// constantes figuratives
dcl-s inact    char(04)  inz(x'00000000') ;
dcl-s actif    char(04)  inz(x'00000001') ;
dcl-s msg      char(50)  inz(' ') ;
dcl-s i        int(10)  inz(0) ;
// Appel de l'API
  wformat = 'SREQ0100' ;
  QWTRTVPX(wrcvvar:wrcvlen:wformat:p_user:werreur) ;
  wnbpos  = 32;  // 8 * 4
// extraction des informations pour les 8 programmes
  wflags = %subst(wrcvvar : 9 : 32) ;
  for i = 1 by 4 to wnbpos   ;
    if  %subst(wflags : i : 4) =  actif ;
      msg = %trim(msg) + '*ON'                    ;
    else ;
      msg = %trim(msg) + '*OFF'                  ;
    endif;
  endfor ;
  // affichage du résulat
  dsply msg  ;
  *inlr = *on ;

Remarque :

L’utilisateur ne reçoit aucun message , mais rien ne se passe

Attention, il ne faut pas le mettre sur tous les profils, mais uniquement ceux qui le nécessitent.

Par exemple une fenêtre bloquante de ressaisie de mot de passe pour une option sensible.

Vous pouvez faire la même chose pour le programme ATTN …

, , , Utilisez les journaux Système

IBM fourni un certain nombre de journaux systèmes que vous pouvez Analyser, la plus part sont dans QUSRSYS et d’autres sont dans QSYS.

Un petit lien ici pour avoir une liste

https://www.ibm.com/docs/fr/i/7.5?topic=journals-working-supplied

Premier exemple, Analyse de l’ajustement des pools mémoires

Mise en œuvre

Valeur système QPFRADJ doit être à 3 ou 2

Vous devez créer le récepteur et le journal

CRTJRNRCV JRNRCV(QUSRSYS/QPFRADJ)
CRTJRN JRN(QSYS/QPFRADJ) JRNRCV(QUSRSYS/QPFRADJ)


Analyse par les fichiers supports ( c’est des fichiers modèles qui sont dans QSYS )
CRTDUPOBJ OBJ(QAWCTPJE) FROMLIB(QSYS) OBJTYPE(*FILE) TOLIB(Votrebib) NEWOBJ(QPFRADJTP)

DSPJRN JRN(QSYS/QPFRADJ) ENTTYP(TP) OUTPUT(*OUTFILE) OUTFILE(Votrebib/QPFRADJTP)

pour analyser le suivi ici du pour des travaux interactifs

SELECT TPPNAM, TPFLG1, TPCSIZ, TPCRES, TPCACT, TPDFLT, TPNFLT,
TPWI, TPAW, TPCJOB, TPAJOB, TPNSIZ, TPNACT
FROM Votrebib/QPFRADJTP
WHERE TPPNAM = ‘*INTERACT’
order by TPDATE, TPTIME

Deuxième exemple, voir les ports filtrés sur votre partition

Analyse par services SQL

create table votrebib.analyse as(
WITH Log_Port AS (
SELECT CAST(ENTRY_DATA AS VARCHAR(1000)) AS entry
FROM TABLE (
QSYS2.DISPLAY_JOURNAL(‘QUSRSYS’, ‘QIPFILTER’, JOURNAL_ENTRY_TYPES => ‘TF’)
)
)
SELECT SUBSTR(entry, 1, 10) AS line,
SUBSTR(entry, 29, 15) AS AdrSrcIp,
SUBSTR(entry, 44, 5) AS SrcPort,
SUBSTR(entry, 49, 15) AS AdrDestIp,
SUBSTR(entry, 64, 5) AS DestPort
FROM Log_Port
) WITH DATA;

Remarques

Certains journaux sont en standard , d’autres devront être démarrés
Si vous n’analysez pas ne les démarrer pas
Pensez à faire le ménage dans les récepteurs si vous les démarrez

Merci à Sylvain pour ca suggestion

, , Trigger sur insert

Vous voulez créer un trigger qui vous indique la création d’un enregistrement dans un fichier par exemple pour superviser, dans notre exemple on enverra un email , il est conseillé de faire un fichier de paramétrage

En CLLE soit le programme Alerte_msg


             PGM        PARM(&BUFFER &BUFLEN)             
/* Paramètres */                                          
             DCL        VAR(&BUFFER) TYPE(*CHAR) LEN(200) 
             DCL        VAR(&BUFLEN) TYPE(*CHAR) LEN(4)   
/* Variables de travail */                                
             DCL        VAR(&USR) TYPE(*CHAR) LEN(10)     
             DCL        VAR(&JOB) TYPE(*CHAR) LEN(10)     
             DCL        VAR(&NBR) TYPE(*CHAR) LEN(06)
             DCL        VAR(&EMAIL) TYPE(*CHAR) LEN(50)
             DCL        VAR(&SUJET) TYPE(*CHAR) LEN(100)
             DCL        VAR(&NOTES) TYPE(*CHAR) LEN(200)
             RTVJOBA    JOB(&JOB) USER(&USR) NBR(&NBR)    
             CHGVAR     VAR(&EMAIL) VALUE('votre@mail.fr')
             CHGVAR     VAR(&SUJET) VALUE('Enregistrement crée')
             CHGVAR     VAR(&NOTES) VALUE('Job :' +
                          *BCAT &NBR *TCAT '/' *TCAT &USR *TCAT '/' +
                          *TCAT &USR)                                    
 SNDSMTPEMM RCP((&EMAIL)) SUBJECT(&SUJET) NOTE(&NOTES) +
             CONTENT(*HTML)            
  MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERREUR))
goto fin                                                           
/* Gestion des erreurs  */                                         
erreur:                                                            
             SNDUSRMSG  MSG('Envoi email impossible pour msgint ' +
                          *bcat &job *bcat &usr *bcat &nbr ) +     
                          MSGTYPE(*INFO)                           
fin:                                                               
ENDPGM 

Pour attacher votre programme et enregistrer votre trigger

 ADDPFTRG   FILE(&LIB/REP_VALID) TRGTIME(*AFTER)     
              TRGEVENT(*INSERT) PGM(&LIB/ALERT_MSG) 
              TRGLIB(&LIB) 

&lib sera le nom de votre bibliothèque

En SQL ca créera un programme CEE et ca l’associera au trigger

CREATE OR REPLACE TRIGGER ALERTE_MSG                                   
 AFTER  INSERT ON REP_VALID                                            
 REFERENCING NEW AS N                                                  
 FOR EACH ROW                                                          
 MODE DB2ROW                                                           
-- email destinataire                                                  
 BEGIN                                                                 
DECLARE W_EMAIL CHAR(50);                                              
DECLARE W_SUJET CHAR(100);                                             
DECLARE W_NOTES CHAR(200);                                             
DECLARE EXIT HANDLER FOR SQLSTATE '38501'                              
 RESIGNAL SQLSTATE '38501' SET MESSAGE_TEXT = 'ENVOI MAIL IMPOSSIBLE.';
SET W_NOTES = 'Job : ' concat trim(N.REPNBR)                  
concat '/' concat trim(N.REPUSER) concat '/' concat trim(N.REPJOB) ;
SET W_EMAIL = 'votre@email.fr' ;                 
SET W_SUJET = 'Enregistrement crée' ;   
CALL QCMDEXC('SNDSMTPEMM RCP((''' concat trim(w_email) concat           
''')) SUBJECT(''' concat trim(replace(w_sujet , '''', '"'))             
concat ''') NOTE('''                                                    
concat trim(replace(W_NOTES , '''' , '"')) concat''') CONTENT(*HTML)') ;
END;  

Remarques :

Dans les 2 cas si l’utilisateur n’est pas inscrit à la liste de distribution votre email ne sera pas envoyé
c’est plus simple de gérer l’erreur en CLP.
Si vous devez accéder aux données du buffer ca sera plus rapide et plus simple en SQL ici n.zone

C’est des triggers après , puisque l’information doit être écrite dans tous les cas .

, Restreindre le menu ATTN

Dans un précédent poste, nous avons expliqué comment changer les options le menu ATTN , https://www.gaia.fr/menu-attn/

Nous allons voir maintenant comment faire, si vous voulez interdire le menu ATTN ou restreindre l’usage du menu sys request

il faut savoir que c’est un panel de groupe QSYS/QGMNSYSR qui est lancé

La méthode radicale c’est d’interdire ce menu

==>GRTOBJAUT OBJ(QSYS/QGMNSYSR) OBJTYPE(PNLGRP) USER(PUBLIC) AUT(*EXCLUDE)

A ce moment la seul, les utilisateurs *ALLOBJ auront accès à ce menu.

Si vous voulez ajouter des utilisateurs , vous pouvez par exemple ajouter une liste d’autorisations sur le panel de groupe.
il vous suffira alors d’ajouter les utilisateurs dans la liste pour qu’il accède à ce menu, vous pouvez utiliser un groupe

Vous avez une deuxième solution à base de programme d’exit

C’est le point d’exit QIBM_QWT_SYSREQPGMS, vous pourrez ajouter votre programme par ==>WRKREGINF

Ce programme reçoit 2 paramètres et renvoi la valeur 0 dans une paramètre intégrer pour interdire l’accès au menu

Voici

Voici 2 squelettes

1 en CLLE

pgm (&sysreqdsp &sysusrdta)
dcl &sysreqdsp *int
dcl &sysusrdta char(128)
dcl &user 
rtvjoba user(&user) 
/* Votre algo de contrôle */ 
if ...
/* si ko */
do
chgvar &sysreqdsp 0 
enddo
else do
/* si ok */
chgvar &sysreqdsp 1
enddo 
ENDPGM

2 en RPGLE

Dcl-Pi *N;                                          
  p_reqdsp             int ;
  p_usrdta             char(128);   
End-Pi;   
// votre algo  
if ... ;
  SysReqDsp = 0; // KO
else ;
  SysReqDsp = 1; // OK
endif ;
*Inlr = *On;   

Dans les 2 programmes vous devrez implémenter votre algorithme de contrôle.

Conclusion :

A vous de choisir la méthode qui vous convient , la deuxième peut vous permettre d’avoir plus de finesse par exemple un rôle dans un ERP , mais vous devrez développer du code

La première est souvent suffisante dans beaucoup de cas, attention au changement de version ce paramétrage sera perdu pas de développement gestion par ==>EDTAUTL

Il est déconseillé d’utiliser les 2 en même temps

Voila simple et efficace , à vous de jouer

Utilisation de PGP sur L’IBMi

Vous avez une notion de PGP dans la mise en place des droits, je vais essayer de vous expliquer en quoi ca consiste.

PGP veut dire groupe principal privé, à ne pas confondre avec le protocole de cryptage, que vous pouvez utiliser sur votre IBMi dans la partie open source pour crypter et décrypter des fichiers reçus de l’extérieur par exemple , pour info ce protocole est souvent utilisé pour le cryptage des mails.

Vous pouvez ajouter un PGP ou le changer s’il y en a déjà un par la commande CHGPGP par CHGOBJPGP

Exemple :

CHGPGP OBJ(‘/qsys.lib/gdata.lib/testpfxx.file’)
NEWPGP(PLB8)
DTAAUT(RWX) OBJAUT(OBJALTER)
RVKOLDAUT(*NO)

EDTOBJAUT gdata/testpfxx *file

On obtient

Utilisat Groupe sur objet
*PUBLIC *CHANGE
QSECOFR *ALL
PLB8 USER DEF < nouveau droit ici

Si vous sauvegardez cet objet

SAVOBJ OBJ(TESTPFXX)
LIB(GDATA)
DEV(*SAVF)
SAVF(GDATA/TESTPFXX1)

et que vous le restaurez

RSTOBJ OBJ(TESTPFXX)
SAVLIB(GDATA)
DEV(*SAVF)
SAVF(GDATA/TESTPFXX1)
RSTLIB(GAIA)

les droits sont conservés
Conclusion, les droits sont stockés sur l’objet et non pas dans le profil comme les droits privés traditionnels que vous ajouter par GRTOBJAUT par exemple.

EDTOBJAUT gaia/testpfxx *file

Utilisat Groupe sur objet
*PUBLIC *CHANGE
QSECOFR *ALL
PLB8 USER DEF << le droit est toujours la

Vous avez des commandes spécifiques
==>go cmdpgp

par exemple , pour voir les objets par PGP

WRKOBJPGP PGP(PLB8)

Conclusion :


C’est un moyen d’avoir un troisième droit sur un objet en plus du public et du propriétaire inclus dans l’objet.
selon les documentations peu nombreuses , ca améliore les performances
Il faut comprendre comment ca fonctionne, si vous en avez sur vos ibmi , mais ce n’est pas stratégique.


Il est conseillé à chaque déploiement de réappliquer les droits sur les objets, ce qui permet de garder une cohérence globale.

il est conseillé de mettre comme propriétaire votre groupe ce qui simplifiera la gestion le pgp et le groupe seront fusionné sur l’objet créé


rappel, si le propriétaire n’existe pas sur le système ou vous restaurez l’objet il sera attribué à QDFTOWN.

, , Gérer les magasins de datas

Une des nouveautés de la dernière TR est de pouvoir analyser et exporter les analyses de journaux d’audit à partir d’un interface graphique dans navigator for i.

le menu

Vous avez la nouvelle option, gérer les magasins d’audit

vous devez commencer par en créer un

Attention la bibliothèque doit existée

Une fois les données agrégées vous avez une liste de vos magasins

vous avez un menu qui vous permet de voir le détail du contenu du magasin

Vous avez le détail de votre magasin que vous pouvez consulter ou exporter par exemple

le menu action

Conclusion

Ca facilite grandement l’utilisation et la restitution des informations d’audit

, Liste complète des droits sur un objet

Il peut être intéressant de voir les droits qui existent sur un objet, pour comprendre et administrer la sécurité.

Les droits sur un objet sont visibles par la commande DSPOBJAUT, mais également par DSPAUTL si votre objet est protégé par une liste.

Prérequis, vous devez avoir au moins le droit *USE sur la bibliothèque qui contient l’objet.

Cette requête résume l’ensemble de ces droits présents

--
-- Voir les droits sur un objet
-- sur l'objet et sur la liste s'il y en a une
-- indiquez votre objet et votre lib 
--
SELECT '2) LISTE' as nature,
'QSYS' as Library ,
AUTHORIZATION_LIST,
'*AUTL' as TYPE,
AUTHORIZATION_NAME ,
OBJECT_OPERATIONAL,
OBJECT_MANAGEMENT,
OBJECT_EXISTENCE,
OBJECT_ALTER,
OBJECT_REFERENCE,
DATA_READ,
DATA_ADD,
DATA_UPDATE,
DATA_DELETE,
DATA_EXECUTE
FROM QSYS2.AUTHORIZATION_LIST_USER_INFO
WHERE AUTHORIZATION_LIST = (SELECT AUTHORIZATION_LIST
FROM QSYS2.OBJECT_PRIVILEGES
WHERE object_schema = 'VOTRE_BIB'
AND object_name = 'VOTRE_OBJ'
FETCH FIRST ROW ONLY)
UNION
SELECT '1) OBJECT' as NATURE,
OBJECT_SCHEMA as library,
OBJECT_NAME as OBJECT,
OBJECT_TYPE as TYPE,
AUTHORIZATION_NAME,
OBJECT_OPERATIONAL,
OBJECT_MANAGEMENT,
OBJECT_EXISTENCE,
OBJECT_ALTER,
OBJECT_REFERENCE,
DATA_READ,
DATA_ADD,
DATA_UPDATE,
DATA_DELETE,
DATA_EXECUTE
FROM QSYS2.OBJECT_PRIVILEGES
WHERE object_schema = 'VOTRE_BIB'
AND object_name = 'VOTRE_OBJ'
ORDER BY 1;

Rappel :

Ces droits ne sont vérifiés que si votre profil et votre profil de groupe ne sont pas *ALLOBJ

Les droits qui sont systématiquement présents sur les objets, sont les droits *PUBLIC et le propriétaire