mercredi 7 juin 2017

flash plugin dans opensuse

Pour disposer du plugin flash-player dans opensuse on peut passer par l'ajout du dépôt adobe comme expliqué ici:
Dans un terminal où on est root lancer les commandes:

linux-cz64:~ # zypper ar --check --refresh http://linuxdownload.adobe.com/linux/x86_64/ adobe
linux-cz64:~ # zypper se -s -r adobe
linux-cz64:~ # zypper in adobe-release-x86_64
linux-cz64:~ # rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-adobe-linux
linux-cz64:~ # zypper in flash-plugin

La première ajoute le dépôt, la deuxième liste les paquets fournis par ce dépôt et la dernière installe le paquet flash-plugin.

Tout ceci est parfait pour firefox mais le dépôt fournit aussi le paquet qui convient pour chromium. Il doit donc être installé.

linux-cz64:~ # zypper in flash-player-ppapi 

Mais cette action ne permet pas de faire fonctionner flash dans chromium.

Recherchons quels sont les fichiers fournis par ce paquet:

linux-cz64:~ # rpm -ql flash-player-ppapi
/usr/lib64/flash-plugin
/usr/lib64/flash-plugin/libpepflashplayer.so
/usr/lib64/flash-plugin/manifest.json
/usr/share/doc/flash-player-ppapi-25.0.0.171
/usr/share/doc/flash-player-ppapi-25.0.0.171/LGPL.txt
/usr/share/doc/flash-player-ppapi-25.0.0.171/license.pdf
/usr/share/doc/flash-player-ppapi-25.0.0.171/notice.txt
/usr/share/doc/flash-player-ppapi-25.0.0.171/readme.txt

Ils ne sont pas au bon endroit.
On pourrait les recopier ailleurs, mais alors adieu les mises à jour (c'est justement là l'avantage des dépôts par rapport aux installations manuelles).
Le mieux est de créer le répertoire qui convient et de créer des liens symboliques:

linux-cz64:~ # cd /usr/lib64/chromium
linux-cz64:/usr/lib64/chromium # mkdir PepperFlash
linux-cz64:/usr/lib64/chromium # cd Pepperflash
linux-cz64:/usr/lib64/chromium/PepperFlash # ln -s /usr/lib64/flash-plugin/libpepflashplayer.so 
linux-cz64:/usr/lib64/chromium/PepperFlash # ln -s /usr/lib64/flash-plugin/manifest.json 
linux-cz64:/usr/lib64/chromium/PepperFlash # 

Et voilà!

(remarque: l'utilisation du dépôt packman permet d'éviter ces soucis)

jeudi 6 avril 2017

Table de pilote des dépenses

Je vais construire dans LibreOffice Calc un tableau croisé dynamique (table de pilote) basé sur la table dépenses de ma base de données PostgreSQL bdtest.
Il faut bien sûr au niveau de LibreOffice Base avoir créé un fichier bdtest.odb qui permette la connexion de LibreOffice à cette base de données.
Dans LibreOffice Calc, CTRL-MAJ-F4 affiche les sources de données.  Si bdtest.odb n'y figure pas, il faut l'ajouter via Outils=> Options => Libreoffice Base => Base de données=> Nouveau.
La structure de la table dépenses est celle-ci :

           Table "public.dépenses"
  Column   |         Type          | Modifiers 
-----------+-----------------------+-----------
 référence | character(9)          | not null
 date_exec | date                  | 
 montant   | numeric(13,2)         | 
 détails   | character varying(50) | 
 code_u    | character(2)          | 

La signification de code_u se trouve dans la table utilisations :

            Table "public.utilisations"
    Column     |         Type          | Modifiers 
---------------+-----------------------+-----------
 code_u        | character(2)          | not null
 signification | character varying(20) | 

Il existe une relation d’intégrité référentielle basée sur code_u entre les 2 tables. Les seules valeurs de code_u qui peuvent exister dans dépenses doivent être définies dans utilisations (ou alors code_u dans dépenses ne doit contenir aucune valeur, c'est à dire être à la valeur NULL).
(La table dépenses est celle dont il est question dans le message précédent, et les données y sont les mêmes)

Afin de faciliter la construction du tableau croisé dynamique, je vais dans LibreOffice Base créer une requête en mode SQL. Dans l'éditeur qui surgit, je saisis :

select a.référence, a.date_exec, a.montant,
a.détails, b.signification as usage
from dépenses a, utilisations b
where a.code_u = b.code_u 

et je sauvegarde cette requête sous le nom dépensesr.
Ensuite j'ouvre LibreOffice Calc et clique sur l'icône adéquate :


Avant de sélectionner la source :


Ensuite il reste à glisser ce qui convient là où ça convient :


Je sélectionne l'ensemble des dates dans le tableau créé :


et CTRL-1 me permet de choisir le format dans les quelles ces dates seront affichées.
Procédant de même je peux également choisir le format d’affichage des montants.

Une date étant sélectionnée, un appui sur F12 donne la possibilité d'effectuer différents groupements :


Je choisis un groupement par Années et par Mois.


Je clique droit sur le tableau et dans le menu contextuel qui surgit, je sélectionne : Éditer la mise en page :


Puis je double clique sur Années car je veux des sous totaux :




Via le bouton Options (à gauche du bouton OK) je pourrais aussi choisir les années à afficher dans le tableau.

Le tableau peut facilement être actualisé par clic droit puis choisir Actualiser.

On pourrait procéder de manière indirecte : importer les données PostgreSQL dans ce qui deviendra la plage active source de la future table de pilote.
J'ai déjà exposé cette méthode ici.
Après appui sur CTRL-MAJ-F4 et choix de la requête dépensesr (de la base de données bdtest), je sélectionne l'ensemble des données (en cliquant sur le rectangle gris du coin supérieur gauche) et j'insère celles-ci dans le tableur via l'icône "Données dans le texte".

Condensé en image :


Au moment de choisir la source de la table de pilote, prendre cette fois Sélection active :


Avant d'actualiser le tableau croisé dynamique (table de pilote) produit de cette manière, il faut d'abord sélectionner puis actualiser la plage.
Attention : si la plage active s'agrandit (ajout de données), ce n'est pas répercuté dans la table de pilote.
On doit adapter manuellement celle-ci en passant par Éditer la mise en page :


Voilà pour les inconvénients de cette méthode qui présente cependant quelques avantages.
Notamment le menu contextuel obtenu en cliquant droit sur le tableau est plus riche de l'option Filtrer qui conduit à ce panneau :



lundi 13 mars 2017

Expressions régulières dans SQL

J’ai déjà traité plusieurs fois de l’utilisation d’expressions régulières dans des instructions SQL, et notamment dans ce billet.
Je vais cette fois étudier le problème de manière systématique.
Pour quelques explications concernant les expressions régulières, voir ce billet.
Dans la table PostgreSQL dépenses (déjà rencontrée ici mais le contenu a changé depuis lors), je recherche les rangées dont la colonne détails contient le mot 'jardin'.
Travaillant dans un terminal psql, je lance l’instruction qui convient, utilisant la fonction regexp_matches :

bdtest=> select référence, montant, détails,
bdtest-> regexp_matches(détails, 'jardins')
bdtest-> from dépenses
bdtest-> order by référence
bdtest-> ;
 référence | montant |       détails       | regexp_matches 
-----------+---------+---------------------+----------------
 2013-0014 |  103,00 | Docteur Desjardins  | {jardins}
 2013-0023 |   40,00 | Station des jardins | {jardins}
 2017-0045 |  173,24 | Les jardins arborés | {jardins}
(3 rows)

Très bien mais une clause
where détails like '%jardins%'
aurait aussi bien fait l’affaire sauf que regexp_matches donne la possibilité d'utiliser des expressions régulières offrant donc plus de souplesse.
Ainsi si je remplace 'jardins' par '\yjardins\y', la rangée 2013-0014 va disparaître du résultat car dans une expression régulière \y indique une bordure de mot.
(Les bordures de mot sont habituellement indiquées par \b, mais pas selon le standard suivi par PostgreSQL)
La fonction substring permet elle aussi l'utilisation d'expressions régulières, mais elle nécessite l'utilisation d'une clause where si on veut exclure du résultat les rangées qui ne satisfont pas au critère.
Exemple :

select référence, montant, détails,
substring(détails, '\yjardins\y')
from dépenses
where substring(détails, '\yjardins\y') is not null
order by référence
;
 référence | montant |       détails       | substring 
-----------+---------+---------------------+-----------
 2013-0023 |   40,00 | Station des jardins | jardins
 2017-0045 |  173,24 | Les jardins arborés | jardins
(2 rows)

A l'inverse avec regexp_matches, il faut utiliser un subselect pour afficher toutes les rangées :

bdtest=> select référence, montant, détails,
bdtest-> (select regexp_matches(détails, '\yjardins\y'))
bdtest-> from dépenses
bdtest-> order by référence
bdtest-> ;
 référence | montant |       détails        | regexp_matches 
-----------+---------+----------------------+----------------
 2013-0014 |  103,00 | Docteur Desjardins   | 
 2013-0015 |   56,47 | Courrefar            | 
 2013-0016 |   49,56 | Station des camélias | 
 2013-0017 |  117,23 | Caro                 | 
 2013-0018 |   43,00 | Docteur Lebon        | 
 2013-0019 |  245,74 | La marmite           | 
 2013-0020 |   24,53 | Phie Arcodor         | 
 2013-0021 |  104,25 | Aupré                | 
 2013-0022 |   68,17 | Courrefar            | 
 2013-0023 |   40,00 | Station des jardins  | {jardins}
 2014-0016 |   87,23 | Caro                 | 
 2014-0017 |   30,00 | Docteur Ledoux       | 
 2014-0018 |  149,57 | La bonne auberge     | 
 2014-0019 |   50,00 | Station Les cafés    | 
 2017-0045 |  173,24 | Les jardins arborés  | {jardins}
(15 rows)

Recherchons les mots de 7 lettres minuscules :

bdtest=> select référence, montant, détails,
bdtest-> regexp_matches(détails, '\y[[:lower:]]{7}\y', 'g')
bdtest-> from dépenses
bdtest-> order by référence
bdtest-> ;
 référence | montant |       détails       | regexp_matches 
-----------+---------+---------------------+----------------
 2013-0019 |  245,74 | La marmite          | {marmite}
 2013-0023 |   40,00 | Station des jardins | {jardins}
 2014-0018 |  149,57 | La bonne auberge    | {auberge}
 2017-0045 |  173,24 | Les jardins arborés | {jardins}
 2017-0045 |  173,24 | Les jardins arborés | {arborés}
(5 rows)

Je rappelle que \y indique une bordure de mots. Celui-ci doit comporter 7 caractères de la classe [[:lower:]]. Nous utilisons cette classe plutôt que la classe [a-z] qui ne comprend pas les caractères accentués.
L’option facultative ‘g’ indique à la fonction regexp_matches d’afficher toutes les occurrences du motif recherché et non pas seulement la première. C’est pourquoi la rangée '2017-0045' apparaît deux fois.
La donnée renvoyée par la fonction regexp_matches est une donnée de type 'array' contenant une ou plusieurs données de type texte.
Mettons cela en évidence :

bdtest=> select référence, montant, détails,
bdtest-> regexp_matches(détails, '\y([[:lower:]]{3})([[:lower:]]{4})\y')
bdtest-> from dépenses
bdtest-> order by référence
bdtest-> ;
 référence | montant |       détails       | regexp_matches 
-----------+---------+---------------------+----------------
 2013-0019 |  245,74 | La marmite          | {mar,mite}
 2013-0023 |   40,00 | Station des jardins | {jar,dins}
 2014-0018 |  149,57 | La bonne auberge    | {aub,erge}
 2017-0045 |  173,24 | Les jardins arborés | {jar,dins}
(4 rows)

Le motif est découpé en deux à l'aide de parenthèses ce qui conduit à des tableaux à deux éléments.
De telles parenthèses (dites mémorisantes) sont utiles quand on envisage de procéder au remplacement de la chaîne trouvée. Dans la chaîne de remplacement, \1, \2, …, correspondent aux différents morceaux de la chaîne d'origine qui sont entre parenthèses.
Illustrons le en utilisant la fonction regexp_replace :

bdtest=> select référence, montant,
bdtest-> regexp_replace(détails, '\y([[:lower:]]{3})([[:lower:]]{4})\y', '\2\1', 'g')
bdtest-> from dépenses
bdtest-> order by référence
bdtest-> ;
 référence | montant |    regexp_replace    
-----------+---------+----------------------
 2013-0014 |  103,00 | Docteur Desjardins
 2013-0015 |   56,47 | Courrefar
 2013-0016 |   49,56 | Station des camélias
 2013-0017 |  117,23 | Caro
 2013-0018 |   43,00 | Docteur Lebon
 2013-0019 |  245,74 | La mitemar
 2013-0020 |   24,53 | Phie Arcodor
 2013-0021 |  104,25 | Aupré
 2013-0022 |   68,17 | Courrefar
 2013-0023 |   40,00 | Station des dinsjar
 2014-0016 |   87,23 | Caro
 2014-0017 |   30,00 | Docteur Ledoux
 2014-0018 |  149,57 | La bonne ergeaub
 2014-0019 |   50,00 | Station Les cafés
 2017-0045 |  173,24 | Les dinsjar orésarb
(15 rows)

regexp_replace renvoie une chaîne inchangée si le motif n'est pas trouvé.
L'option facultative 'g' a la même signification qu'auparavant. En son absence, on aurait pour la rangée '2017-0045' le texte : 'Les dinsjars arborés'.

Je vais maintenant donner un exemple pratique d'utilisation de ces fonctions.
Considérons une table (par exemple mvts) reprenant les mouvements effectués sur un compte en banque. La banque fournit quantité de données (date, montant etc), mais pas directement le numéro de compte de la contrepartie. Aussi quand de nouvelles rangées sont créées lors de l'importation des données fournies, les éléments de la colonne 'compte' prévue pour contenir le numéro de compte sont null ou vides. Cependant ce numéro de compte se trouve parfois perdu au milieu du texte informatif se trouvant dans un champ souvent appelé 'détails', jamais à la même place et parfois sous des formats différents.
L' instruction SQL

select référence, détails, regexp_matches(détails, 'FR[0-9]{2} [0-9]{4} [0-9]{4} [0-9]{4}')
from mvts
where compte is null
or compte = ''

permet de repérer certains de ces comptes.
En image :


Il reste à mettre le champ compte à jour, mais il ne faut pas oublier que le retour de regexp_matches n'est pas du texte. Il faut d'abord le transformer. L'instruction update est donc :

update mvts
set compte = substr(regexp_matches(détails, 'FR[0-9]{2} [0-9]{4} [0-9]{4} [0-9]{4}')::text, 3, 19)
where compte is null
or compte = ''

Il n'y a pas de mise à jour si le motif n'est pas rencontré.

On pourrait utiliser la fonction substring à condition d'adapter la clause where afin d'éviter les mises à jour indésirables:

update mvts
set compte = substring(détails,'FR[0-9]{2} [0-9]{4} [0-9]{4} [0-9]{4}')
where (compte is null
or compte = '')
and substring(détails,'FR[0-9]{2} [0-9]{4} [0-9]{4} [0-9]{4}')
is not null



Les comptes figurant dans 'détails' peuvent se trouver sous un autre format.
L'instruction pour les retrouver doit être adaptée :

select référence, détails, regexp_matches(détails, 'FR[0-9]{14}')
from mvts
where compte is null
or compte = ''

En images le résultat:


L'instruction 'update' est elle aussi modifiée :

update mvts
set compte = substr(regexp_matches(détails, 'FR[0-9]{14}')::text, 2, 16)
where compte is null
or compte = ''

Le problème est que maintenant les comptes se trouvent dans la table mvts sous deux formats différents.
Qu'à cela ne tienne : la fonction regexp_replace nous permet de remettre tout ça en place :

update mvts
set compte = regexp_replace(compte, '(FR[0-9]{2})([0-9]{4})([0-9]{4})([0-9]{4})', '\1 \2 \3 \4')
where compte <> regexp_replace(compte, '(FR[0-9]{2})([0-9]{4})([0-9]{4})([0-9]{4})', '\1 \2 \3 \4')

Le motif est scindé en 4 morceaux à l'aide de parenthèses mémorisantes. Dans la chaîne de remplacement ces morceaux (\1, \2, ...) sont séparées par des espaces. La clause where empêche les mises à jour inutiles (compte inchangé) : en effet regexp_replace retourne le compte d'origine si le motif n'est pas trouvé.

Les numéros de compte peuvent se trouver sous d'autres formats que ceux indiqués dans ces exemples.
Il faut évidemment adapter les expressions régulières en conséquence.

Si on utilise une table 'comptes' qui comprend la clef primaire 'compte', il reste à insérer des rangées pour les comptes de mvts qui n'existent pas dans cette table. Ceci peut se faire avec l'instruction :

insert into comptes
(compte)
select distinct a.compte
from mvts a natural left outer join comptes b
where b.compte is null
and a.compte > ''

Lorsque la colonne a.compte contient une valeur qui n'existe pas dans la table comptes, le système joint à la rangée de la table mvts une rangée fictive de la table comptes dont tous les champs sont à la valeur NULL (pour des informations sur les différents type de join voir ici).
La clause where permet donc d'afficher la liste des comptes présents dans mvts et qui n'existent pas dans la table comptes.

Pour être complet, signalons l'existence des deux fonctions regex_split_to_array et regexp_split_to_table. L'expression régulière sert alors de délimitateur.

Illustrons :


Dans ces instructions la fonction regexp_replace de la clause where est inopérante (la chaîne de remplacement pourrait être n'importe quoi) : elle sert simplement à éliminer les rangées sans le mot 'des' dans détails car les fonctions regexp_split retournent toujours quelque chose même si l'expression régulière n'est pas trouvée.

Montrons le:


Ces fonctions n'admettent pas les options du genre 'g'.

Note: on pourrait dans les 2 premières des 4 instructions précédentes utiliser

where substring(détails, '\ydes\y') is not null

au lieu de

where détails <> regexp_replace(détails, '\ydes\y', '')

jeudi 4 août 2016

sddm: image utilisateur

Vous en avez assez que sddm (écran de connexion graphique pour kde) ressemble à ceci:


Vous préférez plutôt y voir figurer les images (ou les avatars) des utilisateurs.
Cela nécessite une action de chaque utilisateur.
Pour kubuntu, pas de problèmes: il suffit de procéder via Configuration du système -> Détails du compte-> Gestionnaire des utilisateurs.
Pour Fedora kde (ou d'autres distributions), rien n'est prévu à ce niveau.
Mais on peut agir dans un émulateur de terminal, avec la commande kcmshell114.
Pour l’utilisateur toto:

toto@rigel:~$ kcmshell4 kcm_useraccount


mercredi 3 août 2016

Mise à niveau vers Fedora 24

J'ai hésité longtemps avant d'écrire cet article puisque tout était déjà dit dans cet article concernant le passage à Fedora 23. Je rappelle donc les commandes qu'il convient d'exécuter (en tant que root):

[root@rigel ~]# dnf update --refresh

pour mettre à jour le système existant

[root@rigel ~]# dnf install dnf-plugin-system-upgrade

pour installer le programme qui convient

 [root@rigel ~]# dnf system-upgrade download --releasever=24

pour télécharger les paquets de la nouvelle version

[root@rigel ~]# dnf system-upgrade reboot

pour procéder à la mise à niveau proprement dite.

Toutefois si l'étape 3 se termine par une erreur du genre:

Erreur : Erreur du contrôle de transaction
  le fichier /usr/bin de l'installation de google-earth-stable-7.1.4.1529-0.x86_64 entre en conflit avec le fichier du paquet filesystem-3.2-37.fc24.x86_64

cela signifie qu'un dépôt actif fournit un paquet non installable (google-earth-stable-7.1.4.1529-0.x86_64 dans notre exemple).

Il n'est pas trop tard pour supprimer ce dépôt.
Par exemple:

[root@rigel ~]# rm /etc/yum.repos.d/google-earth.repo

L'étape 3 relancée se termine alors rapidement sans aucune erreur (tous les téléchargements ont déjà été effectués).
Toutefois la dernière étape malgré un début prometteur se plante sans aucun message d'erreur.
En fait le paquet litigieux est toujours dans le cache.
il faut le supprimer avant de poursuivre:

[root@rigel ~]# rm /var/lib/dnf/system-upgrade/google-earth-stable-6.0.3.2197-0.x86_64.rpm 

En ce qui concerne la migration des données postgresql, j'ai déjà tout expliqué ici.
Toutefois j'ajouterai qu'il convient en tant que postgres de se placer là où postgres peut écrire (ou sinon le programme pg_upgrade se plante).
La séquence est donc:

[toto@rigel ~]$ su -
Mot de passe :
[root@rigel ~]# su - postgres
bash-4.3$ cd /var/lib/pgsql
bash-4.3$ mv data data_9.4

Ensuite:

[root@rigel ~]# postgresql-setup initdb

Puis:

bash-4.3$ pg_upgrade -b /usr/lib64/pgsql/postgresql-9.4/bin/ -B /usr/bin/ -d data_9.4/ -D data

(ceci suppose que la variable d'environnement PGDATA existe et contient /var/lib/pgsql/data)

Je récupère ensuite l'ancien pg_hba.conf

bash-4.3$ cp /var/lib/pgsql/data_9.4/pg_hba.conf /var/lib/pgsql/data/

En effet si je le récupère d'abord comme indiqué dans l'article précédent et qu'il contient des éléments empêchant le démarrage du nouveau serveur, pg_upgrade va se planter.

L'erreur fatale dont il est question précédemment ne se produit plus.

Ne pas oublier de récupérer pg_ident.conf et d'adapter postgresql.conf

mardi 1 mars 2016

Droits

Une phrase comme celle-ci
"Les droits sur /usr/bin sont du type 0755...."
reprise de l'article précédent a pu intriguer quelques néophytes.
Aussi, bien qu’il existe des centaines d’articles traitant des droits sur les fichiers en linux, je me suis finalement décidé à y mettre mon grain de sel.

Travaillant dans un (émulateur de) terminal, je génère à l'aide de la commande cat le fichier quisuisje contenant le texte :
echo Je suis $USER
Je termine par ENTER pour envoyer la ligne et CTRL+D pour signifier la fin du processus.
J'essaie d'exécuter le fichier avec
./quisuisje
mais évidemment ça ne fonctionne pas tant que je n'ai pas donné le droit d'exécution (chmod +x) :


J'examine (commande ls) quels sont les droits sur le fichier.
Ceux-ci

r droit en lecture
w droit en écriture
x droit en exécution

sont répartis en 3 catégories

  • droits du propriétaire du fichier (c'est moi : toto)
  • droits des membres du groupe indiqué. Ici ce sont les amis du propriétaire (membres du groupe toto)
  • droits des autres utilisateurs

Je ne veux pas que mes amis puissent modifier le fichier, aussi je leur enlève le droit en écriture sur le fichier :



La commande chmod, telle qu’utilisée ici, est suivie d’une ou de plusieurs lettres qui indiquent le ou les utilisateurs concernés :

u désigne le propriétaire
g les membres du groupe
o les autres

Vient ensuite ± puis le ou les droits ajoutés ou retirés selon le cas.
(Note: si rien ne précède +/-, la commande concerne tous les utilisateurs)

L'ensemble des droits sur un fichier constitue un nombre binaire et chaque droit attribué correspond à un bit de ce nombre binaire mis sur ON.
Les droits sur quisuisje correspondent au nombre binaire
000111101101
(Les 3 premiers bits sur OFF sont associés à des droits spéciaux dont il n'a pas été question jusqu’ici).

Je voudrais calculer le nombre hexadécimal correspondant.
Pour ce faire je regroupe les bits par série de 4 et je leur attribue les valeurs 8, 4, 2, 1.
J'annule ces valeurs si le bit est sur OFF, ensuite dans chaque groupe j'additionne les valeurs survivantes pour avoir le chiffre du nombre hexadécimal :

Le nombre décimal vaut :

1x256 + 14x16 + 13 = 493

Mais quel sens faut-il donner à la transformation en hexadécimal du nombre binaire correspondant aux droits ?
Aucun : ça n'a aucun sens. Il s'agit cependant d'un excellent entraînement pour passer maintenant à l'octal.
Les bits sont cette fois regroupés par séries de 3 avec les valeurs 4, 2, 1.
Pour le reste nous procédons de la même façon :


Le nombre décimal équivalent est évidemment inchangé :

7x64 + 5x8 + 5 = 493

Cette fois, ça a du sens.
Plutôt que d'adapter les droits sur quisuisje avec
chmod (g-w) quisuisje
on aurait pu les fixer directement :
chmod 755 quisuisje

Les droits rwx pour un dossier n'ont pas la même signification que pour un fichier :
r droit de lire le répertoire
w droit d'y ajouter ou d'y supprimer des fichiers
x droit d'y aller (dans le dossier)
Je crée dossier puis j’enlève les droits r et x aux utilisateurs qui ne sont ni toto (c’est moi) ni ses amis (membres du groupe toto) :


Au fait quels sont mes amis ?


Seulement riri.
Donc titine n’a pas le droit d’aller dans dossier :


Je rétablis le droit x pour tous. Cette fois titine peut aller dans dossier mais elle ne peut y lire le répertoire (il lui manque le droit r) :


Pour finir je donne à tous les droits rwx sur dossier (chmod 777 dossier).
Mais si un utilisateur à le droit de supprimer des fichiers, il peut tous les supprimer, même ceux qui ne sont pas à lui, même ceux pour lesquels il n'a pas le droit d'écriture!
Ainsi sur la copie d'écran qui suit, riri supprime le fichier hello appartenant à titine :


C'est ici qu'intervient le sticky bit :



S'il est activé pour un dossier dans lequel tous peuvent écrire, chacun ne pourra y supprimer que ces propres fichiers.

Activation :


Vérification:


Les droits sur le dossier sont maintenant décrit par la chaîne rwxrwxrwt et hello est à l'abri de toute suppression (sauf par son propriétaire titine ou toto propriétaire du dossier).
Le nom sticky bit provient d’un usage ancien de ce bit qui n’est pas celui expliqué ici.

Je peux aussi activer pour dossier le bit setgid :



Tout fichier créé par titine (comme salut) sera dorénavant caractérisé par le groupe toto (groupe du dossier de travail):


Comme riri appartient au groupe toto, il pourra donc modifier ce fichier.

Je veux maintenant faire machine arrière : remettre sur off les 2 bits spéciaux qui ont été activés :


Ça fonctionne pour le sticky bit (rwt devient rwx) avec chmod en mode numérique.
Pour le bit setgid, il faut utiliser chmod en mode symbolique.

Un dernier droit spécial n'a pas été évoqué jusqu'à présent.

Afin de pouvoir montrer sur une exemple ce dont il s'agit, je recopie l'exécutable whoami dans mon dossier test :


Comme je suis propriétaire de cette copie de whoami, je peux lui attribuer les droits que je veux.
Aussi j'active pour cet exécutable le bit setuid :



Pour ma copie de whoami lancée par titine, tout se passe comme si c'était moi (toto) qui l'avait lancée. Le whoami d'origine n'est évidemment pas impacté.
Pourquoi ne pas avoir avoir utilisé le fichier quisuisje pour ce qui précède?
Tout simplement parce que pour des raisons de sécurité le bit setuid est désactivé pour les fichiers scripts exécutables.

samedi 9 janvier 2016

Google-earth Fedora vs openSuse

Comme je l'ai indiqué dans le billet précédent, le paquet téléchargé ici pour Fedora 64 bits (à savoir le paquet google-earth-stable_current_x86_64.rpm) n'est pas installable suite à un conflit avec le fichier /usr/bin du paquet filesystem.
J'ai expliqué comment remédier à ce problème: supprimer la ligne

%dir %attr(0755, root, root) "/usr/bin"

dans le fichier spec du paquet (voir le billet précédent).

Cependant sur la page de téléchargement on peut constater que le paquet destiné à openSuse est le même que celui pour Fedora.
Et dans openSuse, l'installation de ce même paquet ne pose aucun problème!
Quel est ce mystère?
La réponse se trouve du côté du fichier /usr/bin fourni par filesystem.
Dans openSuse:




Les droits sur /usr/bin sont du type 0755, exactement comme dans le fichier spec.

Dans Fedora (23):




Les droits ne correspondent plus: ils valent 0555 ce qui provoque le conflit.

Plutôt que de supprimer la ligne litigieuse du fichier spec, il suffit de la modifier.


Donc je lance la commande


toto@rigel:~/Téléchargements$ rpmrebuild -p -e google-earth-stable_current_x86_64.rpm 

Ensuite dans l'éditeur qui s'ouvre (normalement c'est vi), je trouve la ligne ad hoc avec

/usr\/bin

J'amène à l'aide des flèches le curseur sur le 7, puis:

r5
:wq

A la question qui vient, je réponds que je veux continuer, ce qui provoque la création d'un nouveau paquet qu'il suffit d'installer.