, Adoption de droits

Rappel

C’est la possibilité d’avoir accès à une ressource momentanément en passant par un programme qui s’exécutera avec les droits du propriétaire et non celui de l’utilisateur en cours .

Mise en oeuvre

Pour créer un programme adoptant.
C’est le paramètre USRPRF(*OWNER) dans les commandes qui génèrent un

programme.
Vous pouvez également utiliser la commande chgpgm pour modifier ce paramètre.
Dans tous les cas vous devez avoir au minimum le droit *USE sur le profil propriétaire.
Vous héritez également des droits spéciaux, comme *SPLCTL

Exemple :


Un exemple classique c’est le changement de mot de passe par un exploitant qui n’a pas le droit *SECADM dans les paramètres de son profil

Soit le programme suivant chgusrpwd compiler avec propriétaire qsecofr et le paramètre USRPRF(*OWNER)

PGM        PARM(&USR)                                   
DCL VAR(&USR) TYPE(CHAR) LEN(10) CHGUSRPRF USRPRF(&USR) PASSWORD('#password$') + PWDEXP(YES) STATUS(*ENABLED)
MONMSG MSGID(CPF2204) EXEC(SNDUSRMSG MSG('Profil,' +
*BCAT &USER BCAT 'inéxistant') + MSGTYPE(INFO))
ENDPGM

l’utilisateur peut rendre le mot de passe sans avoir le droit *SECADM, en

tapant ==>call chgusrpwd (‘NOMPROFIL’)

Sur un programme, vous avez un deuxième paramètre c’est USEADPAUT(*YES)

c’est est ce qu’on hérite des droits du programme appelant qui lui peut être en adoption de droit (par exemple call qcmd …)

Avantages :


Si vous Maîtrisez bien, c’est un moyen de dire, aucun de mes utilisateurs n’a le droit sur ma base de donnéee, mais il obtient le droit en utilisant mon applicatif, on pense au accès par ODBC par exemple !

Inconvéhients :


Ça peut être une ‘back door‘ pour des individus mal intentionnés.

Analyse et suivi :
La commande DSPPGMADP permet de mettre dans un fichier les programmes adoptants et ensuite vous pouvez interroger ce fichier.

2 valeurs systèmes influent sur l’adoption de droit.

QALWOBJRST

*ALWSYSSTT
Permet aux programmes, programmes de service et modules ayant un attribut état-hérité d’être restaurés. Lorsque le paramètre de la valeur système

QFRCCVNRST entraîne la conversion de l’objet, celui-ci passe à état-

utilisateur.

*ALWPGMADP
Les programmes et programmes de service disposant de l’attribut d’adoption sont restaurés.

Cette valeur contrôle les restaurations d’objets sur votre partition

La deuxiéme valeur système

QUSEADPAUT

Elle indique si vous avez le droit de créer des programmes qui héritent
des droits adoptés , c’est le paramètre USEADPAUT(*YES)

*NONE
Tous les utilisateurs du système on le droit de créer des utilisateurs qui héritent des droits du programme appelant.

nom d’une liste d’autorisation par convention souvent, QUSEADPAUT et seul les utilisateurs inscrits à cette liste et disposant de *use sur celle ci auront le droit de créer ou de modifier des programmes pour demander un héritage de droit.

Limites

Attention, vous héritez également des droits spéciaux , *SECADM par exemple

Attention, L’héritage de droit et la valeur par défaut USEADPAUT(*YES)

L’adoption de droit, ne fonctionne pas sur l’IFS qui est régie par un mode unix

Conclusion

il est important de bien comprendre les mécanismes d’adoption de droit , soit pour les utiliser dans votre application, soit pour les contrôler et les administrer.

, , Utiliser Dynamic compound statement avec SQL

Depuis la version 7.1, vous pouvez composer une instruction SQL dynamique c’est assez similaire à une procédure SQL, sauf qu’elle ne créera pas un objet permanent .
Vous trouverez un fichier source QSQLT00000 , SQL COMPOUND DYNAMIC QCMPD00001 dans votre bibliothèque qtemp

Le but :

Vous pouvez l’utiliser pour ajouter une logique aux scripts, mais aussi pour intercepter les erreurs de traitement entre autres.

Par exemple, il n’existe pas d’instruction pour faire un create replace avec la syntaxe create table as(..)with data.

La solution est donc la suivante :

begin
declare continue handler for sqlstate ‘42704’ — fichier existant
begin end ;
drop table qgpl.liste ;
create table qgpl.liste as( select * from qgpl.qauoopt ) with data ;
end ;

42704 étant le sqlstate pour table non trouvée

Voici un deuxième exemple qui permet d’écrire dans un fichier log, si vous avez au moins une PTF à appliquer (CREATE TABLE LOGPTF(TEXT CHAR (132 ) NOT NULL WITH DEFAULT)), le code est placé dans un RUNSQL pour être exécuté dans un CLLE.

Attention aux nombre de quotes ….

DCS peut être utilisé dans tous les environnements :
srcipte SQL par exemple dans ACS
RUNSQLSTM
RUNSQL
SQL embarqué

Il y a plein de possibilités et la limite c’est votre imagination …

lien à connaitre

https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/sqlp/rbafydyncompound.htm

, ,

Complétion de code avec ACS 1.1.8.3

La version 1.1.8.3 d’Access Client Solutions apporte une fonctionnalité attendue : complétion SQL !

L’outil cherche pour vous les noms des tables et des colonnes :

  • Gain de temps
  • Plus de faute de frappe (en tout cas sur les noms des tables et colonnes)
  • Pas besoin de connaitre tout votre modèle de donnée par cœur

Regardez notre courte vidéo pour vous faire une idée !

,

Facilitez-vous le débogage avec RDi !

Vous êtes nombreux à nous solliciter sur une difficulté récurrente liée au débogage : comment déboguer un programme pour lequel le source n’est pas sur la machine, et qui n’a pas été compilé avec la vue *LISTING

Pour RPG : CRTBNDRPG/CRTRPGMOD … DBGVIEW(*ALL ou *LISTING)

Pour rappel :

  • DBGVIEW(*SOURCE) : le source n’est pas inclus dans l’objet compilé, i lest recherché sur le système lors du débogage
  • DBGVIEW(*LISTING) : le source est inclus dans l’objet compilé. Si le membre source est présent lors du débogage, il est affiché, sinon c’est le source inclus dans l’objet compilé qui est affiché

Il est évidemment bien plus pratique d’indiquer DBGVIEW(*ALL ou *LISTING) pour permettre le débogage.

Vous distribuez vos objets programmes et ne souhaitez pas que vos clients puissent accéder au source ? Il est possible de crypter le source embarqué : lors du débogage, vous devez saisir la clé correspondante pour afficher le source !

Pour changer de vue source (équivalent F15 dans STRDBG), clique droit dans le source, changer la vue …

 

Revenons maintenant à notre cas : vous compilez avec DBGVIEW(*SOURCE) et vous envoyez vos programmes sur un autre système (production, recette/UAT …). Lorsque vous souhaitez déboguer vos programmes en production, impossible d’avoir le source, et donc de faire quoi que ce soit d’intelligent !

Vous pouvez bien sur envoyer le source ….

 

Mais RDi vous permet de déboguer un programme sur une machine de production, tout en accédant au source sur la machine de développement, voir sur votre machine Windows (Linux/Max pour ceux qui souhaitent) !

 

C’est assez simple :

–          Dans RDi, assurez-vous de disposer d’une connexion RSE au système de production et d’une autre connexion au système de développement

–          Evidemment, vous devez savoir où (bibliothèque, fichier …) se trouve le source

Lancez le débogage sur votre machine de production. L’écran suivant s’affiche, le membre source étant introuvable sur ce système :

Cliquez sur « Editer le chemin de recherche des fichiers source … », puis sur « Ajouter… » :

Puis « Fichier source IBM i » :

Sélectionner la connexion RSE correspondant à la machine de développement, puis dérouler les bibliothèques pour sélectionner la bibliothèque/fichier source correspondant, puis OK :

Le source s’affiche, vous pouvez déboguer normalement !

 

La technique peut s’appliquer également si lors de votre process de développement les membres source sont déplacés d’une bibliothèque (développement/version) à une autre (référentiel).

 

Vous avez le source sous forme de fichier texte sur votre machine ? Pas de soucis, vous pouvez également l’indiquer :

 

On peut alors déboguer :

 

Limitations :

–          Impossible d’indiquer le nom du membre source : ne fonctionne pas avec les renommages

–          les includes/copy, coloration, etc …

, 5 raisons pour utiliser Isphere

Isphere est un plugin eclipse que l’on peut installer sous RDi et qui apporte des fonctionnalités complémentaires

Raison 1

Il est gratuit, donc ça ne coûte rien de l’installer pour voir !
et c’est un produit open source vous pouvez même participer à son évolution


Raison 2

Vous avez un comparateur de sources un peu plus simple, qui permet par exemple de comparer 3 Sources …

Raison 3

Sur la gestion de vos spools le plugin permet d’avoir beaucoup plus d’options
C’est également vrai sur la gestion des messages …

Raison 4

Vous avez un outil qui permet de chercher des informations dans des sources avec une grande facilité d’utilisation

Raison 5

Editer simplement le contenu d’un fichier message .

En conclusions :

Voici les principales options qu’on utilise chez GAIA

Il en existe d’autres, par exemple des options ILE sur les objets …

Plus toutes celles qu’on n’a pas trouvé encore !

, Premiers tests services web REST SQL

Une des fonctionnalités attendues disponible avec la 7.4 / 7.3 TR6 (SF99722 niveau 19) est la possibilité de déployer des services web (REST uniquement) basés sur des instructions SQL au lieu de programmes ILE.

 

Voici nos premiers tests, effectués « à vue » la documentation IBM n’étant pas encore disponible …

 

Services REST SQL

En bref, vous avez désormais les possibilités suivantes :

  • effectuer des SELECT, UPDATE, INSERT
  • appeler des fonctions SQL utilisateur (UDF), des fonctions tables (UDTF)
  • appeler des procédures stockées (procédures cataloguées)
  • utiliser directement la syntaxe VALUES …
  • retourner des données BINAIRES (images, pdf, …)

De plus, IWS vous propose également un format de sortie HTML, en plus de JSON et XML déjà en place. De quoi faciliter l’intégration de vos données dans des pages web !

 

Comment fait-on ?

Déployer un nouveau service : vos avez maintenant la possibilité de choisir SQL

Comme d’habitude pour les services REST, vous indiquez nom de service et nom de ressource

Maintenant, vous avez des paramètres spécifiques à un service basé sur SQL vous permettant de régler les conventions de nommage et la résolution des objets non qualifiés dans vos requêtes. Le fonctionnement est habituel en SQL. Pour simplifier : basé sur la *LIBL en convention *SYS, sur un schéma par défaut en *SQL

Vous pouvez indiquer plusieurs « procédures » dans un service REST SQL, c’est à dire plusieurs opérations disponibles au travers de votre service, et identifiées (plus tard) par des URL et/ou des méthodes HTTP différentes

Pour commencer simplement :

Bien sûr, vous pouvez utiliser des paramètres dans vos requêtes SQL, identifiés par « ? » :

L’outil est plutôt bien fait de ce côté-là : il est capable de détecter le type des données correspondant à vos paramètres en analysant le fichier :

Vous devez ensuite régler le comportement attendu de votre traitement :

la suite des écrans est classique et ne présente pas de particularité dû au SQL, en dehors du type de sortie *HTML proposé.

Quelques exemples de résultats fournis par les appels de différents services (renvoyant une ligne ou plusieurs lignes, en JSON, en XML, en HTML …) :

 

L’outil vous permet également d’obtenir des informations sur l’exécution et les erreurs SQL :

 

Données binaires

Maintenant, passons à la possibilité qui ouvre d’autres perspectives !

Avec les services basés sur des programmes ILE RPG/COBOL, nous n’arrivons pas à retourner des images ou documents binaires : toutes les données sont converties en UTF-8 (par défaut) pour sortir sur le flux HTTP. Nos données binaires ne supportent pas bien … seule solution jusqu’ici : encoder en base64 (c’est à dire en caractères) ! Mais cela complexifie, nécessite du temps machine et augmente la taille de la sortie.

Lors du déploiement, sélectionner le type « Media resource »

Vous devez indiquer le type de ressource (seule la première valeur est prise en compte) :

Dès lors, vos services web peuvent retourner des documents (au sens large), par exemple un pdf accessible depuis un navigateur :

Ou une image (vous devriez reconnaître) :

 

Adaptation des scripts shell

Un nouveau script shell a fait son apparition dans /qibm/proddata/os/webservices/bin : getConfigurationFile.sh

 

Les informations disponibles actuellement : https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/dW%20IBM%20Integrated%20Web%20Services%20for%20i/page/Script%20to%20generate%20property%20file%20for%20a%20service

Ce dernier génère deux fichiers pour un service :

  • un fichier .properties
  • un fichier .xml

Le fichier properties contient les attributs du service, des procédures/méthodes, du connecteur jdbc.

Le fichier xml est en réalité un fichier pcml contenant des balises spécifiques utilisées pour le déploiement d’un service.

Ces formats de fichiers permettront également le déploiement par script shell (avec installWebService.sh) des services REST SQL.

 

 

En conclusion

L’outil poursuit sa belle évolution, avec toujours plus de fonctionnalités et de possibilités ! Nous compléterons prochainement avec des tests plus approfondis.

D’ici là, bonnes vacances à tous, et rendez-vous à la rentrée, reposé et bronzé !

,

Contrôler ses données avec SQL as a service

 

L’arrivée de la function table joblog_info qui permet de voir la log d’un travail ouvre de nouvelles manières de travailler.

En voici une qui va vous permettre de savoir si vous avez des données erronées dans vos fichiers PF.

Quand vous faites une requête avec un select sur un pf qui a des données en erreur, en fonction de votre interface vous obtenez des ++++ ou autres qui vous indique que vos données sont en erreur !

Mais surtout ça génère un message CPF5035 dans votre log qui vous indique la ligne et la zone en erreur

Exemple :

select substr(MESSA00007, 1, 10) as fichier ,
substr(MESSA00007, 21, 10) as biblio,
substr(MESSA00009, 55, 71) as texte
from table(qsys2.joblog_info(‘*’)) a
where MESSAGE_ID = ‘CPF5035’

Qui vous donnera

CLIENTS GAIA la zone CLIENTS_1.CAANC, numéro d’enreg 213, format *FIRST, membre
CLIENTS GAIA la zone CLIENTS_1.CAAN1, numéro d’enreg 213, format *FIRST, membre
CLIENTS GAIA la zone CLIENTS_1.CAAN2, numéro d’enreg 213, format *FIRST, membre

Ici on voit que sur l’enregistrement 213 (rang relatif) a des zones CAANC, CAAN1 et CAAN2  qui ont des données en erreur

Vous pouvez corriger facilement en faisant

update gaia.clients a set caanc = 0 where rrn(a) = 213

Voici un petit script CLLE qui vous permettra de savoir si un PF à des données en erreur

pgm parm(&table &lib)
dcl &table *char 10
dcl &lib *char 10
chkobj &lib/&table *file
RUNSQL SQL(‘drop table qtemp/wtest’) COMMIT(*NONE)
monmsg SQL9010
RUNSQL SQL(‘create table qtemp/wtest as (select * +
from’ *BCAT &LIB *TCAT ‘/’ *TCAT &TABLE +
*bcat ‘)with data’) COMMIT(*NONE)
monmsg SQL9010 exec(do)

/* ici votre traitement pour récupérer les erreurs CPF5035 */
/* select substr(MESSA00009, 55, 71) as texte */
/* from table(qsys2.joblog_info(‘*’)) a */
/* where MESSAGE_ID = ‘CPF5035’ */
/* vous devrez par exemple écrire ces données dans une table */

endpgm

Ce script est a améliorer en effet il ne donne que le premier enregistrement corrompu , sql interrompant le traitement à la première erreur.

,

Parser un tableau JSON avec l’opération SQL JSON_TABLE

L’opération SQL JSON_TABLE sert à extraire les données d’un flux JSON pour les intégrer en base de données.

Pour rappel, les services web REST renvoient  la plupart du temps des réponses en JSON.
L’opération fonctionne bien si le premier niveau hiérarchique du flux est un objet JSON,  pouvant lui-même contenir un tableau.
Prenons par exemple un flux JSON contenant l’objet « qteage » étant lui-même un tableau :

{
« qteage »: [
{
« agence »: « LY »,
« qte »: 567
},
{
« agence »: « PA »,
« qte »: 879
}
],
« code »: « OK »,
« message »: «  »
}

Nous pouvons récupérer les éléments du tableau sans problème par la requête :

select u.* from json_table( ‘{
« qteage »: [
{
« agence »: « LY »,
« qte »: 567
},
{
« agence »: « PA »,
« qte »: 879
}
],
« code »: « OK »,
« message »: «  »
}’, ‘strict $.qteage[*]’
COLUMNS( « CodAge » varchar(50) PATH ‘strict $.agence’ ,
« Quantite » decimal   PATH ‘strict $.qte’
)  ) AS U;

Par contre si le flux JSON renvoie directement un tableau, l’opération JSON_TABLE n’arrive plus à extraire les données :

Prenons par exemple, le flux suivant, qui est reconnu par les outils de validation en ligne :

Lorsque nous essayons de travailler avec ce flux, l’opération JSON_TABLE, ne fonctionne plus :

select u.* from json_table( ‘[
{
« agence »: « LY »,
« qte »: 567
},
{
« agence »: « PA »,
« qte »: 879
}
]’, ‘strict $.[*]’
COLUMNS( « CodAge » varchar(50) PATH ‘strict $.agence’ ,
« Quantite » decimal   PATH ‘strict $.qte’
)  ) AS U;

L’instruction est bien traitée, mais le résultat est vide :

IBM confirme que l’instruction attend un objet JSON et non un tableau sur le premier niveau hiérarchique.

Si vous êtes confronté à ce problème, vous n’aurez pas d’autre solution que de modifier le JSON reçu, pour ajouter un niveau hiérarchique qui englobera votre flux initial.

Par exemple par l’ajout de l’objet « data ». Votre flux deviendra :

{ « data » : 

[
{
« agence »: « LY »,
« qte »: 567
},
{
« agence »: « PA »,
« qte »: 879
}
] }

Vous pouvez le faire, entre autre, par SQL  :

SET :donnees = ‘{« data » : ‘ || trim(:donnees) || ‘}’ ;

Attention toutefois à l’encodage de votre résultat, le flux JSON d’origine est encodé en UTF8. Si le CCSID de votre machine est 65535, vous  devrez modifier le CCSID de travail pour que l’instruction SQL s’exécute sans erreur, soit au niveau du job, de l’utilisateur, de variables de travail…. Mais là c’est une autre histoire !