Linux : des droits spécifiques ftp ?

Comment donner des droits spécifiques ftp afin de renforcer (un peu) la sécurité de votre (vos) site(s) ?
Imaginons que l’on souhaite avoir plusieurs personnes qui travaillent sur le même site, qui veulent accéder aux sources via ftp, qui veulent pouvoir écrire dedans.
Imaginons aussi que l’on donne que le droit de lecture au processus apache, afin que si un pirate réussit à s’introduire dans le système via apache, il n’ait le droit que de lire les fichiers.
Configurons Linux de telle sorte que le processus apache soit lancé en tant qu’utilisateur apache.
Disons que nous avons besoin de travailler avec deux personnes :

  • Laurent (utilisateur = laurent)
  • Frédéric (utilisateur = frederic)

Il faut donc que :

  • l’utilisateur = laurent ait les droits en lecture et écriture dans un répertoire et sur des fichiers donnés ;
  • l’utilisateur = frederic ait les droits en lecture et écriture dans le même répertoire et sur les mêmes fichiers ;
  • l’utilisateur = apache ait les droits en lecture uniquement dans le même répertoire et sur les mêmes fichiers.

C’est simple.
Il faut créer un groupe pour les utilisateurs à qui on souhaite donner les droits de lecture et d’écriture. Appelons ce groupe happyfews. Il faut éditer le fichier /etc/groups et y ajouter :
happyfews:x:5000:laurent,frederic, etc,
avec tous les utilisateurs à qui l’on veut donner la possibilité de lire et d’écrire.
Puis sur le(s) répertoire(s) de travail, il faut appliquer les droits suivants :

  • chown apache <repertoire>
  • chgrp happyfews <repertoire>
  • chmod 570 <repertoire>

Ce qui signifie respectivement :

  • Le répertoire appartient à apache ;
  • Le répertoire appartient au groupe « happyfews » ;
  • Le groupe « happyfews » possède les droits de lecture + écriture, mais le propriétaire du répertoire lui-même n’a que le droit de lecture ;
  • Tout utilisateur autre que le propriétaire ou un membre du groupe n’a aucun accès.

Pour mémoire :
5=user:read+execute, 7=group:read+write+execute, 0=other:no access
Il ne restera ensuite qu’à ajouter/supprimer les utilisateurs qui font partie de ce groupe pour autoriser/refuser l’accès en écriture au(x) répertoire(s) concerné(s).

Ma fille a des nuits plutôt agitées

On ne sait pas trop comment gérer la situation : le soir, elle parle, chante, appelle maman, appelle papa, demande un petit peu à boire, etc etc, tant qu’elle peut. A savoir qu’elle dort bien pratiquement depuis qu’elle est née, tous les soirs entre 20h00 et 21h00. Maintenant, elle continue à faire la fête dans son lit jusqu’à 22h00. Alors bien sûr, le matin elle est crevée, elle dort toujours alors que nous sommes levés. Que faire ? Elle est si adorable qu’on n’a pas envie de la disputer ! Ce que je veux dire c’est qu’elle ne fait aucun caprice, elle hurle pas, elle ne pleure pas parce qu’on la laisse dans son lit, non, rien de tout ça : elle est dans son petit monde, elle chante, et… bon ce qui nous ennuie c’est qu’elle nous appelle assez fréquemment. Sandrine pense que si elle a un sommeil agité, c’est parce qu’elle regarde des dessins animés le soir juste avant de s’endormir. Donc on va temporairement repasser aux chansons, ce sera tout aussi sympa mais plus « soft » pour elle.

Ma fille chuchote !

C’est à mourir de rire. Depuis qu’elle est née, elle ne parle qu’à voix haute, même si les adultes parlent à voix basse. Je pense que chez tous les enfants c’est pareil et qu’ils n’ont pas la notion de voix haute ou basse.
Mais depuis 2-3 jours, Inès a compris qu’on peut chuchoter.
Je l’ai prise dans les bras, on est allés se cacher dans la salle de bains et je lui ai murmuré « on va faire peur à maman » et on a attendu que maman passe devant l’entrée de la salle de bains. Pendant ce temps elle m’a répété 2-3 fois tout doucement dans l’oreille « fè peuw », c’était à mourir de rire.

Ce matin, en me levant, je la prends dans les bras. Elle venait de prendre le biberon que sa maman donne tous les matins. On va se regarder devant la glace de l’entrée et je me dis, pour moi, « oulah j’ai fait un rototo ». Elle me regarde et murmure dans l’oreille « pôpa rototo ». A mourir de rire.

Sandrine l'a à nouveau fait exploser de rire !

Ce soir (mercredi), Sandrine à trouvé un nouveau truc qui fait exploser de rire Inès. Cela allait faire très longtemps qu’elle n’avait pas ri aux éclats comme cela. En fait c’est lors du bain, qu’Inès prend avec sa maman. On a des grenouilles, vous savez, les trucs qui ont des ventouses et qui servent à empêcher de glisser, collés au fond de la baignoire. Ces grenouilles ne nous servent absolument pas à cela, à savoir qu’Inès joue tout le temps avec, elle les décolle et les met n’importe où dans le bain pour jouer. Sandrine a eu l’idée, ne me demandez pas comment c’est venu, de prendre une de ces grenouilles, de la plier en deux et de la mordre. Puis elle a ouvert la bouche, et hop, la grenouille est sortie et est tombée dans l’eau, à plat, en faisant un « plof » bien fort. Cela fait systématiquement exploser de rire Inès.

C’est tellement beau une petite qui rit aux éclats !

Une nouvelle année commence… au travers du vomi de ma fille !

Ma fille a attrapé une angine carabinée, elle a été malade du 24 décembre jusqu’à maintenant. Le seul hic, c’est que l’angine, aux dires du docteur, s’est installée partout : dans les intestins, et ça lui a donné une diarrhée carabinée, et dans la gorge : cela la fait vomir. La pauvre. Dans la nuit du 28 au 29 elle était malade comme pas possible et a vomi tout ce qu’elle avait mangé, à tel point que tôt le matin, elle continuait à essayer de vomir, mais rien ne sortait… Elle n’arrivait même plus à marcher, tellement elle n’avait plus de force ! Ceci dit, tout devrait passer et je pense que l’année 2008 sera destinée à tout ce qui touche de près ou de loin la santé !

Pour la nouvelle année… j'ai installé oxyl-box

Voici comment installer quelque chose qui transforme votre Pinnacle Showcenter en un outil pratique, sympa, rapide à utiliser et qui ne surcharge pas votre ordinateur avec plein de choses complètement inutiles.

Le site où j’ai trouvé mon bonheur est ici : oxyl.de

Notez la première chose d’importance : tout est gratuit.

Avant d’aller plus loin, voici la petite histoire de mon Pinnacle Showcenter 200, pour que vous compreniez ma démarche, qui sera peut-être la vôtre aussi.

Un jour, j’ai lu sur Internet, le test d’un lecteur vidéo qui m’a semblé vraiment super sympa. J’ai finalement craqué : j’ai acheté le Pinnacle Showcenter 200.

Lorsque je l’ai reçu, j’ai fait ce que toute personne normale aurait fait, à savoir, insérer le CD et installer le logiciel pour utiliser mon joujou.

Qu’est-ce que je n’avais pas fait ! Il m’a demandé d’installer tout un tas de choses, ça a pris un temps fou, il a récupéré le Framework .Net de Microsoft, il a installé sans me demander mon avis l’intégralité du serveur de base de données Microsoft SQLServer version personnelle, qui prend un maximum de mémoire et de ressources, et, cerise sur le gâteau, a rajouté plus de dix secondes au démarrage de mon ordinateur !

Je me suis dit : il faut trouver une autre solution. J’ai alors cherché sur Internet, et je suis tombé sur ce petit bijoux dont j’ai donné l’adresse déjà plus haut : oxyl.de

Voilà comment faire pour l’installer, parce que ce n’est pas en deux secondes que tout fonctionne, mais au moins, une fois que ça fonctionne, votre PC ne rame pas inutilement, et c’est déjà quelque chose d’énorme.

  1. Récuperer la version complète d’installation ici
  2. L’installer en cliquant « oui », avec toutes les options, y compris si certaines ne sont pas cochées (je crois que « stoWeb » n’est pas coché, il faut le cocher en mode « installation complète sur le disque »)
  3. Après que tout ait été installé, téléchargez cette archive : oxylbox-www.rar
  4. Ensuite, décompressez là directement par dessus le répertoire www d’installation d’oxyd, normalement c’est « C:\Program Files\oxylbox »
  5. Enfin, il faut éditer le fichier « php.ini » qui est dans le répertoire de Windows (normalement, C:\Windows) et cherchez le mot extension_dir. Assurez-vous que vous avez bien ceci :
    extension_dir = "C:\Program Files\oxylbox\php5\ext"
    Sachant que le répertoire est celui où vous avez installé oxyd.

Voilà, tout tourne ! Pour vérifier, ouvrez votre navigateur Internet et tapez cette adresse : http://127.0.0.1:8000/

Normalement tout fonctionne.

Maintenant la note pour les informaticiens :

En réalité, programme est très vieux et le type qui a fait ça est un jeune qui a découvert au fur et à mesure pas mal de fonctionnalités, et les a ajoutées, ce qui donne lieu à un bazar monstre. De plus, en php, il utilise les register_globals=On c’est à dire que dans un POST, si une variable $_POST['P']='zoubida', alors il y accède directement via if (isset($P))… Mais ceci mis à part, il a programmé un mini serveur dédié pour envoyer du flux audio/vidéo etc vers le ShowCenter. Donc ça c’est le côté super sympa. En fait ce qu’il faudrait refaire c’est toute la présentation, de manière à avoir quelque chose de clair, orienté objet, que n’importe qui pourrait facilement réutiliser. C’est vraiment dommage, parce qu’il y avait un bon potentiel derrière tout ça, mais il n’est pas exploitable tant que toute l’interface ne sera pas réécrite. Tous les commentaires sont en Allemand, ils ne sont pas fait selon le standard JavaDoc, donc il est impossible de générer une documentation correcte, les pages générées ne sont pas du tout propres, heureusement que le navigateur du ShowCenter est « souple » et les affiche correctement etc. Ceci dit il y a des idées sympas, par exemple, lorsqu’on lui demande de changer de « skin », il vérifie tous les répertoires existants dans le répertoire « skins » et passe au suivant. Autrement dit en pratique, vous faite simplement un copier coller d’un répertoire, et vous le renommez, changez quelques images pour tester et tout fonctionne sans toucher une ligne de code. Ca c’est super pratique. Si un jour j’ai un peu de temps, je referai tout ça en php. Mais ce n’est pas à l’ordre du jour pour 2008 !

Les jeux électroniques de l'époque : Donkey-kong…

Après une discussion avec ma soeur, je me suis souvenu d’une chose assez suprenante et que je pense caractéristique d’un geek
Quand j’avais 10-12 ans, donc dans les années 80, j’ai découvert les jeux électroniques. Il y avait un jeu qui se nommait Donkey-Kong, vous savez un jeu à écran à cristaux liquides. Ce jeu, tout le monde y jouait. Enfin, tous les jeunes. Ma mère, pour être tranquille quelque temps, vient me voir et me dit « Olivier, le jour où tu réussiras à dépasser 999, je t’achète un autre jeu électronique ».
Moi, je commence à jouer, je regarde, j’analyse, je fais jouer ma soeur, je la regarde et on se bat un peu pour y jouer (normal, quoi), et puis je constate que plus le score est grand, plus ça va vite. Je me dis qu’il doit bien y avoir un moyen de ralentir suffisamment le jeu pour pouvoir aller au bout…
Et je me retrouve seul avec le Donkey-Kong. J’ai alors essayé de créer un faux-contact entre avec les piles dans le jeu : sur la notice ils expliquaient que le jeu redémarrait mais je me doutais qu’il n’y avait peut-être pas que ça. Et après un bon nombre d’essais (ça n’a pas marché du premier coup, croyez-moi !), hop ! L’horloge interne du jeu électronique a été ralentie et j’ai ainsi pu faire trois fois le tour de 999 dans la soirée !
Depuis je n’ai jamais trouvé quelqu’un qui avait fait cette manipulation et trouvé comment ralentir un jeu électronique…
Ceci dit ma mère n’a pas tenu sa promesse : je n’ai eu un autre jeu électronique que bien plus tard…

Php : optimisation vs lisibilité

Attention, ce qui suit ne s’applique pas systématiquement partout, mais il faut avoir cela en tête dans certaines occasions.

Ci-suivent deux possibilités de codes qui font exactement la même chose : vous allez certainement me dire : le code 2 est très nettement moins bien que le code 1, à savoir que si on veut rajouter quelque chose dans le 1 c’est une ligne alors que dans le 2 c’est quatre lignes. Eh bien c’est vrai, mais il faut garder le code 2 qui est plus long et qui semble se répéter de manière inutile. Pourquoi, me demanderez-vous ? Je vais vous dire pourquoi :

Il faut toujours adapter le code en fonction de votre supérieur hiérarchique.

Si, si, je ne plaisante pas. Si vous avec un patron qui vous dit, une bonne fois pour toutes : « Voilà les champs qu’on utilisera cela ne changera pas », et, surtout, que c’est vrai, alors vous pouvez vous faire plaisir et factoriser au maximum. A l’inverse, un patron qui arrive et qui vous dit « Voilà les champs qu’on utilisera cela ne changera pas », et, le connaissant vous savez que c’est faux, alors utilisez le code 2. Cela m’arrive tout le temps : « Au fait Olivier j’ai oublié de te dire : il y a un nouveau champ garantie qui est, en réalité un pourcentage d’une autre garantie et il faut s’assurer que l’autre existe vraiment ». Si vous avez adopté le code 1 avec ce genre de patron, vous êtes fichu : Ce code n’est pas prévu pour gérer des exceptions.

Dernier argument pour le code 2 : il est beaucoup plus compréhensible que le code 1. Beaucoup, beaucoup, beaucoup. Et si quelqu’un doit prendre le relai après vous, votre objectif en tant que professionnel, c’est de lui faciliter la tâche au maximum. Donc… vive le code 2 !

Code 1

private function CreerTableauValeursGarantie($gar,$tab)
{
 foreach ($tab as $fc_aff=>$tab_get) {
  if ($gar->$fc_aff()) {
   foreach ($tab_get as $idx=>$fc_get) {
    $ret[$idx]=$gar->$fc_get();
   }
  }
 }
}


$tab_gar[$id_g][$idp_idf] =
 $this->CreerTableauValeursGarantie($gar, array(
  'getAffSurmortalite' => array(
   VAL_SURMORTALITE => 'getTauxSurprime2'),
  'getAffSurprime1' => array(
   VAL_SURPRIME_ADDITIONNELLE_DUREE_1 => 'getSurprimeAddDuree1',
   VAL_SURPRIME_ADDITIONNELLE_TAUX_1 => 'getSurprimeAddTaux1'),
  'getAffSurprime2' => array(
   VAL_SURPRIME_ADDITIONNELLE_DUREE_2 => 'getSurprimeAddDuree2',
   VAL_SURPRIME_ADDITIONNELLE_TAUX_2 => 'getSurprimeAddTaux2'),
  'getAffSurprime3' => array(
   VAL_SURPRIME_ADDITIONNELLE_DUREE_3 => 'getSurprimeAddDuree3',
   VAL_SURPRIME_ADDITIONNELLE_TAUX_3 => 'getSurprimeAddTaux3'),
  'getAffSurprime4' => array(
   VAL_SURPRIME_ADDITIONNELLE_DUREE_4 => 'getSurprimeAddDuree4',
   VAL_SURPRIME_ADDITIONNELLE_TAUX_4 => 'getSurprimeAddTaux4'),
  'getAffSurprime5' => array(
   VAL_SURPRIME_ADDITIONNELLE_DUREE_5 => 'getSurprimeAddDuree5',
   VAL_SURPRIME_ADDITIONNELLE_TAUX_5 => 'getSurprimeAddTaux5'),
  'getAffExclusionsPathos' => array(
   VAL_GAR_EXCLUSIONSPATHOS => 'getExclusionsPathologies' ),
  'getAffExclusionsSports' => array(
   VAL_GAR_EXCLUSIONSSPORTS => 'getExclusionsSports' ),
  'getAffExclusionsProfs' => array(
   VAL_GAR_EXCLUSIONSPROFS => 'getExclusionsProfessions' ),
  'getAffMensualite' => array(
   VAL_GAR_MENSUALITE => 'getMensualite' ),
  'getAffFranchise' => array(
   VAL_GAR_FRANCHISE => 'getAffFranchise' )));

Code 2


if ($gar->getAffSurmortalite()) {
 $tab_gar[$id_g][$idp_idf][VAL_SURMORTALITE ] =
  $gar->getTauxSurprime2();
}
if ($gar->getAffSurprime1()) {
 $tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_DUREE_1 ] =
  $gar->getSurprimeAddDuree1();
 $tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_TAUX_1 ] =
  $gar->getSurprimeAddTaux1();
}
if ($gar->getAffSurprime2()) {
 $tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_DUREE_2 ] =
  $gar->getSurprimeAddDuree2();
 $tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_TAUX_2 ] =
  $gar->getSurprimeAddTaux2();
}
if ($gar->getAffSurprime3()) {
 $tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_DUREE_3 ] =
  $gar->getSurprimeAddDuree3();
 $tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_TAUX_3 ] =
  $gar->getSurprimeAddTaux3();
}
if ($gar->getAffSurprime4()) {
 $tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_DUREE_4 ] =
  $gar->getSurprimeAddDuree4();
 $tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_TAUX_4 ] =
  $gar->getSurprimeAddTaux4();
}
if ($gar->getAffSurprime5()) {
 $tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_DUREE_5 ] =
  $gar->getSurprimeAddDuree5();
 $tab_gar[$id_g][$idp_idf][VAL_SURPRIME_ADDITIONNELLE_TAUX_5 ] =
  $gar->getSurprimeAddTaux5();
}
if ($gar->getAffExclusionsPathos()) {
 $tab_gar[$id_g][$idp_idf][VAL_GAR_EXCLUSIONSPATHOS ] =
  $gar_cm->getExclusionsPathologies();
}
if ($gar->getAffExclusionsSports()) {
 $tab_gar[$id_g][$idp_idf][VAL_GAR_EXCLUSIONSSPORTS ] =
  $gar_cm->getExclusionsSports();
}
if ($gar->getAffExclusionsProfs()) {
 $tab_gar[$id_g][$idp_idf][VAL_GAR_EXCLUSIONSPROFS ] =
  $gar_cm->getExclusionsProfessions();
}
if ($gar->getAffMensualite()) {
 $tab_gar[$id_g][$idp_idf][VAL_GAR_MENSUALITE ] =
  $gar_cm->getMensualite();
}
if ($gar->getAffFranchise()) {
 $tab_gar[$id_g][$idp_idf][VAL_GAR_FRANCHISE ] =
  $gar_cm->getAffFranchise();
}

MySQL : mémo perso : effacer toutes les décisions prises par moi

DELETE FROM INTERNETEMPRUNTDECISIONMEDICALE
WHERE IDGESTIONNAIRE=14;
DELETE FROM INTERNETEMPRUNTFORMULE
WHERE IDINTERNETEMPRUNTDECISIONMEDICALE
NOT IN

(SELECT ID FROM
INTERNETEMPRUNTDECISIONMEDICALE);

DELETE FROM INTERNETEMPRUNTFORMULEGARANTIE
WHERE IDINTERNETEMPRUNTFORMULE NOT IN

(SELECT ID FROM
INTERNETEMPRUNTFORMULE);