diff --git a/doc/conf/LSaddon.docbook b/doc/conf/LSaddon.docbook
index abf6bcd3..38720e94 100644
--- a/doc/conf/LSaddon.docbook
+++ b/doc/conf/LSaddon.docbook
@@ -16,6 +16,7 @@
&conf-LSaddon_maildir;
&conf-LSaddon_mailquota;
&conf-LSaddon_phpldapadmin;
+ &conf-LSaddon_ppolicy;
&conf-LSaddon_showTechInfo;
diff --git a/doc/conf/LSaddon/LSaddon.entities.xml b/doc/conf/LSaddon/LSaddon.entities.xml
index ae231883..487ab68a 100644
--- a/doc/conf/LSaddon/LSaddon.entities.xml
+++ b/doc/conf/LSaddon/LSaddon.entities.xml
@@ -6,4 +6,5 @@
+
diff --git a/doc/conf/LSaddon/LSaddon_ppolicy.docbook b/doc/conf/LSaddon/LSaddon_ppolicy.docbook
new file mode 100644
index 00000000..bf81274a
--- /dev/null
+++ b/doc/conf/LSaddon/LSaddon_ppolicy.docbook
@@ -0,0 +1,175 @@
+
+ LSaddon_ppolicy
+ Cet &LSaddon; fourni :
+
+
+
+une fonction ppolicy_extraDisplayColumn_password_expiration
+pouvant être utilisée pour la génération d'une extraDisplayedColumn
+affichant l'état d'expiration du mot de passe des objets d'une recherche.
+
+
+ Exemple d'utilisation
+ array (
+ [...]
+ 'password_expiration' => array (
+ 'label' => 'Password expiration',
+ 'generateFunction' => 'ppolicy_extraDisplayColumn_password_expiration',
+ 'additionalAttrs' => array('pwdChangedTime', 'pwdPolicySubentry'),
+ 'escape' => false,
+ ),
+ [...]
+ ),
+ [...]
+ );]]>
+
+
+
+
+une fonction ppolicy_export_search_info
+pouvant être utilisée comme actions
+personnalisées sur les recherches d'&LSobjects; pour exporter au format CSV les
+informations des politiques de mots de passe des objets retournés par la recherche.
+
+
+Exemple d'utilisation
+ array (
+ 'exportPpolicyInfo' => array (
+ 'label' => 'Export password policy info',
+ 'icon' => 'export_csv',
+ 'function' => 'ppolicy_export_search_info',
+ 'noConfirmation' => true,
+ 'disableOnSuccessMsg' => true,
+ 'rights' => array (
+ 'admin',
+ ),
+ ),
+ ),
+ [...]
+);]]>
+
+
+
+
+la méthode d'API exportPpolicyInfo permettant d'exporter
+les informations des politiques de mots de passe de tous les objets d'un type donné. Cette méthode
+est accessible via l'URL au format suivant :
+/api/1.0/exportPpolicyInfo/[object type]
+
+
+la commande CLI export_ppolicy_info permettant d'exporter
+les informations des politiques de mots de passe de tous les objets d'un type donné.
+
+Utilisation
+ldapsaisie export_ppolicy_info [object type] [-o|--output filepath] [-j|--json [-p|--pretty]]
+
+
+
+
+
+
+
+ Des paramètres de configuration sont disponibles dans le fichier de
+ configuration config.LSaddons.ppolicy.php.
+
+
+Structure du fichier
+
+
+
+
+Paramètres de configuration
+
+
+ LS_PPOLICY_DEFAULT_DN
+
+ Constante définissant le DN de la politique par défaut. Si aucune politique par défaut
+ n'est définie, ce paramètre doit valoir null.
+
+
+
+
+ LS_PPOLICY_WARNING_EXPIRATION_THRESHOLD
+
+ Constante définissant le seuil d'alerte pour l'expiration des mots de passe (en
+ seconde). Par défaut : 7 jours.
+
+
+
+
+ LS_PPOLICY_CRITICAL_EXPIRATION_THRESHOLD
+
+ Constante définissant le seuil critique pour l'expiration des mots de passe (en
+ seconde). Par défaut : 2 jours.
+
+
+
+
+ LS_PPOLICY_CSV_DELIMITER
+
+ Constante définissant le caractère utilisé lors de la génération de l'export CSV
+ comme séparateur de champ. Par défaut : un point-virgule.
+
+
+
+
+ LS_PPOLICY_CSV_ENCLOSURE
+
+ Constante définissant le caractère utilisé lors de la génération de l'export CSV
+ pour l'encadrement des champs. Par défaut : un guillemet double.
+
+
+
+
+ LS_PPOLICY_CSV_ESCAPE_CHAR
+
+ Constante définissant le caractère utilisé lors de la génération de l'export CSV
+ pour l'échappement des champs. Par défaut : une barre oblique inverse.
+
+
+
+
+ $GLOBALS['LS_PPOLICY_API_GRANTED_PROFILES']
+
+ Tableau global listant les &LSprofiles; autorisés à utiliser la méthode d'API
+ exportPpolicyInfo.
+
+
+
+
+ $GLOBALS['LS_PPOLICY_INFO_EXPORT_EXTRA_ATTRS']
+
+ Tableau global listant les attributs supplémentaires à inclure lors de l'export des
+ informations de politique de mots de passe.
+
+
+
+
+
+
diff --git a/src/conf/LSaddons/config.LSaddons.ppolicy.php b/src/conf/LSaddons/config.LSaddons.ppolicy.php
new file mode 100644
index 00000000..1a32a509
--- /dev/null
+++ b/src/conf/LSaddons/config.LSaddons.ppolicy.php
@@ -0,0 +1,51 @@
+
+ *
+ * @return boolean true if Ppolicy is totally supported, false in other case
+ *
+ * @author Benjamin Renard
+ */
+function LSaddon_ppolicy_support() {
+ $retval = true;
+
+ $MUST_DEFINE_CONST = array(
+ 'LS_PPOLICY_DEFAULT_DN',
+ 'LS_PPOLICY_WARNING_EXPIRATION_THRESHOLD',
+ 'LS_PPOLICY_CRITICAL_EXPIRATION_THRESHOLD',
+ 'LS_PPOLICY_CSV_DELIMITER',
+ 'LS_PPOLICY_CSV_ENCLOSURE',
+ 'LS_PPOLICY_CSV_ESCAPE_CHAR',
+ );
+
+ foreach($MUST_DEFINE_CONST as $const) {
+ if (!defined($const)) {
+ LSerror :: addErrorCode('PPOLICY_SUPPORT_01', $const);
+ $retval = false;
+ }
+ }
+
+ $MUST_DEFINE_ARRAY= array(
+ 'LS_PPOLICY_API_GRANTED_PROFILES',
+ 'LS_PPOLICY_INFO_EXPORT_EXTRA_ATTRS',
+ );
+ foreach($MUST_DEFINE_ARRAY as $array) {
+ if ( !isset($GLOBALS[$array]) || !is_array($GLOBALS[$array])) {
+ LSerror :: addErrorCode('PPOLICY_SUPPORT_02', $array);
+ $retval = false;
+ }
+ }
+
+ // Init ppolicy objects cache
+ $GLOBALS['PPOLICY_OBJECTS_CACHE'] = array();
+
+ if ($retval) {
+ LSurl :: add_handler(
+ '#^api/1.0/exportPpolicyInfo/(?P[^/]+)/?$#',
+ 'handle/export_api_LSobject_exportPpolicyInfo',
+ true, false, true);
+ }
+
+ return $retval;
+}
+
+/**
+ * Retrieve ppolicy object (from cache if already loaded)
+ *
+ * @param[in] $dn string The DN of the ppolicy object
+ *
+ * @return array|false Array of ppolicy object's attributes on success, false otherwise
+ *
+ * @author Benjamin Renard
+ */
+function get_ppolicy_object($dn) {
+ if (array_key_exists($dn, $GLOBALS['PPOLICY_OBJECTS_CACHE']))
+ return $GLOBALS['PPOLICY_OBJECTS_CACHE'][$dn];
+ $GLOBALS['PPOLICY_OBJECTS_CACHE'][$dn] = LSldap :: getAttrs($dn, '(objectClass=pwdPolicy)');
+ return $GLOBALS['PPOLICY_OBJECTS_CACHE'][$dn];
+}
+
+/**
+ * Retrieve ppolicy password max age
+ *
+ * @param[in] $ppolicy_dn string Optional DN of the ppolicy object to use
+ *
+ * @return int|null|false The ppolicy password max age (in second) if defined, null if no password max age is defined or false in case of error
+ *
+ * @author Benjamin Renard
+ */
+function get_ppolicy_password_max_age($ppolicy_dn=null) {
+ if (!$ppolicy_dn)
+ $ppolicy_dn = LS_PPOLICY_DEFAULT_DN;
+ if (!$ppolicy_dn)
+ return null;
+ $ppolicy = get_ppolicy_object($ppolicy_dn);
+ if (!$ppolicy)
+ return false;
+ if (isset($ppolicy['pwdMaxAge']))
+ return intval($ppolicy['pwdMaxAge']);
+ return null;
+}
+
+/**
+ * Format and return HTML code of a badge
+ *
+ * @param[in] $text string The text of the badge
+ * @param[in] $bg_color string The background color of the badge (optional, default: green)
+ * @param[in] $color string The text color of the badge (optional, default: white)
+ *
+ * @return string The HTML code of the badge
+ *
+ * @author Benjamin Renard
+ */
+function _ppolicy_badge($text, $bg_color='green', $color='white') {
+ // Disable HTML formating on PHP cli
+ if (php_sapi_name() == 'cli') return $text;
+ return sprintf(
+ '%s',
+ $bg_color, $color, $text
+ );
+}
+
+ /**
+ * Retrieve Ppolicy extraDisplayedColumn password expiration
+ *
+ * @param[in] $entry An LSsearchEntry object
+ *
+ * @return string Ppolicy extraDisplayedColumn password expiration
+ *
+ * @author Benjamin Renard
+ */
+function ppolicy_extraDisplayColumn_password_expiration($entry) {
+ $change_time = $entry->pwdChangedTime;
+ if (!$change_time)
+ return _('Never');
+ $change_time = ldapDate2Timestamp($change_time);
+ $max_age = get_ppolicy_password_max_age($entry->pwdPolicySubentry);
+ if ($max_age === false)
+ return _ppolicy_badge(__('Unknown'), 'gray');
+ if (!$max_age)
+ return _('Never');
+ $expiration_date = $change_time + $max_age;
+ $now = time();
+ if ($expiration_date <= $now)
+ return _ppolicy_badge(
+ sprintf(_('Expired (since %s)'), date('Y-m-d H:i', $expiration_date)),
+ 'black');
+ $delta = $expiration_date - $now;
+ if ($delta >= LS_PPOLICY_CRITICAL_EXPIRATION_THRESHOLD)
+ $badge_color = 'red';
+ elseif ($delta >= LS_PPOLICY_WARNING_EXPIRATION_THRESHOLD)
+ $badge_color = 'orange';
+ else
+ $badge_color = 'green';
+ return _ppolicy_badge(
+ sprintf(_('Expire on %s'), date('Y-m-d H:i', $expiration_date)),
+ $badge_color);
+}
+
+/**
+ * Write LSsearch result as CSV and force download of it.
+ *
+ * @param[in] $LSsearch The LSsearch object
+ *
+ * @author Benjamin Renard
+ *
+ * @return boolean Void if CSV file is successfully generated and upload, false in other case
+ */
+function ppolicy_export_search_info($LSsearch, $as_csv=true, $return=false) {
+ if ($as_csv) {
+ $csv = fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');
+
+ if ($csv === false) {
+ LSerror :: addErrorCode('PPOLICY_01');
+ return false;
+ }
+ }
+
+ $attrs = array_merge(
+ array(
+ 'pwdPolicySubentry', 'pwdChangedTime', 'pwdGraceUseTime', 'pwdFailureTime',
+ 'pwdAccountLockedTime', 'pwdReset', 'pwdHistory'
+ ),
+ $GLOBALS['LS_PPOLICY_INFO_EXPORT_EXTRA_ATTRS']
+ );
+ $LSsearch -> setParam('attributes', $attrs);
+
+ if (!$LSsearch -> run()) {
+ LSerror :: addErrorCode('PPOLICY_02');
+ return false;
+ }
+
+ if ($as_csv) {
+ $headers = array($LSsearch->label_objectName, 'DN');
+ foreach($attrs as $attr) {
+ $label = LSconfig::get("LSobjects.".$LSsearch->LSobject.".attrs.$attr.label", $attr, 'string');
+ $headers[] = __($label);
+ }
+
+ if (!_ppolicy_write_row_in_csv($csv, $headers)) {
+ LSerror :: addErrorCode('PPOLICY_03');
+ return false;
+ }
+ }
+ else {
+ $data = array();
+ }
+
+ foreach ($LSsearch -> getSearchEntries() as $e) {
+ $row = array(
+ 'name' => $e -> displayName,
+ 'dn' => $e -> dn,
+ );
+
+ foreach($attrs as $attr) {
+ if ($as_csv) {
+ $values = ensureIsArray($e -> get($attr));
+ if ($values) {
+ $row[] = ($as_json?$values:implode('|', $values));
+ }
+ else {
+ $no_value_label = LSconfig::get(
+ "LSobjects.".$LSsearch->LSobject.".attrs.$attr.no_value_label",
+ ___('Not set'), 'string');
+ $row[] = __($no_value_label);
+ }
+ }
+ else {
+ $row[$attr] = ensureIsArray($e -> get($attr));
+ if (!LSconfig::get("LSobjects.".$LSsearch->LSobject.".attrs.$attr.multiple")) {
+ $row[$attr] = ($row[$attr]?$row[$attr][0]:null);
+ }
+ }
+ }
+
+ if ($as_csv) {
+ if (!_ppolicy_write_row_in_csv($csv, $row)) {
+ LSerror :: addErrorCode('PPOLICY_04');
+ return false;
+ }
+ }
+ else {
+ $data[] = $row;
+ }
+ }
+
+ if (!$as_csv) {
+ if ($return)
+ return $data;
+ header("Content-disposition: attachment; filename=ppolicy-".$LSsearch->LSobject.".json");
+ displayAjaxReturn($data);
+ exit();
+ }
+
+ rewind($csv);
+ if ($return) {
+ $data = stream_get_contents($csv);
+ @fclose($csv);
+ return $data;
+ }
+ header("Content-disposition: attachment; filename=ppolicy-".$LSsearch->LSobject.".csv");
+ header("Content-type: text/csv");
+ print stream_get_contents($csv);
+ @fclose($csv);
+ exit();
+}
+
+/**
+ * Write CSV row in file
+ *
+ * @param[in] $csv The CSV file description reference
+ * @param[in] $row An array of a CSV row fields to write
+ *
+ * @author Benjamin Renard
+ *
+ * @retval boolean True if CSV row is successfully writed, false in other case
+ */
+function _ppolicy_write_row_in_csv(&$csv, &$row) {
+ if (!defined('PHP_VERSION_ID') or PHP_VERSION_ID < 50504) {
+ return (
+ fputcsv($csv, $row, LS_PPOLICY_CSV_DELIMITER, LS_PPOLICY_CSV_ENCLOSURE) !== false
+ );
+ }
+ return (
+ fputcsv(
+ $csv, $row, LS_PPOLICY_CSV_DELIMITER, LS_PPOLICY_CSV_ENCLOSURE,
+ LS_PPOLICY_CSV_ESCAPE_CHAR) !== false
+ );
+}
+
+/**
+ * Handle exportPpolicyInfo API request
+ *
+ * @param[in] $request LSurlRequest The request
+ *
+ * @return void
+ **/
+function handle_api_LSobject_exportPpolicyInfo($request) {
+ get_LSobject_from_API_request($request);
+ $container_dn = LSconfig::get(
+ "LSobjects.".$LSsearch->LSobject.".container_dn",
+ "", "string");
+ $whoami = LSsession :: whoami(
+ $container_dn?
+ $container_dn.','.LSsession::getTopDn():
+ LSsession::getTopDn()
+ );
+ if (!array_intersect($GLOBALS['LS_PPOLICY_API_GRANTED_PROFILES'], $whoami)) {
+ LSerror :: addErrorCode('LSsession_11');
+ LSsession :: displayAjaxReturn();
+ return false;
+ }
+
+ if (!LSsession :: loadLSclass('LSsearch')) {
+ LSerror :: addErrorCode('LSsession_05', 'LSsearch');
+ LSsession :: displayAjaxReturn();
+ return false;
+ }
+
+ $search = new LSsearch(
+ $request->LSobject,
+ 'api'
+ );
+ $search -> setParam('onlyAccessible', True);
+
+ $data = ppolicy_export_search_info($search, false, true);
+ LSsession :: displayAjaxReturn($data);
+}
+
+if (php_sapi_name() != 'cli')
+ return true;
+
+function cli_export_ppolicy_info($command_args) {
+ $objType = null;
+ $output = false;
+ $json = false;
+ $pretty = false;
+ for ($i=0; $i < count($command_args); $i++) {
+ switch($command_args[$i]) {
+ case '-o':
+ case '--output':
+ $i++;
+ $output = $command_args[$i];
+ break;
+
+ case '-j':
+ case '--json':
+ $json = true;
+ break;
+
+ case '-p':
+ case '--pretty':
+ $pretty = true;
+ break;
+
+ default:
+ if (is_null($objType))
+ $objType = $command_args[$i];
+ else
+ LScli :: usage("Invalid ".$command_args[$i]." parameter.");
+ break;
+ }
+ }
+
+ if (is_null($objType))
+ LScli :: usage('You must provide LSobject type.');
+
+ if (!LSsession :: loadLSobject($objType))
+ return false;
+
+ if (!LSsession :: loadLSclass('LSsearch')) {
+ LSerror :: addErrorCode('LSsession_05', 'LSsearch');
+ LSsession :: displayAjaxReturn();
+ return false;
+ }
+
+ $search = new LSsearch($objType, 'cli_export_ppolicy_info');
+ $search -> setParam('onlyAccessible', True);
+
+ $data = ppolicy_export_search_info($search, !$json, true);
+
+ if ($json)
+ $data = json_encode(
+ $data,
+ ($pretty?JSON_PRETTY_PRINT:0)
+ );
+
+ if (!$output) {
+ print($data);
+ exit();
+ }
+ $fd = fopen($output, 'w') or fatal_error("Fail to open output file '$output'");
+ fwrite($fd, $data) or fatal_error("Fail to write result in output file '$output'");
+ @fclose($fd);
+}
+
+/**
+ * Args autocompleter for CLI export_ppolicy_info command
+ *
+ * @param[in] $command_args array List of already typed words of the command
+ * @param[in] $comp_word_num int The command word number to autocomplete
+ * @param[in] $comp_word string The command word to autocomplete
+ * @param[in] $opts array List of global available options
+ *
+ * @retval array List of available options for the word to autocomplete
+ **/
+function cli_export_ppolicy_info_args_autocompleter($command_args, $comp_word_num, $comp_word, $opts) {
+ $opts = array_merge($opts, array ('-o', '--output', '-j', '--json', '-p', '--pretty'));
+
+ // Handle positional args
+ $objType = null;
+ $objType_arg_num = null;
+ for ($i=0; $i < count($command_args); $i++) {
+ if (!in_array($command_args[$i], $opts)) {
+ // If object type not defined
+ if (is_null($objType)) {
+ // Defined it
+ $objType = $command_args[$i];
+ LScli :: unquote_word($objType);
+ $objType_arg_num = $i;
+
+ // Check object type exists
+ $objTypes = LScli :: autocomplete_LSobject_types($objType);
+
+ // Load it if exist and not trying to complete it
+ if (in_array($objType, $objTypes) && $i != $comp_word_num) {
+ LSsession :: loadLSobject($objType, false);
+ }
+ }
+ }
+ }
+
+ // If objType not already choiced (or currently autocomplete), add LSobject types to available options
+ if (!$objType || $objType_arg_num == $comp_word_num)
+ $opts = array_merge($opts, LScli :: autocomplete_LSobject_types($comp_word));
+
+ return LScli :: autocomplete_opts($opts, $comp_word);
+}
+
+LScli :: add_command(
+ 'export_ppolicy_info',
+ 'cli_export_ppolicy_info',
+ 'Export password policy info of a all objects of a specified object type',
+ '[object type] [-o|--output filepath] [-j|--json [-p|--pretty]]',
+ false, // long desc
+ true,
+ 'cli_export_ppolicy_info_args_autocompleter'
+);
diff --git a/src/lang/fr_FR.UTF8/LC_MESSAGES/ldapsaisie.mo b/src/lang/fr_FR.UTF8/LC_MESSAGES/ldapsaisie.mo
index 86abcf6d..f71aa389 100644
Binary files a/src/lang/fr_FR.UTF8/LC_MESSAGES/ldapsaisie.mo and b/src/lang/fr_FR.UTF8/LC_MESSAGES/ldapsaisie.mo differ
diff --git a/src/lang/fr_FR.UTF8/LC_MESSAGES/ldapsaisie.po b/src/lang/fr_FR.UTF8/LC_MESSAGES/ldapsaisie.po
index 7011cea2..241e5f4f 100644
--- a/src/lang/fr_FR.UTF8/LC_MESSAGES/ldapsaisie.po
+++ b/src/lang/fr_FR.UTF8/LC_MESSAGES/ldapsaisie.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: LdapSaisie\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-02-22 18:24+0100\n"
+"PO-Revision-Date: 2022-04-11 18:24+0200\n"
"Last-Translator: Benjamin Renard \n"
"Language-Team: LdapSaisie \n"
@@ -21,6 +21,64 @@ msgstr ""
"X-Generator: Poedit 2.4.2\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:26
+msgid "Password policy Support : The constant %{const} is not defined."
+msgstr ""
+"Support politique de mots de passe : La constante %{const} n'est pas définie."
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:29
+msgid "Password policy Support : The global array %{array} is not defined."
+msgstr ""
+"Support politique de mots de passe : Le tableau global %{array} n'est pas "
+"définie."
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:32
+msgid "Password policy: An error occured generating CSV outfile memory space."
+msgstr ""
+"Politique de mots de passe : Une erreur est survenue en générant l'espace "
+"mémoire pour le fichier CSV."
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:35
+msgid "Password policy: An error occured executing the search."
+msgstr ""
+"Politique de mots de passe : Une erreur est survenue en exécutant la "
+"recherche."
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:38
+msgid "Password policy: An error occured writing CSV header."
+msgstr ""
+"Politique de mots de passe : Une erreur est survenue en écrivant les entêtes "
+"CSV."
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:41
+msgid "Password policy: An error occured writing a CSV row."
+msgstr ""
+"Politique de mots de passe : Une erreur est survenue en écrivant une ligne "
+"CSV."
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:169
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:175
+msgid "Never"
+msgstr "Jamais"
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:173
+msgid "Unknown"
+msgstr "Inconnu"
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:180
+#, php-format
+msgid "Expired (since %s)"
+msgstr "Expiré (depuis %s)"
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:190
+#, php-format
+msgid "Expire on %s"
+msgstr "Expirera le %s"
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:258
+msgid "Not set"
+msgstr "Non défini"
+
#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.samba.php:27
msgid "SAMBA Support: Unable to load smbHash class."
msgstr "Support SAMBA : Impossible de charger la classe smbHash."
@@ -434,6 +492,10 @@ msgstr ""
"MAILDIR : Erreur durant la récupération du chemin distant du dossier des "
"mails."
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.watermark.php:78
+msgid "PRE-PRODUCTION"
+msgstr "PRÉ-PRODUCTION"
+
#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.showTechInfo.php:63
#: templates/default/showTechInfo.tpl:16
msgid "Structural object class"
@@ -1628,39 +1690,39 @@ msgstr ""
"LSformRule_password : Regex invalide configurée : %{regex}. Vous devez "
"utiliser des regex de type PCRE (commencant par le caractère '/')."
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:614
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:629
msgid "LSldap: Error during the LDAP server connection (%{msg})."
msgstr "LSldap : Erreur durant la connexion au serveur LDAP (%{msg})."
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:617
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:632
msgid "LSldap: Error during the LDAP search (%{msg})."
msgstr "LSldap : Erreur pendant la recherche LDAP (%{msg})."
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:620
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:635
msgid "LSldap: Object type unknown."
msgstr "LSldap : Type d'objet inconnu."
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:623
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:638
msgid "LSldap: Error while fetching the LDAP entry."
msgstr "LSldap : Erreur durant la récupération de l'entrée LDAP."
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:626
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:641
msgid "LSldap: Error while changing the LDAP entry (DN : %{dn})."
msgstr "LSldap : Erreur durant la modification de l'entrée LDAP (DN : %{dn})."
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:629
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:644
msgid "LSldap: Error while deleting empty attributes."
msgstr "LSldap : Erreur durant la suppression des attributs vides."
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:632
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:647
msgid "LSldap: Error while changing the DN of the object."
msgstr "LSldap : Erreur pendant la modification du DN de l'objet."
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:635
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:650
msgid "LSldap: LDAP server base DN not configured."
msgstr "LSldap : Le base DN du serveur LDAP n'est pas configuré."
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:638
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:653
msgid "LSldap: Fail to set authz proxy option on LDAP server connection."
msgstr ""
"LSldap : Une erreur est survenue en appliquant l'option d'authz proxy sur la "
diff --git a/src/lang/ldapsaisie.pot b/src/lang/ldapsaisie.pot
index 980e6cfe..c66181ae 100644
--- a/src/lang/ldapsaisie.pot
+++ b/src/lang/ldapsaisie.pot
@@ -1,3 +1,50 @@
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:26
+msgid "Password policy Support : The constant %{const} is not defined."
+msgstr ""
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:29
+msgid "Password policy Support : The global array %{array} is not defined."
+msgstr ""
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:32
+msgid "Password policy: An error occured generating CSV outfile memory space."
+msgstr ""
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:35
+msgid "Password policy: An error occured executing the search."
+msgstr ""
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:38
+msgid "Password policy: An error occured writing CSV header."
+msgstr ""
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:41
+msgid "Password policy: An error occured writing a CSV row."
+msgstr ""
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:169
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:175
+msgid "Never"
+msgstr ""
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:173
+msgid "Unknown"
+msgstr ""
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:180
+#, php-format
+msgid "Expired (since %s)"
+msgstr ""
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:190
+#, php-format
+msgid "Expire on %s"
+msgstr ""
+
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.ppolicy.php:258
+msgid "Not set"
+msgstr ""
+
#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.samba.php:27
msgid "SAMBA Support: Unable to load smbHash class."
msgstr ""
@@ -345,6 +392,10 @@ msgstr ""
msgid "MAILDIR : Error retrieving remote path of the maildir."
msgstr ""
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.watermark.php:78
+msgid "PRE-PRODUCTION"
+msgstr ""
+
#: /home/brenard/dev/ldapsaisie_clean3/src/includes/addons/LSaddons.showTechInfo.php:63
#: templates/default/showTechInfo.tpl:16
msgid "Structural object class"
@@ -1359,39 +1410,39 @@ msgid ""
"(begining by '/' caracter)."
msgstr ""
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:614
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:629
msgid "LSldap: Error during the LDAP server connection (%{msg})."
msgstr ""
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:617
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:632
msgid "LSldap: Error during the LDAP search (%{msg})."
msgstr ""
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:620
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:635
msgid "LSldap: Object type unknown."
msgstr ""
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:623
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:638
msgid "LSldap: Error while fetching the LDAP entry."
msgstr ""
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:626
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:641
msgid "LSldap: Error while changing the LDAP entry (DN : %{dn})."
msgstr ""
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:629
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:644
msgid "LSldap: Error while deleting empty attributes."
msgstr ""
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:632
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:647
msgid "LSldap: Error while changing the DN of the object."
msgstr ""
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:635
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:650
msgid "LSldap: LDAP server base DN not configured."
msgstr ""
-#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:638
+#: /home/brenard/dev/ldapsaisie_clean3/src/includes/class/class.LSldap.php:653
msgid "LSldap: Fail to set authz proxy option on LDAP server connection."
msgstr ""