#!/usr/bin/perl -w use Se; # Algorythme global # ================= if (!defined ($pid = fork)) { die "Impossible de « forker » : $!\n"; } elsif (! $pid) { &traitement_fond; exit(0); } else { &traitement; exit(0); } sub traitement { open ENCOURS, '>/tmp/EnCours.temp'; print ENCOURS '1'; close ENCOURS; # Initialisation des variables # ---------------------------- # Uid de départ $uidNumber = getFirstFreeUid(1000); # Gid de départ $gidNumber = getFirstFreeGid(2000); &entete(STDOUT); if (isAdmin() ne 'Y') { print "

Erreur : vous n'avez pas les droits nécessaires", " pour effectuer l'importation !

"; &pdp(STDOUT); exit(0); } # Récupération, Capitalisation et modification du préfixe $prefix = param('prefix') or $prefix = ''; $prefix =~ tr/a-z/A-Z/; $prefix .= '_' unless ($prefix eq ''); # Récupération de la valeur du flag ANNUELLE $annuelle = param('annuelle'); open INT, '>/tmp/gepInterface.temp' or warn 'Impossible d\'écrire dans /tmp !'; print INT "$prefix:$annuelle"; close INT; # Lecture du fichier optionnel f_uid $fichier = "f_uid"; $nom = param("$fichier"); if ($nom eq '') { $FileUID = 0; } else { $FileUID = 1; $fileHandle = upload("$fichier"); open ( FICHTMP ,">/tmp/f_uid.temp"); while (<$fileHandle>) { chomp; s/#.*//; # suppression des commentaires s/\s+//; # suppression des blancs next unless length; if ( m/^(P?\d+)\|(.+)$/ ) { print FICHTMP $1 . '|' . $2 . "\n"; $Admin_UID{ $1 } = $2; } } close FICHTMP; } # Écriture des fichiers dans /tmp # =============================== foreach $fichier (keys(%format)) { # Vérification du passage d'un fichier # ------------------------------------ $nom = param("$fichier"); if ($nom eq '') { print STDOUT "Pas de fichier fourni pour ", "$fichier !
\n" if ($debug > 1); $atLeastOneNotOk = 1; } else { $fileHandle = upload("$fichier"); # Suppression des retours chariot @gep = <$fileHandle>; $gep = join "", @gep; # Écriture du résultat dans un fichier texte temporaire open ( FICHTMP ,">/tmp/ApacheCgi.temp"); print FICHTMP $gep; close FICHTMP; # Appel de la fonction d'ecriture du fichier vérifié et nettoyé (utf8) # -------------------------------------------------------------------- $res = dbf2txt($fichier); $atLeastOneNotOk = 1 if $res; if ($debug > 1 && $res) { $res =~ /^(\d+),(\d+),(\d+),(\d+)$/; print "Fichier $fichier erroné :\n", "\n"; } unless ($res) { $ok{$fichier} = 1; $atLeastOneOk = 1; } } } # Rapport concernant la validité des fichiers # =========================================== unless ($atLeastOneOk) { print "Aucun fichier valide n'a été fourni !\n"; pdp(STDOUT); exit 0; } if ($debug > 1 && $atLeastOneOk) { print "

Fichiers fournis et valides

\n", "\n"; } if ($debug > 1 && $atLeastOneNotOk) { print "

Fichiers non fournis ou invalides

\n", "\n"; } print "
\n" if ($debug > 1); unless ($ok{'f_div'} or $ok{'f_ele'} or $ok{'f_men'} or $ok{'f_wind'} or $ok{'a_ind'}) { print "Aucun des fichiers fournis ne permet de créer ", "une entrée ldap !\n"; pdp(STDOUT); exit 0; } # Suppression des pages html résultats antérieures # ------------------------------------------------ if (-e "$documentRoot/$webDir/result*") { unlink <$documentRoot/$webDir/result*> or warn "Le serveur Web n'a pas les droits suffisants", " sur le répertoire '$documentRoot/$webDir/result*'."; } # Écriture du fichier html provisoire de résultat final # ----------------------------------------------------- open (RES, ">$documentRoot/$webDir/result.$pid.html") or die "Le serveur Web n'a pas les droits suffisants sur le répertoire '$documentRoot/$webDir/result*'."; &entete(RES); print RES p('Traitement en cours...'); &pdp(RES); close RES; print "

Création des entrées ldap suivantes

\n" if $debug; if ($ok{'f_ele'} or $ok{'f_wind'} or $ok{'a_ind'}) { print "Comptes utilisateur :\n", "\n"; } if ($ok{'f_div'} or $ok{'f_ele'} or $ok{'f_men'}) { print "Groupes :\n", "\n"; } if ($atLeastOneNotOk) { print "

Problèmes liés à l'absence ou à l'invalidité de certains fichiers

\n" if $debug; if (! $ok{'f_ele'} or ! $ok{'f_wind'} or ! $ok{'a_ind'}) { print "Pas de création des comptes utilisateur :\n", "\n"; } if (! $ok{'f_div'} or ! $ok{'f_ele'} or ! $ok{'f_men'}) { print "Pas de création des groupes :\n", "\n"; } if ((! $ok{'f_div'} and ($createClasses or $createEquipes)) or (! $ok{'f_tmt'} and $createMatieres) or (! $ok{'f_gro'} and $createCours)) { print "Pas de description disponible pour les groupes ", "(utilisation du mnémonique) :\n", "\n"; } if (($createCours and (! $ok{'f_eag'} or ! $ok{'f_ele'})) or ($createClasses and ! $ok{'f_ele'})) { print "Pas de membres pour les groupes :\n", "\n"; } } print "
Le traitement pouvant être particulièrement long,", " il va maintenant continuer en tâche de fond.
\n", 'Le rapport final d\'importation sera accessible à l\'adresse :
', "
", "", "$hostname/$webDir/result.$pid.html
\n", "Une fois le traitement terminé, utilisez l'annuaire pour vérifier la validité des résultats.", "
\n"; &pdp(STDOUT); unlink('/tmp/EnCours.temp'); } sub traitement_fond { # Attente de fin du traitement préparatoire sleep(3); $inc=0; while (1) { sleep 1; $inc++; if ($inc == 30) { # Fermeture des entrées/sorties standard close(STDIN); close(STDOUT); open RES, ">$documentRoot/$webDir/result.$$.html"; &entete(RES); print RES "Le traitement préparatoire des fichiers GEP semble avoir été interrompu.
", "Le traitement des fichiers prêts va tout de même se poursuivre.
", "ATTENTION : votre importation risque de ne pas être complète...
"; last; } if (! -f '/tmp/EnCours.temp') { # Fermeture des entrées/sorties standard close(STDIN); close(STDOUT); open RES, ">$documentRoot/$webDir/result.$$.html"; &entete(RES); print RES "Le traitement préparatoire s'est terminé avec succès.
"; last; } } open INT, '; ($prefix, $annuelle) = split /:/, $ligne; close INT; $prefix = '' unless $prefix; annuelle() if ($annuelle); # Création des entrées # ==================== # Initialisation des variables # ---------------------------- # Uid de départ $uidNumber = getFirstFreeUid(1000); # Gid de départ $gidNumber = getFirstFreeGid(2000); # Gid des utilisateurs LCS $gid = $defaultgid; unless (-f '/tmp/f_ele.temp' or -f '/tmp/f_wind.temp' or -f '/tmp/a_ind.temp' or -f '/tmp/f_men.temp' or -f '/tmp/f_div.temp') { exit 0; } # Connexion LDAP # ============== $lcs_ldap = Net::LDAP->new("$slapdIp"); $lcs_ldap->bind( dn => $adminDn, password => $adminPw, version => '3' ); # lecture de f_uid.temp if (-f '/tmp/f_uid.temp') { print RES "

Lecture des identifiants 'uid' prédéfinis des utilisateurs

\n\n"; open UID, ') { chomp; s/#.*//; # suppression des commentaires s/\s+//; # suppression des blancs next unless length; if ( m/^(P?\d+)\|(.+)$/ ) { $Admin_UID{ $1 } = $2; } } print RES "\n"; print RES "
" . keys( %Admin_UID ) . " uid lus
\n"; close UID; } # Profs # ----- if (-f '/tmp/f_wind.temp') { print RES "

Création des comptes 'Profs'

\n\n"; open PROFS, ') { chomp($ligne = $_); ($numind, $nom, $prenom, $date, $sexe) = (split /\|/, $ligne); $uniqueNumber = 'P' . $numind; $res = processGepUser( $uniqueNumber, $nom, $prenom, $date, $sexe, 'undef' ); print RES $res if ($res =~ /Cr/ or ($debug > 1 and $res !~ /Cr/)); unless ($res =~ /conflits/) { # Ajoût de l'uid au groupe Profs $res = $lcs_ldap->search(base => "$profsDn", scope => 'base', filter => "memberUid=$uid"); unless (($res->entries)[0]) { $res = $lcs_ldap->modify( $profsDn, add => { 'memberUid' => $uid } ); warn $res->error if $res->code; } } } print RES "
\n"; close PROFS; } # Administratifs # -------------- if (-f '/tmp/a_ind.temp') { print RES "

Création des comptes 'Administratifs'

\n\n"; open ADMINS, ') { chomp($ligne = $_); ($numind, $nom, $prenom, $date, $sexe) = (split /\|/, $ligne); $uniqueNumber = 'A' . $numind; $res = processGepUser( $uniqueNumber, $nom, $prenom, $date, $sexe, 'undef' ); print RES $res if ($res =~ /Cr/ or ($debug > 1 and $res !~ /Cr/)); unless ($res =~ /conflits/) { # Ajoût de l'uid au groupe Administratifs $res = $lcs_ldap->search(base => "cn=Administratifs,$groupsDn", scope => 'base', filter => "memberUid=$uid"); unless (($res->entries)[0]) { $res = $lcs_ldap->modify( "cn=Administratifs,$groupsDn", add => { 'memberUid' => $uid } ); warn $res->error if $res->code; } } } print RES "
\n"; close ADMINS; } # Classes # ------- if (-f '/tmp/f_div.temp') { print RES "

Création des groupes 'Classe' et 'Equipe'

\n\n"; open DIV, ') { chomp($ligne = $_); ($divcod, $divlib, $profUniqueNumber) = (split/\|/, $ligne); $profUniqueNumber = 'P' . $profUniqueNumber; $divcod =~ s/\s/_/; $divlib = normalize($divlib,4); $libelle{$divcod} = $divlib; $res = $lcs_ldap->search(base => "$peopleDn", scope => 'one', filter => "employeeNumber=$profUniqueNumber"); $profPrincUid = ''; if (($res->entries)[0]) { $profPrincUid = (($res->entries)[0])->get_value('uid'); } # Recherche de l'existence de la classe $res = $lcs_ldap->search(base => "cn=Classe_$prefix$divcod,$groupsDn", scope => 'base', filter => "cn=*"); if (($res->entries)[0]) { if (! (($res->entries)[0])->get_value('description') and $divlib) { print RES "\n" if $debug > 1; $res2 = $lcs_ldap->modify( "cn=Classe_$prefix$divcod,$groupsDn", add => { description => $divlib } ); warn $res2->error if $res2->code; } } else { $gidNumber = getFirstFreeGid($gidNumber); @classEntry = ( 'cn', "Classe_$prefix$divcod", 'objectClass', 'top', 'objectClass', 'posixGroup', 'gidNumber', $gidNumber, ); push @classEntry, ('description', $divlib) if $divlib; $res = $lcs_ldap->add( "cn=Classe_$prefix$divcod,$groupsDn", attrs => \@classEntry ); warn $res->error if $res->code; print RES "\n" if $debug; } # Recherche de l'existence de l'équipe $res = $lcs_ldap->search(base => "cn=Equipe_$prefix$divcod,$groupsDn", scope => 'base', filter => "cn=*"); if (($res->entries)[0]) { if (! (($res->entries)[0])->get_value('description') and $divlib) { print RES "\n" if $debug > 1; $res2 = $lcs_ldap->modify( "cn=Equipe_$prefix$divcod,$groupsDn", add => { description => $divlib } ); warn $res2->error if $res2->code; } if (! (($res->entries)[0])->get_value('owner') and $profPrincUid) { print RES "\n" if $debug > 1; $res2 = $lcs_ldap->modify( "cn=Equipe_$prefix$divcod,$groupsDn", add => { owner => "uid=$profPrincUid,$peopleDn" } ); warn $res2->error if $res2->code; } next; } else { @equipeEntry = ( 'cn', "Equipe_$prefix$divcod", 'objectClass', 'top', 'objectClass', 'groupOfNames', 'member', '' ); push @equipeEntry, ('description', $divlib) if $divlib; push @equipeEntry, ('owner', "uid=$profPrincUid,$peopleDn") if $profPrincUid; $res = $lcs_ldap->add( "cn=Equipe_$prefix$divcod,$groupsDn", attrs => \@equipeEntry ); warn $res->error if $res->code; print RES "\n" if $debug > 1; } } print RES "
$divcod :Mise à jour de la description du groupe 'Classe' : $divlib
$divcod :Création du groupe 'Classe' $divlib
$divcod :Mise à jour de la description du groupe 'Equipe' : $divlib
$divcod :Mise à jour du propriétaire du groupe 'Equipe' : $divlib
$divcod :Création du groupe 'Equipe' $divlib
\n"; } # Eleves # ----- if (-f '/tmp/f_ele.temp') { print RES "

Création des comptes 'Eleves'"; print RES " (et des groupes 'Classes' et 'Equipes' associés)" unless (-f '/tmp/f_div.temp'); print RES "

\n\n"; open ELEVES, ') { chomp($ligne = $_); ($uniqueNumber, $nom, $prenom, $date, $sexe, $divcod) = (split /\|/, $ligne); $divcod =~ s/\s/_/g; next if $divcod eq ''; unless (-f '/tmp/f_div.temp') { # Création des classes $res = $lcs_ldap->search(base => "cn=Classe_$prefix$divcod,$groupsDn", scope => 'base', filter => "cn=*"); unless (($res->entries)[0]) { $gidNumber = getFirstFreeGid($gidNumber); @classEntry = ( 'cn', "Classe_$prefix$divcod", 'objectClass', 'top', 'objectClass', 'posixGroup', 'gidNumber', $gidNumber, ); $res = $lcs_ldap->add( "cn=Classe_$prefix$divcod,$groupsDn", attrs => \@classEntry ); warn $res->error if $res->code; } # Création des Équipes $res = $lcs_ldap->search(base => "cn=Equipe_$prefix$divcod,$groupsDn", scope => 'base', filter => "cn=*"); unless (($res->entries)[0]) { @equipeEntry = ( 'cn', "Equipe_$prefix$divcod", 'objectClass', 'top', 'objectClass', 'groupOfNames', 'member', '' ); $res = $lcs_ldap->add( "cn=Equipe_$prefix$divcod,$groupsDn", attrs => \@equipeEntry ); warn $res->error if $res->code; } } $res = processGepUser($uniqueNumber, $nom, $prenom, $date, $sexe, 'undef'); print RES $res if ($res =~ /Cr/ or ($debug > 1 and $res !~ /Cr/)); unless ($res =~ /conflits/) { # Ajoût de l'uid au groupe Eleves $res = $lcs_ldap->search(base => "$elevesDn", scope => 'base', filter => "memberUid=$uid"); unless (($res->entries)[0]) { $res = $lcs_ldap->modify( $elevesDn, add => { 'memberUid' => $uid } ); warn $res->error if $res->code; } # Remplissage des classes $res = $lcs_ldap->search(base => "cn=Classe_$prefix$divcod,$groupsDn", scope => 'base', filter => "memberUid=$uid"); unless (($res->entries)[0]) { $res = $lcs_ldap->modify( "cn=Classe_$prefix$divcod,$groupsDn", add => { 'memberUid' => $uid } ); warn $res->error if $res->code; } } } print RES "
"; close ELEVES; } # Analyse du fichier F_TMT.DBF # ---------------------------- if (-f '/tmp/f_tmt.temp') { print RES "

Analyse du fichier de matières

\n\n" if $debug > 1; open F_TMT, ") { chomp ($ligne = $_); ($matimn, $matill) = (split/\|/, $ligne); $matimn =~ s/\s/_/g; if ($matill) { $matill = normalize($matill,0); # Alimentation du tableau %libelle $libelle{$matimn} = $matill; print RES "\n" if $debug > 1; } } close F_TMT; print RES "
Matière $matimn :Libellé : $libelle{$matimn}
\n" if $debug > 1; } # Analyse du fichier F_GRO.DBF # ---------------------------- if (-f '/tmp/f_gro.temp') { print RES "

Analyse du fichier de groupes

\n\n" if $debug > 1; open F_GRO, ") { chomp ($ligne = $_); ($grocod, $grolib) = (split/\|/, $ligne); $grocod =~ s/\s/_/g; if ($grolib) { $grolib = normalize($grolib,0); # Alimentation du tableau %libelle $libelle{$grocod} = $grolib; print RES "\n" if $debug > 1; } } close F_GRO; print RES "
Groupe $grocod :Libellé : $libelle{$grocod}
\n" if $debug > 1; } # Analyse du fichier F_EAG.DBF # ---------------------------- if (-f '/tmp/f_eag.temp') { print RES "

Analyse du fichier des élèves par groupe

\n\n" if $debug > 1; open F_EAG, ") { chomp ($ligne = $_); ($uniqueNumber, $grocod) = (split/\|/, $ligne); $grocod =~ s/\s/_/g; # Alimentation du tableau %member associant un code classe # ou groupe avec une liste d'uid (login) d'élèves $res = $lcs_ldap->search(base => "$peopleDn", scope => 'one', filter => "employeeNumber=$uniqueNumber"); if (($res->entries)[0]) { $uid = (($res->entries)[0])->get_value('uid'); $member{$grocod} .= "$uid "; print RES "\n" if $debug > 1; } } close F_EAG; print RES "
Élève $uid :Groupe : $grocod
\n" if $debug > 1; } # Analyse du fichier F_MEN # ------------------------ if (-f '/tmp/f_men.temp') { open F_MEN, "Création des groupes 'Cours' et 'Matiere'\n\n"; while () { chomp ($ligne = $_); ($matimn, $elstco, $uniqueNumber) = (split/\|/, $ligne); $matimn =~ s/\s/_/g; $elstco =~ s/\s/_/g; # Génération du nom du cours (mnémoniqueMatière_codeGroupe) $cours = $matimn . '_' . $elstco; if ($uniqueNumber) { $uniqueNumber = 'P' . $uniqueNumber; $res = $lcs_ldap->search(base => "$peopleDn", scope => 'one', filter => "employeeNumber=$uniqueNumber"); if (($res->entries)[0]) { $profUid = (($res->entries)[0])->get_value('uid'); } else { $profUid = ''; } } else { $profUid = ''; } if ($libelle{$matimn}) { $description = $libelle{$matimn}; } else { $description = $matimn; } if ($libelle{$elstco}) { $description .= " / " . $libelle{$elstco}; } else { $description .= " / " . $elstco; } $res = $lcs_ldap->search(base => "cn=Cours_$prefix$cours,$groupsDn", scope => 'base', filter => "objectClass=*"); if (($res->entries)[0]) { # Mise à jour le cas échéant de la description if ((($res->entries)[0]->get_value('description') =~ /$matimn/ and $description !~ /$matimn/) or (($res->entries)[0]->get_value('description') =~ /$elstco/ and $description !~ /$elstco/)) { $res2 = $lcs_ldap->modify( "cn=Cours_$prefix$cours,$groupsDn", replace => { description => $description } ); warn $res2->error if $res2->code; print RES "\n" if $debug > 1; } } else { $gidNumber = getFirstFreeGid($gidNumber); @coursEntry = ( 'cn', "Cours_$prefix$cours", 'objectClass', 'top', 'objectClass', 'posixGroup', 'gidNumber', $gidNumber, 'description', $description, ); push @coursEntry, ('memberUid', $profUid) if $profUid; $res = $lcs_ldap->add( "cn=Cours_$prefix$cours,$groupsDn", attrs => \@coursEntry ); warn $res->error if $res->code; print RES "\n" if $debug; } # Ajout du prof le cas échéant if ($profUid) { $res = $lcs_ldap->search(base => "cn=Cours_$prefix$cours,$groupsDn", scope => 'base', filter => "memberUid=$profUid"); if (! ($res->entries)[0]) { $res = $lcs_ldap->modify( "cn=Cours_$prefix$cours,$groupsDn", add => { memberUid => $profUid } ); warn $res->error if $res->code; } } # Ajout des autres membres du cours $res = $lcs_ldap->search(base => "cn=Classe_$prefix$elstco,$groupsDn", scope => 'base', filter => "cn=*"); if ($member{$elstco}) { # Cas d'un groupe chop($members = $member{$elstco}); foreach $member (split / /, $members) { $res = $lcs_ldap->search(base => "cn=Cours_$prefix$cours,$groupsDn", scope => 'base', filter => "memberUid=$member"); if (! ($res->entries)[0]) { $res = $lcs_ldap->modify( "cn=Cours_$prefix$cours,$groupsDn", add => { memberUid => $member } ); warn $res->error if $res->code; } print RES "\n" if $debug > 1; } } else { # cas d'une classe $res = $lcs_ldap->search(base => "cn=Classe_$prefix$elstco,$groupsDn", scope => 'base', filter => "objectClass=*"); if (($res->entries)[0]) { @members = ($res->entries)[0]->get_value('memberUid'); foreach $member (@members) { $res = $lcs_ldap->search(base => "cn=Cours_$prefix$cours,$groupsDn", scope => 'base', filter => "memberUid=$member"); if (! ($res->entries)[0]) { $res = $lcs_ldap->modify( "cn=Cours_$prefix$cours,$groupsDn", add => { memberUid => $member } ); warn $res->error if $res->code; } } } } if ($profUid) { # Remplissage de l'équipe pédagogique de la classe $res = $lcs_ldap->search(base => "cn=Equipe_$prefix$elstco,$groupsDn", scope => 'base', filter => "objectClass=*"); if (($res->entries)[0]) { $res = $lcs_ldap->search(base => "cn=Equipe_$prefix$elstco,$groupsDn", scope => 'base', filter => "member=uid=$profUid,$peopleDn"); unless (($res->entries)[0]) { $res = $lcs_ldap->modify( "cn=Equipe_$prefix$elstco,$groupsDn", add => { member => "uid=$profUid,$peopleDn" } ); warn $res->error if $res->code; } } # Remplissage et/ou création du GroupOfNames Matiere # Si la matière n'existe pas encore $res = $lcs_ldap->search(base => "cn=Matiere_$prefix$matimn,$groupsDn", scope => 'base', filter => "objectClass=*"); if (! ($res->entries)[0]) { @matiereEntry = ( 'cn', "Matiere_$prefix$matimn", 'objectClass', 'top', 'objectClass', 'groupOfNames', 'member', '', ); push @matiereEntry, ('description', $libelle{$matimn}) if $libelle{$matimn}; $res = $lcs_ldap->add( "cn=Matiere_$prefix$matimn,$groupsDn", attrs => \@matiereEntry ); } elsif (! ($res->entries)[0]->get_value('description') and $libelle{$matimn}) { # Maj Libellé Matière $res = $lcs_ldap->modify( "cn=Matiere_$prefix$matimn,$groupsDn", add => { description => $libelle{$matimn} } ); warn $res->error if $res->code; } # Avec ses membres $res = $lcs_ldap->search(base => "cn=Matiere_$prefix$elstco,$groupsDn", scope => 'base', filter => "member=uid=$profUid,$peopleDn"); unless (($res->entries)[0]) { $res = $lcs_ldap->modify( "cn=Matiere_$prefix$matimn,$groupsDn", add => { member => "uid=$profUid,$peopleDn" } ); } } } print RES "
Cours gep $cours : Mise à jour de la description du groupe 'Cours'
Cours gep $cours : Création du groupe 'Cours'
Cours gep $cours : Ajoût des élèves du groupe
\n"; close F_MEN; } unlink ; $lcs_ldap->unbind; &pdp(RES); close RES; system ("/usr/bin/lynx --dump $documentRoot/$webDir/result.$$.html | mail $melsavadmin -s 'Importation GEP'"); }