Compare commits

..

124 Commits

Author SHA1 Message Date
c60ad54aab Lex audit files 2025-07-18 10:53:21 +01:00
237f2f21ab * Wed Jul 16 2025 Brian Read <brianr@koozali.org> 11.0.0-109.sme
- A few more error message corrections [SME: 13078]
2025-07-16 15:46:49 +01:00
1708fbe3fa * Wed Jul 16 2025 Brian Read <brianr@koozali.org> 11.0.0-108.sme
- Password change panel - add extra descriptive text [SME: 13081]
2025-07-16 06:19:47 +01:00
9f6e45d98c * Tue Jul 15 2025 Brian Read <brianr@koozali.org> 11.0.0-107.sme
- Email Settings panel: Fix lex strings with long names and no prefix [SME: 13080]
2025-07-15 15:43:30 +01:00
5ba77e4526 * Mon Jul 14 2025 Brian Read <brianr@koozali.org> 11.0.0-106.sme
- Datetime panel: Typo in error message - missing _ [SME: 13078]
- ditto user accounts panel                         [SME: 13078]
- ditto groups panel                                [SME: 13078]
2025-07-14 11:44:49 +01:00
1d00f2aeb2 * Mon Jul 14 2025 Brian Read <brianr@koozali.org> 11.0.0-105.sme
- Adjust db opening in Software install panel [SME: 13077]
2025-07-14 06:38:10 +01:00
b0c6bea0a2 * Mon Jul 07 2025 Brian Read <brianr@koozali.org> 11.0.0-104.sme
- Fix DB not open in Workgrouyp panel sometimes. [SME: 13070]
2025-07-07 06:22:13 +01:00
5a57ffaa34 * Thu Jul 03 2025 Brian Read <brianr@koozali.org> 11.0.0-103.sme
- Fix a couple of typos [SME: 13065]
2025-07-03 11:11:12 +01:00
717d34a53d * Thu Jul 03 2025 Brian Read <brianr@koozali.org> 11.0.0-102.sme
- Local Network panel: Make DEL and ADD robust even if called more than once by browser [SME: 13065]
2025-07-03 10:18:28 +01:00
bec39af49c * Wed Jul 02 2025 Brian Read <brianr@koozali.org> 11.0.0-101.sme
- Fix busy cursor, csp intervened. [SME: 13064]
2025-07-02 14:10:06 +01:00
ff9c2fee8c * Tue Jul 01 2025 Brian Read <brianr@koozali.org> 11.0.0-100.sme
- Add code in top template default.html.ep to incorporate any panel specific js and css [SME: 13062]
2025-07-01 11:28:58 +01:00
21255abf46 * Mon Jun 30 2025 Brian Read <brianr@koozali.org> 11.0.0-99.sme
- Directory panel  - Add in open for config db as required by cacheing  [SME: 13059]
2025-06-30 20:00:21 +01:00
8ada3f36e0 * Sun Jun 29 2025 Brian Read <brianr@koozali.org> 11.0.0-98.sme
- Re-factor email settings panel as error handling not working as expected.  [SME: 12973]
2025-06-30 14:55:58 +01:00
ab42f986e8 Update changelog - lost it on previous build 2025-06-27 13:59:25 +01:00
803bfd1cec * Fri Jun 27 2025 Brian Read <brianr@koozali.org> 11.0.0-96.sme
- fix [SME: ]
2025-06-27 13:52:21 +01:00
0f2e2b82aa * Tue Jun 24 2025 Brian Read <brianr@koozali.org> 11.0.0-95.sme
- Add clock ticker to datetime panel [SME: 13054]
- Add Test Server button for ntp server [SME: 13048]
- Add checking that date is fully valid [SME: 13055]
2025-06-25 10:35:16 +01:00
0341d02608 * Thu Jun 19 2025 Brian Read <brianr@koozali.org> 11.0.0-94.sme
- re-instate datetime routes in SrvMngr.pm - removed by mistake [SME: 13053]
2025-06-19 10:36:50 +01:00
c208419704 * Thu Jun 19 2025 Brian Read <brianr@koozali.org> 11.0.0-93.sme
- Sort out case of first letter of ctlact in routes added in from header on controller file [SME: 13053]
2025-06-19 06:26:38 +01:00
d1f2013375 * Sun Jun 15 2025 Brian Read <brianr@koozali.org> 11.0.0-92.sme
- rework datetime panel [SME: 13020]
- Fix errors in error messages for local networks panel [SME: 13044]
- Add in Config Db open in Proxy.pm needed after  UTF8 change [SME: 13046]
2025-06-18 11:17:51 +01:00
0733537064 * Fri Jun 13 2025 Brian Read <brianr@koozali.org> 11.0.0-91.sme
- Port Forwarding  - Same error as in local networking [SME: 13043]
2025-06-13 17:04:22 +01:00
dcc098b206 * Thu Jun 12 2025 Brian Read <brianr@koozali.org> 11.0.0-90.sme
- Error on empty extra chars for success message [SME: 13041]
- Needed extra open for network-db after add
2025-06-12 19:15:22 +01:00
1a8f935431 * Thu Jun 12 2025 Brian Read <brianr@koozali.org> 11.0.0-89.sme
- rework navigation weights to avoid duplicates [SME: 12996]
2025-06-12 18:15:41 +01:00
e8d6d39583 * Mon Jun 09 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-88.sme
- add datetime getYear_list [SME: 13031]
- use esmith::*DB::UTF8 to access db flat files [SME: 13027]
- fix typo [SME: 13038]
2025-06-10 07:17:32 -04:00
91201b7b02 * Mon Jun 09 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-87.sme
- add datetime getYear_list [SME: 13031]
- use esmith::*DB::UTF8 to access db flat files [SME: 13027]
2025-06-10 00:09:39 -04:00
c85022c49e * Mon Jun 09 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-87.sme
- add datetime getYear_list [SME: 13031]
- use esmith::*DB::UTF8 to access db flat files [SME: 13027]
2025-06-09 23:49:25 -04:00
fd076895ba * Mon Jun 09 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-87.sme
- add datetime getYear_list [SME: 13031]
- WIP use esmith::*DB::UTF8 to access db flat files [SME: 13027]
2025-06-09 12:49:29 -04:00
John Crisp
d993bd9d19 Fix DateTime gen_locale_date_string 2025-06-09 14:08:56 +02:00
John Crisp
a31806f205 Add UTF8 support to local network panel 2025-06-09 13:39:32 +02:00
b44f1c5000 * Mon Jun 09 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-84.sme
- fix Directory caching issue [SME: 13026]
- WIP use esmith::*DB::UTF8 to access db flat files [SME: 13027]
2025-06-09 00:46:19 -04:00
2538ac9ea0 * Mon May 05 2025 Brian Read <brianr@koozali.org> 11.0.0-83.sme
- Mod to SrvMngr-Auth to account for partials matching AdminPanels options
2025-05-05 07:01:25 +01:00
dbfeaa18a3 * Thu May 01 2025 Brian Read <brianr@koozali.org> 11.0.0-82.sme
- Correct Weights for menus [SME: 12996]
2025-05-01 18:16:25 +01:00
ced08b28d4 Update version in spec 2025-05-01 13:29:52 +01:00
c74a71dee1 * Thu May 01 2025 Brian Read <brianr@koozali.org> 11.0.0-81.sme
- Correct Weights for menus [SME: 12996]
2025-05-01 12:07:55 +01:00
96b002e7a9 * Wed Apr 30 2025 Brian Read <brianr@koozali.org> 11.0.0-80.sme
- Remove expansion of css files from createlinks [SME: 12989]
2025-05-01 06:33:46 +01:00
f30b4ab2b5 * Wed Apr 30 2025 Brian Read <brianr@koozali.org> 11.0.0-79.sme
- Add code in SrvMngr to take note of user panel setting
2025-04-30 09:09:16 +01:00
fa286e966d * Thu Apr 17 2025 Brian Read <brianr@koozali.org> 11.0.0-78.sme
- typo in remoteaccess panel
- Fix crash in veiwlogfiles if viewlogfiles key not in DB
2025-04-17 12:16:38 +01:00
9bb2128891 Typo in name for remoteaccess panel 2025-04-16 17:48:37 +01:00
accf96df0d * Sat Apr 12 2025 Brian Read <brianr@koozali.org> 11.0.0-77.sme
- Sort out local and pulic access setting in remote panel  [SME: 12988]
- caching problem, plus confusion between normal and public setting in sshd / access in DB
2025-04-12 09:08:12 +01:00
1c601f0ace * Fri Apr 11 2025 Brian Read <brianr@koozali.org> 11.0.0-76.sme
- Restore css for roundcube embedded  [SME: 12987]
2025-04-11 07:09:03 +01:00
cffbe53fb4 * Wed Apr 09 2025 Brian Read <brianr@koozali.org> 11.0.0-75.sme
- Move review configuration to behind login [SME: 12984]
- Fix crash in port forwarding [SME: 12985]
2025-04-09 10:43:14 +01:00
aad1a458f4 * Wed Mar 26 2025 Brian Read <brianr@koozali.org> 11.0.0-74.sme
- Fix error message and success message format in Local Networking panel [SME: 12969]
2025-03-26 08:58:32 +00:00
252bf20410 * Tue Mar 25 2025 Brian Read <brianr@koozali.org> 11.0.0-73.sme
- Some changes to error message format in css.
- Fix DB Cache problem with port forwarding panel [SME: 12970]
- Fix error and success message display for port forwarding panel [SME: 12969]
2025-03-25 15:05:34 +00:00
ebbe7af9a7 * Mon Mar 24 2025 Brian Read <brianr@koozali.org> 11.0.0-72.sme
- Remove css files from template structure [SME: 12967]
- Rationalise and merge css files
- Adjust some gaps around panels
- Remove HR lines
2025-03-24 17:23:02 +00:00
36de44fcef * Thu Mar 20 2025 Brian Read <brianr@koozali.org> 11.0.0-71.sme
- Sort out navigation menu error on startup [SME: 12946]
- More places where floating panel needed
- Adjust floating panel to make space around it the same
- clean up some css
2025-03-20 12:15:50 +00:00
750ab7dd11 * Wed Mar 19 2025 Brian Read <brianr@koozali.org> 11.0.0-70.sme
- Re-cast the default theme - use proper koozali logo image, unwind multiple divs
- Enhance responsiveness
- Revert Ibay menu name to Ibays
- Remove legacy SM1 button on header
- Remove "?" access to wiki help on header
2025-03-19 13:45:03 +00:00
77ca17c851 * Mon Mar 17 2025 Brian Read <brianr@koozali.org> 11.0.0-69.sme
- Add a total summary report across all existing logs [SME: 12951]
2025-03-17 15:27:16 +00:00
535d78eacb * Mon Mar 17 2025 Brian Read <brianr@koozali.org> 11.0.0-68.sme
- re-write qmailanalog for postfix [SME: 12951]
- Clean up backup.pm
- Enhance module panel - used by mail log analysis and Licence display
2025-03-17 12:22:38 +00:00
88ee369253 * Mon Mar 17 2025 Brian Read <brianr@koozali.org> 11.0.0-67.sme
- re-write qmailanalog for postfix [SME: 12951]
- Clean up backup.pm
- Enhance module panel - used by mail log analysis and Licence display
2025-03-17 12:20:55 +00:00
5be2152e89 * Mon Mar 17 2025 Brian Read <brianr@koozali.org> 11.0.0-67.sme
- re-write qmailanalog for postfix [SME: 12951]
- Clean up backup.pm
- Enhance module panel - used by mail log analysis and Licence display
2025-03-17 12:08:40 +00:00
63973f2bb4 * Tue Mar 11 2025 Brian Read <brianr@koozali.org> 11.0.0-66.sme
- Move the button for each backup panel to the left to conform to all the other panels.
2025-03-11 17:37:44 +00:00
82ff48e641 * Sun Mar 09 2025 Brian Read <brianr@koozali.org> 11.0.0-65.sme
- Sort out missing hostname on nfs and cifs workstation backup on error [SME: 12948]
2025-03-09 15:38:39 +00:00
c5d863b3a0 * Sat Mar 08 2025 Brian Read <brianr@koozali.org> 11.0.0-64.sme
- Add code to check for boot phase completion [SME: 12953]
2025-03-08 10:45:00 +00:00
4f00dfbdb1 * Thu Mar 06 2025 Brian Read <brianr@koozali.org> 11.0.0-63.sme
- Add boot.svg image to Bug Report panel [SME: 12953]
- Move report template to inside smanager tree
- Add one-off systemd task to create boot.svg run from panel
2025-03-07 15:41:55 +00:00
f9bf8cf064 refine spec comment 2025-03-04 14:36:14 +00:00
4f0617f6c3 * Tue Mar 04 2025 Brian Read <brianr@koozali.org> 11.0.0-62.sme
- Update .lex files to conform to standard english punctuation  [SME: 11809]
2025-03-04 14:18:38 +00:00
4c94d768e2 * Tue Mar 04 2025 Brian Read <brianr@koozali.org> 11.0.0-61.sme
- Arrange for the version in the footer to be suppressed if non admin login  [SME: 12887]
2025-03-04 10:11:38 +00:00
1731f75cba * Thu Feb 27 2025 Brian Read <brianr@koozali.org> 11.0.0-60.sme
- Enhance ssh security wording to mention autoblock in remoteaccess panel  [SME: 8309]
2025-02-27 15:54:27 +00:00
5fe285f9f2 * Thu Feb 27 2025 Brian Read <brianr@koozali.org> 11.0.0-59.sme
- Arrange for Urgent notice to be displayed if date is past Rocky 8 EOL [SME: 12918]
2025-02-27 15:02:05 +00:00
1c93be6e8a * Tue Feb 25 2025 Brian Read <brianr@koozali.org> 11.0.0-58.sme
- re-organise open db placement [SME: 12695]
- Re-arrange parameters to tar to avoid warning message in logs [SME: 12943]
2025-02-26 11:57:22 +00:00
ce96f72726 Finally - re-arrange tar params to avoid warning in logs 2025-02-25 12:25:46 +00:00
0fd7137edd sort out open db placements in routes and re-arrange tar params to avoid warning in logs 2025-02-25 12:22:52 +00:00
d179b06f69 Sort out opendb placement and re-arrange tar parameters to avoid warning in logs 2025-02-25 12:14:12 +00:00
c2427189d5 * Fri Feb 21 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-57.sme
- upgrade validate_password sub to use esmith::util [SME: 12937]
  and deduplicate code
2025-02-21 01:35:33 -05:00
887af04bfe Add in buzilla number to changelog line 2025-02-20 15:45:48 +01:00
34b85b1cde * Thu Feb 20 2025 Brian Read <brianr@koozali.org> 11.0.0-56.sme
- open db in routes for backup controller file  [SME: 12933]
- Fix error handling for pre-backup fail [SME:
2025-02-20 14:35:09 +00:00
a5758b4431 * Tue Feb 18 2025 Brian Read <brianr@koozali.org> 11.0.0-55.sme
- fix public ftp access not showing on panel [SME: 12927]
2025-02-18 16:16:36 +00:00
58aa423089 * Sat Feb 15 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-54.sme
- helper to set default value of select field using protected value [SME: 12923]
2025-02-16 02:28:01 -05:00
c0b4d1f90e * Sat Feb 15 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-53.sme
- helper to set default value of select field using protected value [SME: 12923]
2025-02-15 15:19:04 -05:00
a979d472e8 * Wed Feb 12 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-52.sme
- move letsencrypt panel to smeserver-certificates [SME: 12916]
2025-02-12 23:14:38 -05:00
d776f20736 * Mon Feb 10 2025 Brian Read <brianr@koozali.org> 11.0.0-51.sme
- Replace url in call to webmail by browser url rather than system host and domain [SME: 12910]
- Fix up CSS so not inline
- Sort out reveiw panel missing routines from FormMagic [SME: 12907].
2025-02-12 16:31:17 +00:00
a4668da720 * Sun Feb 09 2025 Brian Read <brianr@koozali.org> 11.0.0-50.sme
- Move all routines from FormMagic still called by SM2 panels to SM2 [SME:12906]
- delete all references to FormMagic
2025-02-09 15:34:41 +00:00
7ad224998c * Fri Feb 07 2025 Brian Read <brianr@koozali.org> 11.0.0-49.sme
- Fix delete of ibay - typo in link
- Move across toMB() sub from formmagick to quota.pm
- Recast DB opening so it is specific to the route rather than global [SME: 12905]
2025-02-07 16:21:42 +00:00
3070e0656c Fix typo in ibay delete link 2025-02-07 11:41:04 +00:00
642d013437 * Wed Jan 29 2025 Brian Read <brianr@koozali.org> 11.0.0-48.sme
- Make Country flag display independant of the internet. [SME: 12893]
2025-01-29 12:04:38 +00:00
a62968d2d9 * Tue Jan 28 2025 Brian Read <brianr@koozali.org> 11.0.0-47.sme
- Temp (we hope) remove CSRF protection plugin  [SME: ]
- Fix comparison in footer with config->mode
2025-01-28 15:23:39 +00:00
0e777fd51a * Tue Jan 28 2025 Brian Read <brianr@koozali.org> 11.0.0-46.sme
- Adjust conditions for showing "Reconfigure required" to only check UnSavedChanges DB entry [SME: 12891]
- Add indication of developement mode in footer
2025-01-28 14:02:31 +00:00
eee68afa2b Various - space in reboot panel, max 15 chars for workgroup name, add action for recofigure, remove call to TAI64 in viewlogfiles, add requires for multi-language locales 2025-01-27 15:16:21 +00:00
c2d677594b Add check for 15 characters netbios name in workgroup panel 2025-01-25 14:41:21 +00:00
f6fe2216a0 Add some space in the reboot/reconf/shutdown panel 2025-01-25 10:40:08 +00:00
6d3f8f48c2 * Fri Jan 24 2025 Brian Read <brianr@koozali.org> 11.0.0-44.sme
- Change to network-online for systemd startup to make sure network is up [SME: 12758]
2025-01-24 19:04:28 +00:00
f8d9ec34e3 Fix red error message when goes over one line 2025-01-23 15:53:51 +00:00
835d439e42 mojo update, version in footer, password setting in useraccounts 2025-01-23 15:03:28 +00:00
4797a1b189 Add mojo version to footer 2025-01-23 09:59:29 +00:00
1e4ec809b5 Update spec file to -43 2025-01-23 07:34:50 +00:00
d1197f55cf Update letsencrypt dealing with pointer to hash of params 2025-01-23 07:12:01 +00:00
b5d6de3bcf Update to work for Mojo 9.39 - config accessed through plugin not global hash 2025-01-22 11:53:21 +00:00
ec4f515012 * Fri Jan 17 2025 Brian Read <brianr@koozali.org> 11.0.0-42.sme
- Implement password visibility icon - [SME: 12803]
2025-01-17 12:04:36 +00:00
9b03d377e2 * Wed Jan 15 2025 Brian Read <brianr@koozali.org> 11.0.0-41.sme
- Add journal files to those not viewable [SME: 12870]
2025-01-15 18:44:48 +00:00
957d2ada21 Add journal files to list of files in /var/log NOT viewable 2025-01-15 18:39:22 +00:00
be49419eba * Wed Jan 15 2025 Brian Read <brianr@koozali.org> 11.0.0-40.sme
- Comment out missing prefix message in navigation2-conf action and re-format it with perltidy [SME: 127672]
2025-01-15 11:41:22 +00:00
c1915a722b Reformat Controller perl code using perltidy 2025-01-14 12:49:31 +00:00
7ff51625c0 Update .perltidyrc 2025-01-14 11:52:05 +00:00
18c95a9021 Add .gitignore and .perltidyrc to Controlller directory 2025-01-14 11:06:38 +00:00
5ef3a00a05 * Sat Jan 11 2025 Brian Read <brianr@koozali.org> 11.0.0-38.sme
- Fix password reset for admin in user panel [SME: 12655]
2025-01-11 07:04:32 +00:00
174e140a04 * Thu Jan 09 2025 Brian Read <brianr@koozali.org> 11.0.0-37.sme
- Delete userpanelaccess from base (left in incorrectly after saome testing)  [SME: 12839]
2025-01-09 19:06:51 +00:00
d77b9bd341 Update spec file changelog for 12864 2025-01-09 15:53:59 +00:00
746609ced0 Bug:12864 Correct spelling in Lex file for API 2025-01-09 15:14:10 +00:00
9380ac0264 Bug:12868 fix email settings for spamassassin status 2025-01-09 14:49:56 +00:00
a07bdf4aa5 * Tue Dec 31 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-35.sme
- fix PATH [SME: 12847]
2024-12-31 03:09:36 -05:00
4270814afc * Tue Dec 31 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-34.sme
- fix css warning xxcolor [SME: 12844]
- update CSP style rules [SME: 12840]
2024-12-31 02:00:14 -05:00
58c3f2348a * Mon Dec 30 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-33.sme
- host locally flag-icon.min.css 3.5.0 [SME: 12845]
- remove onclick to comply with strict CSP [SME: 12846]
- add CSP rules with specific hash [SME: 12840]
2024-12-31 01:25:04 -05:00
b58f82a332 Fix up user and localnetwork panels and stop menu moving betweek proxy and reboot 2024-12-18 12:08:00 +00:00
8db1279a3e * Tue Dec 17 2024 Brian Read <brianr@koozali.org> 11.0.0-31.sme
- Edit html to avoid w3c html validation warnings [SME: 6278]
2024-12-17 06:35:33 +00:00
1d3d59b5c1 Fix up action commands for user panel 2024-12-16 19:55:15 +00:00
ff9a84dd29 Fix up action commands for pseudonyms and quota 2024-12-16 16:15:03 +00:00
34e7331845 Fix up action commands for port forwarding and printers 2024-12-16 13:55:52 +00:00
dfda47882d Fix up action commands for Ibays and correct groups link 2024-12-16 13:26:19 +00:00
55269fd685 Fix up action commands for Groups and Host panels 2024-12-15 17:17:32 +00:00
1b1b99955b Fix yp html warnings from w3c - mainly empty paragraphs, but also domain lists recast buttons 2024-12-15 10:15:38 +00:00
c6eb08a727 More Fix up html to conform to W3c standards - avoid duplicate id in nav menu 2024-12-14 14:06:56 +00:00
8e70adc797 A bit more header html fixing 2024-12-13 17:52:32 +00:00
2424684d35 Fix up html warned from w3c validator in header and footed 2024-12-13 16:42:42 +00:00
78bb7743c1 Add in letsencrypt and add requires for certificates and lib 2024-12-13 11:52:45 +00:00
87f6a46502 Add in letsencrypt action routines for SM2 panel 2024-12-01 15:36:46 +00:00
a08767919c Add in getmyip script 2024-11-27 16:01:56 +00:00
2b83be6d70 Fix 1267 in remoteaccess panel 2024-11-26 16:38:31 +00:00
6c1b6ed1f4 Add *.bak to .gitignore 2024-11-12 19:20:21 +00:00
3fa8ab5eda Update README with specific Bugzilla links 2024-10-27 14:23:06 +00:00
55465e3081 Update readme bugzilla link to show all outstanding bugs 2024-10-27 12:12:21 +00:00
e5b9a012d9 * Fri Oct 18 2024 Brian Read <brianr@koozali.org> 11.0.0-28.sme
- Add in emailsettings for port 25,465 and 587  [SME: 12750]
- Comment out change to localhost for roundcube in _user_list email icon setting [SME: 12751]
2024-10-18 11:46:27 +01:00
fbdf3170ec Add in _user_list.html.ep change 2024-10-06 09:48:42 +01:00
87d1d072c0 * Fri Oct 04 2024 Brian Read <brianr@koozali.org> 11.0.0-26.sme
- Add in email link to roundcube from user accounts [SME: 12751]
2024-10-04 12:34:34 +01:00
d49db26f26 Add in email link to roundcube from user accounts 2024-10-04 12:14:56 +01:00
c4f9d67abc First shot at Email icon in action col for user accounts 2024-10-02 16:42:58 +01:00
205 changed files with 13108 additions and 12188 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@
*.log
*spec-20*
*.tar.xz
*.bak

View File

@@ -13,7 +13,14 @@ SMEServer Koozali developed git repo for smeserver-manager smeserver
<br />https://wiki.koozali.org/Server_Manager_2_Howto_incorporate_a_legacy_contrib
## Bugzilla
Show list of outstanding bugs: [here](https://bugs.koozali.org/buglist.cgi?component=smeserver-manager&product=SME%20Server%2010.X&query_format=advanced&limit=0&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=CONFIRMED)
Show list of outstanding bugs:
[All](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=NEEDINFO&bug_status=IN_PROGRESS&bug_status=RESOLVED&bug_status=VERIFIED&cf_package=smeserver-manager&classification=SME+Server&list_id=105756&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[Confirmed](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=CONFIRMED&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[Unconfirmed](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=UNCONFIRMED&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[Need info](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=NEEDINFO&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[In progress](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=IN_PROGRESS&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[Resolved](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=RESOLVED&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
[Verified](https://bugs.koozali.org/buglist.cgi?action=wrap&bug_status=VERIFIED&cf_package=smeserver-manager&classification=SME+Server&order=changeddate+DESC%2Ccomponent%2Cpriority%2Cbug_severity&query_format=advanced)
## Description
@@ -72,4 +79,4 @@ Dependencies: Relies on specific packages and configurations of SME Server, and
### Summary
SMEserver-manager is a powerful tool that brings simplicity and efficiency to server management for small to medium-sized enterprises. By providing a centralized, web-based interface, it allows administrators to manage users, network settings, file sharing, email services, web hosting, and more, all from a single location.
SMEserver-manager is a powerful tool that brings simplicity and efficiency to server management for small to medium-sized enterprises. By providing a centralized, web-based interface, it allows administrators to manage users, network settings, file sharing, email services, web hosting, and more, all from a single location.

View File

@@ -8,12 +8,12 @@ use esmith::Build::CreateLinks qw(:all);
my $mngrdir = '/usr/share/smanager';
# templates to expand
for ( qw( sme_core.css sme_main.css sme_menu.css styles.css ) )
{
templates2events("$mngrdir/themes/default/public/css/$_", qw(
bootstrap-console-save smeserver-manager-update
));
}
#for ( qw( sme_core.css sme_main.css sme_menu.css styles.css ) )
#{
# templates2events("$mngrdir/themes/default/public/css/$_", qw(
# bootstrap-console-save smeserver-manager-update
# ));
#}
templates2events("$mngrdir/conf/srvmngr.conf",
qw( smeserver-manager-update smanager-theme-change smanager-modify bootstrap-console-save ));
@@ -45,6 +45,7 @@ for my $event ( qw( smeserver-manager-update smanager-refresh bootstrap-console-
event_link('locales2-conf', "$event", '80');
}
event_link('post-upgrade-and-reboot','post-upgrade-and-reboot',80);
event_link('systemd-default', "smeserver-manager-update", '88');
event_link('systemd-reload', "smeserver-manager-update", '89');
templates2events("/etc/rsyslog.conf", "smeserver-manager-update");

View File

@@ -0,0 +1 @@
-pbp -nst -nse -l=120 -ce -csc -pt=2 -kbl=0 -mbl=1 -lbl=1

View File

@@ -1,218 +1,207 @@
#!/usr/bin/perl -w
#----------------------------------------------------------------------
# copyright (C) 1999-2006 Mitel Networks Corporation
#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
#----------------------------------------------------------------------
package esmith;
use strict;
use constant SMNGR_LIB => '/usr/share/smanager/lib';
use constant I18NMODULES => 'SrvMngr/I18N/Modules';
use constant WEBFUNCTIONS => 'SrvMngr/Controller';
use constant NAVDIR => '/home/e-smith/db';
use constant SMNGR_LIB => '/usr/share/smanager/lib';
use constant I18NMODULES => 'SrvMngr/I18N/Modules';
use constant WEBFUNCTIONS => 'SrvMngr/Controller';
use constant NAVDIR => '/home/e-smith/db';
use constant NAVIGATIONDIR => 'navigation2';
use constant DEBUG => 0;
use constant DEBUG => 0;
use esmith::NavigationDB;
use esmith::I18N;
use Data::Dumper; # activate if DEBUG
use Data::Dumper; # activate if DEBUG
binmode(STDOUT, ":encoding(UTF-8)");
my $navigation_ignore =
"(\.\.?|Swttheme\.pm|Login\.pm|Request\.pm|Modules\.pm(-.*)?)";
my $i18n = new esmith::I18N;
my $navigation_ignore = "(\.\.?|Swttheme\.pm|Login\.pm|Request\.pm|Modules\.pm(-.*)?)";
my $i18n = new esmith::I18N;
my %navdbs;
opendir FUNCTIONS, SMNGR_LIB.'/'.WEBFUNCTIONS or
die "Couldn't open ", SMNGR_LIB.'/'.WEBFUNCTIONS, "\n";
my @files = grep (!/^${navigation_ignore}$/, readdir (FUNCTIONS));
opendir FUNCTIONS, SMNGR_LIB . '/' . WEBFUNCTIONS
or die "Couldn't open ", SMNGR_LIB . '/' . WEBFUNCTIONS, "\n";
my @files = grep (!/^${navigation_ignore}$/, readdir(FUNCTIONS));
closedir FUNCTIONS;
my @langs = $i18n->availableLanguages();
my @langs = $i18n->availableLanguages();
#my @langs = ('tr'); #Temp override
foreach my $lang (@langs) {
my $long_lex = SMNGR_LIB . '/' . I18NMODULES . "/General/general_$lang.lex";
next unless (-e $long_lex);
open(LEX, '<:encoding(UTF-8)', $long_lex)
or die "Couldn't open ", $long_lex, " for reading.\n";
my @gen_lex = <LEX>;
close LEX;
#my @files = ('Portforwarding.pm'); #Temp override
foreach my $file (@files) {
next if (-d SMNGR_LIB . '/' . WEBFUNCTIONS . "/$file");
foreach my $lang (@langs)
{
my $long_lex = SMNGR_LIB.'/'.I18NMODULES."/General/general_$lang.lex";
next unless ( -e $long_lex );
# next unless ( $file =~ m/D.*\.pm$/ );
next unless ($file =~ m/[A-Z].*\.pm$/);
my $file2 = lc($file);
$file2 =~ s/\.pm$//;
open(LEX, '<:encoding(UTF-8)', $long_lex)
or die "Couldn't open ", $long_lex, " for reading.\n";
my @gen_lex = <LEX>;
close LEX;
#--------------------------------------------------
# extract heading, description and weight information
# from Mojo controller
#--------------------------------------------------
open(SCRIPT, SMNGR_LIB . '/' . WEBFUNCTIONS . "/$file");
my $heading = undef;
my $description = undef;
my $heading_weight = undef;
my $description_weight = undef;
my $menucat = undef;
my $routes = undef;
#my @files = ('Portforwarding.pm'); #Temp override
foreach my $file (@files)
{
next if (-d SMNGR_LIB.'/'.WEBFUNCTIONS . "/$file");
# next unless ( $file =~ m/D.*\.pm$/ );
next unless ( $file =~ m/[A-Z].*\.pm$/ );
while (<SCRIPT>) {
$heading = $1 if (/^\s*#\s*heading\s*:\s*(.+?)\s*$/);
$description = $1
if (/^\s*#\s*description\s*:\s*(.+?)\s*$/);
($heading_weight, $description_weight) = ($1, $2)
if (/^\s*#\s*navigation\s*:\s*(\d+?)\s+(\d+?)\s*$/);
$menucat = $1
if (/^\s*#\s*menu\s*:\s*(.+?)\s*$/);
last
if (defined $heading
and defined $description
and defined $heading_weight
and defined $description_weight
and defined $menucat);
my $file2 = lc($file);
$file2 =~ s/\.pm$//;
#--------------------------------------------------
# extract heading, description and weight information
# from Mojo controller
#--------------------------------------------------
open(SCRIPT, SMNGR_LIB.'/'.WEBFUNCTIONS . "/$file");
my $heading = undef;
my $description = undef;
my $heading_weight = undef;
my $description_weight = undef;
my $menucat = undef;
my $routes = undef;
# routes : end (stop before eof if 'menu' is not here before 'routes'!!!
$routes = $1 if (/^\s*#\s*routes\s*:\s*(.+?)\s*$/);
last if (defined $routes and $routes eq 'end');
} ## end while (<SCRIPT>)
close SCRIPT;
print "updating script $file for lang $lang\n" if DEBUG;
my $navdb = $navdbs{$lang};
my $navinfo = NAVDIR . '/' . NAVIGATIONDIR . "/navigation.$lang";
$navdb ||= esmith::NavigationDB->open($navinfo);
$navdb ||= esmith::NavigationDB->create($navinfo)
or die "Couldn't create $navinfo\n";
$navdbs{$lang} ||= $navdb;
my $rec = $navdb->get($file2)
|| $navdb->new_record($file2, { type => 'panel' });
my @panel_lex = ();
$long_lex = SMNGR_LIB . '/' . I18NMODULES . '/' . ucfirst($file2) . "/${file2}_$lang.lex";
while ( <SCRIPT> )
{
$heading = $1 if (/^\s*#\s*heading\s*:\s*(.+?)\s*$/);
$description = $1
if (/^\s*#\s*description\s*:\s*(.+?)\s*$/);
($heading_weight, $description_weight) = ($1, $2)
if (/^\s*#\s*navigation\s*:\s*(\d+?)\s+(\d+?)\s*$/);
$menucat = $1
if (/^\s*#\s*menu\s*:\s*(.+?)\s*$/);
if (-e $long_lex) {
open(LEX, '<:encoding(UTF-8)', $long_lex)
or die "Couldn't open ", $long_lex, " for reading.\n";
@panel_lex = <LEX>;
close LEX;
} ## end if (-e $long_lex)
last if (defined $heading and
defined $description and
defined $heading_weight and
defined $description_weight and
defined $menucat);
#Extract the prefix for this module
my @keys = values @panel_lex; # Get all values from the array
my $i = 0; # Initialize the index
my $found = 0; # Flag to check if the prefix was found
my $prefix = "xx_"; # Probably never match!!
# routes : end (stop before eof if 'menu' is not here before 'routes'!!!
$routes = $1 if (/^\s*#\s*routes\s*:\s*(.+?)\s*$/);
last if (defined $routes and $routes eq 'end');
}
close SCRIPT;
while ($i < @keys) { # Loop until we run out of entries
my $extracted_value = $keys[$i] || ""; # The current entry
#print("Extracted val: ".$extracted_value."\n");
print "updating script $file for lang $lang\n"if DEBUG;
my $navdb = $navdbs{$lang};
my $navinfo = NAVDIR.'/'.NAVIGATIONDIR . "/navigation.$lang";
$navdb ||= esmith::NavigationDB->open($navinfo);
$navdb ||= esmith::NavigationDB->create($navinfo) or
die "Couldn't create $navinfo\n";
$navdbs{$lang} ||= $navdb;
my $rec = $navdb->get($file2) ||
$navdb->new_record($file2, { type => 'panel' } );
my @panel_lex = ();
$long_lex = SMNGR_LIB.'/'.I18NMODULES.'/'.ucfirst($file2)."/${file2}_$lang.lex";
if ( -e $long_lex ) {
open(LEX, '<:encoding(UTF-8)', $long_lex)
or die "Couldn't open ", $long_lex, " for reading.\n";
@panel_lex = <LEX>;
close LEX;
}
#Extract the prefix for this module
my @keys = values @panel_lex; # Get all values from the array
my $i = 0; # Initialize the index
my $found = 0; # Flag to check if the prefix was found
my $prefix = "xx_"; # Probably never match!!
# Extract prefix from the second value (up to and including the first underscore)
#my ($prefix) = $second_value =~ /^'(.*?_)/; # Match everything up to and including the first underscore
($prefix) = $extracted_value =~ /^'(.*?_)/; # Match everything up to and including the first underscore
while ($i < @keys) { # Loop until we run out of entries
my $extracted_value = $keys[$i] || ""; # The current entry
#print("Extracted val: ".$extracted_value."\n");
if (defined $prefix) {
$found = 1; # Set found flag to true
last; # Exit the loop if prefix is found
} else {
# Extract prefix from the second value (up to and including the first underscore)
#my ($prefix) = $second_value =~ /^'(.*?_)/; # Match everything up to and including the first underscore
($prefix) = $extracted_value =~ /^'(.*?_)/; # Match everything up to and including the first underscore
if (defined $prefix) {
$found = 1; # Set found flag to true
last; # Exit the loop if prefix is found
} else {
#print("Extracted Val: " . $extracted_value . "\n");
}
#print("Extracted Val: " . $extracted_value . "\n");
}
$i++; # Increment the index to check the next entry
} ## end while ($i < @keys)
$i++; # Increment the index to check the next entry
}
if (!$found) {
#print(STDERR "No valid prefix found in any entries: " . $file2 . " (" . $lang . ")\n"); # if DEBUG;
$prefix = "xx_"; # Probably never match!!
}
if (!$found) {
print(STDERR "No valid prefix found in any entries: ".$file2." (".$lang.")\n"); # if DEBUG;
$prefix = "xx_"; # Probably never match!!
}
#print("Prefix: ".$prefix." ".$file2." (".$lang.")\n");
my %Lexicon = ();
push(@panel_lex, @gen_lex);
my $top_error = 0;
#print("Prefix: ".$prefix." ".$file2." (".$lang.")\n");
my %Lexicon = ();
push(@panel_lex, @gen_lex);
my $top_error = 0;
chomp @panel_lex;
chomp @panel_lex;
for (@panel_lex) {
next unless $_; # first one empty
my ($k, $v) = split / => /, $_;
# errors on split to $v (use DEBUG to see)
if ( $k and $v ) {
$k =~ s/\'//g;
$v =~ s/\'//g;
$v =~ s/,$//g;
$Lexicon{ lc($k) } = $v;
} else {
$k = "?" unless ($k);
print STDERR "Error for $lang $file2 on $k \n" if DEBUG;
$top_error++;
}
}
if ( $top_error > 0) {
if ( DEBUG ) {
print STDERR "$top_error errors for $lang $file2\n";
# print Dumper(\@panel_lex);
# print Dumper(\%Lexicon);
# exit 1;
}
}
$heading = "" unless defined $heading;
$description = "" unless defined $description;
# Get the base language code from $lang
my $base_lang = (split('-', $lang))[0];
my $loc_heading = process_localization( \%Lexicon, $heading, $lang, $prefix );
my $loc_description = process_localization( \%Lexicon, $description, $lang, $prefix );
$loc_heading =~ s/^\s*(\w.*?)\s*$/$1/;
$loc_description =~ s/^\s*(\w.*?)\s*$/$1/;
for (@panel_lex) {
next unless $_; # first one empty
my ($k, $v) = split / => /, $_;
$rec->merge_props(
Heading => $loc_heading,
Description => $loc_description,
HeadingWeight => localise( \%Lexicon, $heading_weight ),
DescriptionWeight => localise( \%Lexicon, $description_weight ),
MenuCat => (defined $menucat ? $menucat : 'A'));
}
#warn "trying to close for lang $lang\n";
my $navdb = $navdbs{$lang};
$navdb->close();
}
# errors on split to $v (use DEBUG to see)
if ($k and $v) {
$k =~ s/\'//g;
$v =~ s/\'//g;
$v =~ s/,$//g;
$Lexicon{ lc($k) } = $v;
} else {
$k = "?" unless ($k);
print STDERR "Error for $lang $file2 on $k \n" if DEBUG;
$top_error++;
}
} ## end for (@panel_lex)
if ($top_error > 0) {
if (DEBUG) {
print STDERR "$top_error errors for $lang $file2\n";
# print Dumper(\@panel_lex);
# print Dumper(\%Lexicon);
# exit 1;
} ## end if (DEBUG)
} ## end if ($top_error > 0)
$heading = "" unless defined $heading;
$description = "" unless defined $description;
# Get the base language code from $lang
my $base_lang = (split('-', $lang))[0];
my $loc_heading = process_localization(\%Lexicon, $heading, $lang, $prefix);
my $loc_description = process_localization(\%Lexicon, $description, $lang, $prefix);
$loc_heading =~ s/^\s*(\w.*?)\s*$/$1/;
$loc_description =~ s/^\s*(\w.*?)\s*$/$1/;
$rec->merge_props(
Heading => $loc_heading,
Description => $loc_description,
HeadingWeight => localise(\%Lexicon, $heading_weight),
DescriptionWeight => localise(\%Lexicon, $description_weight),
MenuCat => (defined $menucat ? $menucat : 'A')
);
} ## end foreach my $file (@files)
#warn "trying to close for lang $lang\n";
my $navdb = $navdbs{$lang};
$navdb->close();
} ## end foreach my $lang (@langs)
sub localise {
my ($lexicon, $string) = @_;
#print("Looking up:".$string."\n");
$string = "" unless defined $string;
$string = "" unless defined $string;
my $lc_string = lc($string);
my $res = $lexicon->{$lc_string} || $string;
my $res = $lexicon->{$lc_string} || $string;
#print("Returning:".$res."\n");
return $res;
}
} ## end sub localise
# Subroutine to process localization
sub process_localization {
@@ -226,15 +215,17 @@ sub process_localization {
# Check the condition
if ($loc_heading eq $heading && $base_lang ne 'en') {
# Construct the new key by combining the prefix and the original heading
my $key = $prefix . $heading;
# Localize using the constructed key
$loc_heading = localise($lexicon_ref, $key);
# See if it got a hit
if ($loc_heading eq $key){
$loc_heading = $heading;
}
}
return $loc_heading; # Optionally return the localized heading
}
if ($loc_heading eq $key) {
$loc_heading = $heading;
}
} ## end if ($loc_heading eq $heading...)
return $loc_heading; # Optionally return the localized heading
} ## end sub process_localization

View File

@@ -0,0 +1,3 @@
#!/bin/bash
/usr/sbin/e-smith/signal-event post-upgrade
/usr/sbin/e-smith/signal-event reboot

View File

@@ -39,7 +39,18 @@
$OUT .= "# private access by default\n";
$OUT .= " Require ip $localAccess $externalSSLAccess\n";
}
$OUT .= " </Location>\n";
# any smanager script or style added in line should be hashed and added here to run in a modern browser
$OUT .= " Header set Content-Security-Policy \"script-src 'self' 'unsafe-eval' 'unsafe-hashes' "
." 'sha256-X8Qwlk0M9iDTQZqFVpbVcThRjBqQXpwTOZCLX8I+Frk=' 'sha256-inQ04nmqTZI75Z5g/tAzjahedNugPFfrhxHyoFezFkM=' 'sha256-5IsIX+Vbow7wwy2RjR3+5X06R/0CQZPkw3OHj/228cM=' 'sha256-tfVskwioRaNsV75h89itf7FujMgIrodfs1Ea4UAJNpE=' 'sha256-P51OyslUh5bGkoWk9qY+o4Su4HuwNFoQcFCeNxF7Ms8=' ; "
." style-src 'self' 'unsafe-hashes' "
#'sha256-EhT63KK1JBrsUM27H+5RMNifDFpVB+GXcTtavKXwCK8=' #h2l1
#'sha256-msdEhWmYTu7vqzGaQHDfvy6lzlDsbKkouwvN2R6Co9E=' #busy-indicator
#'sha256-iYwYhiMcsGmXCUzLEpEzZNz5dINrlkqf1sLbLhEcqGM=' _footer.html.ep style="position:relative;"
#'sha256-bOTFT8zacR4Rfja/WIKXgAQQXVaPyG3oBlvAhU4ga8g=' _usr_list style="min-width:35em"
#'sha256-CP93jJ1Y8nMwUoDzFbo1srdgsbADPasAc0Wjig1ahpY=' groups style="min-width:15em"
." 'sha256-msdEhWmYTu7vqzGaQHDfvy6lzlDsbKkouwvN2R6Co9E=' 'sha256-iYwYhiMcsGmXCUzLEpEzZNz5dINrlkqf1sLbLhEcqGM=' 'sha256-bOTFT8zacR4Rfja/WIKXgAQQXVaPyG3oBlvAhU4ga8g=' 'sha256-CP93jJ1Y8nMwUoDzFbo1srdgsbADPasAc0Wjig1ahpY=' 'sha256-EhT63KK1JBrsUM27H+5RMNifDFpVB+GXcTtavKXwCK8=' ;"
." \"\n";
$OUT .= " </Location>\n";
# prevent caching of manager files in browser
$OUT .= " <LocationMatch \"/$place/.+\.(html|cgi)\$\">\n";
$OUT .= " Header set Cache-Control no-store\n";

View File

@@ -1,250 +0,0 @@
{
$OUT = <<'EOF';
/* from e-smith-manager to smanager (smeserver_manager2) */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/* This is the stylesheet used as the basis for older broswers.
Note that you CANNOT simly add styles here and hope they work. ONLY CSS
level 1 styles should be in this file. Everyting else goes into the other 3
files.
These basic styles ensire that browsers that don't understand the @import
method will still be usable. All modern browsers will use the styles in
sme_main.css, sme_menu.css or sme_header.css depending on the frame in which
the page is found.
*/
/* Default HTML styles */
body {
background: #ffffff;
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
border-width: 0;
}
table, tr, td, div, p, form {
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
p {
margin-top: 8px;
margin-bottom: 2px;
}
form {
margin-top: 2px;
margin-bottom: 2px;
}
span {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
.notsmall {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
h1, .h1 {
font-family: Verdana, Arial, Helvetica, sans-serif;
color: #333333;
font-size: 18px;
margin-bottom: 4px;
margin-top: 12px;
}
h2, .h2 {
font-family: Verdana, Arial, Helvetica, sans-serif;
color: #333333;
font-size: 14px;
margin-bottom: 3px;
margin-top: 12px;
}
h3, .h3 {
font-family: Verdana, Arial, Helvetica, sans-serif;
color: #333333;
font-size: 12px;
margin-bottom: 2px;
margin-top: 12px;
}
h4, .h4 {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-style: italic;
color: #333333;
font-size: 12px;
margin-bottom: 2px;
margin-top: 10px;
}
ol, ul, li {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
font-weight: normal;
color: black;
}
ul {
list-style-type: circle;
}
/* Core styles for use with sme_header.css*/
body.header {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #cccccc;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
}
.hilightbar {
background-color: #ffc50a;
font-size: 4px;
}
.infobar {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background-color: #cccccc;
}
.darkergrey {
color: #666666;
}
td.darkgrey {
background-color: #888888;
}
a.update {
color: red;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #cccccc;
}
/* Core styles for use with sme_menu.css */
body.menu {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background-color: #e8f3e1;
}
td.section {
padding-bottom: 2px;
padding-top: 8px;
}
.section {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
font-weight: bold;
background-color: #e8f3e1;
}
a.item {
color: #00008b;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
a.sl {
color: green;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
a.alert {
color: red;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
/* Core styles for use with sme_main.css */
body.main {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background-color: #ffffff;
color: #000000;
}
td.sme-noborders-label {
font-weight: bold;
width: 33%;
text-align: right;
}
hr.sectionbar {
color: #666666;
background-color: #666666;
height: 1px;
width: 80%;
border: 0;
}
hr.sme-copyrightbar {
color: #dddddd;
background-color: #dddddd;
height: 1px;
width: 100%;
border: 0;
}
.sme-copyright {
color: #777777;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
}
/*These style definitions were found int he old css file (manager.css)
but don't seem to ever be referenced in the code. They're here
for reference.
.centerit {
text-align: center;
}
.highlight {
background: #ffc61e;
}
.subheading {
background: #ffffff;
color: #1e385b;
}
*/
EOF
}

View File

@@ -1,87 +0,0 @@
{
$OUT =<<'HERE';
/* from e-smith-manager to smanager (smeserver_manager2) */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/*contribs.org styling
*/
body.header {
background: #bee6a2;
}
.hilightbar {
background-color: #ffffff;
}
.infobar {
background-color: #98d36e;
}
a.update {
font-size: 11px;
background: #98d36e;
}
/* Core styles for use with sme_menu.css */
body.menu {
background-color: #e8f3e1;
}
td.section {
background-color: #e8f3e1;
}
a.item {
background: #e8f3e1;
}
a.sl {
background: #e8f3e1;
}
a.alert {
background: #e8f3e1;
}
/* Core Styles for use with sme_main.css */
hr.sectionbar {
color: #8ebe43;
background-color: #8ebe43;
}
hr.sme-copyrightbar {
color: #8ebe43;
background-color: #8ebe43;
}
/* flag container no flag */
#flag-container span {
font-size: 24px;
}
.fallback-box {
display: inline-block; /* Make it inline-block to fit around the content */
border: 2px solid gray; /* Change the border color as desired */
padding: 10px; /* Add some padding */
border-radius: 10px; /* Round the corners of the box */
font-size: 60px; /* Adjust size if needed */
margin-top: 10px; /* Add some margin */
text-align: center; /* Center text inside the box */
}
HERE
}

View File

@@ -1 +0,0 @@
/* DO NOT MODIFY THIS FILE! It is updated automatically */

View File

@@ -1,440 +0,0 @@
{
$OUT = <<'EOF';
/* from e-smith-manager to smanager (smeserver_manager2) */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/* This is the stylesheet used in the main panels only.
This file inherits the styles use in sme_core in the "header" section, and
as noted in the code below. Note that some of the styles here are empty.
This is because the style definition has moved safely to sme_core.css
and the placeholder is left here for reference or future use.
There are a lot of styles in here, so read carefully. Each one is documented.
Styles that were in the old stylesheets, but are not used in the UI are at the
bottom, commented out. These can be removed at the end of the 6.0 cycle */
/* general page properties */
body, body.main {
margin-top: 5px;
margin-right: 20px;
margin-bottom: 5px;
margin-left: 5px;
}
/* Table properties ****************************************/
/* There are THREE types of tables
1. *.sme-layout* is used for layout purposes. It is the "master
container" on a page. It controls the top-level table
inside of which everything else is put.
2. *.sme-noborders* is used for layout, and defines a borderless table and
cells used within it.
2. *.sme-border* is used for tabular data, and defines a header row and borders
for tables that need borders
*/
/*First, some defaults */
td {
text-align: left;
}
/*
sme-layout* : Used for top-level layout
*/
table.sme-layout {
border-collapse: collapse;
margin-bottom: 2px;
margin-top: 2px;
}
tr.sme-layout {
border: 1px solid #dddddd;
}
td.sme-layout {
border: 1px solid #dddddd;
}
/*This special style is actually used only for the button row along the bottom of each page*/
th.sme-layout {
border: 1px solid #dddddd;
background-color: #e8f3e1;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9pt;
font-weight: bold;
color: #000000;
text-align: right;
padding: 4px;
}
/*
sme-noborders* : Used for mid-level layout
*/
table.sme-noborders {
padding: 0px;
margin-top: 0px;
margin-bottom: 20px;
margin-left: 0px;
margin-right: 0px;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
td.sme-noborders-label {
font-weight: bold;
/*width: 250px;*/
text-align: right;
/*vertical-align: top;*/
background-color: #e8f3e1;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
td.sme-noborders-content {
text-align: left;
vertical-align: top;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
td.sme-noborders-info, div.sme-noborders-info {
text-align: left;
vertical-align: top;
}
/* Used for a left-most column of radio buttons (see date/time panel) */
td.sme-radiobutton {
width: 30px;
}
/*
sme-border* : Used for tabular data
*/
table.sme-border {
border-collapse: collapse;
border: 2px solid #cccccc;
empty-cells: show;
margin: 5px 5px 5px 2px;
}
td.sme-border,
td.sme-border-warning,
td.sme-border-right,
td.sme-border-center {
border: 1px solid #cccccc;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
font-weight: normal;
color: #000000;
text-align: left;
padding-left: 2px;
padding-right: 2px;
padding-top: 3px;
padding-bottom: 3px;
}
td.sme-border-warning {
color: red;
}
td.sme-border-right {text-align: right;}
td.sme-border-center {text-align: center;}
th.sme-border {
border: 1px solid #cccccc;
background-color: #bee6a2;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
font-weight: bold;
color: #000000;
text-align: center;
vertical-align: bottom;
padding-left: 2px;
padding-right: 2px;
padding-left: 3px;
padding-right: 3px;
padding-top: 3px;
padding-bottom: 3px;
/*border-width: 1px;
border-style: solid;
border-color: #F2F0EE #75736E #75736E #F2F0EE ;*/
}
td.sme-border a, td.sme-border-right a, td.sme-border-center a {
font-size: 10px;
}
/* misc layout stuff*/
/* these two are for any error messages that pop up*/
div.error, div.sme-error, span.error, span.sme-error {
color: red;
background-color: #ffffff;
border-width: 1px;
border-style: solid;
border-color: red ;
padding: 2px;
margin-left: 20px;
margin-right: 20px;
margin-top:0px;
margin-bottom:0px;
}
div.error-noborders, div.sme-error-noborders,
span.error-noborders, span.sme-error-noborders
{
color: red;
background-color: #ffffff;
border-width: 0px;
}
div.error h2, span.error h2,
div.error p, span.error p
{
color: red;
}
/* These are for the special case of a link being inside an error message */
div.sme-error a, div.error a, span.error a, span.sme-error a,
div.error-noborders a, div.sme-error-noborders a,
span.error-noborders a, span.sme-error-noborders a
{
color: #ff0000;
font-weight: bold;
text-decoration: underline;
}
/* For when a link is the error message */
a.error:link, a.error:visited, a.error:hover, a.error:active {
color: #ff0000;
font-weight: normal;
text-decoration: underline;
}
/* these two are for any success messages that pop up*/
div.success, span.success {
color: #006400;
background-color: #ffffff;
border-width: 1px;
border-style: solid;
border-color: #006400 ;
padding: 2px;
margin-left: 20px;
margin-right: 20px;
margin-top:0px;
margin-bottom:0px;
}
/* These two are for the special case of a link being inside a success message */
div.success a, span.success a
{
color: #006400;
font-weight: bold;
text-decoration: underline;
}
div.success h2, span.success h2,
div.success p, span.success p
{
color: green;
}
/*These two define the copyright footer styles, one for the line and one for the text*/
hr.sme-copyrightbar {
}
.sme-copyright {
}
/* These ones define styles for the links that are made to look like
standard form submit buttons */
a.button-like:link,
a.button-like:visited,
a.button-like:hover,
a.button-like:active,
a.button-like-small:link,
a.button-like-small:visited,
a.button-like-small:hover,
a.button-like-small:active {
font-family: sans-serif;
font-size: 13px;
color: black;
background: #D4D0C8;
text-decoration: none;
text-align: left;
border-color: #F2F0EE #75736E #75736E #F2F0EE ;
margin-top: 10px;
margin-right: 2px;
margin-bottom: 10px;
margin-left: 2px;
border-style: solid;
border-top-width: 2px;
border-right-width: 2px;
border-bottom-width: 2px;
border-left-width: 2px;
padding-top: 2px;
padding-bottom: 2px;
padding-left: 6px;
padding-right: 6px;
}
a.button-like-small:link,
a.button-like-small:visited,
a.button-like-small:hover,
a.button-like-small:active {
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
font-size: 10px;
padding-top: 0px;
padding-bottom: 0px;
padding-left: 1px;
padding-right: 1px;
}
a.button-like:active,
a.button-like-small:active {
border-color: #75736E #F2F0EE #F2F0EE #75736E ;
}
/* EXPERIMENTAL SECTION */
/* These are styles used to experiment with. */
/* class for links, similar to the class in sme_menu.css, but for a red button */
a.button-like-red:link,
a.button-like-red:visited,
a.button-like-red:hover,
a.button-like-red:active {
border-left: #F1726C 2px solid;
border-right: #B42025 2px solid;
border-top: #F1726C 2px solid;
border-bottom: #B42025 2px solid;
}
a.button-like-red:active {
border-color: #75736E #F2F0EE #F2F0EE #75736E ;
}
/*These are style definitions found in the UI but not defined in any file I
could locate. They're listed here for historical purposes, but have been
removed from the UI
pagedescription (used in the first paragraph of text on a page) [HTML.pm]
label (used in forms) [HTML.pm]
field (used in forms) [HTML.pm]
fielddescription (used ???)[HTML.pm]
buttons (used in forms) [HTML.pm]
*/
/*td.sme-submitbutton {
text-align: right;
}
*/
/*These style definitions were found int he old css file (manager.css)
but don't seem to ever be referenced in the code. They're here
for reference.
.banner {
background: #000000;
color: #ffffff;
}
.banner-right {
font-family: Verdana, Arial, Helvetica, sans-serif;
background: #e17200;
color: #ffffff;
}
.border {
background: #000000;
color: #000000;
border-color: #000000;
}
.sidebar {
width: 200px;
background: #ffffff;
font-size: smaller;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: normal;
}
.sidebar-title {
background: #1e385b;
color: #ffffff;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: bold;
}
.newsitem {
background: #ffffff;
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
margin-left: 5px;
margin-right: 5px;
margin-top: 5px;
margin-bottom: 5px;
}
.newsitem-title {
background: #cccccc;
color: #ffffff;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: bold;
}
.newsitem-footer {
background: #cccccc;
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: smaller;
text-align: right;
}
.newsitem-detail {
font-size: smaller;
font-weight: normal;
}
.formlabel {
background: #c0c0c0;
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: small;
font-weight: bold;
text-align: right;
}
.welcome-link {
background: #ffffff;
color: #1e385b;
}
.littlelink {
font-family: Verdana, Arial, Helvetica, sans-serif;
}
#textlayer {
position: absolute;
visibility: inherit;
top: 160px;
left: 50px;
z-index: 2;
}
#para {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: bold;
color: #000000;
}
#title {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: bold;
padding: 7px 7px 7px 7px;
color: #ffffff;
}
*/
EOF
}

View File

@@ -1,50 +0,0 @@
{
$OUT =<<'HERE';
/* from e-smith-manager to smanager (smeserver_manager2) */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/*contribs.org styling */
/* This special style is actually used only for the button row along the bottom of each page */
th.sme-layout {
border: 1px solid #8ebe43;
background-color: #bee6a2;
}
table.sme-border {
border: 2px solid #dddddd;
}
td.sme-border-warning,
td.sme-border-right,
td.sme-border-center {
border: 1px solid #dddddd;
}
td.sme-border-right {text-align: right;}
td.sme-border-center {text-align: center;}
th.sme-border {
border: 1px solid #dddddd;
background-color: #e8f3e1;
}
HERE
}

View File

@@ -1 +0,0 @@
/* DO NOT MODIFY THIS FILE! It is updated automatically */

View File

@@ -1,229 +0,0 @@
{
$OUT = <<'EOF';
/* from e-smith-manager to smanager (smeserver_manager2) */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/* This is the stylesheet used in the navigation panel only
This file inherits the styles use in sme_core in the "navigation" section,
and as noted in the code below. Note that some of the styles here are empty.
This is because the style definition has moved safely to sme_core.css and
the placeholder is left here for reference or future use.
There are a lot of styles in here, so read carefully. Each one is
documented.
Styles that were in the old stylesheets, but are not used in the UI are at
the bottom, commented out. These can be removed at the end of the 6.0
cycle */
/* Sets the general page properties */
body, body.menu {
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 2px;
}
/* This is the section heading style */
.section {
}
td.menu-cell {
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
padding-bottom: 0px;
}
/*
All the a links use pseudoclasses to control the two visual link styles.
For example:
a.item:link the general link item
a.item-current:link: the active link item
The switch from item to item-current is done with a javascript script in the head of the
navigation page, using the onClick event.
We are making heavy use of the cascade with these.
*/
/* a:link controls the look of a link when the mouse is nowhere near it */
a.item:link, a.item-current:link,
a.warn:link, a.warn-current:link {
display: block;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
color: black;
background: #e8f3e1;
text-decoration: none;
text-align: left;
border-color: #e8f3e1;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
border-style: solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-top: 0px;
padding-bottom: 2px;
}
/* a:visited controls the look of a visited link (one that has been clicked) */
a.item:visited, a.item-current:visited,
a.warn:visited, a.warn-current:visited {
display: block;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
color: black;
background: #e8f3e1;
text-decoration: none;
border-color: #e8f3e1;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
border-style: solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
/* a:hover controls the look of a link under the curser*/
a.item:hover, a.item-current:hover,
a.warn:hover, a.warn-current:hover {
display: block;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
color: black;
text-decoration: none;
background: #cccccc;
border-color: #888888;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
border-style: solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
/* a:active controls the look of a link as it is selected*/
a.item:active, a.item-current:active,
a.warn:active, a.warn-current:active {
display: block;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
color: white;
background: black;
text-decoration: none ;
border-color: #000000;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
border-style: solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
/*
These styles are to ensure that a selected link appears selected, even if the link
opens in another frame. This uses a javascript chunk in the head of the navigation
frame to change the style using the onClick event.
*/
a.item-current:link, a.warn-current:link,
a.item-current:visited, a.warn-current:visited,
a.item-current:active, a.warn-current:active,
a.item-current:hover, a.warn-current:hover {
display: block;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
color: black;
text-decoration: none;
background: #ffffff;
border-color: #888888;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
border-style: solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
/* these two add a border on the styles defined directly above when
the mouse is hovering over them */
a.item-current:hover, a.warn-current:hover {
border-color: #888888;
}
/* These redefine a few elements to make room for the icon to the left of the warn class*/
a.warn:link, a.warn-current:link,
a.warn:visited, a.warn-current:visited,
a.warn:active, a.warn-current:active,
a.warn:hover, a.warn-current:hover {
background-image: url(/server-common/warn.gif);
background-repeat: no-repeat;
background-position: 10px;
padding-left: 25px;
}
/*end*/
EOF
}

View File

@@ -1 +0,0 @@
/* DO NOT MODIFY THIS FILE! It is updated automatically */

View File

@@ -1,279 +0,0 @@
{
$OUT = <<'EOF';
/* smeserver_manager2 */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/* This is the basic stylesheet originally used in the mojo version.
*/
body{
background-color: #FFF;
}
#container{
max-width: 100%;
position: relative;
margin: auto;
}
#navigation{
width: 190px;
position: absolute;
margin-left: 0px;
padding: 5px;
background-color: #E8F3E1;
/* height: 600px; */
overflow: auto;
}
#main{
margin-left: 195px;
padding: 10px;
}
#central{
margin-left: 0px;
padding: 5px;
}
#footer{
margin-left: 0px;
padding: 5px;
}
#header {
background: #bee6a2;
}
#header h1, a:link, a:visited {
color: black;
text-decoration: none;
/* contribs.org styling */
}
a:link { color: #006921; text-decoration: none; }
a:visited { color: #063; text-decoration: none; }
a:hover { color: #F00; text-decoration: none; }
a:active { color: #606060; text-decoration: none; }
.sme-error {
color: red;
background-color: #ffffff;
border-width: 1px;
border-style: solid;
border-color: red ;
padding: 2px;
margin-left: 10px;
margin-right: 10px;
margin-top:0px;
margin-bottom:0px;
}
.sme-warning {
color: orange;
background-color: #ffffff;
border-width: 1px;
border-style: solid;
border-color: orange ;
padding: 4px;
margin-left: 20px;
margin-right: 20px;
margin-top:2px;
margin-bottom:2px;
}
#footer img {
float: right;
position: fixed;
margin-left: 40%;
}
label.field-with-error {
color: #dd7e5e
}
input.field-with-error {
background-color: #fd9e7e
}
span.label {
display: inline-block;
font-weight: bold;
background-color: #e8f3e1; /*lightgreen;*/
width: 30%;
text-align: right;
}
td.label {
font-weight: bold;
background-color: #e8f3e1; /*lightgreen;*/
width: 30%;
text-align: right;
}
span.label2 {
display: inline-block;
font-weight: bold;
background-color: #e8f3e1; /*lightgreen;*/
text-align: right;
}
span.data {
padding: 2px;
font-weight: bold;
margin-left: 0%;
/* background-color: lightblue;*/
}
span.data2 {
padding: 2px;
/* background-color: lightblue; */
}
input.action {
margin-left: 0px;
background-color: #bee6a2; /*lightgreen;*/
color: darkgreen;
border-radius: 8px;
border: 2px solid #4CAF50; /* Green */
display: flex;
justify-content: center;
align-items: center;
}
input.action:hover {background-color: #3e8e41; color:white;}
input.action:active {
background-color: #3e8e41;
transform: translate(-2px,2px);
}
.center {
display: flex;
justify-content: center;
}
input.action2 {
margin-left: 0px;
color: black;
background-color: #d4d0c8;
display: flex;
justify-content: center;
}
#modul.desc {
padding: 3px;
background-color: grey;
}
[type = 'text'] {
margin-left: 0px;
/*background-color: lightblue;*/
}
.a, .return {
color: #661866;
font-weight: bold;
}
a.section {
}
.a, .item {
line-height: 12px;
}
a.section-title {
display: inline-block;
color: #6CA345; /*#888;*/
padding-left: 5px;
padding-right: 5px;
line-height: 18px;
font-weight: bold;
}
a.menu-title {
display: inline-block;
color: #1A6D1A; /*#666;*/
padding-left: 1px;
padding-right: 1px;
font-weight: bold;
}
#module {
/* height: 600px; */
overflow: auto;
}
#h2l1 {
height: 40px;
width: 100%;
}
#h2e11 {
width: 50%;
float: left;
}
#h2e12 {
background-color: #C0E7A6;
float: left;
text-align: right;
}
#h2l2 {
/* background-color: #A8F9E7;*/
border-top: solid white 3px;
border-bottom: solid white 2px;
height: 14px;
width: 100%;
padding: 1px;
}
#h2e21 {
float: left;
width: 70%;
}
#h2e22,#h2e23,#h2e12 {
float: left;
width: 14em;
text-align: center;
}
.toggle-password {
margin-left: -30px;
}
.tg-icon {
position: relative;
top: 5px;
left: 2px;
}
/*end*/
EOF
}

View File

@@ -1 +0,0 @@
/* DO NOT MODIFY THIS FILE! It is updated automatically */

View File

@@ -0,0 +1,9 @@
[Unit]
Description=Koozali SME Server boot diagnostic tool
After=sme-server.target
PartOf=sme-server.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c "/usr/bin/systemd-analyze plot > /usr/share/smanager/themes/default/public/images/boot.svg"
RemainAfterExit=yes

View File

@@ -1,7 +1,7 @@
[Unit]
Description=Server Manager 2 Mojo
Requires=network.target httpd-e-smith.service ldap.service
After=network.target
Requires=network-online.target httpd-e-smith.service ldap.service
After=network-online.target
[Service]
Type=simple

View File

@@ -4,6 +4,7 @@ package SrvMngr;
use strict;
use warnings;
use utf8;
binmode(STDOUT);
use Mojo::Base 'Mojolicious';
@@ -17,6 +18,7 @@ use Mojo::Home;
use DBM::Deep;
use Mojo::JWT;
use POSIX qw(strftime);
use Mojolicious::Plugin::Config;
#use Mojolicious::Plugin::I18N;
@@ -27,8 +29,15 @@ use SrvMngr::Model::Main;
use SrvMngr::Plugin::WithoutCache;
use esmith::I18N;
use esmith::ConfigDB::UTF8;
use esmith::NavigationDB; # no UTF8 raw is ok for ASCII only flat file
# Import the function(s) you need
use SrvMngr_Auth qw(check_admin_access);
#this is overwrittrn with the "release" by the spec file - release can be "99.el8.sme"
our $VERSION = '';
our $VERSION = '94.el8.sme';
#Extract the release value
if ($VERSION =~ /^(\d+)/) {
$VERSION = $1; # $1 contains the matched numeric digits
@@ -40,9 +49,10 @@ $VERSION = eval $VERSION;
use Exporter 'import';
our @EXPORT_OK = qw(
init_session get_mod_url theme_list
getNavigation ip_number is_normal_password email_simple
getNavigation ip_number validate_password is_normal_password email_simple
mac_address_or_blank mac_address ip_number_or_blank
lang_space get_routes_list subnet_mask get_reg_mask
gen_locale_date_string get_public_ip_address simpleNavMerge
);
has home => sub {
@@ -208,6 +218,22 @@ sub setup_helpers {
Mojo::JWT->new(secret => shift->app->secrets->[0] || die)
});
$self->helper( selected_field => sub {
my $self = shift;
my @options = shift;
my $selected = shift;
my $count = 0;
# search for occurence of value $selected in arrays; if found add selected => 'selected'
for (my $i = 0; $i <= $#{$options[0]} ; $i++){
if (grep /^$selected$/, @{$options[0][$i]}) {
push( @{$options[0][$i]} ,'selected', 'selected' );
$count++;last;
}
}
push ( @{$options[0]} ,[ ucfirst( $selected), $selected, 'selected', 'selected'] ) if ($count <1);
return @options;
});
}
@@ -224,12 +250,12 @@ sub setup_plugins {
# CSRF protection if production mode
# $self->plugin('Mojolicious::Plugin::CSRFDefender' => {
# Adapted plugin for use with GET method
$self->plugin('SrvMngr::Plugin::CSRFDefender' => {
onetime => 1,
error_status => 400,
error_content => 'Error: CSRF token is invalid or outdated'
#$self->plugin('SrvMngr::Plugin::CSRFDefender' => {
#onetime => 1,
#error_status => 400,
#error_content => 'Error: CSRF token is invalid or outdated'
#error_template => 'csrf_400'
}) if ( $self->mode eq 'production' );
#}) if ( $self->mode eq 'production' );
$self->plugin('SrvMngr::Plugin::I18N' => {namespace => 'SrvMngr::I18N', default => 'en'});
@@ -281,10 +307,11 @@ sub setup_routing {
$if_logged_in->get('/userpassword')->to('userpassword#main')->name('passwd');
$if_logged_in->post('/userpassword')->to('userpassword#change_password')->name('passwd2');
my $if_admin = $r->under( sub {
my $c =shift;
return $c->is_admin || $c->auth_fail($c->l("acs_ADMIN"));
});
my $if_admin = $r->under( sub {
my $c = shift;
# Call the imported function directly
return check_admin_access($c) || $c->auth_fail($c->l("acs_ADMIN"));
});
$if_admin->get('/backup')->to('backup#main')->name('backup');
$if_admin->post('/backup')->to('backup#do_display')->name('backupd');
@@ -299,7 +326,10 @@ sub setup_routing {
$if_admin->post('/clamav')->to('clamav#do_update')->name('clamav2');
$if_admin->get('/datetime')->to('datetime#main')->name('datetime');
$if_admin->post('/datetime')->to('datetime#do_update')->name('datetime2');
$if_admin->post('/datetimeu')->to('datetime#do_update')->name('datetimeu');
$if_admin->get('/datetimed')->to('datetime#do_display')->name('datetimed');
$if_admin->post('/datetimet')->to('datetime#do_testntp')->name('datetimet');
$if_admin->get('/directory')->to('directory#main')->name('directory');
$if_admin->post('/directory')->to('directory#do_update')->name('directory2');
@@ -394,28 +424,59 @@ sub setup_routing {
# additional routes (for contribs) got from 'routes' db
#my @routes = @{SrvMngr::get_routes_list()};
foreach (@{SrvMngr::get_routes_list()}) {
if ( defined $_->{method} and defined $_->{url} and defined $_->{ctlact} and defined $_->{name} ) {
my $menu = defined $_->{menu} ? $_->{menu} : 'A';
if ( $menu eq 'N' ) {
$r->get($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'get');
$r->post($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'post');
} elsif ( $menu eq 'U' ) {
$if_logged_in->get($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'get');
$if_logged_in->post($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'post');
} else {
$if_admin->get($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'get');
$if_admin->post($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'post');
}
#foreach (@{SrvMngr::get_routes_list()}) {
#if ( defined $_->{method} and defined $_->{url} and defined $_->{ctlact} and defined $_->{name} ) {
#my $menu = defined $_->{menu} ? $_->{menu} : 'A';
#if ( $menu eq 'N' ) {
#$r->get($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'get');
#$r->post($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'post');
#} elsif ( $menu eq 'U' ) {
#$if_logged_in->get($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'get');
#$if_logged_in->post($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'post');
#} else {
#$if_admin->get($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'get');
#$if_admin->post($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'post');
#}
#}
#}
foreach my $route (@{SrvMngr::get_routes_list()}) {
if (defined $route->{method} && defined $route->{url} && defined $route->{ctlact} && defined $route->{name}) {
my $menu = defined $route->{menu} ? $route->{menu} : 'A';
# Fix controller case: convert "ControllerName" to "controllername" in "ControllerName#action"
# this is so that AdminLTE breadcrumb works - it appears that perl Packages names are NOT case sensitive
# and that the breadcrumb package assumes that the package name is the same as the main route.
my ($controller, $action) = split /#/, $route->{ctlact}, 2;
my $fixed_ctlact = lc($controller) . '#' . $action;
if ($menu eq 'N') {
$r->get($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'get';
$r->post($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'post';
}
elsif ($menu eq 'U') {
$if_logged_in->get($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'get';
$if_logged_in->post($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'post';
}
else { # Default: menu 'A'
$if_admin->get($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'get';
$if_admin->post($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'post';
}
}
}
}
$if_admin->get('/config/:key' => {key => qr/[a-z0-9]{2,32}/})->to('request#getconfig')->name('getconfig');
$if_admin->get('/account/:key' => {key => qr/[a-z0-9]{2,32}/})->to('request#getaccount')->name('getaccount');
@@ -526,12 +587,10 @@ sub theme_list {
#------------------------------------------------------------
sub getNavigation {
use esmith::NavigationDB;
my $c = shift;
my $class = shift; #not the controller as it is called as an external, not part of the controller.
my $lang = shift || 'en-us';
my $menu = shift || 'N';
my $username = shift || ''; #Username when logged in as a user not admin
# my $lang = $c->session->{lang} || 'en-us';
@@ -540,13 +599,33 @@ sub getNavigation {
my @files = ();
my %files_hash = ();
# Added: Store allowed admin panels for non-admin users
my @allowed_admin_panels = ();
my $is_admin = 1; # Default to admin (full access)
# Added: Check if user is non-admin and get their allowed panels
if ($username ne '') {
# Get the AccountsDB to check user permissions
my $accountsdb = esmith::AccountsDB::UTF8->open_ro() or
die "Couldn't open AccountsDB\n";
# Check if user has AdminPanels property
my $user_rec = $accountsdb->get($username);
if (defined $user_rec && $user_rec->prop('AdminPanels')) {
$is_admin = 0; # User is non-admin with specific panel access
# Get comma-separated list of allowed admin panels
my $admin_panels = $user_rec->prop('AdminPanels');
@allowed_admin_panels = split(/,/, $admin_panels);
}
}
#-----------------------------------------------------
# Determine the directory where the functions are kept
#-----------------------------------------------------
my $navigation_ctlr_ignore =
"(\.\.?|Swttheme\.pm|Login\.pm|Request\.pm|Modules\.pm|Legacypanel\.pm(-.*)?)";
# "(\.\.?|Initial\.pm|Manual\.pm|Swttheme\.pm|Request\.pm|Modules\.pm(-.*)?)";
"(\.\.?|.*\-Custom\.pm|Swttheme\.pm|Login\.pm|Request\.pm|Modules\.pm|Legacypanel\.pm(-.*)?)";
# "(\.\.?|Initial\.pm|.*Manual\.pm|Swttheme\.pm|Request\.pm|Modules\.pm(-.*)?)";
my $navigation_cgi_ignore =
"(\.\.?|navigation|noframes|online-manual|(internal|pleasewait)(-.*)?)";
@@ -601,8 +680,7 @@ sub getNavigation {
my $navinfo = NAVIGATIONDIR . "/navigation.$lang";
my $navdb = esmith::NavigationDB->open_ro( $navinfo ) or
die "Couldn't open $navinfo\n";
my $navdb = esmith::NavigationDB->open_ro( $navinfo ) or die "Couldn't open $navinfo\n"; # no UTF8
# Check the navdb for anything with a UrlPath, which means that it doesn't
# have a cgi file to be picked up by the above code. Ideally, only pages
@@ -618,70 +696,110 @@ sub getNavigation {
}
foreach my $file (keys %files_hash)
{
#my $heading = 'Unknown';
my $heading = 'Legacy';
my $description = $file;
my $headingWeight = 99999;
my $descriptionWeight = 99999;
my $urlpath = '';
my $menucat = 'A'; # admin menu (default)
{
#my $heading = 'Unknown';
my $heading = 'Legacy';
my $description = $file;
my $headingWeight = 99999;
my $descriptionWeight = 99999;
my $urlpath = '';
my $menucat = 'A'; # admin menu (default)
my $rec = $navdb->get($file);
my $rec = $navdb->get($file);
if (defined $rec)
{
$heading = $rec->prop('Heading');
$description = $rec->prop('Description');
$headingWeight = $rec->prop('HeadingWeight') || 99999; #Stop noise in logs if file in dir does not have nav header.
$descriptionWeight = $rec->prop('DescriptionWeight');
$urlpath = $rec->prop('UrlPath') || '';
$menucat = $rec->prop('MenuCat') || 'A'; # admin menu (default)
}
next if $menu ne $menucat;
if (defined $rec)
{
$heading = $rec->prop('Heading');
$description = $rec->prop('Description');
$headingWeight = $rec->prop('HeadingWeight') || 99999; #Stop noise in logs if file in dir does not have nav header.
$descriptionWeight = $rec->prop('DescriptionWeight');
$urlpath = $rec->prop('UrlPath') || '';
$menucat = $rec->prop('MenuCat') || 'A'; # admin menu (default)
}
# Added: Check if this is an admin menu item and if user has access
if ($menucat eq 'A' && !$is_admin) {
# Skip this admin panel if user doesn't have access to it
my $has_access = 0;
my $file_no_ext = $file;
$file_no_ext =~ s/\.pm$//; # Remove .pm extension if present
foreach my $allowed_panel (@allowed_admin_panels) {
if ($file_no_ext eq lc($allowed_panel)) {
#die("Here!!$file $file_no_ext $allowed_panel ");
$has_access = 1;
last;
}
}
next if !$has_access;
}
#--------------------------------------------------
# add heading, description and weight information to data structure
#--------------------------------------------------
next if $menu ne $menucat;
unless (exists $nav {$heading})
{
$nav {$heading} = { COUNT => 0, WEIGHT => 0, DESCRIPTIONS => [] };
}
#--------------------------------------------------
# add heading, description and weight information to data structure
#--------------------------------------------------
$nav {$heading} {'COUNT'} ++;
$nav {$heading} {'WEIGHT'} += $headingWeight;
unless (exists $nav {$heading})
{
$nav {$heading} = { COUNT => 0, WEIGHT => 0, DESCRIPTIONS => [] };
}
# Check for manager panel, and assign the appropriate
# cgi-bin prefix for the links.
# Grab the last 2 directories by splitting for '/'s and
# then concatenating the last 2
# probably a better way, but I don't know it.
$nav {$heading} {'COUNT'} ++;
$nav {$heading} {'WEIGHT'} += $headingWeight;
my $path;
if ( $files_hash{$file} eq 'ctrl') {
$path = "2";
} elsif ( $files_hash{$file} eq 'cgim') {
$path = "/cgi-bin";
} else {
my @filename = split /\//, $files_hash{$file};
$path = "/$filename[scalar @filename - 2]/$filename[scalar @filename - 1]";
};
# Check for manager panel, and assign the appropriate
# cgi-bin prefix for the links.
# Grab the last 2 directories by splitting for '/'s and
# then concatenating the last 2
# probably a better way, but I don't know it.
push @{ $nav {$heading} {'DESCRIPTIONS'} },
{ DESCRIPTION => $description,
WEIGHT => $descriptionWeight,
FILENAME => $urlpath ? $urlpath : "$path/$file",
CGIPATH => $path,
MENUCAT => $menucat
my $path;
if ( $files_hash{$file} eq 'ctrl') {
$path = "2";
} elsif ( $files_hash{$file} eq 'cgim') {
$path = "/cgi-bin";
} else {
my @filename = split /\//, $files_hash{$file};
$path = "/$filename[scalar @filename - 2]/$filename[scalar @filename - 1]";
};
push @{ $nav {$heading} {'DESCRIPTIONS'} },
{ DESCRIPTION => $description,
WEIGHT => $descriptionWeight,
FILENAME => $urlpath ? $urlpath : "$path/$file",
CGIPATH => $path,
MENUCAT => $menucat
};
}
return \%nav;
}
sub simpleNavMerge {
#Used to merge two nav structures - used for the user and selected admin menu.
my ($class,$nav1, $nav2) = @_;
my %result = %$nav1; # Start with a copy of first nav
# Merge in second nav
foreach my $heading (keys %$nav2) {
if (exists $result{$heading}) {
# Add counts and weights
$result{$heading}{COUNT} += $nav2->{$heading}{COUNT};
$result{$heading}{WEIGHT} += $nav2->{$heading}{WEIGHT};
# Append descriptions
push @{$result{$heading}{DESCRIPTIONS}}, @{$nav2->{$heading}{DESCRIPTIONS}};
} else {
# Just copy the heading
$result{$heading} = $nav2->{$heading};
}
}
return \%result;
}
sub _lang_space {
@@ -729,7 +847,7 @@ sub get_routes_list {
my $c = shift;
my $rtdb = esmith::ConfigDB->open_ro('routes') || die 'Cannot open Routes db';
my $rtdb = esmith::ConfigDB::UTF8->open_ro('routes') || die 'Cannot open Routes db';
my @routes = $rtdb->get_all();
my @rt;
@@ -768,7 +886,23 @@ sub ip_number {
return 'OK';
}
sub validate_password {
my ($c, $strength, $pass) = @_;
use esmith::util;
use POSIX qw(locale_h);
use locale;
my $old_locale = setlocale(LC_ALL);
setlocale(LC_ALL, "en_US");
my $reason = esmith::util::validatePassword($pass,$strength);
return "OK" if ($reason eq "ok");
setlocale(LC_ALL, $old_locale);
return
$c->l("Bad Password Choice") . ": "
. $c->l("The password you have chosen is not a good choice, because") . " "
. $c->l($reason). ".";
} ## end sub validate_password
# to deprecate : this is not anymore a way to validate our passwords
sub is_normal_password {
# from CGI::FormMagick::Validator qw( password );
@@ -784,6 +918,29 @@ sub is_normal_password {
}
}
sub gen_locale_date_string
{
my $self = shift;
my $i18n = esmith::I18N->new();
$i18n->setLocale('formmagick', $i18n->preferredLanguage());
return strftime "%c", localtime;
}
sub get_public_ip_address
{
my $self = shift;
my $cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $sysconfig = $cdb->get('sysconfig');
if ($sysconfig)
{
my $publicIP = $sysconfig->prop('PublicIP');
if ($publicIP)
{
return $publicIP;
}
}
return undef;
}
sub email_simple {
my ($c, $data) = @_;
@@ -866,4 +1023,4 @@ sub get_reg_mask {
}
1;
1;

View File

@@ -0,0 +1 @@
*.tdy

View File

@@ -0,0 +1 @@
-pbp -nst -nse -l=120 -ce -csc -pt=2 -kbl=0 -mbl=1 -lbl=1

File diff suppressed because it is too large Load Diff

View File

@@ -3,173 +3,175 @@ package SrvMngr::Controller::Bugreport;
#----------------------------------------------------------------------
# heading : Investigation
# description : Report a bug
# navigation : 7000 500
# navigation : 7000 300
# routes : end
#------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use Text::Template;
use File::Basename;
use esmith::FormMagick qw( gen_locale_date_string );
use SrvMngr qw( gen_locale_date_string );
use esmith::ConfigDB::UTF8;
our $cdb = esmith::ConfigDB::UTF8->open or die "Couldn't open ConfigDB\n";
our $cdb = esmith::ConfigDB->open or die "Couldn't open ConfigDB\n";
use constant FALSE => 0;
use constant TRUE => 1;
# Get some basic info on the current SME install
our $sysconfig = $cdb->get('sysconfig');
our $systemmode = $cdb->get('SystemMode')->value;
our $sysconfig = $cdb->get('sysconfig');
our $systemmode = $cdb->get('SystemMode')->value;
our $previoussystemmode = $sysconfig->prop('PreviousSystemMode');
our $releaseversion = $sysconfig->prop('ReleaseVersion');
our $releaseversion = $sysconfig->prop('ReleaseVersion');
# Prepare some filehandles for templates and reports
our $templatefile = '/tmp/bugreport_template.txt';
our $templatefile = '/tmp/bugreport_template.txt';
our $configreportfile = '/tmp/configreport.txt';
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %bugr_datas = ();
my $title = $c->l('bugr_FORM_TITLE');
my $modul = $c->render_to_string( inline => $c->l('bugr_DESCRIPTION'));
my $title = $c->l('bugr_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('bugr_DESCRIPTION'));
$bugr_datas{'trt'} = 'SHOW';
$c->stash(title => $title, modul => $modul, bugr_datas => \%bugr_datas);
$c->render(template => 'bugreport');
};
} ## end sub main
sub do_report {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('bugr_FORM_TITLE');
my $trt = $c->param('trt') || 'SHOW';
my $title = $c->l('bugr_FORM_TITLE');
my $trt = $c->param('trt') || 'SHOW';
my %bugr_datas = ();
$bugr_datas{'trt'} = $trt;
if ( $trt eq 'SHOW' ) {
create_configuration_report();
if ($trt eq 'SHOW') {
create_configuration_report();
my $out = $c->render_to_string(inline => show_config_report());
$bugr_datas{'trt'} = 'DOWN';
$c->stash(title => $title, modul => $out, bugr_datas => \%bugr_datas);
$c->render(template => 'bugreport2');
} ## end if ($trt eq 'SHOW')
$bugr_datas{'trt'} = 'DOWN';
$c->stash(title => $title, modul => $out, bugr_datas => \%bugr_datas);
$c->render(template => 'bugreport2');
}
if ( $trt eq 'DOWN' ) {
my $modul = 'Bug report download';
# $c->render_file(
# 'filepath' => "$configreportfile",
# 'format' => 'x-download',
# 'content_disposition' => 'attachment',
# 'cleanup' => 1,
# );
# the following in this sub will not be used !!!
# $bugr_datas{'trt'} = 'DOWN';
# $c->stash(title => $title, modul => $modul, bugr_datas => \%bugr_datas);
# $c->render(template => 'bugreport');
}
};
if ($trt eq 'DOWN') {
my $modul = 'Bug report download';
# $c->render_file(
# 'filepath' => "$configreportfile",
# 'format' => 'x-download',
# 'content_disposition' => 'attachment',
# 'cleanup' => 1,
# );
# the following in this sub will not be used !!!
# $bugr_datas{'trt'} = 'DOWN';
# $c->stash(title => $title, modul => $modul, bugr_datas => \%bugr_datas);
# $c->render(template => 'bugreport');
} ## end if ($trt eq 'DOWN')
} ## end sub do_report
sub create_configuration_report {
my $c = shift;
# TBD: possibly check $q for a boolean value eg. from a checkbox
# indicating the user has read privacy warning etc.
# create the reporting template
my $configreport_template = Text::Template->new(TYPE => 'FILE', SOURCE => '/etc/e-smith/web/common/configuration_report.tmpl', UNTAINT => 1);
my $configreport_template = Text::Template->new(
TYPE => 'FILE',
SOURCE => '/usr/share/smanager/themes/default/public/configuration_report.tmpl',
UNTAINT => 1
);
my $report_creation_time = gen_locale_date_string;
# curent kernel
my $curkernel = `uname -r`;
# get additional RPMs
my @newrpms = `/sbin/e-smith/audittools/newrpms`;
# get additional Repositories
my @repositories = `/sbin/e-smith/audittools/repositories`;
#print @repositories;
#print @repositories;
# get templates
my @templates = `/sbin/e-smith/audittools/templates`;
# get events
my @events = `/sbin/e-smith/audittools/events`;
# set template variables
my %vars = (report_creation_time => \$report_creation_time,
releaseversion => \$releaseversion,
curkernel => \$curkernel,
systemmode => \$systemmode,
previoussystemmode => \$previoussystemmode,
newrpms => \@newrpms,
templates => \@templates,
events => \@events,
repositories => \@repositories,
);
my %vars = (
report_creation_time => \$report_creation_time,
releaseversion => \$releaseversion,
curkernel => \$curkernel,
systemmode => \$systemmode,
previoussystemmode => \$previoussystemmode,
newrpms => \@newrpms,
templates => \@templates,
events => \@events,
repositories => \@repositories,
);
# prcess template
my $result = $configreport_template->fill_in(HASH => \%vars);
#take out any multiple blank lines
#$result =~ s/\n{3,}/\n/g;
# write processed template to file
open (my $cfgrep, '>', $configreportfile) or die "Could not create temporary file for config report!";
open(my $cfgrep, '>', $configreportfile) or die "Could not create temporary file for config report!";
print $cfgrep $result;
close $cfgrep;
}
#check if boot phase has completed.
if (wait_for_boot_completion()) {
#And create boot analysis image - now run externally following boot.
$result = `/usr/bin/systemctl start bootsequence.service`;
if (!$? == 0) {
warn "/usr/bin/systemd-analyze plot Command failed \n";
}
}
} ## end sub create_configuration_report
sub wait_for_boot_completion {
my $timeout = 60; # 1-minute timeout
my $end_time = time() + $timeout;
while (time() < $end_time) {
if (`systemctl list-jobs 2>&1` =~ /No jobs running/) {
return TRUE; # Success
}
sleep 5;
}
warn "Boot did not complete within $timeout seconds.\n";
return FALSE; # Failure
} ## end wait_for_boot_completion
sub show_config_report {
my $c = shift;
my $c = shift;
my $out = '';
$out .= sprintf "<PRE>";
open (my $cfgrep, '<', $configreportfile) or die "Could not find temporary config report file!";
open(my $cfgrep, '<', $configreportfile) or die "Could not find temporary config report file!";
while (<$cfgrep>) {
$out .= sprintf("%s", $_);
$out .= sprintf("%s", $_);
}
$out .= sprintf "</PRE>";
return $out;
}
} ## end sub show_config_report
sub download_config_report {
my $c = shift;
$c->render_file(
'filepath' => "$configreportfile",
'format' => 'x-download',
'content_disposition' => 'attachment',
'cleanup' => 1,
'filepath' => "$configreportfile",
'format' => 'x-download',
'content_disposition' => 'attachment',
'cleanup' => 1,
);
}
} ## end sub download_config_report
1;

View File

@@ -7,107 +7,86 @@ package SrvMngr::Controller::Clamav;
#
# routes : end
#------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::ConfigDB::UTF8;
#package esmith::FormMagick::Panel::clamav;
our $db = esmith::ConfigDB->open() || die "Couldn't open config db";
our $db;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %clm_datas = ();
my $title = $c->l('clm_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('clm_DESC_FILESYSTEM_SCAN_PERIOD'));
$clm_datas{'FilesystemScan'} = ($db->get_prop('clamav','FilesystemScan')) || 'disabled';
$clm_datas{'Quarantine'} = ($db->get_prop('clamav','Quarantine')) || 'disabled';
$clm_datas{'clam_versions'} = get_clam_versions();
$c->stash( title => $title, modul => $modul, clm_datas => \%clm_datas );
my $title = $c->l('clm_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('clm_DESC_FILESYSTEM_SCAN_PERIOD'));
$db = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
$clm_datas{'FilesystemScan'} = ($db->get_prop('clamav', 'FilesystemScan')) || 'disabled';
$clm_datas{'Quarantine'} = ($db->get_prop('clamav', 'Quarantine')) || 'disabled';
$clm_datas{'clam_versions'} = get_clam_versions();
$c->stash(title => $title, modul => $modul, clm_datas => \%clm_datas);
$c->render(template => 'clamav');
};
} ## end sub main
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $http_clamav_status = $c->param('http_clamav_status') || 'disabled';
my $smtp_clamav_status = $c->param('smtp_clamav_status') || '';
my $result = "";
my $result = "";
$c->change_settings();
# Update the system
system("/sbin/e-smith/signal-event clamav-update") == 0
or $result = $c->l('clm_ERROR_UPDATING_CONFIGURATION');
if ( ! $result ) {
$result = $c->l('clm_SUCCESS') ;
$c->flash( success => $result );
if (!$result) {
$result = $c->l('clm_SUCCESS');
$c->flash(success => $result);
} else {
$c->flash( error => $result );
$c->flash(error => $result);
}
$c->redirect_to('/clamav');
};
} ## end sub do_update
sub change_settings {
my $c = shift;
my $status = $c->param('status');
my $FilesystemScan = ( $c->param('FilesystemScan') || 'disabled' );
my $Quarantine = ( $c->param('Quarantine') || 'disabled' );
my $DatabaseMirror = ( $c->param('DatabaseMirror') || 'db.us.clamav.net' );
my $UpdateOfficeHrs = ( $c->param('UpdateOfficeHrs') || 'disabled' );
my $UpdateNonOfficeHrs = ( $c->param('UpdateNonOfficeHrs') || 'disabled' );
my $UpdateWeekend = ( $c->param('UpdateWeekend') || 'disabled' );
my $HTTPProxyServer = ( $c->param('HTTPProxyServer') || '' );
my $HTTPProxyPort = ( $c->param('HTTPProxyPort') || '' );
my $HTTPProxyUsername = ( $c->param('HTTPProxyUsername') || '' );
my $HTTPProxyPassword = ( $c->param('HTTPProxyPassword') || '' );
my $clamav = $db->get('clamav') || $db->new_record('clamav', {type=>'service'});
my $c = shift;
$db = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $status = $c->param('status');
my $FilesystemScan = ($c->param('FilesystemScan') || 'disabled');
my $Quarantine = ($c->param('Quarantine') || 'disabled');
my $DatabaseMirror = ($c->param('DatabaseMirror') || 'db.us.clamav.net');
my $UpdateOfficeHrs = ($c->param('UpdateOfficeHrs') || 'disabled');
my $UpdateNonOfficeHrs = ($c->param('UpdateNonOfficeHrs') || 'disabled');
my $UpdateWeekend = ($c->param('UpdateWeekend') || 'disabled');
my $HTTPProxyServer = ($c->param('HTTPProxyServer') || '');
my $HTTPProxyPort = ($c->param('HTTPProxyPort') || '');
my $HTTPProxyUsername = ($c->param('HTTPProxyUsername') || '');
my $HTTPProxyPassword = ($c->param('HTTPProxyPassword') || '');
my $clamav = $db->get('clamav') || $db->new_record('clamav', { type => 'service' });
$status ||= $clamav->prop('status');
$clamav->merge_props(
status => $status,
FilesystemScan => $FilesystemScan,
Quarantine => $Quarantine,
DatabaseMirror => $DatabaseMirror,
UpdateOfficeHrs => $UpdateOfficeHrs,
UpdateNonOfficeHrs => $UpdateNonOfficeHrs,
UpdateWeekend => $UpdateWeekend,
HTTPProxyServer => $HTTPProxyServer,
HTTPProxyPort => $HTTPProxyPort,
HTTPProxyUsername => $HTTPProxyUsername,
HTTPProxyPassword => $HTTPProxyPassword,
);
status => $status,
FilesystemScan => $FilesystemScan,
Quarantine => $Quarantine,
DatabaseMirror => $DatabaseMirror,
UpdateOfficeHrs => $UpdateOfficeHrs,
UpdateNonOfficeHrs => $UpdateNonOfficeHrs,
UpdateWeekend => $UpdateWeekend,
HTTPProxyServer => $HTTPProxyServer,
HTTPProxyPort => $HTTPProxyPort,
HTTPProxyUsername => $HTTPProxyUsername,
HTTPProxyPassword => $HTTPProxyPassword,
);
} ## end sub change_settings
}
sub get_clam_versions
{
sub get_clam_versions {
my $version = `/usr/bin/freshclam -V`;
chomp $version;
$version =~ s/^ClamAV //;
return $version;
}
} ## end sub get_clam_versions
1;

View File

@@ -0,0 +1,359 @@
#
# Generated by SM2Gen version:0.9(20Jan2025) Chameleon version:4.5.4 On Python:3.12.3 at 2025-06-15 12:45:47
#
#
# Routines to be edited by the developer to provide content and validation for parameters
# and provison of the control data for table(s)
#
use esmith::util;
use esmith::util::network;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB;
use esmith::NetworksDB::UTF8;
use esmith::HostsDB;
use esmith::DomainsDB::UTF8;
use DateTime;
use constant FALSE => 0;
use constant TRUE => 1;
#The most common ones - open DB when required.
my $cdb;
my $adb;
my $ndb;
my $hdb;
my $ddb;
#The most common ones - you might want to use these if you need to make sure that the DB is refreshed.
#$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
#$adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
#$ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
#$hdb = esmith::HostsDB::UTF8->open() || die("Couldn't open Hosts db");
#$ddb = esmith::DomainsDB::UTF8->open() || die("Couldn't open Domains db");
# Validation routines - parameters for each panel
sub validate_PARAMS {
my $c = shift;
my $dat_data = shift; #Data hash as parameter
# Validation for each field
my $ret = '';
if (! TRUE) #validate $c->param('time_mode')
{$ret .= 'Validation for time_mode failed';}
if (! TRUE) #validate $c->param('ntpserver')
{$ret .= 'Validation for ntpserver failed';}
if (! TRUE) #validate $c->param('year')
{$ret .= 'Validation for year failed';}
if (! TRUE) #validate $c->param('month')
{$ret .= 'Validation for month failed';}
if (! TRUE) #validate $c->param('day')
{$ret .= 'Validation for day failed';}
if (! TRUE) #validate $c->param('hour')
{$ret .= 'Validation for hour failed';}
if (! TRUE) #validate $c->param('minute')
{$ret .= 'Validation for minute failed';}
if (! TRUE) #validate $c->param('second')
{$ret .= 'Validation for second failed';}
if ($ret eq '') {$ret = 'ok';}
return $ret;
}
# Get singleton data for each panel
sub get_data_for_panel_PARAMS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
# --- Setup options ---
# Get today's date and time
my ($today_sec, $today_min, $today_hour, $today_mday, $today_mon, $today_year) = localtime;
$today_year += 1900;
$today_mon += 1;
my $today_mon = sprintf('%02d', $today_mon);
my $today_mday = sprintf('%02d', $today_mday);
my $now_hour = sprintf('%02d', $today_hour);
my $now_min = sprintf('%02d', $today_min);
my $now_sec = sprintf('%02d', $today_sec);
my $current_year = $today_year;
my $ntpserverurl = $cdb->get_prop('ntpd','NTPServer');
my $now = DateTime->now( time_zone => 'local' );
my %ret = (
# fields from Inputs
'time_mode'=>($ntpserverurl eq '' ? 'dat_manually_set' : 'dat_ntp_server'),
'ntpserver'=>"$ntpserverurl",
'year'=>"$today_year",
'month'=>"$today_mon",
'day'=>"$today_mday",,
'hour'=>"$now_hour",
'minute'=>"$now_min",
'second'=>"$now_sec",
'ntpstatus' => $cdb->get_prop('ntpd','status') || 'disabled',
# and the current time as a full format
'currentdatetime' => $now->strftime('%Y-%m-%dT%H:%M:%S')
);
return %ret;
}
# Get control data for table(s)
# Return hash with values from row in which link clicked on table
sub get_selected_PARAMS {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = ();
#gather the values here
return %ret;
}
#after sucessful modify or create or whatever and submit then perfom (if the params validate)
sub perform_PARAMS {
my $c = shift;
my $dat_data = shift; #Data hash as parameter
my $ret = '';
$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
my $db = $cdb; #maybe one of the others
my $dbkey = 'ntpd';
# To make it write to DB as comment, delete this (regex) string in each if statement "TRUE\) \#copy or perform with value: .* e.g."
#$ntpserverurl = ( $c->param('time_mode') eq 'dat_manually_set' ? '' : $c->param('ntpserver'));
#if (!$db->set_prop($dbkey,'NTPServer',$ntpserverurl,type=>'service'))
#{$ret .= 'Perform/save failed for NTPServer';}
#if (! TRUE) #copy or perform with value: year e.g. $db->set_prop($dbkey,'year',$c->param('year'),type=>'service'))
#{$ret .= 'Perform/save failed for year';}
#if (! TRUE) #copy or perform with value: month e.g. $db->set_prop($dbkey,'month',$c->param('month'),type=>'service'))
#{$ret .= 'Perform/save failed for month';}
#if (! TRUE) #copy or perform with value: day e.g. $db->set_prop($dbkey,'day',$c->param('day'),type=>'service'))
#{$ret .= 'Perform/save failed for day';}
#if (! TRUE) #copy or perform with value: hour e.g. $db->set_prop($dbkey,'hour',$c->param('hour'),type=>'service'))
#{$ret .= 'Perform/save failed for hour';}
#if (! TRUE) #copy or perform with value: minute e.g. $db->set_prop($dbkey,'minute',$c->param('minute'),type=>'service'))
#{$ret .= 'Perform/save failed for minute';}
#if (! TRUE) #copy or perform with value: second e.g. $db->set_prop($dbkey,'second',$c->param('second'),type=>'service'))
#{$ret .= 'Perform/save failed for second';}
if ($c->param('time_mode') eq 'dat_manually_set'){
# Time and date set manually
$ret .= $c->disable_ntp();
$ret .= $c->validate_change_datetime()
} else {
# Time set by ntp server - set up parameters to it
$ret = $c->update_ntpserver($c->param('ntpserver'))
}
if ($ret eq '') {$ret = 'ok';}
return $ret;
}
sub create_link{
# WIP
my ($c,$route, $panel, $index) = @_;
my $link = "$route?trt=$panel&Selected=$index";
return $link;
}
sub getZone_list {
my $c = shift;
#--------------------------------------------------
# Get a sorted list of time zones
#--------------------------------------------------
$ENV{BASH_ENV} = '';
if (!open(ZONES, "cd /usr/share/zoneinfo; /usr/bin/find . -type f -or -type l | /bin/grep '^./[A-Z]' |")) {
warn($c->l('COULD_NOT_OPEN_TZ_FILE') . $! . '.');
return undef;
}
my $zone;
my @zones = ();
while (defined($zone = <ZONES>)) {
chop($zone);
$zone =~ s/^.\///;
push @zones, $zone;
} ## end while (defined($zone = <ZONES>...))
close ZONES;
my @zt = sort @zones;
return \@zt;
} ## end sub getZone_list
sub getTimezone {
#--------------------------------------------------
# Figure out time zone by looking first looking at
# the configuration database value of TimeZone.
# If that is not defined, try and get it from /etc/localtime.
# If that doesn't work, default to US/Eastern.
#--------------------------------------------------
my $localtime;
my $timezonedefault = "US/Eastern";
if (defined $cdb->get('TimeZone')) {
$timezonedefault = $cdb->get('TimeZone')->value;
} else {
if (defined($localtime = readlink '/etc/localtime')) {
my $pos = index $localtime, 'zoneinfo/';
if ($pos > -1) {
$timezonedefault = substr $localtime, ($pos + 9);
}
} ## end if (defined($localtime...))
} ## end else [ if (defined $cdb->get(...))]
return $timezonedefault;
} ## end sub getTimezone
sub validate_change_datetime {
my $c = shift;
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
#--------------------------------------------------
# Untaint parameters and check for validity
#--------------------------------------------------
my $timezone = $c->param('Timezone');
if ($timezone =~ /^([\w\-]+\/?[\w\-+]*)$/) {
$timezone = $1;
} else {
$timezone = "US/Eastern";
}
my $month = $c->param('month');
my $day = $c->param('day');
my $year = $c->param('year');
if (!is_valid_date($year, $month, $day)){
return $c->l('dat_Invalid_date')
}
my $hour = $c->param('hour');
if ($hour =~ /^(\d{1,2})$/) {
$hour = $1;
} else {
$hour = "12";
}
if (($hour < 1) || ($hour > 23)) {
return $c->l('dat_INVALID_HOUR') . " $hour. " . $c->l('dat_BETWEEN_0_AND_23');
}
my $minute = $c->param('minute');
if ($minute =~ /^(\d{1,2})$/) {
$minute = $1;
} else {
$minute = "0";
}
if (($minute < 0) || ($minute > 59)) {
return $c->l('dat_INVALID_MINUTE') . " $minute. " . $c->l('dat_BETWEEN_0_AND_59');
}
my $second = $c->param('second');
if ($second =~ /^(\d{1,2})$/) {
$second = $1;
} else {
$second = "0";
}
if (($second < 0) || ($second > 59)) {
return $c->l('dat_INVALID_SECOND') . " $second. " . $c->l('dat_BETWEEN_0_AND_59');
}
#--------------------------------------------------
# Store time zone in configuration database
#--------------------------------------------------
my $old = $cdb->get('UnsavedChanges')->value;
my $rec = $cdb->get('TimeZone');
unless ($rec) {
$rec = $cdb->new_record('TimeZone', undef);
}
$rec->set_value($timezone);
$cdb->get('UnsavedChanges')->set_value($old);
#--------------------------------------------------
# Signal event to change time zone, system time
# and hardware clock
#--------------------------------------------------
my $newdate = sprintf "%02d%02d%02d%02d%04d.%02d", $month, $day, $hour, $minute, $year, $second;
$c->app->log->info("Changing date manually to $newdate");
esmith::util::backgroundCommand(2, "/sbin/e-smith/signal-event", "timezone-update", $newdate); #TEMP!!!
return '';
} ## end sub validate_change_datetime
sub is_valid_date {
my ($year, $month, $day) = @_;
# Check if all parts are defined and integers
return 0 unless defined $year && defined $month && defined $day;
return 0 unless $year =~ /^\d+$/ && $month =~ /^\d+$/ && $day =~ /^\d+$/;
# Try to construct a DateTime object
eval {
DateTime->new(year => $year, month => $month, day => $day);
1;
} or return 0;
return 1;
}
sub update_ntpserver {
my $c = shift;
my $ntpserver = shift;
my $msg = '';
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
#------------------------------------------------------------
# Looks good; go ahead and change the parameters.
#------------------------------------------------------------
my $old = $cdb->get('UnsavedChanges')->value;
my $rec = $cdb->get('ntpd');
if ($rec) {
$rec->set_prop('status', 'enabled');
$rec->set_prop('NTPServer', $ntpserver);
} else {
$rec = $cdb->new_record('ntpd',
{ type => 'service', status => 'enabled', SyncToHWClockSupported => 'yes', NTPServer => $ntpserver });
}
$cdb->get('UnsavedChanges')->set_value($old);
$msg = ''; #$c->l('dat_SETTINGS_CHANGED');
if ($ntpserver =~ /^\s*$/) {
$rec->set_prop('status', ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' ? 'enabled' : 'disabled');
$rec->set_prop('NTPServer', '');
$msg = $c->l('dat_INVALID_NTP_SERVER') if ($rec->prop('SyncToHWClockSupported') || 'yes') ne 'yes';
} ## end if ($ntpserver =~ /^\s*$/)
esmith::util::backgroundCommand(2, "/sbin/e-smith/signal-event", "timeserver-update");
return $msg;
} ## end sub update_ntpserver
sub disable_ntp {
# make sure that the parameters are set for disabled
my $old = $cdb->get('UnsavedChanges')->value;
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $rec = $cdb->get('ntpd');
if ($rec) {
$rec->set_prop('status', ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' ? 'enabled' : 'disabled');
$rec->set_prop('NTPServer', '');
} else {
$rec = $cdb->new_record('ntpd',
{ type => 'service', status => 'enabled', SyncToHWClockSupported => 'yes', NTPServer => '' });
}
$cdb->get('UnsavedChanges')->set_value($old);
return '';
} ## end sub disable_ntp
1;

View File

@@ -1,404 +1,333 @@
package SrvMngr::Controller::Datetime;
#
# Generated by SM2Gen version:0.9(20Jan2025) Chameleon version:4.5.4 On Python:3.12.3 at 2025-06-15 12:45:47
# Remember that each route must be unique (else they just overwrite each other).
# you cannot have get and post on the same name and url.
#
#----------------------------------------------------------------------
# heading : System
# description : Date and time
# navigation : 4000 400
# navigation : 4000 300
#
# ######name : datetimet, method : post, url : /datetimet, ctlact : datetime#testntp
#
# routes : end
#------------------------------
#
# Documentation: https://wiki.contribs.org/Datetime
#----------------------------------------------------------------------
#
# Scheme of things:
#
# TBA!!
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use constant FALSE => 0;
use constant TRUE => 1;
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::FormMagick;
use esmith::util;
use Data::Dumper;
our $cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
use esmith::util;
use esmith::util::network;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB;
use esmith::NetworksDB;
use esmith::HostsDB::UTF8;
use esmith::DomainsDB::UTF8;
my $cdb;
my $adb;
my $ndb;
my $hdb;
my $ddb;
my %dat_data;
require '/usr/share/smanager/lib/SrvMngr/Controller/Datetime-Custom.pm'; #The code that is to be added by the developer
sub main {
#
# Initial entry - route is "/<whatever>"
#
#set initial panel
#for initial panel:
#Specifiy panel to enter
#load up _data hash with DB fields
#load up stash with pointer(s) to control fields hash(= get-))
#and a pointer to the prefix_data hash
#render initial panel
my $c = shift;
$c->app->log->info( $c->log_req );
#The most common ones - you might want to delete some of these if they are not used.
$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
$adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
$ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
$hdb = esmith::HostsDB::UTF8->open() || die("Couldn't open Hosts db");
$ddb = esmith::DomainsDB::UTF8->open() || die("Couldn't open Domains db");
%dat_data = ();
my $title = $c->l('dat_FORM_TITLE');
my $modul = $c->l('dat_INITIAL_DESC');
$dat_data{'trt'} = 'PARAMS';
#Load any DB entries into the <prefix>_data area so as they are preset in the form
# which DB - this only really works if the initial panel is a PARAMS type panel and not a TABLE
my $db = $cdb; #pickup local or global db or Default to config
$c->do_display($dat_data{'trt'});
}
# Post request with params - submit from the form
sub do_update {
#
# Return after submit pushed on panel (this is a post) - route is "/<whatever>u"
# parameters in the params hash.
#
#load up all params into prefix_data hash:
#By panel (series of if statements - only one executed):
#call validate-PANEL() - return ret = ok or error message
#if validation not ok:
#render back to current panel with error message in stash
#otherwise:
#By panel (series of if statements - only one executed):
#do whatever is required: call perform-PANEL() - return 'ok' or Error Message
#call signal-event for any global actions specified (check it exists - error and continue?)
#if action smeserver-<whatever>-update exists
#signal_event smeserver-<whatever>-update
#call signal-event for any specific actions for thids panel (check it exists first - error and continue)
#set success in stash
#if no "nextpanel" entry:
#set firstpanel
#else
#set nextpanel
#call render
my $c = shift;
$c->app->log->info($c->log_req);
#$c->app->log->info($c->param('month'));
my %dat_datas = ();
my $title = $c->l('dat_FORM_TITLE');
my $modul = $c->l('dat_INITIAL_DESC');
#The most common ones - you might want to delete some of these if they are not used.
$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
$adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
$ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
$hdb = esmith::HostsDB::UTF8->open() || die("Couldn't open Hosts db");
$ddb = esmith::DomainsDB::UTF8->open() || die("Couldn't open Domains db");
my $title = $c->l('dat_FORM_TITLE');
my $modul = $c->l('dat_INITIAL_DESC');
$dat_datas{ntpstatus} = 'disabled';
# Accessing all POST/GET parameters
#my $params = $c->req->params->to_hash;
my $rec = $cdb->get('ntpd');
if ($rec) {
$dat_datas{'ntpserver'} = $rec->prop('NTPServer') || '';
if ( $rec->prop('status') eq 'enabled' ) {
$dat_datas{ntpstatus} = 'enabled'
unless ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' and $dat_datas{ntpserver} =~ m#^\s*$#;
}
}
# Get number of POST parameters
#my $num_params = keys scaler %$params;
#Params are available in the hash "params" - copy to the prefix_data hash
#while (my ($key, $value) = each %{$c->req->params->to_hash}) {
# $dat_data{$key} = $value;
#}
($dat_datas{weekday}, $dat_datas{monthname},
$dat_datas{month}, $dat_datas{day}, $dat_datas{year},
$dat_datas{hour}, $dat_datas{minute}, $dat_datas{second},
$dat_datas{ampm}) = split /\|/,
`/bin/date '+%A|%B|%-m|%-d|%Y|%-I|%M|%S|%p'`;
# the value of trt will tell you which panel has returned
my $trt = $c->param('trt') || 'PARAMS'; #hidden control on every form.
my $ret = 'ok';
# get rid of trailing carriage return on last field
chop ($dat_datas{ampm});
$dat_datas{'now_string'} = esmith::FormMagick->gen_locale_date_string();
$c->stash( title => $title, modul => $modul, dat_datas => \%dat_datas );
$c->render('datetime');
};
sub do_update {
my $c = shift;
my %dat_datas = ();
my $title = $c->l('dat_FORM_TITLE');
my $modul = $c->l('dat_INITIAL_DESC');
my $result;
my $success;
my $old_ntpstatus = $c->param('Old_ntpstatus');
$dat_datas{ntpstatus} = $c->param('Ntpstatus');
if ( $dat_datas{ntpstatus} ne $old_ntpstatus) {
if ( $dat_datas{ntpstatus} eq 'disabled' ) {
($dat_datas{weekday},
$dat_datas{monthname},
$dat_datas{month},
$dat_datas{day},
$dat_datas{year},
$dat_datas{hour},
$dat_datas{minute},
$dat_datas{second},
$dat_datas{ampm}) = split /\|/,
`/bin/date '+%A|%B|%-m|%-d|%Y|%-I|%M|%S|%p'`;
# get rid of trailing carriage return on last field
chop ($dat_datas{ampm});
} else {
$dat_datas{ntpserver} = ($cdb->get_prop('ntpd','NTPServer')) || '';
}
$dat_datas{now_string} = esmith::FormMagick->gen_locale_date_string();
#Validate the parameters in a custom sub one for each panel (although only one of these will be executed)
my $thispanel;
if ($trt eq 'PARAMS'){
#Validate form parameters for panel PARAMS
$ret = $c->validate_PARAMS(\%dat_data);
$thispanel = 'PARAMS';
}
$c->stash( title => $title, modul => $modul, dat_datas => \%dat_datas );
return $c->render('datetime');
}
if ($ret ne 'ok'){
$c->stash(error => $c->l($ret));
$c->do_display($thispanel);
} else {
#Do whatever is needed, including writing values to the DB
if ($trt eq 'PARAMS'){
#do whatever is required ...
$ret = $c->perform_PARAMS(\%dat_data);
if ($ret ne 'ok') {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
dat_data => \%dat_data
);
$c->render(template => "datetime");
return
} else {
if ($c->param('time_mode') eq 'dat_manually_set') {
$c->stash( success => $c->l('dat_UPDATING_CLOCK'));
} else {
$c->stash( success => $c->l('dat_SETTINGS_CHANGED'));
}
}
}
if ( $dat_datas{ntpstatus} eq 'enabled' ) {
# and call any signal-events needed
#TBD
# Setup shared data and call panel
if ('none' eq 'none') {
$dat_data{'trt'} = 'PARAMS';
} else {
$dat_data{'trt'} = 'none';
}
$c->do_display($dat_data{'trt'});
}
}
# update ntpserver
sub do_display {
#
# Return after link clicked in table (this is a get) - route is "/<whatever>d"
# Expects ?trt=PANEL&selected="TableRowName" plus any other required
#
# OR it maybe a post from the main panel to add a new record
#
#load up all supplied params into prefix_data hash
#call get-selected-PANEL() - returns hash of all relevent parameters
#load up returned hash into prefix_data
#render - to called panel
$dat_datas{ntpserver} = $c->param('Ntpserver') || '';
my ($c,$trt) = @_;
$c->app->log->info($c->log_req);
if ( $dat_datas{ntpserver} eq "pool.ntp.org" ) {
$result .= $c->l('dat_INVALID_NTP_ADDR');
} elsif ( $dat_datas{ntpserver} =~ /^([a-zA-Z0-9\.\-]+)$/ ) {
$dat_datas{ntpserver} = $1;
# } elsif ( $dat_datas{ntpserver} =~ /^\s*$/ ) {
# $dat_datas{ntpserver} = "";
} else {
$result .= $c->l('dat_INVALID_NTP_ADDR');
}
#The most common ones - you might want to delete some of these if they are not used.
$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
$adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
$ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
$hdb = esmith::HostsDB::UTF8->open() || die("Couldn't open Hosts db");
$ddb = esmith::DomainsDB::UTF8->open() || die("Couldn't open Domains db");
my $title = $c->l('dat_FORM_TITLE');
my $modul = $c->l('dat_INITIAL_DESC');
if ( ! $result ) {
$success = update_ntpserver( $c, $dat_datas{ntpserver} );
# Accessing all parameters
#my $params = $c->req->params->to_hash;
# Get number of parameters
#my $num_params = keys %$params;
#Tag as Post or Get (ie. create new entry or edit existing one
my $is_new_record = ($c->req->method() eq 'POST');
#Params are available in the hash "params" - copy to the prefix_data hash
#while (my ($key, $value) = each %{$c->req->params->to_hash}) {
# $dat_data{$key} = $value;
#}
# the value of trt will tell you which panel has returned
if (! $trt){
$trt = $c->param('trt') || 'PARAMS'; #Indicates where to go now
}
} else {
# set Locale time & clean ntpserver
#my $servername = ($c->param('ServerName') || 'WS');
if ( ! $result ) {
$result = validate_change_datetime( $c );
if ( $result eq 'OK' ) {
$success = $c->l('dat_UPDATING_CLOCK');
$result = '';
disable_ntp();
$success .= '<br>'. $c->l('dat_SERVER_DISABLED_DESC');
}
}
}
if ( $result ) {
$c->stash( error => $result );
$c->stash( title => $title, modul => $modul, dat_datas => \%dat_datas );
return $c->render('datetime');
}
#$result = $c->l('dat_SUCCESS');
my $message = "'Datetime' update DONE";
$c->app->log->info($message);
$c->flash( success => $success );
$c->redirect_to('/datetime');
};
sub validate_change_datetime {
my $c = shift;
#--------------------------------------------------
# Untaint parameters and check for validity
#--------------------------------------------------
my $timezone = $c->param ('Timezone');
if ($timezone =~ /^([\w\-]+\/?[\w\-+]*)$/) {
$timezone = $1;
} else {
$timezone = "US/Eastern";
}
my $month = $c->param ('Month');
if ($month =~ /^(\d{1,2})$/) {
$month = $1;
} else {
$month = "1";
}
if (($month < 1) || ($month > 12)) {
return $c->l('dat_INVALID_MONTH')." $month. ". $c->l('dat_MONTH_BETWEEN_1_AND_12');
}
my $day = $c->param ('Day');
if ($day =~ /^(\d{1,2})$/) {
$day = $1;
} else {
$day = "1";
}
if (($day < 1) || ($day > 31)) {
return $c->l('dat_INVALID_DAY')." $day. ". $c->l('dat_BETWEEN_1_AND_31');
}
my $year = $c->param ('Year');
if ($year =~ /^(\d{4})$/) {
$year = $1;
} else {
$year = "2000";
}
if (($year < 1900) || ($year > 2200)) {
return $c->l('dat_INVALID_YEAR')." $year. ". $c->l('dat_FOUR_DIGIT_YEAR');
}
my $hour = $c->param ('Hour');
if ($hour =~ /^(\d{1,2})$/) {
$hour = $1;
} else {
$hour = "12";
}
if (($hour < 1) || ($hour > 12)) {
return $c->l('dat_INVALID_HOUR')." $hour. ". $c->l('dat_BETWEEN_1_AND_12');
}
my $minute = $c->param ('Minute');
if ($minute =~ /^(\d{1,2})$/) {
$minute = $1;
} else {
$minute = "0";
}
if (($minute < 0) || ($minute > 59)) {
return $c->l('datINVALID_MINUTE')." $minute. ".$c->l('dat_BETWEEN_0_AND_59');
}
# Now add in the params from the selected row from the table
my %selectedrow;
my $second = $c->param ('Second');
if ($second =~ /^(\d{1,2})$/) {
$second = $1;
} else {
$second = "0";
if ($trt eq 'PARAMS'){
#Validate Get selected row (if applicable) PARAMS
%selectedrow = $c->get_selected_PARAMS($dat_data{'Selected'},$is_new_record);
}
#Copy in the selected row params to the prefix_data hash to pass to the panel
while (my ($key, $value) = each %selectedrow){
$dat_data{$key} = $value;
}
if (($second < 0) || ($second > 59)) {
return $c->l('dat_INVALID_SECOND')." $second. ". $c->l('dat_BETWEEN_0_AND_59');
}
my $ampm = $c->param ('Ampm');
if ($ampm =~ /^(AM|PM)$/) {
$ampm = $1;
} else {
$ampm = "AM";
}
# convert to 24 hour time
$hour = $hour % 12;
if ($ampm eq "PM") {
$hour = $hour + 12;
}
#--------------------------------------------------
# Store time zone in configuration database
#--------------------------------------------------
my $conf = esmith::ConfigDB->open();
my $old = $conf->get('UnsavedChanges')->value;
my $rec = $conf->get('TimeZone');
unless ($rec) {
$rec = $conf->new_record('TimeZone',undef);
}
$rec->set_value($timezone);
$conf->get('UnsavedChanges')->set_value($old);
#--------------------------------------------------
# Signal event to change time zone, system time
# and hardware clock
#--------------------------------------------------
my $newdate = sprintf "%02d%02d%02d%02d%04d.%02d",
$month, $day, $hour, $minute, $year, $second;
esmith::util::backgroundCommand(2,
"/sbin/e-smith/signal-event","timezone-update",$newdate);
return 'OK';
}
sub update_ntpserver {
my $c = shift;
my $ntpserver = shift;
# Where to go now
$dat_data{'trt'} = $trt;
# Set up other shared data according to the panel to go to
my $msg;
#------------------------------------------------------------
# Looks good; go ahead and change the parameters.
#------------------------------------------------------------
my $old = $cdb->get('UnsavedChanges')->value;
my $rec = $cdb->get('ntpd');
if ($rec) {
$rec->set_prop('status','enabled');
$rec->set_prop('NTPServer',$ntpserver);
} else {
$rec = $cdb->new_record( 'ntpd',
{ type=>'service', status=>'enabled', SyncToHWClockSupported => 'yes', NTPServer=>$ntpserver } );
}
$cdb->get('UnsavedChanges')->set_value($old);
$msg = $c->l('dat_SETTINGS_CHANGED');
if ( $ntpserver =~ /^\s*$/ ) {
$rec->set_prop('status', ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' ? 'enabled' : 'disabled');
$rec->set_prop('NTPServer', '');
$msg = $c->l('dat_INVALID_NTP_SERVER') if ($rec->prop('SyncToHWClockSupported') || 'yes') ne 'yes';
}
esmith::util::backgroundCommand( 2, "/sbin/e-smith/signal-event", "timeserver-update" );
return $msg;
}
sub disable_ntp {
# make sure that the parameters are set for disabled
my $old = $cdb->get('UnsavedChanges')->value;
my $rec = $cdb->get('ntpd');
if ($rec) {
$rec->set_prop('status', ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' ? 'enabled' : 'disabled');
$rec->set_prop('NTPServer','');
} else {
$rec = $cdb->new_record('ntpd',
{type=>'service', status=>'enabled', SyncToHWClockSupported => 'yes', NTPServer=>''});
}
$cdb->get('UnsavedChanges')->set_value($old);
}
sub getTimezone {
#--------------------------------------------------
# Figure out time zone by looking first looking at
# the configuration database value of TimeZone.
# If that is not defined, try and get it from /etc/localtime.
# If that doesn't work, default to US/Eastern.
#--------------------------------------------------
my $localtime;
my $timezonedefault = "US/Eastern";
if (defined $cdb->get('TimeZone')) {
$timezonedefault = $cdb->get('TimeZone')->value;
} else {
if (defined ($localtime = readlink '/etc/localtime')) {
my $pos = index $localtime, 'zoneinfo/';
if ( $pos > -1 ) {
$timezonedefault = substr $localtime, ($pos + 9);
}
}
}
return $timezonedefault;
}
sub getZone_list {
if ($trt eq 'PARAMS'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_PARAMS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$dat_data{$key} = $value;
}
}
# and table control fields
# Data for panel
$c->stash(
title => $title,
modul => $modul,
dat_data => \%dat_data
);
$c->render(template => "datetime");
}
sub do_testntp {
my $c = shift;
my $server = $c->req->json->{ntpserver} // '';
#--------------------------------------------------
# Get a sorted list of time zones
#--------------------------------------------------
$ENV{BASH_ENV} = '';
if (! open (ZONES, "cd /usr/share/zoneinfo; /usr/bin/find . -type f -or -type l | /bin/grep '^./[A-Z]' |"))
{
warn ( $c->l('COULD_NOT_OPEN_TZ_FILE').$!.'.' );
return undef;
# Strict validation: hostname or IPv4
unless ($server =~ /^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*|\d{1,3}(?:\.\d{1,3}){3})$/) {
return $c->render(json => { success => 0, error => 'Invalid server name or IP' });
}
my $zone;
my @zones = ();
while (defined ($zone = <ZONES>))
{
chop ($zone);
$zone =~ s/^.\///;
push @zones, $zone;
my $timeout = 5;
my @cmd = ('timeout', $timeout, 'ntpdate', '-q', $server);
# Run ntpdate and capture output
my $output = qx{@cmd 2>&1};
$c->app->log->info($output);
my $exit_code = $? >> 8;
# Parse for known errors
if ($exit_code == 124) {
return $c->render(json => { success => 0, error => "Timeout: NTP server did not respond within $timeout seconds" });
}
close ZONES;
my @zt = sort @zones;
return \@zt;
if ($output =~ /no server suitable for synchronization found/i) {
return $c->render(json => { success => 0, error => "No suitable NTP server found or server unreachable" });
}
if ($output =~ /Name or service not known|Temporary failure in name resolution/i) {
return $c->render(json => { success => 0, error => "DNS resolution failed for $server" });
}
if ($output =~ /ntpdig: no eligible servers/i) {
return $c->render(json => { success => 0, error => "Not a an NTP server" });
}
if ($output =~ /permission denied/i) {
return $c->render(json => { success => 0, error => "Permission denied running ntpdate" });
}
if ($exit_code != 0) {
return $c->render(json => { success => 0, error => "ntpdate failed (exit code $exit_code): $output" });
}
# Extract date and time down to seconds from adjust line
my ($datetime) = $output =~ /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/m;
if ($datetime) {
return $c->render(json => { success => 1, time => $datetime });
} else {
return $c->render(json => { success => 0, error => "Could not parse date/time from NTP server response." });}
}
sub getMonth_list {
my $c = shift;
return [[ $c->l('dat_JANUARY') => '1'],
[ $c->l('dat_FEBRUARY') => '2'],
[ $c->l('dat_MARCH') => '3'],
[ $c->l('dat_APRIL') => '4'],
[ $c->l('dat_MAY') => '5'],
[ $c->l('dat_JUNE') => '6'],
[ $c->l('dat_JULY') => '7'],
[ $c->l('dat_AUGUST') => '8'],
[ $c->l('dat_SEPTEMBER') => '9'],
[ $c->l('dat_OCTOBER') => '10'],
[ $c->l('dat_NOVEMBER') => '11'],
[ $c->l('dat_DECEMBER') => '12']];
}
1;
1;

View File

@@ -3,95 +3,95 @@ package SrvMngr::Controller::Directory;
#----------------------------------------------------------------------
# heading : User management
# description : Directory
# navigation : 2000 300
# navigation : 2000 400
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB::UTF8;
use SrvMngr qw(theme_list init_session);
#use esmith::util qw(ldapBase);
use esmith::FormMagick::Panel::directory;
our $db = esmith::ConfigDB->open() || die "Couldn't open config db";
our $db;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$db = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my %dir_datas = ();
my $title = $c->l('dir_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('dir_DESCRIPTION'));
$dir_datas{'root'} = get_ldap_base();
$dir_datas{'access'} = ($db->get_prop('ldap','access')) || 'private';
$dir_datas{'department'} = ($db->get_prop('ldap','defaultDepartment')) || '';
$dir_datas{'company'} = ($db->get_prop('ldap','defaultCompany')) || '';
$dir_datas{'street'} = ($db->get_prop('ldap','defaultStreet')) || '';
$dir_datas{'city'} = ($db->get_prop('ldap','defaultCity')) || '';
$dir_datas{'phonenumber'} = ($db->get_prop('ldap','defaultPhoneNumber')) || '';
$c->stash( title => $title, modul => $modul, dir_datas => \%dir_datas );
my $title = $c->l('dir_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('dir_DESCRIPTION'));
$dir_datas{'root'} = get_ldap_base();
$dir_datas{'access'} = ($db->get_prop('ldap', 'access')) || 'private';
$dir_datas{'department'} = ($db->get_prop('ldap', 'defaultDepartment')) || '';
$dir_datas{'company'} = ($db->get_prop('ldap', 'defaultCompany')) || '';
$dir_datas{'street'} = ($db->get_prop('ldap', 'defaultStreet')) || '';
$dir_datas{'city'} = ($db->get_prop('ldap', 'defaultCity')) || '';
$dir_datas{'phonenumber'} = ($db->get_prop('ldap', 'defaultPhoneNumber')) || '';
$c->stash(title => $title, modul => $modul, dir_datas => \%dir_datas);
$c->render(template => 'directory');
};
} ## end sub main
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $access = $c->param('access');
my $department = $c->param('department');
my $company = $c->param('company');
my $street = $c->param('street');
my $city = $c->param('city');
$db = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $access = $c->param('access');
my $department = $c->param('department');
my $company = $c->param('company');
my $street = $c->param('street');
my $city = $c->param('city');
my $phonenumber = $c->param('phonenumber');
my $existing = $c->param('existing');
my $result = "";
$db->get('ldap')->set_prop('access', $access);
$db->get('ldap')->set_prop('defaultDepartment', $department);
$db->get('ldap')->set_prop('defaultCompany', $company);
$db->get('ldap')->set_prop('defaultStreet', $street);
$db->get('ldap')->set_prop('defaultCity', $city);
my $existing = $c->param('existing');
my $result = "";
$db->get('ldap')->set_prop('access', $access);
$db->get('ldap')->set_prop('defaultDepartment', $department);
$db->get('ldap')->set_prop('defaultCompany', $company);
$db->get('ldap')->set_prop('defaultStreet', $street);
$db->get('ldap')->set_prop('defaultCity', $city);
$db->get('ldap')->set_prop('defaultPhoneNumber', $phonenumber);
if ($existing eq 'update') {
my $ac = esmith::AccountsDB->open() || die "Couldn't open accounts db";
my @users = $ac->users();
foreach my $user (@users) {
$user->set_prop('Phone', $phonenumber);
$user->set_prop('Company', $company);
$user->set_prop('Dept', $department);
$user->set_prop('City', $city);
$user->set_prop('Street', $street);
}
}
my $ac = esmith::AccountsDB::UTF8->open() || die "Couldn't open accounts db";
my @users = $ac->users();
foreach my $user (@users) {
$user->set_prop('Phone', $phonenumber);
$user->set_prop('Company', $company);
$user->set_prop('Dept', $department);
$user->set_prop('City', $city);
$user->set_prop('Street', $street);
} ## end foreach my $user (@users)
} ## end if ($existing eq 'update')
#
# Update the system
#
system ("/sbin/e-smith/signal-event ldap-update") == 0
or $result = $c->l('ERROR_UPDATING_CONFIGURATION');
system("/sbin/e-smith/signal-event ldap-update") == 0
or $result = $c->l('ERROR_UPDATING_CONFIGURATION');
my $title = $c->l('dir_FORM_TITLE');
if ( $result eq '' ) { $result = $c->l('dir_SUCCESS'); }
$c->stash( title => $title, modul => $result );
if ($result eq '') { $result = $c->l('dir_SUCCESS'); }
$c->stash(title => $title, modul => $result);
$c->render(template => 'module');
} ## end sub do_update
};
sub get_ldap_base {
return esmith::util::ldapBase(get_value('','DomainName'));
}
1;
sub get_value {
my $fm = shift;
my $item = shift;
$db = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $record = $db->get($item);
if ($record) {
return $record->value();
}
else {
return '';
}
}
1;

View File

@@ -10,493 +10,417 @@ package SrvMngr::Controller::Domains;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::DomainsDB::UTF8;
use esmith::AccountsDB::UTF8;
#use Data::Dumper;
#use esmith::FormMagick::Panel::domains;
use esmith::DomainsDB;
use esmith::AccountsDB;
#use URI::Escape;
our $ddb = esmith::DomainsDB->open || die "Couldn't open domains db";
our $cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
our ($ddb,$cdb,$adb);
our $REGEXP_DOMAIN = qq([a-zA-Z0-9\-\.]+);
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %dom_datas = ();
my $title = $c->l('dom_FORM_TITLE');
my $title = $c->l('dom_FORM_TITLE');
$ddb = esmith::DomainsDB::UTF8->open || die "Couldn't open domains db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$dom_datas{trt} = 'LST';
my @domains;
for ($ddb->domains())
{
for ($ddb->domains()) {
my $ns = $_->prop('Nameservers') || 'internet';
push @domains,
{ Domain => $_->key, $_->props,
Nameservers => $ns,
}
}
$dom_datas{forwarder} = $cdb->get_prop('dnscache', 'Forwarder');
$dom_datas{forwarder2} = $cdb->get_prop('dnscache', 'Forwarder2') || '';
$c->stash( title => $title, dom_datas => \%dom_datas, domains => \@domains );
push @domains,
{
Domain => $_->key,
$_->props,
Nameservers => $ns,
};
} ## end for ($ddb->domains())
$dom_datas{forwarder} = $cdb->get_prop('dnscache', 'Forwarder');
$dom_datas{forwarder2} = $cdb->get_prop('dnscache', 'Forwarder2') || '';
$c->stash(title => $title, dom_datas => \%dom_datas, domains => \@domains);
$c->render(template => 'domains');
};
} ## end sub main
sub do_display {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = $c->param('trt');
my $rt = $c->current_route;
my $trt = $c->param('trt');
my $domain = $c->param('Domain') || '';
$ddb = esmith::DomainsDB::UTF8->open || die "Couldn't open domains db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
#$trt = 'DEL' if ( $rt eq 'domaindel1' );
#$trt = 'UPD' if ( $rt eq 'domainupd1' );
#$trt = 'UP2' if ( $rt eq 'domainup21' );
#$trt = 'ADD' if ( $rt eq 'domainadd1' );
my %dom_datas = ();
my $title = $c->l('dom_FORM_TITLE');
my $result = '';
my $title = $c->l('dom_FORM_TITLE');
my $result = '';
$dom_datas{'trt'} = $trt;
if ( $trt ne 'ADD' and $trt ne 'UPD' and $trt ne 'UP2' and $trt ne 'DEL' ) {
$result = "Trt unknown ( $trt ) !"
}
if ( $trt eq 'ADD' ) {
#nothing
}
if ( $trt eq 'UPD' ) {
my $rec = $ddb->get($domain);
if ( $rec ) {
$dom_datas{domain} = $domain;
$dom_datas{description} = $rec->prop('Description') || '';
$dom_datas{content} = $rec->prop('Content') || '';
$dom_datas{nameservers} = $rec->prop('Nameservers') || 'internet';
} else {
$result = "Domain $domain not found !"
}
}
if ( $trt eq 'UP2' ) {
$dom_datas{forwarder} = $cdb->get_prop('dnscache', 'Forwarder') || '';
$dom_datas{forwarder2} = $cdb->get_prop('dnscache', 'Forwarder2') || '';
}
if ( $trt eq 'DEL' ) {
my $rec = $ddb->get($domain);
if ( $rec ) {
$dom_datas{domain} = $domain;
$dom_datas{description} = $rec->prop('Description') || '';
}
}
if ( $trt eq 'LST' ) {
my @domains;
if ($adb) {
@domains = $ddb->domains();
}
$c->stash( domains => \@domains );
}
if ( ! $result ) {
$c->stash( error => $result );
if ($trt ne 'ADD' and $trt ne 'UPD' and $trt ne 'UP2' and $trt ne 'DEL') {
$result = "Trt unknown ( $trt ) !";
}
$c->stash( title => $title, dom_datas => \%dom_datas );
$c->render( template => 'domains' );
};
if ($trt eq 'ADD') {
#nothing
}
if ($trt eq 'UPD') {
my $rec = $ddb->get($domain);
if ($rec) {
$dom_datas{domain} = $domain;
$dom_datas{description} = $rec->prop('Description') || '';
$dom_datas{content} = $rec->prop('Content') || '';
$dom_datas{nameservers} = $rec->prop('Nameservers') || 'internet';
} else {
$result = "Domain $domain not found !";
}
} ## end if ($trt eq 'UPD')
if ($trt eq 'UP2') {
$dom_datas{forwarder} = $cdb->get_prop('dnscache', 'Forwarder') || '';
$dom_datas{forwarder2} = $cdb->get_prop('dnscache', 'Forwarder2') || '';
}
if ($trt eq 'DEL') {
my $rec = $ddb->get($domain);
if ($rec) {
$dom_datas{domain} = $domain;
$dom_datas{description} = $rec->prop('Description') || '';
}
} ## end if ($trt eq 'DEL')
if ($trt eq 'LST') {
my @domains;
if ($adb) {
@domains = $ddb->domains();
}
$c->stash(domains => \@domains);
} ## end if ($trt eq 'LST')
if (!$result) {
$c->stash(error => $result);
}
$c->stash(title => $title, dom_datas => \%dom_datas);
$c->render(template => 'domains');
} ## end sub do_display
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = $c->param('trt');
my $rt = $c->current_route;
my $trt = $c->param('trt');
$ddb = esmith::DomainsDB::UTF8->open || die "Couldn't open domains db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
my %dom_datas = ();
my ($res, $result) = '';
#my $domain = uri_unescape($c->param('domain'));
my $domain = $c->param('Domain');
if ( $trt eq 'ADD' ) {
if ($trt eq 'ADD') {
my $account = $c->param('Account');
# controls (validate ?????)
#? validate_new_domain_name( $c, $domain, $account );
#$result .= $res unless $res eq 'OK';
# controls (validate ?????)
#? validate_new_domain_name( $c, $domain, $account );
#$result .= $res unless $res eq 'OK';
#$result .= ' blocked';
$res = '';
#$result .= ' blocked';
$res = '';
if ( ! $result ) {
$res = $c->create_modify_domain( 'create', $domain );
$result .= $res unless $res eq 'OK';
}
if ( ! $result ) {
$result = $c->l('dom_SUCCESSFULLY_CREATED') . " $domain";
}
}
if (!$result) {
$res = $c->create_modify_domain('create', $domain);
$result .= $res unless $res eq 'OK';
}
if ( $trt eq 'UPD' ) {
if (!$result) {
$result = $c->l('dom_SUCCESSFULLY_CREATED') . " $domain";
}
} ## end if ($trt eq 'ADD')
if ($trt eq 'UPD') {
my $description = $c->param('Description');
my $content = $c->param('Content');
my $content = $c->param('Content');
my $nameservers = $c->param('Nameservers');
# controls
#$res = validate_description( $c, $account );
#$result .= $res unless $res eq 'OK';
# controls
#$res = validate_description( $c, $account );
#$result .= $res unless $res eq 'OK';
#$result .= 'blocked';
$res = '';
#$result .= 'blocked';
if (!$result) {
$res = $c->create_modify_domain('modify', $domain);
$result .= $res unless $res eq 'OK';
}
$res = '';
if ( ! $result ) {
$res = $c->create_modify_domain( 'modify', $domain );
$result .= $res unless $res eq 'OK';
}
if (!$result) {
$result = $c->l('dom_SUCCESSFULLY_MODIFIED') . " $domain";
}
} ## end if ($trt eq 'UPD')
if ( ! $result ) {
$result = $c->l('dom_SUCCESSFULLY_MODIFIED') . " $domain";
}
}
if ( $trt eq 'UP2' ) {
my $forwarder = $c->param('Forwarder');
if ($trt eq 'UP2') {
my $forwarder = $c->param('Forwarder');
my $forwarder2 = $c->param('Forwarder2');
# controls
# controls
$res = $c->ip_number_or_blank($forwarder);
$result .= $res unless $res eq 'OK';
$res = $c->ip_number_or_blank($forwarder2);
$result .= $res unless $res eq 'OK';
$res = $c->ip_number_or_blank( $forwarder );
$result .= $res unless $res eq 'OK';
#$result .= 'blocked';
$res = '';
$res = $c->ip_number_or_blank( $forwarder2 );
$result .= $res unless $res eq 'OK';
#$result .= 'blocked';
$res = '';
if ( ! $result ) {
$res = $c->modify_dns( $forwarder, $forwarder2 );
$result .= $res unless $res eq 'OK';
}
if ( ! $result ) {
$result = $c->l('SUCCESS') . " $forwarder $forwarder2";
}
}
if (!$result) {
$res = $c->modify_dns($forwarder, $forwarder2);
$result .= $res unless $res eq 'OK';
}
if (!$result) {
$result = $c->l('SUCCESS') . " $forwarder $forwarder2";
}
} ## end if ($trt eq 'UP2')
if ( $trt eq 'DEL' ) {
if ($trt eq 'DEL') {
# controls
#$res = validate_is_domain($c, $domain);
#$result .= $res unless $res eq 'OK';
#$result .= 'blocked';
$res = '';
if ( ! $result ) {
$res = $c->delete_domain( $domain );
$result .= $res unless $res eq 'OK';
}
if ( ! $result ) {
$result = $c->l('dom_SUCCESSFULLY_DELETED') . " $domain";
}
}
# controls
#$res = validate_is_domain($c, $domain);
#$result .= $res unless $res eq 'OK';
#$result .= 'blocked';
$res = '';
if (!$result) {
$res = $c->delete_domain($domain);
$result .= $res unless $res eq 'OK';
}
if (!$result) {
$result = $c->l('dom_SUCCESSFULLY_DELETED') . " $domain";
}
} ## end if ($trt eq 'DEL')
# common parts
if ($res ne 'OK') {
my $title = $c->l('dom_FORM_TITLE');
$dom_datas{'domain'} = $domain;
$dom_datas{'trt'} = $trt;
$c->stash( error => $result . "($res)" );
$c->stash( title => $title, dom_datas => \%dom_datas );
return $c->render( 'domains' );
}
my $title = $c->l('dom_FORM_TITLE');
$dom_datas{'domain'} = $domain;
$dom_datas{'trt'} = $trt;
$c->stash(error => $result . "($res)");
$c->stash(title => $title, dom_datas => \%dom_datas);
return $c->render('domains');
} ## end if ($res ne 'OK')
my $message = "'Domains' updates ($trt) DONE";
$c->app->log->info($message);
$c->flash( success => $result );
$c->flash(success => $result);
$c->redirect_to('/domains');
};
} ## end sub do_update
sub create_modify_domain {
my ($c, $action, $domain) = @_;
$domain = $1 if ($domain =~ /^($REGEXP_DOMAIN)$/);
unless ($domain) {
return ($c->l($action eq 'create' ? 'dom_ERROR_CREATING_DOMAIN'
: 'dom_ERROR_MODIFYING_DOMAIN') . ' Ctl');
}
unless ($domain) {
return (
$c->l(
$action eq 'create'
? 'dom_ERROR_CREATING_DOMAIN'
: 'dom_ERROR_MODIFYING_DOMAIN'
)
. ' Ctl'
);
} ## end unless ($domain)
$ddb = esmith::DomainsDB::UTF8->open || die "Couldn't open domains db";
my $rec = $ddb->get($domain);
if ($rec and $action eq 'create') {
return $c->l('dom_DOMAIN_IN_USE_ERROR');
}
if (not $rec and $action eq 'modify') {
return $c->l('dom_NONEXISTENT_DOMAIN_ERROR');
}
$rec ||= $ddb->new_record($domain, { type => 'domain' });
my %props;
$props{$_} = $c->param($_) for ( qw(Content Description Nameservers) );
$props{$_} = $c->param($_) for (qw(Content Description Nameservers));
$rec->merge_props(%props);
if ( system( "/sbin/e-smith/signal-event",
"domain-$action", "$domain" ) != 0 ) {
return ($c->l($action eq 'create' ? 'dom_ERROR_CREATING_DOMAIN'
: 'dom_ERROR_MODIFYING_DOMAIN') . " Exe $action");
}
if (system("/sbin/e-smith/signal-event", "domain-$action", "$domain") != 0) {
return (
$c->l(
$action eq 'create'
? 'dom_ERROR_CREATING_DOMAIN'
: 'dom_ERROR_MODIFYING_DOMAIN'
)
. " Exe $action"
);
} ## end if (system("/sbin/e-smith/signal-event"...))
return 'OK';
}
} ## end sub create_modify_domain
sub delete_domain {
my ($c, $domain) = @_;
$domain = $1 if ($domain =~ /^($REGEXP_DOMAIN)$/);
return ($c->l('dom_ERROR_WHILE_REMOVING_DOMAIN') . ' Ctl') unless ($domain);
my $rec = $ddb->get($domain);
return ($c->l('dom_NONEXISTENT_DOMAIN_ERROR')) if (not $rec);
$rec->set_prop('type', 'domain-deleted');
if (system("/sbin/e-smith/signal-event", "domain-delete", "$domain") != 0) {
return ($c->l('dom_ERROR_WHILE_REMOVING_DOMAIN') . 'Exe');
return ($c->l('dom_ERROR_WHILE_REMOVING_DOMAIN') . 'Exe');
}
$rec->delete;
return 'OK';
}
} ## end sub delete_domain
sub modify_dns {
my ($c, $forwarder, $forwarder2) = @_;
my $dnscache = $cdb->get('dnscache');
($forwarder, $forwarder2) = ($forwarder2, '')
if ($forwarder2 and not $forwarder);
if ($forwarder) {
$dnscache->set_prop('Forwarder', $forwarder);
$dnscache->set_prop('Forwarder', $forwarder);
} else {
$dnscache->delete_prop('Forwarder');
}
if ($forwarder2) {
$dnscache->set_prop('Forwarder2', $forwarder2);
} else {
$dnscache->delete_prop('Forwarder2');
$dnscache->delete_prop('Forwarder');
}
unless ( system( "/sbin/e-smith/signal-event", "dns-update" ) == 0 )
{
if ($forwarder2) {
$dnscache->set_prop('Forwarder2', $forwarder2);
} else {
$dnscache->delete_prop('Forwarder2');
}
unless (system("/sbin/e-smith/signal-event", "dns-update") == 0) {
return $c->l('dom_ERROR_UPDATING');
}
return 'OK';
}
} ## end sub modify_dns
sub existing_accounts_list {
my $c = shift;
my @existingAccounts = ( ['Administrator' => 'admin']);
my @existingAccounts = ([ 'Administrator' => 'admin' ]);
foreach my $a ($adb->get_all) {
if ($a->prop('type') =~ /(user|group)/) {
push @existingAccounts, [ $a->key => $a->key ];
}
if ($a->prop('type') eq "domain") {
my $target = $adb->get($a->prop('Account'));
unless ($target)
{
warn "WARNING: domain (" . $a->key . ") => missing Account("
. $a->prop('Account') . ")\n";
unless ($target) {
warn "WARNING: domain (" . $a->key . ") => missing Account(" . $a->prop('Account') . ")\n";
next;
}
push @existingAccounts, [ $a->key, $a->key ]
unless ($target->prop('type') eq "domain");
}
}
return(\@existingAccounts);
}
} ## end if ($a->prop('type') eq...)
} ## end foreach my $a ($adb->get_all)
return (\@existingAccounts);
} ## end sub existing_accounts_list
sub content_options_list {
my $c = shift;
my @options = ( [ $c->l('dom_PRIMARY_SITE') => 'Primary' ]);
my @options = ([ $c->l('dom_PRIMARY_SITE') => 'Primary' ]);
foreach ($adb->ibays) {
push @options, [ $_->prop('Name') => $_->key ]
if ($_->key ne 'Primary');
push @options, [ $_->prop('Name') => $_->key ]
if ($_->key ne 'Primary');
}
return \@options;
} ## end sub content_options_list
return \@options
}
sub get_content_value
{
my $c = shift;
sub get_content_value {
my $c = shift;
my $domain = shift;
return $domain ? $ddb->get_prop($domain, 'Content') : 'Primary';
}
} ## end sub get_content_value
sub get_description_value
{
sub get_description_value {
my $c = shift;
my $domain = $c->param('Domain') || undef;
return $ddb->get_prop($domain, 'Description');
}
} ## end sub get_description_value
sub nameserver_options_list {
my $c = shift;
my $c = shift;
my $domain = $c->param('Domain') || undef;
my @opts = qw(localhost internet);
my @opts = qw(localhost internet);
push @opts, 'corporate' if ($cdb->get_prop('dnscache', 'Forwarder'));
my $ns = ($ddb->get_prop($domain, 'Nameservers') || 'internet');
push @opts, $ns unless scalar grep { /^$ns$/ } @opts;
push @opts, $ns unless scalar grep {/^$ns$/} @opts;
my @options;
foreach (@opts) {
push @options, [ $c->l( "dom_$_" ) => $_ ];
push @options, [ $c->l("dom_$_") => $_ ];
}
return \@options;
}
} ## end sub nameserver_options_list
sub get_nameserver_value {
my $c = shift;
$ddb = esmith::DomainsDB::UTF8->open || die "Couldn't open domains db";
my $domain = $c->param('Domain') || undef;
return ($ddb->get_prop($domain, 'Nameservers') || 'internet');
}
} ## end sub get_nameserver_value
sub validate_Domain
{
my $c = shift;
sub validate_Domain {
my $c = shift;
my $domain = lc shift;
return ($domain =~ /^($REGEXP_DOMAIN)$/)
? 'OK'
: 'DOMAIN_NAME_VALIDATION_ERROR';
} ## end sub validate_Domain
return ($domain =~ /^($REGEXP_DOMAIN)$/) ? 'OK' :
'DOMAIN_NAME_VALIDATION_ERROR';
}
sub validate_Description {
sub validate_Description
{
# XXX - FIXME - NOTREACHED
# We used to use the Description in the Appletalk volume name
# which meant it needed validation. I don't see any reason to
# do this any more
my $c = shift;
my $c = shift;
my $description = shift;
return ($description =~ /^([\-\'\w][\-\'\w\s\.]*)$/) ? 'OK' :
'DOMAIN_DESCRIPTION_VALIDATION_ERROR';
}
return ($description =~ /^([\-\'\w][\-\'\w\s\.]*)$/)
? 'OK'
: 'DOMAIN_DESCRIPTION_VALIDATION_ERROR';
} ## end sub validate_Description
sub ip_number_or_blank {
# XXX - FIXME - we should push this down into CGI::FormMagick
my $c = shift;
my $c = shift;
my $ip = shift;
if (!defined($ip) || $ip eq "")
{
if (!defined($ip) || $ip eq "") {
return 'OK';
}
return ip_number( $c, $ip );
}
return ip_number($c, $ip);
} ## end sub ip_number_or_blank
sub ip_number {
# from CGI::FormMagick::Validator qw( ip_number );
# from CGI::FormMagick::Validator qw( ip_number );
my ($c, $data) = @_;
return undef unless defined $data;
return $c->l('FM_IP_NUMBER1') unless $data =~ /^[\d.]+$/;
my @octets = split /\./, $data;
my $dots = ($data =~ tr/.//);
return $c->l('FM_IP_NUMBER2') unless (scalar @octets == 4 and $dots == 3);
foreach my $octet (@octets) {
return $c->l("FM_IP_NUMBER3", $octet) if $octet > 255;
}
return 'OK';
}
} ## end sub ip_number
1;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -11,329 +11,256 @@ package SrvMngr::Controller::Groups;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::AccountsDB::UTF8;
use esmith::ConfigDB::UTF8;
#use Data::Dumper;
#use esmith::FormMagick::Panel::groups;
use esmith::AccountsDB;
our $cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
our ($cdb,$adb);
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %grp_datas = ();
my $title = $c->l('grp_FORM_TITLE');
my $title = $c->l('grp_FORM_TITLE');
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$grp_datas{trt} = 'LST';
my @groups;
if ($adb) {
@groups = $adb->groups();
}
$c->stash( title => $title, grp_datas => \%grp_datas, groups => \@groups );
$c->stash(title => $title, grp_datas => \%grp_datas, groups => \@groups);
$c->render(template => 'groups');
};
} ## end sub main
sub do_display {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LST');
my $group = $c->param('group');
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LST');
my $group = $c->param('group');
my %grp_datas = ();
my $title = $c->l('grp_FORM_TITLE');
my $title = $c->l('grp_FORM_TITLE');
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$grp_datas{'trt'} = $trt;
if ( $trt eq 'ADD' ) {
#nothing
}
if ($trt eq 'ADD') {
#nothing
}
if ( $trt eq 'UPD' ) {
my %members = ();
my %users = ();
if ($trt eq 'UPD') {
my %members = ();
my %users = ();
my $rec = $adb->get($group);
my $rec = $adb->get($group);
if ($rec and $rec->prop('type') eq 'group') {
if ($rec and $rec->prop('type') eq 'group') {
$grp_datas{group} = $group;
$grp_datas{description} = $rec->prop('Description') || '';
%members = @{ $c->gen_members_list($group) };
} ## end if ($rec and $rec->prop...)
$c->stash(members => \%members, users => \%users);
} ## end if ($trt eq 'UPD')
$grp_datas{group} = $group;
$grp_datas{description} = $rec->prop('Description') || '';
if ($trt eq 'DEL') {
my %members = ();
my %ibays = ();
my $rec = $adb->get($group);
%members = @{$c->gen_members_list( $group )};
}
if ($rec and $rec->prop('type') eq 'group') {
$grp_datas{group} = $group;
$grp_datas{description} = $rec->prop('Description') || '';
%members = @{ $c->gen_members_list($group) };
%ibays = @{ $c->gen_ibays_list($group) };
} ## end if ($rec and $rec->prop...)
$c->stash(members => \%members, ibays => \%ibays);
} ## end if ($trt eq 'DEL')
$c->stash( members => \%members, users => \%users );
}
if ( $trt eq 'DEL' ) {
my %members = ();
my %ibays = ();
my $rec = $adb->get($group);
if ($rec and $rec->prop('type') eq 'group') {
$grp_datas{group} = $group;
$grp_datas{description} = $rec->prop('Description') || '';
%members = @{$c->gen_members_list($group)};
%ibays = @{$c->gen_ibays_list($group)};
}
$c->stash( members => \%members, ibays => \%ibays );
if ($trt eq 'LST') {
my @groups;
if ($adb) {
@groups = $adb->groups();
}
if ( $trt eq 'LST' ) {
my @groups;
if ($adb) {
@groups = $adb->groups();
}
$c->stash( groups => \@groups );
}
$c->stash( title => $title, grp_datas => \%grp_datas );
$c->render( template => 'groups' );
};
$c->stash(groups => \@groups);
} ## end if ($trt eq 'LST')
$c->stash(title => $title, grp_datas => \%grp_datas);
$c->render(template => 'groups');
} ## end sub do_display
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LST');
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LST');
my $groupName = $c->param('groupName') || '';
my $title = $c->l('grp_FORM_TITLE');
my $title = $c->l('grp_FORM_TITLE');
my ($res, $result) = '';
my %grp_datas = ();
$grp_datas{'trt'} = $trt;
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$grp_datas{'trt'} = $trt;
$grp_datas{'group'} = $groupName;
my @members = ();
if ( $trt eq 'ADD' ) {
if ($trt eq 'ADD') {
my $groupDesc = $c->param('groupDesc');
@members = @{$c->every_param('groupMembers')};
@members = @{ $c->every_param('groupMembers') };
my $members = join(",", @members);
my $members = join ( ",", @members );
# controls
$res = $c->validate_group($groupName);
$result .= $res . '<br>' unless $res eq 'OK';
$res = $c->validate_group_length($groupName);
$result .= $res . '<br>' unless $res eq 'OK';
$res = $c->validate_group_naming_conflict($groupName);
$result .= $res . '<br>' unless $res eq 'OK';
$res = $c->validate_description($groupDesc);
$result .= $res . '<br>' unless $res eq 'OK';
$res = $c->validate_group_has_members(@members);
$result .= $res . '<br>' unless $res eq 'OK';
my %props = ('type', 'group', 'Description', $groupDesc, 'Members', $members);
$res = '';
# controls
$res = $c->validate_group( $groupName );
$result .= $res . '<br>' unless $res eq 'OK';
if (!$result) {
$adb->new_record($groupName, \%props);
$res = $c->validate_group_length( $groupName );
$result .= $res . '<br>' unless $res eq 'OK';
# Untaint groupName before use in system()
($groupName) = ($groupName =~ /^([a-z][\-\_\.a-z0-9]*)$/);
system("/sbin/e-smith/signal-event", "group-create", "$groupName") == 0
or $result .= $c->l('grp_CREATE_ERROR') . "\n";
} ## end if (!$result)
$res = $c->validate_group_naming_conflict( $groupName );
$result .= $res . '<br>' unless $res eq 'OK';
$res = $c->validate_description( $groupDesc );
$result .= $res . '<br>' unless $res eq 'OK';
$res = $c->validate_group_has_members( @members );
$result .= $res . '<br>' unless $res eq 'OK';
my %props = (
'type', 'group', 'Description',
$groupDesc, 'Members', $members
);
$res = '';
if ( ! $result ) {
$adb->new_record( $groupName, \%props );
# Untaint groupName before use in system()
($groupName) = ($groupName =~ /^([a-z][\-\_\.a-z0-9]*)$/);
system("/sbin/e-smith/signal-event", "group-create", "$groupName") == 0
or $result .= $c->l('qgp_CREATE_ERROR')."\n";
}
if ( ! $result ) {
$result = $c->l('grp_CREATED_GROUP') . ' ' . $groupName;
$res = 'OK';
}
}
if ( $trt eq 'UPD' ) {
if (!$result) {
$result = $c->l('grp_CREATED_GROUP') . ' ' . $groupName;
$res = 'OK';
}
} ## end if ($trt eq 'ADD')
if ($trt eq 'UPD') {
my $groupDesc = $c->param('groupDesc');
@members = @{$c->every_param('groupMembers')};
my $members = join ( ",", @members );
@members = @{ $c->every_param('groupMembers') };
my $members = join(",", @members);
# controls
$res = '';
$res = validate_description( $c, $groupDesc );
$result .= $res . '<br>' unless $res eq 'OK';
# controls
$res = '';
$res = validate_description($c, $groupDesc);
$result .= $res . '<br>' unless $res eq 'OK';
$res = validate_group_has_members($c, @members);
$result .= $res . '<br>' unless $res eq 'OK';
$res = '';
$res = validate_group_has_members( $c, @members );
$result .= $res . '<br>' unless $res eq 'OK';
if (!$result) {
$adb->get($groupName)->set_prop('Members', $members);
$adb->get($groupName)->set_prop('Description', $groupDesc);
$res = '';
if ( ! $result ) {
# Untaint groupName before use in system()
($groupName) = ($groupName =~ /^([a-z][\-\_\.a-z0-9]*)$/);
system("/sbin/e-smith/signal-event", "group-modify", "$groupName") == 0
or $result .= $c->l('grp_MODIFY_ERROR') . "\n";
} ## end if (!$result)
$adb->get($groupName)->set_prop( 'Members', $members );
$adb->get($groupName)->set_prop( 'Description', $groupDesc );
if (!$result) {
$result = $c->l('grp_MODIFIED_GROUP') . ' ' . $groupName;
$res = 'OK';
}
} ## end if ($trt eq 'UPD')
# Untaint groupName before use in system()
($groupName) = ($groupName =~ /^([a-z][\-\_\.a-z0-9]*)$/);
if ($trt eq 'DEL') {
if ($groupName =~ /^([a-z][\-\_\.a-z0-9]*)$/) {
$groupName = $1;
} else {
$result .= $c->l('grp_ERR_INTERNAL_FAILURE') . ':' . $groupName;
}
my $rec = $adb->get($groupName);
$result .= $c->l('grp_ERR_INTERNAL_FAILURE') . ':' . $groupName unless ($rec);
$res = '';
system("/sbin/e-smith/signal-event", "group-modify", "$groupName") ==0
or $result .= $c->l('qgp_MODIFY_ERROR')."\n";
}
if (!$result) {
$res = delete_group($c, $groupName);
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('grp_MODIFIED_GROUP') . ' ' . $groupName;
$res = 'OK';
}
}
if ( $trt eq 'DEL' ) {
if ($groupName =~ /^([a-z][\-\_\.a-z0-9]*)$/) {
$groupName = $1;
} else {
$result .= $c->l('grp_ERR_INTERNAL_FAILURE') . ':' . $groupName;
}
my $rec = $adb->get($groupName);
$result .= $c->l('grp_ERR_INTERNAL_FAILURE') . ':' . $groupName unless ($rec);
$res = '';
if ( ! $result ) {
$res = delete_group( $c, $groupName );
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('grp_DELETED_GROUP') . ' ' . $groupName;
$res = 'OK';
}
}
}
if (!$result) {
$result = $c->l('grp_DELETED_GROUP') . ' ' . $groupName;
$res = 'OK';
}
} ## end if (!$result)
} ## end if ($trt eq 'DEL')
# common parts
if ($res ne 'OK') {
$c->stash( error => $result );
my %members = @{$c->gen_members_list($groupName)};
$c->stash( title => $title, members => \%members, grp_datas => \%grp_datas );
return $c->render('groups');
}
$c->stash(error => $result);
my %members = @{ $c->gen_members_list($groupName) };
$c->stash(title => $title, members => \%members, grp_datas => \%grp_datas);
return $c->render('groups');
} ## end if ($res ne 'OK')
my $message = "'Groups' updates ($trt) DONE";
$c->app->log->info($message);
$c->flash( success => $result );
$c->flash(success => $result);
$c->redirect_to('/groups');
};
} ## end sub do_update
sub delete_group {
my ( $c, $groupName ) = @_;
my ($c, $groupName) = @_;
# Update the db account (1)
$adb->get($groupName)->set_prop('type', 'group-deleted');
# Untaint groupName before use in system()
($groupName) = ($groupName =~ /^([a-z][\-\_\.a-z0-9]*)$/);
return (system ("/sbin/e-smith/signal-event", "group-delete", "$groupName") ||
! $adb->get($groupName)->delete()) ?
$c->l('DELETE_ERROR') : 'OK';
}
return (system("/sbin/e-smith/signal-event", "group-delete", "$groupName") || !$adb->get($groupName)->delete())
? $c->l('DELETE_ERROR')
: 'OK';
} ## end sub delete_group
sub gen_members_list {
my ( $c, $group ) = @_;
my ($c, $group) = @_;
my @members = ();
my $rec = $adb->get($group);
@members = split ( /,/, $rec->prop('Members') ) if ( $rec );
my $rec = $adb->get($group);
@members = split(/,/, $rec->prop('Members')) if ($rec);
my %names;
foreach my $m (@members) {
my $name;
if ( $m eq 'admin' ) {
if ($m eq 'admin') {
$name = "Administrator";
} else {
$name = $adb->get($m)->prop('FirstName') . " " . $adb->get($m)->prop('LastName');
}
else {
$name = $adb->get($m)->prop('FirstName') . " "
. $adb->get($m)->prop('LastName');
}
$names{$m} = $name;
}
$names{$m} = $name;
} ## end foreach my $m (@members)
@members = %names;
return \@members;
}
} ## end sub gen_members_list
sub gen_ibays_list {
my ( $c, $group ) = @_;
my ($c, $group) = @_;
my %names;
foreach my $ibay ( $adb->ibays ) {
if ( $ibay->prop('Group') eq $group ) {
$names{$ibay->key} = $ibay->prop('Name');
foreach my $ibay ($adb->ibays) {
if ($ibay->prop('Group') eq $group) {
$names{ $ibay->key } = $ibay->prop('Name');
}
}
} ## end foreach my $ibay ($adb->ibays)
my @ibays = %names;
return \@ibays;
}
} ## end sub gen_ibays_list
sub gen_users_list {
my $c = shift;
my @users = sort { $a->key() cmp $b->key() } $adb->users();
my %names;
foreach my $user ( @users ) {
$names{$user->key} = $user->prop('FirstName') . " "
. $user->prop('LastName');
foreach my $user (@users) {
$names{ $user->key } = $user->prop('FirstName') . " " . $user->prop('LastName');
}
return \%names;
}
} ## end sub gen_users_list
=head1 VALIDATION
@@ -350,21 +277,17 @@ ok($panel->validate_is_group('ro2ot') eq 'NOT_A_GROUP', "Ro2ot is not a group");
=cut
sub validate_is_group () {
my $c = shift;
my $group = shift;
my $c = shift;
my $group = shift;
my @groups = $adb->groups();
my %groups = map { $_->key => 1 } @groups;
unless ( exists $groups{$group} ) {
unless (exists $groups{$group}) {
return ($c->l('grp_NOT_A_GROUP'));
}
return ("OK");
}
} ## end sub validate_is_group
=head2 validate_group_naming_conflict FM GROUPNAME
@@ -375,29 +298,21 @@ Returns "NAME_CONFLICT" if this group name conflicts with anything else
ok (undef, 'need testing for validate_naming_Conflicts');
=cut
sub validate_group_naming_conflict
{
my $c = shift;
sub validate_group_naming_conflict {
my $c = shift;
my $groupName = shift;
my $account = $adb->get($groupName);
my $account = $adb->get($groupName);
my $type;
if (defined $account)
{
$type = $account->prop('type');
}
elsif (defined getpwnam($groupName) || defined getgrnam($groupName))
{
$type = "system";
}
else
{
return('OK');
if (defined $account) {
$type = $account->prop('type');
} elsif (defined getpwnam($groupName) || defined getgrnam($groupName)) {
$type = "system";
} else {
return ('OK');
}
return ($c->l('grp_ACCOUNT_CONFLICT', $groupName, $type));
}
} ## end sub validate_group_naming_conflict
=head2 validate_group FM groupname
@@ -414,14 +329,14 @@ ok(validate_group('','f&oo') eq 'GROUP_CONTAINS_INVALD', 'f&oo is not a valid gr
=cut
sub validate_group {
my $c = shift;
my $c = shift;
my $groupName = shift;
unless ( $groupName =~ /^([a-z][\-\_\.a-z0-9]*)$/ ) {
unless ($groupName =~ /^([a-z][\-\_\.a-z0-9]*)$/) {
return $c->l('grp_GROUP_NAMING');
}
return ('OK');
}
} ## end sub validate_group
=head2 validate_group_length FM GROUPNAME
@@ -438,22 +353,21 @@ ok(($panel->validate_group_length('fooooooooooooooooo') eq 'GROUP_TOO_LONG'), "a
=cut
sub validate_group_length {
my $c = shift;
my $groupName = shift;
my $c = shift;
my $groupName = shift;
my $maxGroupNameLength = (
$cdb->get('maxGroupNameLength')
? $cdb->get('maxGroupNameLength')->prop('type')
: ""
)
|| 12;
my $maxGroupNameLength = ($cdb->get('maxGroupNameLength')
? $cdb->get('maxGroupNameLength')->prop('type')
: "") || 12;
if ( length $groupName > $maxGroupNameLength ) {
if (length $groupName > $maxGroupNameLength) {
return $c->l('grp_GROUP_TOO_LONG', $maxGroupNameLength);
}
else {
} else {
return ('OK');
}
}
} ## end sub validate_group_length
=head2 validate_group_has_members FM MEMBERS
@@ -473,17 +387,16 @@ ok(validate_group_has_members('') eq 'NO_MEMBERS', "We do ok with a group with
=cut
sub validate_group_has_members {
my $c = shift;
my $c = shift;
my @members = (@_);
my $count = @members;
if ( $count == 0 ) {
if ($count == 0) {
return ($c->l('grp_NO_MEMBERS'));
}
else {
} else {
return ('OK');
}
}
} ## end sub validate_group_has_members
=pod
@@ -492,16 +405,13 @@ Checks the supplied description. Period is allowed in description
=cut
sub validate_description
{
sub validate_description {
my ($c, $description) = @_;
if ( $description =~ /^([\-\'\w][\-\'\w\s\.]*)$/ ) {
if ($description =~ /^([\-\'\w][\-\'\w\s\.]*)$/) {
return ('OK');
}
else {
} else {
return ($c->l('FM_ERR_UNEXPECTED_DESC'));
}
}
1
} ## end sub validate_description
1

View File

@@ -11,107 +11,86 @@ package SrvMngr::Controller::Hostentries;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
#use Data::Dumper;
#use esmith::FormMagick::Panel::hostentries;
use esmith::DomainsDB;
use esmith::AccountsDB;
use esmith::HostsDB;
use esmith::NetworksDB;
use HTML::Entities;
use Net::IPv4Addr qw(ipv4_in_network);
use esmith::DomainsDB::UTF8;
use esmith::ConfigDB::UTF8;
use esmith::HostsDB::UTF8;
use esmith::NetworksDB::UTF8;
#use URI::Escape;
our $ddb = esmith::DomainsDB->open || die "Couldn't open hostentries db";
our $cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
our $hdb = esmith::HostsDB->open || die "Couldn't open hosts db";
our $ndb = esmith::NetworksDB->open || die "Couldn't open networks db";
our ($ddb,$cdb,$hdb,$ndb);
sub main {
my $c = shift;
$c->app->log->info( $c->log_req );
$c->app->log->info($c->log_req);
my %hos_datas = ();
my $title = $c->l('hos_FORM_TITLE');
my $notif = '';
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$hdb = esmith::HostsDB::UTF8->open || die "Couldn't open hosts db";
$ndb = esmith::NetworksDB::UTF8->open || die "Couldn't open networks db";
$hos_datas{trt} = 'LIST';
my %dom_hosts = ();
foreach my $d ( @{ domains_list() } ) {
foreach my $d (@{ domains_list() }) {
$dom_hosts{$d} = { COUNT => 0, HOSTS => [] };
if ( my @hosts = $hdb->get_hosts_by_domain($d) ) {
if (my @hosts = $hdb->get_hosts_by_domain($d)) {
$dom_hosts{$d}{'COUNT'} = scalar(@hosts);
# my @entries;
push @{ $dom_hosts{$d}{'HOSTS'} }, host_data($_) foreach (@hosts);
}
}
} ## end if (my @hosts = $hdb->...)
} ## end foreach my $d (@{ domains_list...})
$c->stash(
title => $title,
notif => $notif,
hos_datas => \%hos_datas,
dom_hosts => \%dom_hosts
);
$c->render( template => 'hostentries' );
}
$c->render(template => 'hostentries');
} ## end sub main
sub do_display {
my $c = shift;
$c->app->log->info( $c->log_req );
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = $c->param('trt') || 'LST';
my $hostname = $c->param('Hostname') || '';
$trt = 'ADD' if ( $rt eq 'hostentryadd' );
$trt = 'LST' if ( $trt ne 'DEL' && $trt ne 'UPD' && $trt ne 'ADD' );
$trt = 'ADD' if ($rt eq 'hostentryadd');
$trt = 'LST' if ($trt ne 'DEL' && $trt ne 'UPD' && $trt ne 'ADD');
my %hos_datas = ();
my $title = $c->l('hos_FORM_TITLE');
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$hdb = esmith::HostsDB::UTF8->open || die "Couldn't open hosts db";
$ndb = esmith::NetworksDB::UTF8->open || die "Couldn't open networks db";
my $notif = '';
$hos_datas{'trt'} = $trt;
if ( $trt eq 'ADD' ) {
if ($trt eq 'ADD') {
}
if ( $trt eq 'UPD' or $trt eq 'DEL' ) {
if ($trt eq 'UPD' or $trt eq 'DEL') {
my $rec = $hdb->get($hostname);
if ($rec) {
$hos_datas{hostname} = $rec->key;
( $hos_datas{name}, $hos_datas{domain} ) =
split_hostname($hostname);
($hos_datas{name}, $hos_datas{domain})
= split_hostname($hostname);
$hos_datas{internalip} = $rec->prop('InternalIP') || '';
$hos_datas{externalip} = $rec->prop('ExternalIP') || '';
$hos_datas{macaddress} = $rec->prop('MACAddress') || '';
$hos_datas{hosttype} = $rec->prop('HostType');
$hos_datas{comment} =
HTML::Entities::encode( $rec->prop('Comment') );
}
else {
$hos_datas{comment} = HTML::Entities::encode($rec->prop('Comment'));
} else {
$notif = "Hostname $hostname not found !";
}
}
} ## end if ($trt eq 'UPD' or $trt...)
#if ( $trt eq 'DEL' ) {
# my $rec = $hdb->get($hostname);
# if ( $rec ) {
# get_hos_datas( $rec, %hos_datas );
@@ -119,29 +98,24 @@ sub do_display {
# $notif = "Hostname $hostname not found !"
# }
#}
if ( $trt eq 'LIST' ) {
if ($trt eq 'LIST') {
}
$c->stash( title => $title, notif => $notif, hos_datas => \%hos_datas );
$c->render( template => 'hostentries' );
}
$c->stash(title => $title, notif => $notif, hos_datas => \%hos_datas);
$c->render(template => 'hostentries');
} ## end sub do_display
sub do_update {
my $c = shift;
$c->app->log->info( $c->log_req );
my $rt = $c->current_route;
my $trt = ( $c->param('trt') || 'LIST' );
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my %hos_datas = ();
my $title = $c->l('hos_FORM_TITLE');
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$hdb = esmith::HostsDB::UTF8->open || die "Couldn't open hosts db";
$ndb = esmith::NetworksDB::UTF8->open || die "Couldn't open networks db";
my $notif = '';
my $result = '';
$hos_datas{'name'} = lc $c->param('Name');
$hos_datas{'domain'} = lc $c->param('Domain');
$hos_datas{'hostname'} = $c->param('Hostname');
@@ -151,199 +125,180 @@ sub do_update {
$hos_datas{'macaddress'} = $c->param('Macaddress');
$hos_datas{'externalip'} = $c->param('Externalip');
my $hostname = "$hos_datas{'name'}.$hos_datas{'domain'}";
if ( $trt eq 'ADD' ) {
$hos_datas{'hostname'} = $hostname;
if ($trt eq 'ADD') {
$hos_datas{'hostname'} = $hostname;
# controls
my $res = '';
unless ( $hos_datas{'name'} =~ /^[a-z0-9][a-z0-9-]*$/ ) {
unless ($hos_datas{'name'} =~ /^[a-z0-9][a-z0-9-]*$/) {
$result .= $c->l('hos_HOSTNAME_VALIDATOR_ERROR') . '<br>';
}
unless ( $hos_datas{comment} =~ /^([a-zA-Z0-9][\_\.\-,A-Za-z0-9\s]*)$/
|| $hos_datas{comment} eq '' )
unless ($hos_datas{comment} =~ /^([a-zA-Z0-9][\_\.\-,A-Za-z0-9\s]*)$/
|| $hos_datas{comment} eq '')
{
$result .= $c->l('hos_HOSTNAME_COMMENT_ERROR') . '<br>';
}
} ## end unless ($hos_datas{comment...})
# Look for duplicate hosts.
my $hostrec = undef;
if ( $hostrec = $hdb->get($hostname) ) {
if ($hostrec = $hdb->get($hostname)) {
$result .= $c->l(
'hos_HOSTNAME_EXISTS_ERROR',
{
fullHostName => $hostname,
{ fullHostName => $hostname,
type => $hostrec->prop('HostType')
}
) . '<br>',;
}
} ## end if ($hostrec = $hdb->get...)
if ( !$result and $hos_datas{hosttype} ne 'Self' ) {
if ( $hos_datas{hosttype} eq 'Local' ) {
if (!$result and $hos_datas{hosttype} ne 'Self') {
if ($hos_datas{hosttype} eq 'Local') {
$hos_datas{'trt'} = 'ALC'; # ADD/LOCAL
}
else {
} else {
$hos_datas{'trt'} = 'ARM'; # ADD/REMOVE
}
$c->stash( title => $title, notif => '', hos_datas => \%hos_datas );
return $c->render( template => 'hostentries' );
}
$c->stash(title => $title, notif => '', hos_datas => \%hos_datas);
return $c->render(template => 'hostentries');
} ## end if (!$result and $hos_datas...)
#!#$result .= ' blocked';
if ( !$result ) {
$res = create_modify_hostentry( $c, $trt, %hos_datas );
if (!$result) {
$res = create_modify_hostentry($c, $trt, %hos_datas);
$result .= $res unless $res eq 'OK';
}
if ( !$result ) {
if (!$result) {
$result = $c->l('hos_CREATE_OR_MODIFY_SUCCEEDED') . ' ' . $hostname;
$trt = 'SUC';
}
}
} ## end if ($trt eq 'ADD')
if ( $trt eq 'UPD' ) {
if ($trt eq 'UPD') {
# controls
my $res = '';
#$res = validate_description( $c, $account );
#$result .= $res unless $res eq 'OK';
unless ( $hos_datas{comment} =~ /^([a-zA-Z0-9][\_\.\-,A-Za-z0-9\s]*)$/
|| $hos_datas{comment} eq '' )
unless ($hos_datas{comment} =~ /^([a-zA-Z0-9][\_\.\-,A-Za-z0-9\s]*)$/
|| $hos_datas{comment} eq '')
{
$result .= $c->l('hos_HOSTNAME_COMMENT_ERROR') . '<br>';
}
if ( !$result and $hos_datas{hosttype} ne 'Self' ) {
if ( $hos_datas{hosttype} eq 'Local' ) {
if (!$result and $hos_datas{hosttype} ne 'Self') {
if ($hos_datas{hosttype} eq 'Local') {
$hos_datas{'trt'} = 'ULC'; # UPDATE/LOCAL
}
else {
} else {
$hos_datas{'trt'} = 'URM'; # UPDATE/REMOVE
}
$c->stash( title => $title, notif => '', hos_datas => \%hos_datas );
return $c->render( template => 'hostentries' );
}
$c->stash(title => $title, notif => '', hos_datas => \%hos_datas);
return $c->render(template => 'hostentries');
} ## end if (!$result and $hos_datas...)
#!#$result .= 'blocked';
if ( !$result ) {
$res = create_modify_hostentry( $c, $trt, %hos_datas );
if (!$result) {
$res = create_modify_hostentry($c, $trt, %hos_datas);
$result .= $res unless $res eq 'OK';
}
if ( !$result ) {
if (!$result) {
$result = $c->l('hos_MODIFY_SUCCEEDED') . ' ' . $hostname;
$trt = 'SUC';
}
}
} ## end if ($trt eq 'UPD')
if ( $trt =~ /^.LC$/ ) {
if ($trt =~ /^.LC$/) {
# controls
my $res = '';
$res = ip_number( $c, $hos_datas{internalip} );
$res = ip_number($c, $hos_datas{internalip});
$result .= $res . ' ' unless $res eq 'OK';
$res = not_in_dhcp_range( $c, $hos_datas{internalip} );
$res = not_in_dhcp_range($c, $hos_datas{internalip});
$result .= $res . ' ' unless $res eq 'OK';
$res = not_taken( $c, $hos_datas{internalip} );
$res = not_taken($c, $hos_datas{internalip});
$result .= $res . ' ' unless $res eq 'OK';
$res = must_be_local( $c, $hos_datas{internalip} );
$res = must_be_local($c, $hos_datas{internalip});
$result .= $res . ' ' unless $res eq 'OK';
$res = mac_address_or_blank( $c, $hos_datas{macaddress} );
$res = mac_address_or_blank($c, $hos_datas{macaddress});
$result .= $res . ' ' unless $res eq 'OK';
#!#$result .= 'blocked';
if ( !$result ) {
$res = create_modify_hostentry( $c, $trt, %hos_datas );
if (!$result) {
$res = create_modify_hostentry($c, $trt, %hos_datas);
$result .= $res unless $res eq 'OK';
}
if ( !$result ) {
if (!$result) {
$result = $c->l('hos_MODIFY_SUCCEEDED') . ' ' . $hostname;
$trt = 'SUC';
}
}
} ## end if ($trt =~ /^.LC$/)
if ( $trt =~ /^.RM$/ ) {
if ($trt =~ /^.RM$/) {
# controls
my $res = '';
$res = ip_number_or_blank( $c, $hos_datas{externalip} );
$res = ip_number_or_blank($c, $hos_datas{externalip});
$result .= $res . '<br>' unless $res eq 'OK';
#!#$result .= 'blocked';
if ( !$result ) {
$res = create_modify_hostentry( $c, $trt, %hos_datas );
if (!$result) {
$res = create_modify_hostentry($c, $trt, %hos_datas);
$result .= $res unless $res eq 'OK';
}
if ( !$result ) {
if (!$result) {
$result = $c->l('hos_MODIFY_SUCCEEDED') . ' ' . $hostname;
$trt = 'SUC';
}
}
} ## end if ($trt =~ /^.RM$/)
#if ( $trt eq 'ULC' ) {
#}
#if ( $trt eq 'URM' ) {
#}
if ( $trt eq 'DEL' ) {
if ($trt eq 'DEL') {
# controls
my $res = '';
#$res = validate_is_hostentry($c, $hostname);
#$result .= $res unless $res eq 'OK';
#!#$result .= 'blocked';
if ( !$result ) {
my $res = delete_hostentry( $c, $hos_datas{hostname} );
if (!$result) {
my $res = delete_hostentry($c, $hos_datas{hostname});
$result .= $res unless $res eq 'OK';
}
if ( !$result ) {
if (!$result) {
$result = $c->l('hos_REMOVE_SUCCEEDED') . ' ' . $hostname;
$trt = 'SUC';
}
}
} ## end if ($trt eq 'DEL')
$hos_datas{'hostname'} = $hostname;
$hos_datas{'trt'} = $trt;
$c->stash(title => $title, notif => $result, hos_datas => \%hos_datas);
$c->stash( title => $title, notif => $result, hos_datas => \%hos_datas );
if ( $hos_datas{trt} ne 'SUC' ) {
return $c->render( template => 'hostentries' );
if ($hos_datas{trt} ne 'SUC') {
return $c->render(template => 'hostentries');
}
$c->redirect_to('/hostentries');
}
} ## end sub do_update
sub create_modify_hostentry {
my ( $c, $trt, %hos_datas ) = @_;
my ($c, $trt, %hos_datas) = @_;
my $hostname = $hos_datas{hostname};
my $action;
if ( $trt eq 'ADD' or $trt eq 'ALC' or $trt eq 'ARM' ) {
if ($trt eq 'ADD' or $trt eq 'ALC' or $trt eq 'ARM') {
$action = 'create';
}
if ( $trt eq 'UPD' or $trt eq 'ULC' or $trt eq 'URM' ) {
if ($trt eq 'UPD' or $trt eq 'ULC' or $trt eq 'URM') {
$action = 'modify';
}
@@ -353,20 +308,20 @@ sub create_modify_hostentry {
? $c->l('hos_ERROR_CREATING_HOST')
: $c->l('hos_ERROR_MODIFYING_HOST')
);
}
} ## end unless ($hostname)
# Untaint and lowercase $hostname
$hostname =~ /([\w\.-]+)/;
$hostname = lc($1);
my $rec = $hdb->get($hostname);
if ( $rec and $action eq 'create' ) {
if ($rec and $action eq 'create') {
return $c->l('hos_HOSTNAME_IN_USE_ERROR');
}
if ( not $rec and $action eq 'modify' ) {
if (not $rec and $action eq 'modify') {
return $c->l('hos_NONEXISTENT_HOSTNAME_ERROR');
}
my %props = (
type => 'host',
HostType => $hos_datas{hosttype},
@@ -376,240 +331,194 @@ sub create_modify_hostentry {
Comment => $hos_datas{comment},
);
if ( $action eq 'create' ) {
if ( $hdb->new_record( $hostname, \%props ) ) {
if (
system( "/sbin/e-smith/signal-event", "host-$action",
$hostname ) != 0
)
{
if ($action eq 'create') {
if ($hdb->new_record($hostname, \%props)) {
if (system("/sbin/e-smith/signal-event", "host-$action", $hostname) != 0) {
return $c->l('hos_ERROR_WHILE_CREATING_HOST');
}
}
}
} ## end if ($hdb->new_record($hostname...))
} ## end if ($action eq 'create')
if ( $action eq 'modify' ) {
if ( $rec->merge_props(%props) ) {
if (
system( "/sbin/e-smith/signal-event", "host-$action",
$hostname ) != 0
)
{
if ($action eq 'modify') {
if ($rec->merge_props(%props)) {
if (system("/sbin/e-smith/signal-event", "host-$action", $hostname) != 0) {
rturn $c->l('hos_ERROR_WHILE_MODIFYING_HOST');
}
}
}
} ## end if ($rec->merge_props(...))
} ## end if ($action eq 'modify')
return 'OK';
}
} ## end sub create_modify_hostentry
sub delete_hostentry {
my ( $c, $hostname ) = @_;
my ($c, $hostname) = @_;
# Untaint $hostname before use in system()
$hostname =~ /([\w\.-]+)/;
$hostname = $1;
return ( $c->l('hos_ERROR_WHILE_REMOVING_HOST') ) unless ($hostname);
return ($c->l('hos_ERROR_WHILE_REMOVING_HOST')) unless ($hostname);
my $rec = $hdb->get($hostname);
return ( $c->l('hos_NONEXISTENT_HOST_ERROR') ) if ( not $rec );
return ($c->l('hos_NONEXISTENT_HOST_ERROR')) if (not $rec);
if ( $rec->delete() ) {
if (
system( "/sbin/e-smith/signal-event", "host-delete", "$hostname" )
== 0 )
{
if ($rec->delete()) {
if (system("/sbin/e-smith/signal-event", "host-delete", "$hostname") == 0) {
return 'OK';
}
}
return ( $c->l('hos_ERROR_WHILE_DELETING_HOST') );
}
} ## end if ($rec->delete())
return ($c->l('hos_ERROR_WHILE_DELETING_HOST'));
} ## end sub delete_hostentry
sub domains_list {
my $d = esmith::DomainsDB->open_ro() or die "Couldn't open DomainsDB";
$ddb = esmith::DomainsDB::UTF8->open_ro() or die "Couldn't open DomainsDB";
my @domains;
for ( $d->domains ) {
my $ns = $_->prop("Nameservers") || 'localhost';
push @domains, $_->key if ( $ns eq 'localhost' );
}
for ($ddb->domains) {
my $ns = $_->prop("Nameservers") || 'localhost';
push @domains, $_->key if ($ns eq 'localhost');
}
return \@domains;
}
} ## end sub domains_list
sub host_data {
my $host_record = shift;
my $ht = $host_record->prop('HostType');
my $ip =
( $ht eq 'Self' ) ? $cdb->get_value('LocalIP')
: ( $ht eq 'Remote' ) ? $host_record->prop('ExternalIP')
: $host_record->prop('InternalIP');
my $ht = $host_record->prop('HostType');
my $ip
= ($ht eq 'Self') ? $cdb->get_value('LocalIP')
: ($ht eq 'Remote') ? $host_record->prop('ExternalIP')
: $host_record->prop('InternalIP');
my %data = (
'IP' => $ip,
'HostName' => $host_record->key(),
'HostType' => $host_record->prop('HostType'),
'MACAddress' => ( $host_record->prop('MACAddress') || '' ),
'Comment' => ( $host_record->prop('Comment') || '' ),
'static' => ( $host_record->prop('static') || 'no' )
'MACAddress' => ($host_record->prop('MACAddress') || ''),
'Comment' => ($host_record->prop('Comment') || ''),
'static' => ($host_record->prop('static') || 'no')
);
return \%data
}
return \%data;
} ## end sub host_data
sub hosttype_list {
my $c = shift;
return [
[ $c->l('SELF') => 'Self' ],
[ $c->l('LOCAL') => 'Local' ],
[ $c->l('REMOTE') => 'Remote' ]
];
return [ [ $c->l('SELF') => 'Self' ], [ $c->l('LOCAL') => 'Local' ], [ $c->l('REMOTE') => 'Remote' ] ];
}
sub split_hostname {
my $hostname = shift;
return ( $hostname =~ /^([^\.]+)\.(.+)$/ );
return ($hostname =~ /^([^\.]+)\.(.+)$/);
}
sub mac_address_or_blank {
my ( $c, $data ) = @_;
my ($c, $data) = @_;
return "OK" unless $data;
return mac_address( $c, $data );
}
return mac_address($c, $data);
} ## end sub mac_address_or_blank
sub mac_address {
# from CGI::FormMagick::Validator::Network
my ( $c, $data ) = @_;
my ($c, $data) = @_;
$_ = lc $data; # easier to match on $_
if ( not defined $_ ) {
if (not defined $_) {
return $c->l('FM_MAC_ADDRESS1');
}
elsif (/^([0-9a-f][0-9a-f](:[0-9a-f][0-9a-f]){5})$/) {
} elsif (/^([0-9a-f][0-9a-f](:[0-9a-f][0-9a-f]){5})$/) {
return "OK";
}
else {
} else {
return $c->l('FM_MAC_ADDRESS2');
}
}
} ## end sub mac_address
sub ip_number_or_blank {
# XXX - FIXME - we should push this down into CGI::FormMagick
my $c = shift;
my $ip = shift;
if ( !defined($ip) || $ip eq "" ) {
if (!defined($ip) || $ip eq "") {
return 'OK';
}
return ip_number( $c, $ip );
}
return ip_number($c, $ip);
} ## end sub ip_number_or_blank
sub ip_number {
# from CGI::FormMagick::Validator qw( ip_number );
my ( $c, $data ) = @_;
my ($c, $data) = @_;
return undef unless defined $data;
return $c->l('FM_IP_NUMBER1') unless $data =~ /^[\d.]+$/;
my @octets = split /\./, $data;
my $dots = ( $data =~ tr/.// );
return $c->l('FM_IP_NUMBER2') unless ( scalar @octets == 4 and $dots == 3 );
my $dots = ($data =~ tr/.//);
return $c->l('FM_IP_NUMBER2') unless (scalar @octets == 4 and $dots == 3);
foreach my $octet (@octets) {
return $c->l( "FM_IP_NUMBER3", $octet ) if $octet > 255;
return $c->l("FM_IP_NUMBER3", $octet) if $octet > 255;
}
return 'OK';
}
} ## end sub ip_number
sub not_in_dhcp_range {
my $c = shift;
my $address = shift;
my $status = $cdb->get('dhcpd')->prop('status') || "disabled";
my $status = $cdb->get('dhcpd')->prop('status') || "disabled";
return 'OK' unless $status eq "enabled";
my $start = $cdb->get('dhcpd')->prop('start');
my $end = $cdb->get('dhcpd')->prop('end');
return ( esmith::util::IPquadToAddr($start) <=
esmith::util::IPquadToAddr($address)
&& esmith::util::IPquadToAddr($address) <=
esmith::util::IPquadToAddr($end) )
? $c->l('hos_ADDR_IN_DHCP_RANGE')
: 'OK';
}
return ( esmith::util::IPquadToAddr($start) <= esmith::util::IPquadToAddr($address)
&& esmith::util::IPquadToAddr($address) <= esmith::util::IPquadToAddr($end))
? $c->l('hos_ADDR_IN_DHCP_RANGE')
: 'OK';
} ## end sub not_in_dhcp_range
sub not_taken {
my $c = shift;
my $localip = shift;
my $server_localip = $cdb->get_value('LocalIP') || '';
my $server_gateway = $cdb->get_value('GatewayIP') || '';
my $c = shift;
my $localip = shift;
my $server_localip = $cdb->get_value('LocalIP') || '';
my $server_gateway = $cdb->get_value('GatewayIP') || '';
my $server_extip = $cdb->get_value('ExternalIP') || '';
#$c->debug_msg("\$localip is $localip");
#$c->debug_msg("\$server_localip is $server_localip");
#$c->debug_msg("\$server_gateway is $server_gateway");
#$c->debug_msg("\$server_extip is $server_extip");
if ( $localip eq $server_localip ) {
if ($localip eq $server_localip) {
return $c->l('hos_ERR_IP_IS_LOCAL_OR_GATEWAY');
}
if ( $localip eq $server_gateway ) {
if ($localip eq $server_gateway) {
return $c->l('hos_ERR_IP_IS_LOCAL_OR_GATEWAY');
}
if ( ( $cdb->get_value('SystemMode') ne 'serveronly' )
&& ( $server_extip eq $localip ) )
if ( ($cdb->get_value('SystemMode') ne 'serveronly')
&& ($server_extip eq $localip))
{
return $c->l('hos_ERR_IP_IS_LOCAL_OR_GATEWAY');
}
} ## end if (($cdb->get_value('SystemMode'...)))
if ( $localip eq '127.0.0.1' ) {
if ($localip eq '127.0.0.1') {
return $c->l('hos_ERR_IP_IS_LOCAL_OR_GATEWAY');
}
else {
} else {
return 'OK';
}
}
} ## end sub not_taken
sub must_be_local {
my $c = shift;
my $localip = shift;
# Make sure that the IP is indeed local.
#my $ndb = esmith::NetworksDB->open_ro;
#$ndb = esmith::NetworksDB::UTF8->open_ro;
my @local_list = $ndb->local_access_spec;
foreach my $spec (@local_list) {
next if $spec eq '127.0.0.1';
if ( eval { Net::IPv4Addr::ipv4_in_network( $spec, $localip ) } ) {
if (eval { Net::IPv4Addr::ipv4_in_network($spec, $localip) }) {
return 'OK';
}
}
} ## end foreach my $spec (@local_list)
# Not OK. The IP is not on any of our local networks.
return $c->l('hos_ERR_IP_NOT_LOCAL');
}
} ## end sub must_be_local
1;

View File

@@ -2,291 +2,261 @@ package SrvMngr::Controller::Ibays;
#----------------------------------------------------------------------
# heading : Network
# description : Shared areas (was ibays)
# description : Ibays
# navigation : 6000 100
#
#
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw( theme_list init_session is_normal_password );
use SrvMngr qw( theme_list init_session validate_password );
use esmith::AccountsDB::UTF8;
use esmith::ConfigDB::UTF8;
use esmith::DomainsDB::UTF8;
use esmith::AccountsDB;
use esmith::ConfigDB;
use esmith::DomainsDB;
#use esmith::FormMagick::Panel::ibays;
our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
our $cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
my ($adb,$cdb);
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %iba_datas = ();
my $title = $c->l('iba_FORM_TITLE');
my $title = $c->l('iba_FORM_TITLE');
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
$iba_datas{'trt'} = 'LIST';
my @ibays;
if ($adb)
{
if ($adb) {
@ibays = $adb->ibays();
}
$c->stash( title => $title, iba_datas => \%iba_datas, ibays => \@ibays );
$c->stash(title => $title, iba_datas => \%iba_datas, ibays => \@ibays);
$c->render(template => 'ibays');
};
} ## end sub main
sub do_display {
my $c = shift;
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $c = shift;
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $ibay = $c->param('ibay') || '';
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
#$trt = 'DEL' if ( $ibay );
#$trt = 'ADD' if ( $rt eq 'ibayadd' );
my %iba_datas = ();
my $title = $c->l('iba_FORM_TITLE');
my $modul = '';
my $title = $c->l('iba_FORM_TITLE');
my $modul = '';
$iba_datas{'trt'} = $trt;
if ( $trt eq 'ADD' ) {
if ($trt eq 'ADD') {
$iba_datas{ibay} = '';
$iba_datas{description} = '';
$iba_datas{group} = '';
$iba_datas{userAccess} = '';
$iba_datas{publicAccess} = '';
$iba_datas{CgiBin} = '';
$iba_datas{SSL} = '';
} ## end if ($trt eq 'ADD')
$iba_datas{ibay} = '';
$iba_datas{description} = '';
$iba_datas{group} = '';
$iba_datas{userAccess} = '';
$iba_datas{publicAccess} = '';
$iba_datas{CgiBin} = '';
$iba_datas{SSL} = '';
if ($trt eq 'UPD') {
my $rec = $adb->get($ibay);
if ($rec and $rec->prop('type') eq 'ibay') {
$iba_datas{ibay} = $ibay;
$iba_datas{description} = $rec->prop('Name') || '';
$iba_datas{group} = $rec->prop('Group') || '';
$iba_datas{userAccess} = $rec->prop('UserAccess') || '';
$iba_datas{publicAccess} = $rec->prop('PublicAccess') || '';
$iba_datas{CgiBin} = $rec->prop('CgiBin') || 'disabled';
$iba_datas{SSL} = $rec->prop('SSL') || 'disabled';
} ## end if ($rec and $rec->prop...)
} ## end if ($trt eq 'UPD')
if ($trt eq 'DEL') {
my $rec = $adb->get($ibay);
if ($rec and $rec->prop('type') eq 'ibay') {
$iba_datas{ibay} = $ibay;
$iba_datas{description} = $rec->prop('Name') || '';
$modul .= print_vhost_message($c, $ibay);
} ## end if ($rec and $rec->prop...)
} ## end if ($trt eq 'DEL')
if ($trt eq 'PWD') {
my $rec = $adb->get($ibay);
if ($rec and $rec->prop('type') eq 'ibay') {
$iba_datas{ibay} = $ibay;
$iba_datas{description} = $rec->prop('Name') || '';
}
} ## end if ($trt eq 'PWD')
if ( $trt eq 'UPD' ) {
if ($trt eq 'LIST') {
my @ibays;
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
my $rec = $adb->get($ibay);
if ($rec and $rec->prop('type') eq 'ibay') {
$iba_datas{ibay} = $ibay;
$iba_datas{description} = $rec->prop('Name') || '';
$iba_datas{group} = $rec->prop('Group') || '';
$iba_datas{userAccess} = $rec->prop('UserAccess') || '';
$iba_datas{publicAccess} = $rec->prop('PublicAccess') || '';
$iba_datas{CgiBin} = $rec->prop('CgiBin') || 'disabled';
$iba_datas{SSL} = $rec->prop('SSL') || 'disabled';
}
if ($adb) {
@ibays = $adb->ibays();
}
if ( $trt eq 'DEL' ) {
my $rec = $adb->get($ibay);
if ($rec and $rec->prop('type') eq 'ibay') {
$iba_datas{ibay} = $ibay;
$iba_datas{description} = $rec->prop('Name') || '';
$modul .= print_vhost_message( $c, $ibay );
}
}
if ( $trt eq 'PWD' ) {
my $rec = $adb->get($ibay);
if ($rec and $rec->prop('type') eq 'ibay') {
$iba_datas{ibay} = $ibay;
$iba_datas{description} = $rec->prop('Name') || '';
}
}
if ( $trt eq 'LIST' ) {
my @ibays;
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
if ($adb)
{
@ibays = $adb->ibays();
}
$c->stash( ibays => \@ibays );
}
$c->stash( title => $title, modul => $modul, iba_datas => \%iba_datas );
$c->render( template => 'ibays' );
};
$c->stash(ibays => \@ibays);
} ## end if ($trt eq 'LIST')
$c->stash(title => $title, modul => $modul, iba_datas => \%iba_datas);
$c->render(template => 'ibays');
} ## end sub do_display
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my %iba_datas = ();
my $title = $c->l('iba_FORM_TITLE');
my $title = $c->l('iba_FORM_TITLE');
$iba_datas{'trt'} = $trt;
my $result = '';
my $res;
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
if ( $trt eq 'ADD' ) {
if ($trt eq 'ADD') {
my $name = ($c->param('ibay') || '');
my $name = ($c->param('ibay') || '');
# controls
$res = validate_ibay($c, $name);
$result .= $res unless $res eq 'OK';
# controls
$res = validate_ibay( $c, $name );
$result .= $res unless $res eq 'OK';
if (!$result) {
$res = create_ibay($c, $name);
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$res = create_ibay( $c, $name );
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('iba_SUCCESSFULLY_CREATED_IBAY') . ' ' . $name;
$iba_datas{trt} = 'LST';
}
}
}
if (!$result) {
$result = $c->l('iba_SUCCESSFULLY_CREATED_IBAY') . ' ' . $name;
$iba_datas{trt} = 'LST';
}
} ## end if (!$result)
} ## end if ($trt eq 'ADD')
if ( $trt eq 'UPD' ) {
if ($trt eq 'UPD') {
my $name = ($c->param('ibay') || '');
my $name = ($c->param('ibay') || '');
# controls
$res = '';
# controls
$res = '';
if (!$result) {
$res = modify_ibay($c, $name);
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$res = modify_ibay( $c, $name );
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('iba_SUCCESSFULLY_MODIFIED_IBAY') . ' ' . $name;
$iba_datas{trt} = 'LST';
}
}
}
if (!$result) {
$result = $c->l('iba_SUCCESSFULLY_MODIFIED_IBAY') . ' ' . $name;
$iba_datas{trt} = 'LST';
}
} ## end if (!$result)
} ## end if ($trt eq 'UPD')
if ( $trt eq 'PWD' ) {
my $ibay = ($c->param('ibay') || '');
my $pass1 = ($c->param('newPass') || '');
if ($trt eq 'PWD') {
my $ibay = ($c->param('ibay') || '');
my $pass1 = ($c->param('newPass') || '');
my $pass2 = ($c->param('newPassVerify') || '');
# controls
# controls
unless ($pass1 eq $pass2) {
$result .= $c->l('iba_IBAY_PASSWD_VERIFY_ERROR') . ' - ';
}
}
$res = check_password($c, $pass1);
$result .= $res unless $res eq 'OK';
$res = check_password( $c, $pass1 );
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$res = reset_password( $c, $ibay, $pass1 );
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('iba_SUCCESSFULLY_RESET_PASSWORD') . ' ' . $ibay;
$iba_datas{trt} = 'LST';
}
}
}
if (!$result) {
$res = reset_password($c, $ibay, $pass1);
$result .= $res unless $res eq 'OK';
if ( $trt eq 'DEL' ) {
my $ibay = $c->param ('ibay');
if (!$result) {
$result = $c->l('iba_SUCCESSFULLY_RESET_PASSWORD') . ' ' . $ibay;
$iba_datas{trt} = 'LST';
}
} ## end if (!$result)
} ## end if ($trt eq 'PWD')
if ($ibay =~ /^([a-z][a-z0-9]*)$/) {
$ibay = $1;
} else {
$result .= $c->l('iba_ERR_INTERNAL_FAILURE') . ':' . $ibay;
}
if ($trt eq 'DEL') {
my $ibay = $c->param('ibay');
if ( ! $result ) {
$res = remove_ibay( $c, $ibay );
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('iba_SUCCESSFULLY_DELETED_IBAY') . ' ' . $ibay;
$iba_datas{trt} = 'LST';
}
}
}
if ($ibay =~ /^([a-z][a-z0-9]*)$/) {
$ibay = $1;
} else {
$result .= $c->l('iba_ERR_INTERNAL_FAILURE') . ':' . $ibay;
}
if (!$result) {
$res = remove_ibay($c, $ibay);
$result .= $res unless $res eq 'OK';
if (!$result) {
$result = $c->l('iba_SUCCESSFULLY_DELETED_IBAY') . ' ' . $ibay;
$iba_datas{trt} = 'LST';
}
} ## end if (!$result)
} ## end if ($trt eq 'DEL')
# common parts
if ($res ne 'OK') {
$c->stash( error => $result );
$c->stash( title => $title, iba_datas => \%iba_datas );
return $c->render('ibays');
$c->stash(error => $result);
$c->stash(title => $title, iba_datas => \%iba_datas);
return $c->render('ibays');
}
my $message = "'Ibays' updates ($trt) DONE";
$c->app->log->info($message);
$c->flash( success => $result );
$c->flash(success => $result);
$c->redirect_to('/ibays');
};
} ## end sub do_update
sub validate_ibay {
my ($c, $name) = @_;
my $msg = validate_name($c, $name);
unless ($msg eq "OK")
{
unless ($msg eq "OK") {
return ($msg);
}
$msg = max_ibay_name_length($c, $name);
unless ($msg eq "OK")
{
unless ($msg eq "OK") {
return ($msg);
}
$msg = conflict_check($c, $name);
unless ($msg eq "OK")
{
unless ($msg eq "OK") {
return ($msg);
}
return ('OK');
}
} ## end sub validate_ibay
sub create_ibay {
my ($c, $name) = @_;
my $msg;
my $uid = $adb->get_next_uid();
if (my $acct = $adb->new_record($name, {
Name => $c->param('ibayDesc'),
CgiBin => $c->param('CgiBin'),
Group => $c->param('group'),
PublicAccess => $c->param('publicAccess'),
SSL => $c->param('SSL'),
UserAccess => $c->param('userAccess'),
Uid => $uid,
Gid => $uid,
PasswordSet => 'no',
type => 'ibay',
}) )
my $uid = $adb->get_next_uid();
if (my $acct = $adb->new_record(
$name,
{ Name => $c->param('ibayDesc'),
CgiBin => $c->param('CgiBin'),
Group => $c->param('group'),
PublicAccess => $c->param('publicAccess'),
SSL => $c->param('SSL'),
UserAccess => $c->param('userAccess'),
Uid => $uid,
Gid => $uid,
PasswordSet => 'no',
type => 'ibay',
}
)
)
{
# Untaint $name before use in system()
$name =~ /(.+)/; $name = $1;
if (system ("/sbin/e-smith/signal-event", "ibay-create", $name) == 0) {
$name =~ /(.+)/;
$name = $1;
if (system("/sbin/e-smith/signal-event", "ibay-create", $name) == 0) {
$msg = 'OK';
} else {
$msg = $c->l('iba_ERROR_WHILE_CREATING_IBAY');
@@ -295,14 +265,12 @@ sub create_ibay {
$msg = $c->l('iba_CANT_CREATE_IBAY');
}
return $msg;
}
} ## end sub create_ibay
sub modify_ibay {
my ($c, $name) = @_;
my $msg;
if (my $acct = $adb->get($name)) {
if ($acct->prop('type') eq 'ibay') {
$acct->merge_props(
@@ -315,10 +283,10 @@ sub modify_ibay {
);
# Untaint $name before use in system()
$name =~ /(.+)/; $name = $1;
if (system ("/sbin/e-smith/signal-event", "ibay-modify",
$name) == 0)
{
$name =~ /(.+)/;
$name = $1;
if (system("/sbin/e-smith/signal-event", "ibay-modify", $name) == 0) {
$msg = 'OK';
} else {
$msg = $c->l('iba_ERROR_WHILE_MODIFYING_IBAY');
@@ -329,53 +297,47 @@ sub modify_ibay {
} else {
$msg = $c->l('iba_CANT_FIND_IBAY');
}
return $msg;
}
} ## end sub modify_ibay
sub print_vhost_message {
my $c = shift;
my $name = $c->param('ibay');
my $c = shift;
my $name = $c->param('ibay');
my $result = '';
my $domaindb = esmith::DomainsDB::UTF8->open();
my @domains = $domaindb->get_all_by_prop(Content => $name);
my $vhostListItems = join "\n", (map ($_->key . " " . $_->prop('Description'), @domains));
my $result = '';
my $domaindb = esmith::DomainsDB->open();
my @domains = $domaindb->get_all_by_prop(Content => $name);
my $vhostListItems = join "\n",
(map ($_->key." ".$_->prop('Description'), @domains));
if ($vhostListItems)
{
if ($vhostListItems) {
$result = $c->l('iba_VHOST_MESSAGE') . "<br><ul>";
foreach ( $vhostListItems ) {
$result .= "<li> $_ </li>";
}
$result .= '</ul>'
}
return $result;
}
foreach ($vhostListItems) {
$result .= "<li> $_ </li>";
}
$result .= '</ul>';
} ## end if ($vhostListItems)
return $result;
} ## end sub print_vhost_message
sub remove_ibay {
my ($c, $name) = @_;
my $msg = '';
if (my $acct = $adb->get($name)) {
if ($acct->prop('type') eq 'ibay') {
$acct->set_prop('type', 'ibay-deleted');
my $domains_db = esmith::DomainsDB::UTF8->open();
my @domains = $domains_db->get_all_by_prop(Content => $name);
my $domains_db = esmith::DomainsDB->open();
my @domains = $domains_db->get_all_by_prop(Content=>$name);
foreach my $d (@domains) {
$d->set_prop(Content => 'Primary');
}
# Untaint $name before use in system()
$name =~ /(.+)/; $name = $1;
if (system ("/sbin/e-smith/signal-event", "ibay-delete",
$name) == 0)
{
$name =~ /(.+)/;
$name = $1;
if (system("/sbin/e-smith/signal-event", "ibay-delete", $name) == 0) {
$msg = 'OK';
$acct->delete();
} else {
@@ -384,27 +346,25 @@ sub remove_ibay {
} else {
$msg = $c->l('iba_CANT_FIND_IBAY');
}
} else {
$msg = $c->l('iba_CANT_FIND_IBAY');
}
return $msg;
}
} ## end sub remove_ibay
sub reset_password {
my ($c, $name, $newPass) = @_;
my ($msg, $acct);
if (($acct = $adb->get($name)) && ($acct->prop('type') eq 'ibay')) {
esmith::util::setIbayPassword ($acct->key, $newPass);
esmith::util::setIbayPassword($acct->key, $newPass);
$acct->set_prop('PasswordSet', 'yes');
# Untaint $name before use in system()
$name =~ /(.+)/; $name = $1;
if (system ("/sbin/e-smith/signal-event", "password-modify",
$name) == 0)
{
$name =~ /(.+)/;
$name = $1;
if (system("/sbin/e-smith/signal-event", "password-modify", $name) == 0) {
$msg = 'OK';
} else {
$msg = $c->l('iba_ERROR_WHILE_RESETTING_PASSWORD');
@@ -413,51 +373,15 @@ sub reset_password {
$msg = $c->l('iba_CANT_FIND_IBAY');
}
return $msg;
}
} ## end sub reset_password
sub check_password {
my ($c, $password) = @_;
my $strength;
my $rec = $cdb->get('passwordstrength');
$strength = ($rec ? ($rec->prop('Ibays') || 'none') : 'none');
return validate_password( $c, $strength, $password );
}
sub validate_password {
my ($c, $strength, $pass) = @_;
use Crypt::Cracklib;
my $reason;
if ($strength eq "none") {
return $c->l("Passwords must be at least 7 characters long") unless (length($pass) > 6);
return "OK";
}
$reason = is_normal_password($c, $pass, undef);
return $reason unless ($reason eq "OK");
return "OK" unless ($strength eq "strong");
if ( -f '/usr/lib64/cracklib_dict.pwd' ) {
$reason = fascist_check($pass, '/usr/lib64/cracklib_dict');
} else {
$reason = fascist_check($pass, '/usr/lib/cracklib_dict');
}
$reason ||= "Software error: password check failed";
return "OK" if ($reason eq "ok");
return $c->l("Bad Password Choice") . ": "
. $c->l("The password you have chosen is not a good choice, because")
. " " . $c->($reason) . ".";
}
return validate_password($c, $strength, $password);
} ## end sub check_password
=head2 group_list()
@@ -468,18 +392,14 @@ drop down list.
=cut
sub group_list_m {
my @groups = $adb->groups();
my @grps = ( ['Admin' => 'admin'], ['Everyone' => 'shared']);
my @grps = ([ 'Admin' => 'admin' ], [ 'Everyone' => 'shared' ]);
foreach my $g (@groups) {
push @grps, [ $g->prop('Description')." (". $g->key.")", $g->key() ];
push @grps, [ $g->prop('Description') . " (" . $g->key . ")", $g->key() ];
}
return \@grps;
}
} ## end sub group_list_m
=head2 userAccess_list
@@ -489,13 +409,13 @@ drop down list.
=cut
sub userAccess_list_m {
my $c = shift;
return [[ $c->l('WARG') => 'wr-admin-rd-group'],
[ $c->l('WGRE') => 'wr-group-rd-everyone'],
[ $c->l('WGRG') => 'wr-group-rd-group']];
}
return [
[ $c->l('WARG') => 'wr-admin-rd-group' ],
[ $c->l('WGRE') => 'wr-group-rd-everyone' ],
[ $c->l('WGRG') => 'wr-group-rd-group' ]
];
} ## end sub userAccess_list_m
=head2 publicAccess_list
@@ -505,19 +425,18 @@ access drop down list.
=cut
sub publicAccess_list_m {
my $c = shift;
return [[ $c->l('NONE') => 'none'],
[ $c->l('LOCAL_NETWORK_NO_PASSWORD') => 'local'],
[ $c->l('LOCAL_NETWORK_PASSWORD') => 'local-pw'],
[ $c->l('ENTIRE_INTERNET_NO_PASSWORD') => 'global'],
[ $c->l('ENTIRE_INTERNET_PASSWORD') => 'global-pw'],
[ $c->l('ENTIRE_INTERNET_PASSWORD_REMOTE') => 'global-pw-remote']];
}
return [
[ $c->l('NONE') => 'none' ],
[ $c->l('LOCAL_NETWORK_NO_PASSWORD') => 'local' ],
[ $c->l('LOCAL_NETWORK_PASSWORD') => 'local-pw' ],
[ $c->l('ENTIRE_INTERNET_NO_PASSWORD') => 'global' ],
[ $c->l('ENTIRE_INTERNET_PASSWORD') => 'global-pw' ],
[ $c->l('ENTIRE_INTERNET_PASSWORD_REMOTE') => 'global-pw-remote' ]
];
} ## end sub publicAccess_list_m
sub max_ibay_name_length {
my ($c, $data) = @_;
$cdb->reload();
my $max = $cdb->get('maxIbayNameLength')->value;
@@ -526,52 +445,42 @@ sub max_ibay_name_length {
return "OK";
} else {
return $c->l('iba_MAX_IBAY_NAME_LENGTH_ERROR', $data, $max, $max);
# {acctName => $data,
# maxIbayNameLength => $max,
# maxLength => $max});
}
}
# {acctName => $data,
# maxIbayNameLength => $max,
# maxLength => $max});
} ## end else [ if (length($data) <= $max)]
} ## end sub max_ibay_name_length
sub conflict_check {
my ($c, $name) = @_;
my $rec = $adb->get($name);
my $type;
if (defined $rec)
{
my $type = $rec->prop('type');
if ($type eq "pseudonym")
{
my $acct = $rec->prop("Account");
my $acct_type = $adb->get($acct)->prop('type');
return $c->l('iba_ACCT_CLASHES_WITH_PSEUDONYM', $name, $acct_type, $acct);
}
}
elsif (defined getpwnam($name) || defined getgrnam($name))
{
if (defined $rec) {
my $type = $rec->prop('type');
if ($type eq "pseudonym") {
my $acct = $rec->prop("Account");
my $acct_type = $adb->get($acct)->prop('type');
return $c->l('iba_ACCT_CLASHES_WITH_PSEUDONYM', $name, $acct_type, $acct);
} ## end if ($type eq "pseudonym")
} elsif (defined getpwnam($name) || defined getgrnam($name)) {
$type = 'system';
}
else
{
} else {
# No account record and no account
return 'OK';
}
return $c->l('iba_ACCOUNT_EXISTS', $name, $type);
}
} ## end sub conflict_check
sub validate_name {
my ($c, $acctName) = @_;
unless ($acctName =~ /^([a-z][\_\.\-a-z0-9]*)$/)
{
unless ($acctName =~ /^([a-z][\_\.\-a-z0-9]*)$/) {
return $c->l('iba_ACCT_NAME_HAS_INVALID_CHARS', $acctName);
}
return "OK";
}
} ## end sub validate_name
1

View File

@@ -9,29 +9,18 @@ package SrvMngr::Controller::Initial;
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
#use SrvMngr::Model::Main;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('initial_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('initial_FRAMES_BODY'));
$c->stash( title => $title, modul => $modul );
$c->stash(title => $title, modul => $modul);
$c->render(template => 'initial');
}
} ## end sub main
1;

View File

@@ -10,37 +10,27 @@ package SrvMngr::Controller::Legacypanel;
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
#use SrvMngr::Model::Main;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('legacy panel');
my $legacy_url = $c->param('url');
my $title = $c->l('legacy panel');
my $legacy_url = $c->param('url');
my $legacy_height = $c->param('height') | 600;
$c->stash( title => $title, modul => $legacy_url, height => $legacy_height );
$c->stash(title => $title, modul => $legacy_url, height => $legacy_height);
$c->render(template => 'embedded');
}
} ## end sub main
sub getlegacyurl {
my $c = shift;
my $url = shift;
return "/smanager/legacypanel?url=$url";
}
my $c = shift;
my $url = shift;
return "/smanager/legacypanel?url=$url";
} ## end sub getlegacyurl
1;

View File

@@ -4,288 +4,299 @@ package SrvMngr::Controller::Localnetworks;
# heading : Network
# description : Local networks
# navigation : 6000 500
#
#
#$if_admin->get('/localnetworks')->to('localnetworks#main')->name('localnetworks');
#$if_admin->post('/localnetworks')->to('localnetworks#do_display')->name('localnetworks');
#$if_admin->post('/localnetworksa')->to('localnetworks#do_display')->name('localnetworksadd');
#$if_admin->post('/localnetworksb')->to('localnetworks#do_display')->name('localnetworksadd1');
#$if_admin->get('/localnetworksd')->to('localnetworks#do_display')->name('localnetworksdel');
#$if_admin->post('/localnetworkse')->to('localnetworks#do_display')->name('localnetworksdel1');
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session subnet_mask get_reg_mask ip_number);
#use Data::Dumper;
use esmith::util;
use esmith::HostsDB;
my $network_db = esmith::NetworksDB->open() || die("Couldn't open networks db");
use esmith::HostsDB::UTF8;
use esmith::NetworksDB::UTF8;
use esmith::ConfigDB::UTF8;
my $ret = "OK";
our ($network_db,$config_db);
sub main {
my $c = shift;
$c->app->log->info( $c->log_req );
$c->app->log->info($c->log_req);
my %ln_datas = ();
$ln_datas{return} = "";
my $title = $c->l('ln_LOCAL NETWORKS');
$network_db = esmith::NetworksDB::UTF8->open() || die("Couldn't open networks db");
my $modul = '';
$ln_datas{trt} = 'LIST';
my @localnetworks;
if ($network_db) {
@localnetworks = $network_db->get_all_by_prop( type => 'network' );
}
if ($network_db) {
@localnetworks = $network_db->get_all_by_prop(type => 'network');
}
$c->stash(
title => $title,
modul => $modul,
ln_datas => \%ln_datas,
localnetworks => \@localnetworks
);
$c->render( template => 'localnetworks' );
}
$c->render(template => 'localnetworks');
} ## end sub main
sub do_display {
my $c = shift;
$c->app->log->info( $c->log_req );
my $rt = $c->current_route;
my $trt = ( $c->param('trt') || 'LIST' );
$trt = 'DEL' if ( $rt eq 'localnetworksdel' );
$trt = 'ADD' if ( $rt eq 'localnetworksadd' );
$trt = 'ADD1' if ( $rt eq 'localnetworksadd1' );
$trt = 'DEL1' if ( $rt eq 'localnetworksdel1' );
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
$network_db = esmith::NetworksDB::UTF8->open() || die("Couldn't open networks db");
$trt = 'DEL' if ($rt eq 'localnetworksdel');
$trt = 'ADD' if ($rt eq 'localnetworksadd');
$trt = 'ADD1' if ($rt eq 'localnetworksadd1');
$trt = 'DEL1' if ($rt eq 'localnetworksdel1');
$c->app->log->info("Localnetworks:trt:$trt");
my %ln_datas = ();
my $title = $c->l('ln_LOCAL NETWORKS');
my $modul = '';
if ( $trt eq 'ADD' ) {
#Add a network - called from the list panel
# Nothing to do here...as just need fields to input data.
if ($trt eq 'ADD') {
}
#Add a network - called from the list panel
# Nothing to do here...as just need fields to input data.
} ## end if ($trt eq 'ADD')
if ( $trt eq 'ADD1' ) {
#Add a network - called after new network details filled in
my %ret = add_network($c);
#Return to list page if success
if ((index($ret{ret},"SUCCESS") != -1)) {
$trt = "LIST";
} else {
#Error - return to Add page
$trt = "ADD";
}
$network_db = esmith::NetworksDB->open() || die("Failed to open Networkdb-3"); #Refresh the network DB
$c->stash(ret=>\%ret); #stash it away for the template
}
if ($trt eq 'ADD1') {
if ( $trt eq 'DEL1' ) {
#After Remove clicked on Delete network panel
my $network_db = esmith::NetworksDB->open() || die("Failed to open Networkdb-1");
#Add a network - called after new network details filled in
my %ret = add_network($c);
$network_db = esmith::NetworksDB::UTF8->open();
#Return to list page if success
if ((index($ret{ret}, "SUCCESS") != -1)) {
$trt = "LIST";
} else {
#Error - return to Add page
$trt = "ADD";
}
#$network_db = esmith::NetworksDB::UTF8->open() || die("Failed to open Networkdb-3"); #Refresh the network DB
$c->stash(ret => \%ret); #stash it away for the template
} ## end if ($trt eq 'ADD1')
if ($trt eq 'DEL1') {
#After Remove clicked on Delete network panel
#$network_db = esmith::NetworksDB::UTF8->open() || die("Failed to open Networkdb-1");
my $localnetwork = $c->param("localnetwork");
my $delete_hosts = $c->param("deletehost")||"1"; #default to deleting them.
my $rec = $network_db->get($localnetwork)||die("Failed to find network on db:$localnetwork");
if ( $rec and $rec->prop('type') eq 'localnetwork' ) {
$ln_datas{localnetwork} = $localnetwork;
}
my %ret = remove_network($localnetwork,$delete_hosts);
$network_db = esmith::NetworksDB->open() || die("Failed to open Networkdb-2"); #Refresh the network DB
my $delete_hosts = $c->param("deletehost") || "1"; #default to deleting them.
$c->app->log->info("Localnetworks:deleting $localnetwork");
my ($rec,%ret);
if ($rec = $network_db->get($localnetwork)){ #|| die("Failed to find network on db:$localnetwork");
if ($rec and $rec->prop('type') eq 'localnetwork') {
$ln_datas{localnetwork} = $localnetwork;
}
%ret = $c->remove_network($localnetwork, $delete_hosts);
} else {
$c->app->log->info("Local network: delete failed to find network in db: $localnetwork");
%ret = (ret => "");
}
#$network_db = esmith::NetworksDB::UTF8->open() || die("Failed to open Networkdb-2"); #Refresh the network DB
my @localnetworks;
if ($network_db) {
@localnetworks = $network_db->get_all_by_prop( type => 'network' );
@localnetworks = $network_db->get_all_by_prop(type => 'network');
}
# Load up ln_datas with values need by template
$ln_datas{subnet} = $rec->prop('Mask');
$ln_datas{router} = $rec->prop('Router');
$c->stash( ln_datas => \%ln_datas, localnetworks => \@localnetworks ,ret =>\%ret);
}
if ($rec){
$ln_datas{subnet} = $rec->prop('Mask');
$ln_datas{router} = $rec->prop('Router');
}
$c->stash(ln_datas => \%ln_datas, localnetworks => \@localnetworks, ret => \%ret);
} ## end if ($trt eq 'DEL1')
if ( $trt eq 'DEL' ) {
#Initial delete panel requiring confirmation
my $localnetwork = $c->param("localnetwork") || '';
$c->stash(localnetwork=>$localnetwork);
my $rec = $network_db->get($localnetwork) || die("Failed to get local network in db::$localnetwork");
my $subnet = $rec->prop('Mask');
$ln_datas{subnet} = $subnet;
$ln_datas{router} = $rec->prop('Router');
my $numhosts = hosts_on_network($localnetwork,$subnet);
$ln_datas{localnetwork} = $localnetwork;
$ln_datas{deletehosts} = $numhosts>0?1:0;
}
if ($trt eq 'DEL') {
if ( $trt eq 'LIST' ) {
#List all the networks
#Initial delete panel requiring confirmation
my $localnetwork = $c->param("localnetwork") || '';
my ($rec,%ret);
$c->stash(localnetwork => $localnetwork);
if ($rec = $network_db->get($localnetwork)){
my $subnet = $rec->prop('Mask');
$ln_datas{subnet} = $subnet;
$ln_datas{router} = $rec->prop('Router');
my $numhosts =$c->hosts_on_network($localnetwork, $subnet);
$ln_datas{localnetwork} = $localnetwork;
$ln_datas{deletehosts} = $numhosts > 0 ? 1 : 0;
} else {
$c->app->log->info("Local network:Initial Failed to find network in Db: $localnetwork");
$c->flash('error',$c->l('ln_Failed to find network in Db'));
$trt = 'LIST';
}
} ## end if ($trt eq 'DEL')
if ($trt eq 'LIST') {
#List all the networks
my @localnetworks;
if ($network_db) {
@localnetworks = $network_db->get_all_by_prop( type => 'network' );
@localnetworks = $network_db->get_all_by_prop(type => 'network');
}
$c->stash( localnetworks => \@localnetworks );
## $c->redirect_to('/localnetworks');
}
$c->stash(localnetworks => \@localnetworks);
## $c->redirect_to('/localnetworks');
} ## end if ($trt eq 'LIST')
$ln_datas{'trt'} = $trt;
$c->stash( title => $title, modul => $modul, ln_datas => \%ln_datas );
$c->render( template => 'localnetworks' );
}
$c->stash(title => $title, modul => $modul, ln_datas => \%ln_datas);
$c->render(template => 'localnetworks');
} ## end sub do_display
sub remove_network {
my $network = shift;
my $network_db = esmith::NetworksDB->open();
my $record = $network_db->get($network);
my $delete_hosts = shift;
my $c = shift;
my $network = shift;
$network_db = esmith::NetworksDB::UTF8->open();
my $record = $network_db->get($network);
my $delete_hosts = shift;
if ( my $record = $network_db->get($network) ) {
if (my $record = $network_db->get($network)) {
my $subnet = $record->prop('Mask');
my $router = $record->prop('Router');
$record->set_prop( type => 'network-deleted' );
$record->set_prop(type => 'network-deleted');
# Untaint $network before use in system()
$network =~ /(.+)/;
$network = $1;
if ( system( "/sbin/e-smith/signal-event", "network-delete", $network ) == 0 ) {
if (system("/sbin/e-smith/signal-event", "network-delete", $network) == 0) {
if ($delete_hosts) {
my @hosts_to_delete = hosts_on_network( $network, $subnet );
my @hosts_to_delete = $c->hosts_on_network($network, $subnet);
foreach my $host (@hosts_to_delete) {
$host->delete;
}
}
} ## end if ($delete_hosts)
$record->delete;
return (ret=>'ln_SUCCESS_REMOVED_NETWORK',vars=>"$network,$subnet,$router");
}
else {
return (ret=>"ln_ERROR_DELETING_NETWORK");
return (ret => 'ln_SUCCESS_REMOVED_NETWORK', vars => "$network,$subnet,$router");
} else {
return (ret => "ln_ERROR_DELETING_NETWORK");
}
} else {
return (ret => "ln_NO_SUCH_NETWORK");
}
else {
return (ret=>"ln_NO_SUCH_NETWORK");
}
}
} ## end sub remove_network
sub hosts_on_network {
my $c = shift;
my $network = shift;
my $netmask = shift;
die if not $network and $netmask;
my $cidr = "$network/$netmask";
my $hosts = esmith::HostsDB->open() || die("Couldn't open hosts db");
my @localhosts = grep { $_->prop('HostType') eq 'Local' } $hosts->hosts;
my $cidr = "$network/$netmask";
my $hosts = esmith::HostsDB::UTF8->open() || die("Couldn't open hosts db");
my @localhosts = grep { $_->prop('HostType') eq 'Local' } $hosts->hosts;
my @hosts_on_network = ();
foreach my $host (@localhosts) {
my $ip = $host->prop('InternalIP') || "";
if ($ip) {
if ( Net::IPv4Addr::ipv4_in_network( $cidr, $ip ) ) {
if (Net::IPv4Addr::ipv4_in_network($cidr, $ip)) {
push @hosts_on_network, $host;
}
}
}
} ## end if ($ip)
} ## end foreach my $host (@localhosts)
return @hosts_on_network if wantarray;
return scalar @hosts_on_network;
}
} ## end sub hosts_on_network
sub add_network
{
my ($fm) = @_;
my $networkAddress = $fm->param('networkAddress');
my $networkMask = $fm->param('networkMask');
my $networkRouter = $fm->param('networkRouter');
sub add_network {
my ($c) = @_;
my $networkAddress = $c->param('networkAddress');
my $networkMask = $c->param('networkMask');
my $networkRouter = $c->param('networkRouter');
#Start by checking that the network does not already exist
#Validate Ips and subnet mask
my $res = ip_number($fm, $networkAddress);
return (ret=>'ln_INVALID_IP_ADDRESS', vars=>"Network Address $res") unless $res eq 'OK';
$res = subnet_mask( $networkMask );
return (ret=>'ln_INVALID_SUBNET_MASK', vars=>"$networkMask" ) unless $res eq 'OK';
$res = ip_number($fm, $networkRouter);
return (ret=>'ln_INVALID_IP_ADDRESS' , vars=>"Routeur Address $res") unless $res eq 'OK';
my $res = ip_number($c, $networkAddress);
return (ret => 'ln_INVALID_IP_ADDRESS', vars => "Network Address $res") unless $res eq 'OK';
$res = subnet_mask($networkMask);
return (ret => 'ln_INVALID_SUBNET_MASK', vars => "$networkMask") unless $res eq 'OK';
$res = ip_number($c, $networkRouter);
return (ret => 'ln_INVALID_IP_ADDRESS', vars => "Routeur Address $res") unless $res eq 'OK';
# we transform bit mask to regular mask
$networkMask = get_reg_mask( $networkAddress, $networkMask );
my $network_db = esmith::NetworksDB->open()
|| esmith::NetworksDB->create();
my $config_db = esmith::ConfigDB->open();
$networkMask = get_reg_mask($networkAddress, $networkMask);
my $network_db = esmith::NetworksDB::UTF8->open()
|| esmith::NetworksDB::UTF8->create();
my $config_db = esmith::ConfigDB::UTF8->open();
my $localIP = $config_db->get('LocalIP');
my $localNetmask = $config_db->get('LocalNetmask');
my ( $localNetwork, $localBroadcast ) =
esmith::util::computeNetworkAndBroadcast( $localIP->value(),
$localNetmask->value() );
my ( $routerNetwork, $routerBroadcast ) =
esmith::util::computeNetworkAndBroadcast( $networkRouter,
$localNetmask->value() );
my ($localNetwork, $localBroadcast)
= esmith::util::computeNetworkAndBroadcast($localIP->value(), $localNetmask->value());
my ($routerNetwork, $routerBroadcast)
= esmith::util::computeNetworkAndBroadcast($networkRouter, $localNetmask->value());
# Note to self or future developers:
# the following tests should probably be validation routines
# in the form itself, but it just seemed too fiddly to do that
# at the moment. -- Skud 2002-04-11
# I agree --bjr 2020-04-18
if ( $routerNetwork ne $localNetwork )
{
return (ret=>'ln_NOT_ACCESSIBLE_FROM_LOCAL_NETWORK');
my ($network, $broadcast) = esmith::util::computeNetworkAndBroadcast($networkAddress, $networkMask);
if ($routerNetwork ne $localNetwork) {
return (ret => 'ln_NOT_ACCESSIBLE_FROM_LOCAL_NETWORK', vars => "$network,$networkMask,$networkRouter");
}
my ( $network, $broadcast ) =
esmith::util::computeNetworkAndBroadcast( $networkAddress, $networkMask );
if ( $network eq $localNetwork )
{
return (ret=>'ln_NETWORK_ALREADY_LOCAL');
if ($network eq $localNetwork) {
return (ret => 'ln_NETWORK_ALREADY_LOCAL', vars => "$network,$networkMask,$networkRouter");
}
if ( $network_db->get($network) )
{
return (ret=>'ln_NETWORK_ALREADY_ADDED');
if ($network_db->get($network)) {
return (ret => 'ln_NETWORK_ALREADY_ADDED', vars => "$network,$networkMask,$networkRouter");
}
$network_db->new_record(
$res = $network_db->new_record(
$network,
{
Mask => $networkMask,
{ Mask => $networkMask,
Router => $networkRouter,
type => 'network',
}
);
# Untaint $network before use in system()
$network =~ /(.+)/;
$network = $1;
system( "/sbin/e-smith/signal-event", "network-create", $network ) == 0
or ( return (ret=>'ln_ERROR_CREATING_NETWORK' ));
my ( $totalHosts, $firstAddr, $lastAddr ) =
esmith::util::computeHostRange( $network, $networkMask );
if (! $res) {
#Record already existed
$c->app->log->info("Local Network:Network already exists:$network");
#return success message
} else {
#Only call underlying batch if new record created
# Untaint $network before use in system()
$network =~ /(.+)/;
$network = $1;
system("/sbin/e-smith/signal-event", "network-create", $network) == 0
or (return (ret => 'ln_ERROR_CREATING_NETWORK', vars => "$network,$networkMask,$networkRouter"));
}
my ($totalHosts, $firstAddr, $lastAddr) = esmith::util::computeHostRange($network, $networkMask);
my $msg;
if ( $totalHosts == 1 )
if ($totalHosts == 1) {
return (ret => 'ln_SUCCESS_SINGLE_ADDRESS', vars => "$network,$networkMask,$networkRouter");
} elsif (($totalHosts == 256)
|| ($totalHosts == 65536)
|| ($totalHosts == 16777216))
{
return (ret=>'ln_SUCCESS_SINGLE_ADDRESS',vars=>"$network,$networkMask,$networkRouter");
}
elsif (( $totalHosts == 256 )
|| ( $totalHosts == 65536 )
|| ( $totalHosts == 16777216 ) )
{
return ( ret=>'ln_SUCCESS_NETWORK_RANGE',vars=>"$network,$networkMask,$networkRouter,$totalHosts,$firstAddr,$lastAddr");
}
else
{ my $simpleMask = esmith::util::computeLocalNetworkPrefix( $network, $networkMask );
return ( ret => 'ln_SUCCESS_NONSTANDARD_RANGE',
vars=>"$network,$networkMask,$networkRouter,$totalHosts,$firstAddr,$lastAddr,$simpleMask");
}
}
return (
ret => 'ln_SUCCESS_NETWORK_RANGE',
vars => "$network,$networkMask,$networkRouter,$totalHosts,$firstAddr,$lastAddr"
);
} else {
my $simpleMask = esmith::util::computeLocalNetworkPrefix($network, $networkMask);
return (
ret => 'ln_SUCCESS_NONSTANDARD_RANGE',
vars => "$network,$networkMask,$networkRouter,$totalHosts,$firstAddr,$lastAddr,$simpleMask"
);
} ## end else [ if ($totalHosts == 1) ]
} ## end sub add_network
1;

View File

@@ -3,271 +3,222 @@ package SrvMngr::Controller::Login;
#----------------------------------------------------------------------
# heading : Support
# description : Login
# navigation : 0000 001
# navigation : 0 200
# menu : N
#
# routes : end
#----------------------------------------------------------------------
# for information
# $r->get('/login')->to('login#main')->name('login');
# $r->post('/login')->to('login#login')->name('signin');
# $r->get('/login2')->to('login#pwdrescue')->name('pwdresc');
# $r->get('/loginc')->to('login#confpwd')->name('resetpwdconf');
# for information
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use esmith::AccountsDB;
use esmith::AccountsDB::UTF8;
use SrvMngr::I18N;
use SrvMngr::Model::Main;
use SrvMngr qw( theme_list init_session );
my $MAX_LOGIN_ATTEMPTS = 3;
my $DURATION_BLOCKED = 30 * 60; # access blocked for 30 min
my $MAX_LOGIN_ATTEMPTS = 3;
my $DURATION_BLOCKED = 30 * 60; # access blocked for 30 min
my $TIMEOUT_FAILED_LOGIN = 1;
my $RESET_DURATION = 2 * 60 * 60; # 2 hours for resetting
our $adb = esmith::AccountsDB->open() or die "Couldn't open DB Accounts\n";
my $RESET_DURATION = 2 * 60 * 60; # 2 hours for resetting
our $adb;
my $allowed_user_re = qr/^\w{5,10}$/;
my %Login_Attempts;
sub main {
my $c = shift;
$c->stash( trt => 'NORM' );
$c->render('login');
}
my $c = shift;
$c->stash(trt => 'NORM');
$c->render('login');
} ## end sub main
sub login {
my $c = shift;
my $trt = $c->param('Trt');
my $c = shift;
my $trt = $c->param('Trt');
$adb = esmith::AccountsDB::UTF8->open() or die "Couldn't open DB Accounts\n";
# password reset request
if ( $trt eq 'RESET' ) {
my $res = $c->mail_rescue();
if ( $res ne 'OK' ) {
$c->stash( error => $res, trt => $trt );
return $c->render('login');
}
$c->flash( success => $c->l('use_RESET_REGISTERED') );
record_login_attempt($c, 'RESET');
return $c->redirect_to( $c->home_page );
}
if ($trt eq 'RESET') {
my $res = $c->mail_rescue();
if ($res ne 'OK') {
$c->stash(error => $res, trt => $trt);
return $c->render('login');
}
$c->flash(success => $c->l('use_RESET_REGISTERED'));
record_login_attempt($c, 'RESET');
return $c->redirect_to($c->home_page);
} ## end if ($trt eq 'RESET')
# normal loggin
my $name = $c->param('Username');
my $pass = $c->param('Password');
my $from = $c->param('From');
my $name = $c->param('Username');
my $pass = $c->param('Password');
my $from = $c->param('From');
if ( is_denied($c) ) {
$c->stash( error => $c->l('use_TOO_MANY_LOGIN'), trt => 'NORM' );
return $c->render('login');
}
# untaint
unless ( ($name =~ /^([a-z][\-\_\.a-z0-9]*)$/) && ($pass =~ /^([ -~]+)$/) ) {
record_login_attempt($c, 'FAILED');
$c->stash( error => $c->l('use_INVALID_DATA'), trt => 'NORM' );
return $c->render('login');
}
my $alias = SrvMngr::Model::Main->check_adminalias( $c );
if ( $alias ) {
if ( $name eq $alias ) {
$name = 'admin';
} elsif ( $name eq 'admin' ) {
record_login_attempt($c, 'FAILED');
$c->stash( error => $c->l('use_SORRY'), trt => 'NORM' );
return $c->render('login');
if (is_denied($c)) {
$c->stash(error => $c->l('use_TOO_MANY_LOGIN'), trt => 'NORM');
return $c->render('login');
}
}
if (SrvMngr::Model::Main->check_credentials($name, $pass)) {
$c->session(logged_in => 1); # set the logged_in flag
$c->session(username => $name); # keep a copy of the username
# if ( $name eq 'admin' || $adb->is_user_in_group($name, 'AdmiN') ) # for futur use
if ( $name eq 'admin' ) {
$c->session(is_admin => 1);
# untaint
unless (($name =~ /^([a-z][\-\_\.a-z0-9]*)$/) && ($pass =~ /^([ -~]+)$/)) {
record_login_attempt($c, 'FAILED');
$c->stash(error => $c->l('use_INVALID_DATA'), trt => 'NORM');
return $c->render('login');
}
my $alias = SrvMngr::Model::Main->check_adminalias($c);
if ($alias) {
if ($name eq $alias) {
$name = 'admin';
} elsif ($name eq 'admin') {
record_login_attempt($c, 'FAILED');
$c->stash(error => $c->l('use_SORRY'), trt => 'NORM');
return $c->render('login');
}
} ## end if ($alias)
if (SrvMngr::Model::Main->check_credentials($name, $pass)) {
$c->session(logged_in => 1); # set the logged_in flag
$c->session(username => $name); # keep a copy of the username
# if ( $name eq 'admin' || $adb->is_user_in_group($name, 'Admin') ) # for futur use
if ($name eq 'admin') {
$c->session(is_admin => 1);
} else {
$c->session(is_admin => 0);
}
$c->session(expiration => $c->config->{timeout} ); # expire this session in the time set in config
$c->flash(success => $c->l('use_WELCOME'));
record_login_attempt($c, 'SUCCESS');
} else {
$c->session(is_admin => 0);
}
$c->session(expiration => 600); # expire this session in 10 minutes
$c->flash( success => $c->l('use_WELCOME') );
record_login_attempt($c, 'SUCCESS');
} else {
record_login_attempt($c, 'FAILED');
sleep $TIMEOUT_FAILED_LOGIN;
$c->stash( error => $c->l('use_SORRY'), trt => 'NORM' );
return $c->render('login');
}
$from = $c->home_page if ( $from eq 'login' );
$c->redirect_to( $from );
}
record_login_attempt($c, 'FAILED');
sleep $TIMEOUT_FAILED_LOGIN;
$c->stash(error => $c->l('use_SORRY'), trt => 'NORM');
return $c->render('login');
} ## end else [ if (SrvMngr::Model::Main...)]
$from = $c->home_page if ($from eq 'login');
$c->redirect_to($from);
} ## end sub login
sub pwdrescue {
my $c = shift;
$c->stash( trt => 'RESET' );
$c->render('login');
}
my $c = shift;
$c->stash(trt => 'RESET');
$c->render('login');
} ## end sub pwdrescue
sub mail_rescue {
my $c = shift;
my $name = $c->param('Username');
my $from = $c->param('From');
$adb = esmith::AccountsDB::UTF8->open() or die "Couldn't open DB Accounts\n";
my $res;
$res .= $c->l('use_TOO_MANY_LOGIN') if (is_denied($c));
my $c = shift;
my $name = $c->param('Username');
my $from = $c->param('From');
my $res;
$res .= $c->l('use_TOO_MANY_LOGIN') if ( is_denied($c) );
# untaint
if ( ! $res && $name !~ /^([a-z][\-\_\.a-z0-9]*)$/ ) {
record_login_attempt($c, 'FAILED');
$res .= $c->l('use_ERR_NAME');
}
if ( ! $res && $name eq 'admin' ) {
$res .= $c->l('use_NOT_THAT_OPER');
}
# user exists ?
if ( ! $res ) {
my $acct = $adb->get($name);
if ( ! $acct || $acct->prop('type') ne "user" || $acct->prop('PasswordSet') ne 'yes' ) {
$res .= $c->l('use_NOT_THAT_OPER');
}
# untaint
if (!$res && $name !~ /^([a-z][\-\_\.a-z0-9]*)$/) {
record_login_attempt($c, 'FAILED');
$res .= $c->l('use_ERR_NAME');
}
if (!$res && $name eq 'admin') {
$res .= $c->l('use_NOT_THAT_OPER');
}
# user exists ?
if (!$res) {
my $acct = $adb->get($name);
if (!$acct || $acct->prop('type') ne "user" || $acct->prop('PasswordSet') ne 'yes') {
$res .= $c->l('use_NOT_THAT_OPER');
}
} ## end if (!$res)
return $res if $res;
# send email
my $email = $name .'@'. $c->session->{DomainName};
# send email
my $email = $name . '@' . $c->session->{DomainName};
my $until = time() + $RESET_DURATION;
$c->pwdrst->{$name} = {
email => $email,
date => $until,
confirmed => 0,
};
my $jwt = $c->jwt->claims({ username => $name })->encode;
my $url = $c->url_for('loginc')->to_abs->query(jwt => $jwt);
$c->pwdrst->{$name} = {
email => $email,
date => $until,
confirmed => 0,
};
my $jwt = $c->jwt->claims({username => $name})->encode;
my $url = $c->url_for('loginc')->to_abs->query(jwt => $jwt);
# $c->email( $email, $c->l('use_CONFIRM_RESET'), $c->render_to_string(inline => $c->l('use_GO_TO_URL', $url) ) );
# directly (without minion)
$c->send_email( $email, $c->l('use_CONFIRM_RESET'), $c->render_to_string(inline => $c->l('use_GO_TO_URL', $url) ) );
return 'OK';
}
# $c->email( $email, $c->l('use_CONFIRM_RESET'), $c->render_to_string(inline => $c->l('use_GO_TO_URL', $url) ) );
# directly (without minion)
$c->send_email($email, $c->l('use_CONFIRM_RESET'), $c->render_to_string(inline => $c->l('use_GO_TO_URL', $url)));
return 'OK';
} ## end sub mail_rescue
sub logout {
my $c = shift;
$c->app->log->info($c->log_req);
$c->session( expires => 1 );
$c->flash( success => $c->l('use_BYE') );
$c->flash( error => 'Byegood' );
$c->redirect_to( $c->home_page );
}
my $c = shift;
$c->app->log->info($c->log_req);
$c->session(expires => 1);
$c->flash(success => $c->l('use_BYE'));
$c->flash(error => 'Byegood');
$c->redirect_to($c->home_page);
} ## end sub logout
sub confpwd {
my $c = shift;
my $jwt = $c->param('jwt');
my $name = $c->jwt->decode($jwt)->{username};
my $c = shift;
my $jwt = $c->param('jwt');
my $name = $c->jwt->decode($jwt)->{username};
# request already treated or outdated
if ( $c->pwdrst->{$name}{confirmed} != 0 or $c->pwdrst->{$name}{date} < time() ) {
$c->flash( error => $c->l('use_INVALID_REQUEST'));
return $c->redirect_to( $c->home_page );
}
if ($c->pwdrst->{$name}{confirmed} != 0 or $c->pwdrst->{$name}{date} < time()) {
$c->flash(error => $c->l('use_INVALID_REQUEST'));
return $c->redirect_to($c->home_page);
}
# reset password for this account
$c->pwdrst->{$name}{confirmed} = 1;
$c->flash( success => $c->l('use_OK_FOR_RESET') );
$c->pwdrst->{$name}{confirmed} = 1;
$c->flash(success => $c->l('use_OK_FOR_RESET'));
# call userpassword with encoded name
my $url = $c->url_for('userpasswordr')->to_abs->query(jwt => $jwt);
my $url = $c->url_for('userpasswordr')->to_abs->query(jwt => $jwt);
# warn "confpwd: " . $url . "\n";
return $c->redirect_to( $url );
}
return $c->redirect_to($url);
} ## end sub confpwd
sub record_login_attempt {
my ($c, $result) = @_;
my $user = $c->param('Username');
my $ip_address = $c->tx->remote_address;
my ($c, $result) = @_;
my $user = $c->param('Username');
my $ip_address = $c->tx->remote_address;
if ($result eq 'RESET') {
$c->app->log->info(join "\t", "Password reset requested for : $user at ", $ip_address);
} elsif ($result eq 'SUCCESS') {
$c->app->log->info(join "\t", "Login succeeded: $user", $ip_address);
$Login_Attempts{$ip_address}->{tries} = 0; # reset the number of login attempts
} else {
$c->app->log->info(join "\t", "Login FAILED: $user", $ip_address);
$Login_Attempts{$ip_address}->{tries}++;
if ( $Login_Attempts{$ip_address}->{tries} > $MAX_LOGIN_ATTEMPTS ) {
$Login_Attempts{$ip_address}->{denied_until} = time() + $DURATION_BLOCKED;
}
}
}
if ($result eq 'RESET') {
$c->app->log->info(join "\t", "Password reset requested for : $user at ", $ip_address);
} elsif ($result eq 'SUCCESS') {
$c->app->log->info(join "\t", "Login succeeded: $user", $ip_address);
$Login_Attempts{$ip_address}->{tries} = 0; # reset the number of login attempts
} else {
$c->app->log->info(join "\t", "Login FAILED: $user", $ip_address);
$Login_Attempts{$ip_address}->{tries}++;
if ($Login_Attempts{$ip_address}->{tries} > $MAX_LOGIN_ATTEMPTS) {
$Login_Attempts{$ip_address}->{denied_until} = time() + $DURATION_BLOCKED;
}
} ## end else [ if ($result eq 'RESET')]
} ## end sub record_login_attempt
sub is_denied {
my ($c) = @_;
my $ip_address = $c->tx->remote_address;
return unless exists $Login_Attempts{$ip_address}
my ($c) = @_;
my $ip_address = $c->tx->remote_address;
return
unless exists $Login_Attempts{$ip_address}
&& exists $Login_Attempts{$ip_address}->{denied_until};
return 'Denied'
if $Login_Attempts{$ip_address}->{denied_until} > time();
return 'Denied'
if $Login_Attempts{$ip_address}->{denied_until} > time();
# TIMEOUT has expired, reset attempts
delete $Login_Attempts{$ip_address}->{denied_until};
$Login_Attempts{$ip_address}->{tries} = 0;
return;
}
# TIMEOUT has expired, reset attempts
delete $Login_Attempts{$ip_address}->{denied_until};
$Login_Attempts{$ip_address}->{tries} = 0;
return;
} ## end sub is_denied
1;

View File

@@ -3,32 +3,23 @@ package SrvMngr::Controller::Logout;
#----------------------------------------------------------------------
# heading : Current User
# description : Logout
# navigation : 1000 900
# navigation : 1000 1000
# menu : U
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw( theme_list init_session );
sub logout {
my $c = shift;
$c->app->log->info($c->log_req);
$c->session( expires => 1 );
$c->flash( success => 'Goodbye' );
$c->redirect_to( $c->home_page );
}
my $c = shift;
$c->app->log->info($c->log_req);
$c->session(expires => 1);
$c->flash(success => 'Goodbye');
$c->redirect_to($c->home_page);
} ## end sub logout
1;

View File

@@ -3,32 +3,24 @@ package SrvMngr::Controller::Manual;
#----------------------------------------------------------------------
# heading : Support
# description : Online manual
# navigation : 0000 100
# navigation : 0 300
# menu : N
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('manual_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('manual_DESCRIPTION'));
$c->stash( title => $title, modul => $modul);
$c->stash(title => $title, modul => $modul);
$c->render(template => 'manual');
}
} ## end sub main
1;

View File

@@ -1,71 +1,57 @@
package SrvMngr::Controller::Modules;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
#
# routes : end
#----------------------------------------------------------------------
use SrvMngr qw(theme_list init_session);
sub bugreport {
my $c = shift;
$c->app->log->info($c->log_req);
my $modul = $c->render_to_string( inline => "<p># my (\$lang, \$releaseVersion,
my $modul = $c->render_to_string(
inline => "<p># my (\$lang, \$releaseVersion,
<br># \$c->stash\(\'lang\', \'releaseVer\'
# \'navigation\'</p>");
$c->stash( modul => $modul );
};
# \'navigation\'</p>"
);
$c->stash(modul => $modul);
} ## end sub bugreport
sub support {
my $c = shift;
$c->app->log->info($c->log_req);
my $modul = $c->stash('modul');
$modul .= 'Mail result is 1 + 8.';
$c->stash( modul => $modul, PwdSet => '0', Unsafe => '0' );
$c->stash(modul => $modul, PwdSet => '0', Unsafe => '0');
#$c->render('modules/support');
};
} ## end sub support
sub modsearch {
my $c = shift;
my $c = shift;
my $module = $c->param('module');
$c->app->log->info($c->log_req);
my $redirect_url = SrvMngr->get_mod_url($module);
if($redirect_url ne "-1"){
#$c->render(text => "mod_search: $module to $redirect_url");
if ($redirect_url ne "-1") {
#$c->render(text => "mod_search: $module to $redirect_url");
return $c->redirect_to($redirect_url);
#return $c->redirect_to( url_for($redirect_url) );
}
} ## end if ($redirect_url ne "-1")
#$c->render(text => "mod_search: $module to 'welcome'");
return $c->redirect_to( $c->home_page );
};
return $c->redirect_to($c->home_page);
} ## end sub modsearch
sub whatever {
my $c = shift;
my $c = shift;
my $whatever = $c->param('whatever');
$c->app->log->info($c->log_req . ' ' . $whatever);
$c->render(text => "whatever: /$whatever did not match.", status => 404);
};
} ## end sub whatever
1;

View File

@@ -10,248 +10,252 @@ package SrvMngr::Controller::Portforwarding;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
#use Regexp::Common qw /net/;
#use Data::Dumper;
use esmith::util;
use esmith::HostsDB;
our $db = esmith::ConfigDB->open
|| die "Can't open configuration database: $!\n";
our $tcp_db = esmith::ConfigDB->open('portforward_tcp')
|| die "Can't open portforward_tcp database: $!\n";
our $udp_db = esmith::ConfigDB->open('portforward_udp')
|| die "Can't open portforward_udp database: $!\n";
use esmith::ConfigDB::UTF8;
my ($cdb,$tcp_db,$udp_db);
my %ret = ();
use constant FALSE => 0;
use constant TRUE => 1;
sub main {
my $c = shift;
$c->app->log->info( $c->log_req );
$c->app->log->info($c->log_req);
my %pf_datas = ();
$pf_datas{return} = "";
my $title = $c->l('pf_FORM_TITLE');
my $modul = '';
$cdb = esmith::ConfigDB::UTF8->open || die "Can't open configuration database: $!\n";
$tcp_db = esmith::ConfigDB::UTF8->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
$udp_db = esmith::ConfigDB::UTF8->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
$pf_datas{trt} = 'LIST';
my @tcpforwards = $tcp_db->get_all;
my @udpforwards = $udp_db->get_all;
my $empty = 1 if not @tcpforwards and not @udpforwards;
$c->stash(
title => $title,
modul => $modul,
pf_datas => \%pf_datas,
tcpforwards =>\@tcpforwards,
udpforwards =>\@udpforwards,
empty => $empty
my $empty = 1 if not @tcpforwards and not @udpforwards;
$c->stash(
title => $title,
modul => $modul,
pf_datas => \%pf_datas,
tcpforwards => \@tcpforwards,
udpforwards => \@udpforwards,
empty => $empty
);
$c->render( template => 'portforwarding' );
}
$c->render(template => 'portforwarding');
} ## end sub main
sub do_display {
my $c = shift;
$c->app->log->info( $c->log_req );
my $rt = $c->current_route;
my $trt = ( $c->param('trt') || 'LIST' );
$trt = 'DEL' if ( $rt eq 'portforwardingdel' );
$trt = 'ADD' if ( $rt eq 'portforwardingadd' );
$trt = 'ADD1' if ( $rt eq 'portforwardingadd1' );
$trt = 'DEL1' if ( $rt eq 'portforwardingdel1' );
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $cdb = esmith::ConfigDB::UTF8->open || die "Can't open configuration database: $!\n";
my $tcp_db = esmith::ConfigDB::UTF8->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
my $udp_db = esmith::ConfigDB::UTF8->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
$trt = 'DEL' if ($rt eq 'portforwardingdel');
$trt = 'ADD' if ($rt eq 'portforwardingadd');
$trt = 'ADD1' if ($rt eq 'portforwardingadd1');
$trt = 'DEL1' if ($rt eq 'portforwardingdel1');
my %pf_datas = ();
my $title = $c->l('pf_FORM_TITLE');
my $modul = '';
if ( $trt eq 'ADD' ) {
# Add a portforward- called from the list panel
# Nothing to do here...as just need template to display fields to input data.
if ($trt eq 'ADD') {
}
# Add a portforward- called from the list panel
# Nothing to do here...as just need template to display fields to input data.
} ## end if ($trt eq 'ADD')
if ( $trt eq 'ADD1' ) {
#Add a port forward - called after new pf details filled in
my %ret = add_portforward($c);
#Return to list page if success
if ((index($ret{ret},"SUCCESS") != -1)) {
$trt = "LIST";
} else {
#Error - return to Add page
$trt = "ADD";
}
$c->stash(ret=>\%ret);
}
if ($trt eq 'ADD1') {
if ( $trt eq 'DEL1' ) {
##After Remove clicked on Delete network panel
my $sport = $c->param("sport") || '';
my $proto = $c->param("proto") || '';
#work out which protocol
#Add a port forward - called after new pf details filled in
my %ret = add_portforward($c);
#Return to list page if success
if ((index($ret{ret}, "SUCCESS") != -1)) {
$trt = "LIST";
} else {
#Error - return to Add page
$trt = "ADD";
}
$c->stash(ret => \%ret);
} ## end if ($trt eq 'ADD1')
if ($trt eq 'DEL1') {
##After Remove clicked on Delete network panel
my $sport = $c->param("sport") || '';
my $proto = $c->param("proto") || '';
#work out which protocol
my $fdb;
if ($proto eq 'TCP') {
$fdb = $tcp_db;
}
else {
} else {
$fdb = $udp_db;
}
#check that the sport is in the db
my $entry = $fdb->get($sport) || die("Unable to find sport and proto $sport $proto");
#check that the sport is in the db
my $entry = $fdb->get($sport) || die("Unable to find sport and proto $sport $proto");
$entry->delete;
system( "/sbin/e-smith/signal-event", "portforwarding-update") == 0
or ( die($c->l('pf_ERR_NONZERO_RETURN_EVENT')));
$trt = "LIST";
my %ret = (ret=>"pf_SUCCESS");
$c->stash(ret=>\%ret);
}
system("/sbin/e-smith/signal-event", "portforwarding-update") == 0
or (die($c->l('pf_ERR_NONZERO_RETURN_EVENT')));
$trt = "LIST";
my %ret = (ret => "pf_SUCCESS");
$c->stash(ret => \%ret);
} ## end if ($trt eq 'DEL1')
if ( $trt eq 'DEL' ) {
##Initial delete panel requiring confirmation
my $sport = $c->param("sport") || '';
my $proto = $c->param("proto") || '';
$c->stash(sport=>$sport);
#work out which protocol
if ($trt eq 'DEL') {
##Initial delete panel requiring confirmation
my $sport = $c->param("sport") || '';
my $proto = $c->param("proto") || '';
$c->stash(sport => $sport);
#work out which protocol
my $fdb;
if ($proto eq 'TCP') {
$fdb = $tcp_db;
}
else {
} else {
$fdb = $udp_db;
}
#pull out details and pass to template
my $entry = $fdb->get($sport) || die("Unable to find sport and proto $sport $proto");
#pull out details and pass to template
my $entry = $fdb->get($sport) || die("Unable to find sport and proto $sport $proto");
$pf_datas{proto} = $proto;
$pf_datas{sport} = $sport;
$pf_datas{dhost} = $entry->prop('DestHost');
$pf_datas{dport} = $entry->prop('DestPort') || '';
$pf_datas{cmmnt} = $entry->prop('Comment') || '';
$pf_datas{allow} = $entry->prop('AllowHosts') || '';
}
$pf_datas{cmmnt} = $entry->prop('Comment') || '';
$pf_datas{allow} = $entry->prop('AllowHosts') || '';
} ## end if ($trt eq 'DEL')
if ( $trt eq 'LIST' ) {
#List all the port forwards
my @tcpforwards = $tcp_db->get_all;
my @udpforwards = $udp_db->get_all;
my $empty = 1 if not @tcpforwards and not @udpforwards;
if ($trt eq 'LIST') {
$c->stash(
tcpforwards =>\@tcpforwards,
udpforwards =>\@udpforwards,
empty => $empty
);
#List all the port forwards
# Open them again as maybe written to above
$tcp_db = esmith::ConfigDB::UTF8->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
$udp_db = esmith::ConfigDB::UTF8->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
#my %forwards = (TCP=>@tcpforwards,UDP=>@udpforwards);
#$c->stash(portforwarding => %forwards);
}
my @tcpforwards = $tcp_db->get_all;
my @udpforwards = $udp_db->get_all;
my $empty = 1 if not @tcpforwards and not @udpforwards;
$c->stash(
tcpforwards => \@tcpforwards,
udpforwards => \@udpforwards,
empty => $empty
);
$pf_datas{'trt'} = $trt;
$c->stash( title => $title, modul => $modul, pf_datas => \%pf_datas );
$c->render( template => 'portforwarding' );
}
#my %forwards = (TCP=>@tcpforwards,UDP=>@udpforwards);
#$c->stash(portforwarding => %forwards);
} ## end if ($trt eq 'LIST')
$pf_datas{'trt'} = $trt;
$c->stash(title => $title, modul => $modul, pf_datas => \%pf_datas);
$c->render(template => 'portforwarding');
} ## end sub do_display
sub add_portforward {
my $c = shift;
my $sport = $c->param("sport") || '';
my $proto = $c->param("proto") || '';
#work out which protocol
my $fdb;
if ($proto eq 'TCP') {
$tcp_db = esmith::ConfigDB->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
$fdb = $tcp_db;
}
else {
$udp_db = esmith::ConfigDB->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
$fdb = $udp_db;
}
#Get the other values
my $dport = $c->param("dport");
my $dhost = get_destination_host($c);
my $cmmnt = $c->param("cmmnt") || "";
my $allow = $c->param("allow") || "";
my $deny = (($c->param("allow")) ? "0.0.0.0/0" : "");
$proto =~ s/^\s+|\s+$//g;
$sport =~ s/^\s+|\s+$//g;
$dport =~ s/^\s+|\s+$//g;
$dhost =~ s/^\s+|\s+$//g;
#Validate the values
%ret=validate_source_port($c) ; unless (index($ret{ret},"SUCCESS")!= -1) {return %ret;}
%ret=validate_allowed_hosts($c) ; if (index($ret{ret},"SUCCESS")== -1) {return %ret;}
%ret=validate_destination_port($c) ; if (index($ret{ret},"SUCCESS")== -1) {return %ret;}
%ret=validate_destination_host($c) ; if (index($ret{ret},"SUCCESS")== -1) {return %ret;}
# and then write it to the DB and tell the exec about it.
my $entry = $fdb->get($sport) || $fdb->new_record($sport, { type => 'forward' });
$entry->set_prop('DestHost', $dhost);
$entry->set_prop('DestPort', $dport) if $dport;
$entry->set_prop('Comment', $cmmnt);
$entry->set_prop('AllowHosts', $allow);
$entry->set_prop('DenyHosts', $deny);
system( "/sbin/e-smith/signal-event", "portforwarding-update") == 0
or ( return (ret=>'pf_ERR_NONZERO_RETURN_EVENT' ));
my %ret = (ret=>"pf_SUCCESS");
my $c = shift;
my $sport = $c->param("sport") || '';
my $proto = $c->param("proto") || '';
#work out which protocol
my $fdb;
if ($proto eq 'TCP') {
$tcp_db = esmith::ConfigDB::UTF8->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
$fdb = $tcp_db;
} else {
$udp_db = esmith::ConfigDB::UTF8->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
$fdb = $udp_db;
}
#Get the other values
my $dport = $c->param("dport");
my $dhost = get_destination_host($c);
my $cmmnt = $c->param("cmmnt") || "";
my $allow = $c->param("allow") || "";
my $deny = (($c->param("allow")) ? "0.0.0.0/0" : "");
$proto =~ s/^\s+|\s+$//g;
$sport =~ s/^\s+|\s+$//g;
$dport =~ s/^\s+|\s+$//g;
$dhost =~ s/^\s+|\s+$//g;
#Validate the values
%ret = validate_source_port($c);
unless (index($ret{ret}, "SUCCESS") != -1) { return %ret; }
%ret = validate_allowed_hosts($c);
if (index($ret{ret}, "SUCCESS") == -1) { return %ret; }
%ret = validate_destination_port($c);
if (index($ret{ret}, "SUCCESS") == -1) { return %ret; }
%ret = validate_destination_host($c);
if (index($ret{ret}, "SUCCESS") == -1) { return %ret; }
# and then write it to the DB and tell the exec about it.
my $entry = $fdb->get($sport) || $fdb->new_record($sport, { type => 'forward' });
$entry->set_prop('DestHost', $dhost);
$entry->set_prop('DestPort', $dport) if $dport;
$entry->set_prop('Comment', $cmmnt);
$entry->set_prop('AllowHosts', $allow);
$entry->set_prop('DenyHosts', $deny);
system("/sbin/e-smith/signal-event", "portforwarding-update") == 0
or (return (ret => 'pf_ERR_NONZERO_RETURN_EVENT'));
my %ret = (ret => "pf_SUCCESS");
return %ret;
}
} ## end sub add_portforward
sub get_destination_host
{
my $q = shift;
my $dhost = $q->param("dhost");
my $localip = $db->get_prop('InternalInterface', 'IPAddress');
my $external_ip = $db->get_prop('ExternalInterface', 'IPAddress') || $localip;
sub get_destination_host {
my $q = shift;
$cdb = esmith::ConfigDB::UTF8->open || die "Can't open configuration database: $!\n";
my $dhost = $q->param("dhost");
my $localip = $cdb->get_prop('InternalInterface', 'IPAddress');
my $external_ip = $cdb->get_prop('ExternalInterface', 'IPAddress') || $localip;
if ($dhost =~ /^(127.0.0.1|$localip|$external_ip)$/i) {
if ($dhost =~ /^(127.0.0.1|$localip|$external_ip)$/i)
{
# localhost token gets expanded at runtime to current external IP
$dhost = 'localhost';
}
} ## end if ($dhost =~ /^(127.0.0.1|$localip|$external_ip)$/i)
return $dhost;
}
} ## end sub get_destination_host
sub validate_source_port {
my $q = shift;
my $q = shift;
my $sport = $q->param('sport');
$sport =~ s/^\s+|\s+$//g;
# If this is a port range, split it up and validate it individually.
my @ports = ();
if ($sport =~ /-/)
{
if ($sport =~ /-/) {
@ports = split /-/, $sport;
if (@ports > 2)
{
if (@ports > 2) {
#$self->debug_msg("found more than 2 ports: @ports");
return (ret=>'pf_ERR_BADPORT');
}
}
else
{
return (ret => 'pf_ERR_BADPORT');
} ## end if (@ports > 2)
} else {
push @ports, $sport;
}
#$self->debug_msg("the ports array is: @ports");
foreach my $port (@ports)
{
foreach my $port (@ports) {
#$self->debug_msg("looping on port $port");
if (! isValidPort($port))
{
if (!isValidPort($port)) {
#$self->debug_msg("returning: " . $self->localise('ERR_BADPORT'));
return (ret=>'pf_ERR_BADPORT');
return (ret => 'pf_ERR_BADPORT');
}
}
# Now, lets screen any duplicates.
} ## end foreach my $port (@ports)
# Now, lets screen any duplicates.
my $protocol = $q->param('protocol');
my @forwards = ();
@@ -261,152 +265,136 @@ sub validate_source_port {
} elsif ($protocol eq 'UDP') {
@forwards = map { $_->key } $udp_db->get_all;
}
foreach my $psport (@forwards)
{
if (detect_collision($sport, $psport))
{
return (ret=>'pf_ERR_PORT_COLLISION');
}
}
return (ret=>"pf_SUCCESS");
}
sub detect_collision
{
foreach my $psport (@forwards) {
if (detect_collision($sport, $psport)) {
return (ret => 'pf_ERR_PORT_COLLISION');
}
} ## end foreach my $psport (@forwards)
return (ret => "pf_SUCCESS");
} ## end sub validate_source_port
sub detect_collision {
my $port_a = shift;
my $port_b = shift;
# If they're both single ports, see if they're the same.
if (($port_a !~ /-/) && ($port_b !~ /-/))
{
if (($port_a !~ /-/) && ($port_b !~ /-/)) {
return $port_a eq $port_b;
}
# If port_a is not a range but port_b is, is a in b?
elsif ($port_a !~ /-/)
{
elsif ($port_a !~ /-/) {
my ($b1, $b2) = split /-/, $port_b;
return (($port_a >= $b1) && ($port_a <= $b2));
}
elsif ($port_b !~ /-/)
{
} elsif ($port_b !~ /-/) {
my ($a1, $a2) = split /-/, $port_a;
return (($port_b >= $a1) && ($port_b <= $a2));
}
else
{
} else {
# They're both ranges. Do they overlap?
my ($a1, $a2) = split /-/, $port_a;
my ($b1, $b2) = split /-/, $port_b;
# They can overlap in two ways. Either a1 is in b, or b1 is in a.
if (($a1 >= $b1) && ($a1 <= $b2))
{
if (($a1 >= $b1) && ($a1 <= $b2)) {
return TRUE;
}
elsif (($b1 >= $a1) && ($b1 <= $a2))
{
} elsif (($b1 >= $a1) && ($b1 <= $a2)) {
return TRUE;
}
return FALSE;
}
}
} ## end else [ if (($port_a !~ /-/) &&...)]
} ## end sub detect_collision
sub validate_destination_port {
my $c = shift;
my $c = shift;
my $dport = $c->param('dport');
$dport =~ s/^\s+|\s+$//g;
# If the dport is empty, that's ok.
return (ret=>'pf_SUCCESS') if not $dport;
# If the dport is empty, that's ok.
return (ret => 'pf_SUCCESS') if not $dport;
# If this is a port range, split it up and validate it individually.
my @ports = ();
if ($dport =~ /-/)
{
if ($dport =~ /-/) {
@ports = split /-/, $dport;
if (@ports > 2)
{
if (@ports > 2) {
#$self->debug_msg("found more than 2 ports: @ports");
return (ret=>'pf_ERR_BADPORT');
}
}
else
{
return (ret => 'pf_ERR_BADPORT');
} ## end if (@ports > 2)
} else {
push @ports, $dport;
}
#$self->debug_msg("the ports array is: @ports");
foreach my $port (@ports) {
foreach my $port (@ports)
{
#$self->debug_msg("looping on port $port");
if (! isValidPort($port))
{
#$self->debug_msg("returning: " . $self->localise('ERR_BADPORT'));
return (ret=>'pf_ERR_BADPORT');
}
}
return (ret=>'pf_SUCCESS');
}
if (!isValidPort($port)) {
#$self->debug_msg("returning: " . $self->localise('ERR_BADPORT'));
return (ret => 'pf_ERR_BADPORT');
}
} ## end foreach my $port (@ports)
return (ret => 'pf_SUCCESS');
} ## end sub validate_destination_port
sub isValidPort() {
my $port = shift;
return FALSE unless defined $port;
if (($port =~ /^\d+$/) &&
($port > 0) &&
($port < 65536))
if ( ($port =~ /^\d+$/)
&& ($port > 0)
&& ($port < 65536))
{
return TRUE;
}
else {
} else {
return FALSE;
}
}
} ## end sub isValidPort
sub validate_destination_host {
my $c = shift;
my $c = shift;
$cdb = esmith::ConfigDB::UTF8->open || die "Can't open configuration database: $!\n";
my $dhost = $c->param('dhost');
$dhost =~ s/^\s+|\s+$//g;
my $localip = $cdb->get_prop('InternalInterface', 'IPAddress');
my $external_ip = $cdb->get_prop('ExternalInterface', 'IPAddress') || $localip;
my $localip = $db->get_prop('InternalInterface', 'IPAddress');
my $external_ip = $db->get_prop('ExternalInterface', 'IPAddress') || $localip;
if ($dhost =~ /^(localhost|127.0.0.1|$localip|$external_ip)$/i) {
if ($dhost =~ /^(localhost|127.0.0.1|$localip|$external_ip)$/i)
{
# localhost token gets expanded at runtime to current external IP
$c->param(-name=>'dhost', -value=>'localhost');
return (ret=>'pf_SUCCESS');
}
my $systemmode = $db->get_value('SystemMode');
$c->param(-name => 'dhost', -value => 'localhost');
return (ret => 'pf_SUCCESS');
} ## end if ($dhost =~ /^(localhost|127.0.0.1|$localip|$external_ip)$/i)
my $systemmode = $cdb->get_value('SystemMode');
if ($systemmode eq 'serveronly') {
return (ret=>'pf_IN_SERVERONLY');
return (ret => 'pf_IN_SERVERONLY');
}
if (isValidIP($dhost)) {
return (ret=>'pf_SUCCESS');
return (ret => 'pf_SUCCESS');
} else {
return (ret => 'pf_ERR_BADIP');
}
else {
return (ret=>'pf_ERR_BADIP');
}
}
} ## end sub validate_destination_host
sub validate_allowed_hosts {
my $c = shift;
my $c = shift;
my $ahost = $c->param('allow');
$ahost =~ s/^\s+|\s+$//g;
my %valid_ahost_list = (ret=>"pf_SUCCESS");
my %valid_ahost_list = (ret => "pf_SUCCESS");
foreach (split(/[\s,]+/, $ahost)) {
my $valid_ipnet = 0;
$valid_ipnet = 1 if ($_ =~ m/^\d+\.\d+\.\d+\.\d+$/);
$valid_ipnet = 1 if ($_ =~ m/^\d+\.\d+\.\d+\.\d+\/\d+$/);
%valid_ahost_list = (ret=>"pf_ERR_BADAHOST") if ($valid_ipnet != 1);
}
%valid_ahost_list = (ret => "pf_ERR_BADAHOST") if ($valid_ipnet != 1);
} ## end foreach (split(/[\s,]+/, $ahost...))
return %valid_ahost_list;
}
} ## end sub validate_allowed_hosts
1;

View File

@@ -11,236 +11,201 @@ package SrvMngr::Controller::Printers;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::FormMagick::Panel::printers;
our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
use esmith::AccountsDB::UTF8;
our $adb;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %prt_datas = ();
my $title = $c->l('prt_FORM_TITLE');
my $title = $c->l('prt_FORM_TITLE');
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$prt_datas{'trt'} = 'LIST';
my @printerDrivers;
if ($adb)
{
if ($adb) {
@printerDrivers = $adb->printers();
}
$c->stash( title => $title, prt_datas => \%prt_datas, printerDrivers => \@printerDrivers );
$c->stash(title => $title, prt_datas => \%prt_datas, printerDrivers => \@printerDrivers);
$c->render(template => 'printers');
};
} ## end sub main
sub do_display {
my $c = shift;
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $c = shift;
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $printer = $c->param('printer') || '';
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
#$trt = 'DEL' if ( $printer );
#$trt = 'ADD' if ( $rt eq 'printeradd' );
my %prt_datas = ();
my $title = $c->l('prt_FORM_TITLE');
my $title = $c->l('prt_FORM_TITLE');
$prt_datas{'trt'} = $trt;
if ( $trt eq 'ADD' ) {
if ($trt eq 'ADD') {
# nothing
# nothing
}
if ($trt eq 'DEL') {
my $rec = $adb->get($printer);
if ($rec and $rec->prop('type') eq 'printer') {
$prt_datas{printer} = $printer;
$prt_datas{description} = $rec->prop('Description') || '';
}
} ## end if ($trt eq 'DEL')
if ( $trt eq 'DEL' ) {
my $rec = $adb->get($printer);
if ($rec and $rec->prop('type') eq 'printer') {
$prt_datas{printer} = $printer;
$prt_datas{description} = $rec->prop('Description') || '';
}
if ($trt eq 'LIST') {
my @printerDrivers;
if ($adb) {
@printerDrivers = $adb->printers();
}
if ( $trt eq 'LIST' ) {
my @printerDrivers;
if ($adb)
{
@printerDrivers = $adb->printers();
}
$c->stash( printerDrivers => \@printerDrivers );
}
$c->stash( title => $title, prt_datas => \%prt_datas );
$c->render( template => 'printers' );
};
$c->stash(printerDrivers => \@printerDrivers);
} ## end if ($trt eq 'LIST')
$c->stash(title => $title, prt_datas => \%prt_datas);
$c->render(template => 'printers');
} ## end sub do_display
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my %prt_datas = ();
my $title = $c->l('prt_FORM_TITLE');
my $title = $c->l('prt_FORM_TITLE');
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$prt_datas{'trt'} = $trt;
my ($res, $result) = '';
if ( $trt eq 'ADD' ) {
my $name = ($c->param('Name') || '');
if ($trt eq 'ADD') {
my $name = ($c->param('Name') || '');
my $description = ($c->param('Description') || '');
my $location = ($c->param('Location') || '');
my $location = ($c->param('Location') || '');
# controls
$res = $c->validate_printer( $name, $description, $location );
$result .= $res unless $res eq 'OK';
# controls
$res = $c->validate_printer($name, $description, $location);
$result .= $res unless $res eq 'OK';
if ( $location eq 'remote' and ! $result) {
$prt_datas{'trt'} = 'NET';
$prt_datas{'name'} = $name;
$prt_datas{'description'} = $description;
$prt_datas{'location'} = $location;
$c->stash( title => $title, prt_datas => \%prt_datas );
return $c->render( template => 'printers' );
}
$res = '';
if ( ! $result ) {
$res = $c->new_printer( $name, $description, $location );
#$remoteName, $address );
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('prt_CREATED_SUCCESSFULLY') . ' ' . $name;
}
}
}
if ($location eq 'remote' and !$result) {
$prt_datas{'trt'} = 'NET';
$prt_datas{'name'} = $name;
$prt_datas{'description'} = $description;
$prt_datas{'location'} = $location;
$c->stash(title => $title, prt_datas => \%prt_datas);
return $c->render(template => 'printers');
} ## end if ($location eq 'remote'...)
$res = '';
if ( $trt eq 'NET' ) {
if (!$result) {
$res = $c->new_printer($name, $description, $location);
my $name = ($c->param('Name') || '');
#$remoteName, $address );
$result .= $res unless $res eq 'OK';
if (!$result) {
$result = $c->l('prt_CREATED_SUCCESSFULLY') . ' ' . $name;
}
} ## end if (!$result)
} ## end if ($trt eq 'ADD')
if ($trt eq 'NET') {
my $name = ($c->param('Name') || '');
my $description = ($c->param('Description') || '');
my $location = ($c->param('Location') || '');
my $remoteName = ($c->param ('RemoteName') || '');
my $address = ($c->param ('Address') || '');
my $location = ($c->param('Location') || '');
my $remoteName = ($c->param('RemoteName') || '');
my $address = ($c->param('Address') || '');
$prt_datas{'name'} = $name;
$prt_datas{'description'} = $description;
$prt_datas{'location'} = $location;
$prt_datas{'name'} = $name;
$prt_datas{'description'} = $description;
$prt_datas{'location'} = $location;
# controls
$res = $c->validate_network($location, $remoteName, $address);
$result .= $res unless $res eq 'OK';
$res = '';
# controls
$res = $c->validate_network( $location, $remoteName, $address);
$result .= $res unless $res eq 'OK';
if (!$result) {
$res = $c->new_printer($name, $description, $location, $remoteName, $address);
$result .= $res unless $res eq 'OK';
$res = '';
if ( ! $result ) {
$res = $c->new_printer( $name, $description, $location, $remoteName, $address );
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('prt_CREATED_SUCCESSFULLY') . ' ' . $name;
}
}
}
if (!$result) {
$result = $c->l('prt_CREATED_SUCCESSFULLY') . ' ' . $name;
}
} ## end if (!$result)
} ## end if ($trt eq 'NET')
if ( $trt eq 'DEL' ) {
my $printer = ($c->param ('printer') || '');
if ($trt eq 'DEL') {
my $printer = ($c->param('printer') || '');
if ($printer =~ /^([a-z][a-z0-9]*)$/) {
$printer = $1;
} else {
$result .= $c->l('prt_ERR_INTERNAL_FAILURE') . ':' . $printer;
}
if ($printer =~ /^([a-z][a-z0-9]*)$/) {
$printer = $1;
} else {
$result .= $c->l('prt_ERR_INTERNAL_FAILURE') . ':' . $printer;
}
my $rec = $adb->get($printer);
$result .= $c->l('prt_ERR_INTERNAL_FAILURE') . ':' . $printer unless ($rec);
$res = '';
my $rec = $adb->get($printer);
$result .= $c->l('prt_ERR_INTERNAL_FAILURE') . ':' . $printer unless ($rec);
if (!$result) {
$res = $c->del_printer($printer);
$result .= $res unless $res eq 'OK';
$res = '';
if ( ! $result ) {
$res = $c->del_printer( $printer );
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('prt_DELETED_SUCCESSFULLY') . ' ' . $printer;
}
}
}
if (!$result) {
$result = $c->l('prt_DELETED_SUCCESSFULLY') . ' ' . $printer;
}
} ## end if (!$result)
} ## end if ($trt eq 'DEL')
# common parts
if ($res ne 'OK') {
$c->stash( error => $result );
$c->stash( title => $title, prt_datas => \%prt_datas );
return $c->render('printers');
$c->stash(error => $result);
$c->stash(title => $title, prt_datas => \%prt_datas);
return $c->render('printers');
}
my $message = "'Printers' updates ($trt) DONE";
$c->app->log->info($message);
$c->flash( success => $result );
$c->flash(success => $result);
#$c->flash( error => 'No changes applied !!' ); # for testing purpose
$c->redirect_to('/printers');
};
} ## end sub do_update
sub del_printer {
my ( $c, $printer ) = @_;
my ($c, $printer) = @_;
# Update the db account (1)
my $rec = $adb->get($printer);
$rec->set_prop('type', 'printer-deleted');
system ("/sbin/e-smith/signal-event printer-delete $printer") == 0
or return $c->error('ERR_DELETING');
system("/sbin/e-smith/signal-event printer-delete $printer") == 0
or return $c->error('ERR_DELETING');
$rec->delete();
return 'OK';
}
} ## end sub del_printer
sub validate_printer {
my ($c, $name, $description, $location, $remoteName, $address ) = @_;
my ($c, $name, $description, $location, $remoteName, $address) = @_;
#------------------------------------------------------------
# Validate parameters and untaint them
#------------------------------------------------------------
if ($name =~ /^([a-z][a-z0-9]*)$/) {
if ($name =~ /^([a-z][a-z0-9]*)$/) {
$name = $1;
} else {
} else {
return $c->l('prt_ERR_UNEXPECTED_NAME') . ': ' . $name;
}
if ($description =~ /^([\'\w\s]+)$/) {
$description = $1;
$description = $1;
} else {
return $c->l('prt_ERR_UNEXPECTED_DESC') . ': ' . $description;
}
if ($location =~ /^(lp[0-9]+|remote|usb\/lp[0-9]+)$/){
if ($location =~ /^(lp[0-9]+|remote|usb\/lp[0-9]+)$/) {
$location = $1;
} else {
$location = "lp0";
@@ -249,26 +214,22 @@ sub validate_printer {
#------------------------------------------------------------
# Looks good. Find out if this printer has been taken
#------------------------------------------------------------
my $rec = $adb->get($name);
my $type;
if ($rec and ($type = $rec->prop('type'))) {
return $c->l('prt_ERR_EXISTS') . ' : ' . $name;
}
return 'OK';
}
} ## end sub validate_printer
sub validate_network {
my ($c, $location, $remoteName, $address ) = @_;
my ($c, $location, $remoteName, $address) = @_;
if ($location eq 'remote') {
my $msg = hostname_or_ip2($c, $address);
return $msg unless $msg eq 'OK';
my $msg = hostname_or_ip2 ( $c, $address );
return $msg unless $msg eq 'OK';
if ($address =~ /^([a-zA-Z0-9\.\-]+)$/) {
$address = $1;
} else {
@@ -280,82 +241,63 @@ sub validate_network {
} else {
return $c->l('prt_ERR_INVALID_REMOTE_NAME') . ' : ' . $remoteName;
}
}
} ## end if ($location eq 'remote')
return 'OK';
}
} ## end sub validate_network
sub new_printer {
my ($c, $name, $description, $location, $remoteName, $address ) = @_;
my ($c, $name, $description, $location, $remoteName, $address) = @_;
#------------------------------------------------------------
# Printer name is available! Update printers database and
# Printer name is available! Update printers database and
# signal the create-printer event.
#------------------------------------------------------------
my $result = '';
my $rec = $adb->new_record($name,
{type=>'printer',
Description => $description,
Address => $address,
RemoteName => $remoteName,
Location => $location});
system ("/sbin/e-smith/signal-event printer-create $name") == 0
or return $c->error('ERR_CREATING');
return 'OK',
}
my $rec = $adb->new_record(
$name,
{ type => 'printer',
Description => $description,
Address => $address,
RemoteName => $remoteName,
Location => $location
}
);
system("/sbin/e-smith/signal-event printer-create $name") == 0
or return $c->error('ERR_CREATING');
return 'OK',;
} ## end sub new_printer
sub hostname_or_ip2 {
my ($fm, $data) = @_;
if ($data =~ /^[\d\.]+$/) {
if (ip_number2($fm, $data) eq "OK")
{
if (ip_number2($fm, $data) eq "OK") {
return "OK";
}
else
{
} else {
return $fm->l('prt_MUST_BE_VALID_HOSTNAME_OR_IP');
}
}
elsif ($data =~ /^([a-zA-Z0-9\.\-]+)$/ )
{
} elsif ($data =~ /^([a-zA-Z0-9\.\-]+)$/) {
return "OK";
}
else
{
} else {
return $fm->l('prt_MUST_BE_VALID_HOSTNAME_OR_IP');
}
}
} ## end sub hostname_or_ip2
sub ip_number2 {
# from CGI::FormMagick::Validator::ip_number($fm, $data)
my ($fm, $data) = @_;
return undef unless defined $data;
return 'FM_IP_NUMBER1' unless $data =~ /^[\d.]+$/;
my @octets = split /\./, $data;
my $dots = ($data =~ tr/.//);
return 'FM_IP_NUMBER2' unless (scalar @octets == 4 and $dots == 3);
foreach my $octet (@octets) {
return $fm->l("FM_IP_NUMBER3", {octet => $octet}) if $octet > 255;
return $fm->l("FM_IP_NUMBER3", { octet => $octet }) if $octet > 255;
}
return 'OK';
}
} ## end sub ip_number2
=head2 publicAccess_list
@@ -365,15 +307,14 @@ access drop down list.
=cut
sub printerLocation_list {
my $c = shift;
return [[ $c->l('prt_LOCAL_PRINTER_0') => 'lp0'],
[ $c->l('prt_LOCAL_PRINTER_1') => 'lp1'],
[ $c->l('prt_LOCAL_PRINTER_2') => 'lp2'],
[ $c->l('prt_NET_PRINTER') => 'remote' ],
[ $c->l('prt_FIRST_USB_PRINTER') => 'usb/lp0'],
[ $c->l('prt_SECOND_USB_PRINTER') => 'usb/lp1']];
}
return [
[ $c->l('prt_LOCAL_PRINTER_0') => 'lp0' ],
[ $c->l('prt_LOCAL_PRINTER_1') => 'lp1' ],
[ $c->l('prt_LOCAL_PRINTER_2') => 'lp2' ],
[ $c->l('prt_NET_PRINTER') => 'remote' ],
[ $c->l('prt_FIRST_USB_PRINTER') => 'usb/lp0' ],
[ $c->l('prt_SECOND_USB_PRINTER') => 'usb/lp1' ]
];
} ## end sub printerLocation_list
1

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Proxy;
#----------------------------------------------------------------------
# heading : System
# description : Proxy settings
# navigation : 4000 700
# navigation : 4000 200
#----------------------------------------------------------------------
#
# routes : end
@@ -11,65 +11,54 @@ package SrvMngr::Controller::Proxy;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::ConfigDB::UTF8;
our $db = esmith::ConfigDB->open || die "Couldn't open config db";
our $db;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$db = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my %prx_datas = ();
my $title = $c->l('prx_TITLE');
my $modul = $c->render_to_string(inline => $c->l('prx_FIRST_PAGE_DESCRIPTION'));
$prx_datas{'http_proxy_status'} = ($db->get_prop('squid','status')) || 'disabled';
my $title = $c->l('prx_TITLE');
my $modul = $c->render_to_string(inline => $c->l('prx_FIRST_PAGE_DESCRIPTION'));
$prx_datas{'http_proxy_status'} = ($db->get_prop('squid', 'status')) || 'disabled';
#if (system('/bin/rpm -q e-smith-email > /dev/null') == 0)
#{
$prx_datas{'smtp_proxy_status'} = $db->get_prop('qpsmtpd','Proxy') || undef;
$prx_datas{'smtp_proxy_status'} = $db->get_prop('qpsmtpd', 'Proxy') || undef;
#}
#(system('/bin/rpm -q e-smith-email > /dev/null') == 0) ?
$c->stash( title => $title, modul => $modul, prx_datas => \%prx_datas );
$c->stash(title => $title, modul => $modul, prx_datas => \%prx_datas);
$c->render(template => 'proxy');
};
} ## end sub main
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $http_proxy_status = $c->param('http_proxy_status') || 'disabled';
my $smtp_proxy_status = $c->param('smtp_proxy_status') || '';
my $result = "";
my $result = "";
$db = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my $squid = $db->get('squid') or $result = $c->l('prx_ERR_NO_SQUID_REC');
# smtpd is allowed to not exist, as the relevant packages may not be
# installed.
my $smtpd = $db->get('qpsmtpd') || undef;
$squid->set_prop('status', $http_proxy_status);
$smtpd->set_prop('Proxy', $smtp_proxy_status) if $smtpd;
#
# Update the system
#
system("/sbin/e-smith/signal-event proxy-update") == 0
or $result = $c->l('prx_ERR_PROXY_UPDATE_FAILED');
or $result = $c->l('prx_ERR_PROXY_UPDATE_FAILED');
my $title = $c->l('prx_TITLE');
if ( $result eq '' ) { $result = $c->l('prx_SUCCESS'); }
$c->stash( title => $title, modul => $result );
if ($result eq '') { $result = $c->l('prx_SUCCESS'); }
$c->stash(title => $title, modul => $result);
$c->render(template => 'module');
};
1;
} ## end sub do_update
1;

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Pseudonyms;
#----------------------------------------------------------------------
# heading : User management
# description : Pseudonyms
# navigation : 2000 210
# navigation : 2000 300
#----------------------------------------------------------------------
#
# routes : end
@@ -11,288 +11,251 @@ package SrvMngr::Controller::Pseudonyms;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::AccountsDB::UTF8;
use esmith::DomainsDB::UTF8;
#use Data::Dumper;
#use esmith::FormMagick::Panel::pseudonyms;
use esmith::AccountsDB;
#use URI::Escape;
our $cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
our ($cdb,$adb);
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %pse_datas = ();
my $title = $c->l('pse_FORM_TITLE');
my $notif = '';
my $title = $c->l('pse_FORM_TITLE');
my $notif = '';
$pse_datas{trt} = 'LST';
my @pseudonyms;
if ($adb)
{
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
if ($adb) {
@pseudonyms = $adb->pseudonyms();
}
$c->stash( title => $title, notif => $notif, pse_datas => \%pse_datas, pseudonyms => \@pseudonyms );
$c->stash(title => $title, notif => $notif, pse_datas => \%pse_datas, pseudonyms => \@pseudonyms);
$c->render(template => 'pseudonyms');
};
} ## end sub main
sub do_display {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LST');
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LST');
my $pseudonym = $c->param('pseudonym') || '';
my $title = $c->l('pse_FORM_TITLE');
my $title = $c->l('pse_FORM_TITLE');
my %pse_datas = ();
$pse_datas{'trt'} = $trt;
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$pse_datas{'trt'} = $trt;
if ( $trt eq 'ADD' ) {
#nothing
}
if ($trt eq 'ADD') {
if ( $trt eq 'UPD' ) {
my $rec = $adb->get($pseudonym);
if ($rec and $rec->prop('type') eq 'pseudonym') {
#nothing
}
$pse_datas{pseudonym} = $pseudonym;
$pse_datas{account} = $rec->prop('Account') || '';
$pse_datas{internal} = is_pseudonym_internal($pseudonym);
}
}
if ($trt eq 'UPD') {
my $rec = $adb->get($pseudonym);
if ( $trt eq 'DEL' ) {
if ($rec and $rec->prop('type') eq 'pseudonym') {
$pse_datas{pseudonym} = $pseudonym;
$pse_datas{account} = $rec->prop('Account') || '';
$pse_datas{internal} = is_pseudonym_internal($pseudonym);
} ## end if ($rec and $rec->prop...)
} ## end if ($trt eq 'UPD')
my $rec = $adb->get($pseudonym);
if ($rec and $rec->prop('type') eq 'pseudonym') {
if ($trt eq 'DEL') {
my $rec = $adb->get($pseudonym);
$pse_datas{pseudonym} = $pseudonym;
$pse_datas{account} = $rec->prop('Account') || '';
$pse_datas{internal} = is_pseudonym_internal($pseudonym);
if ($rec and $rec->prop('type') eq 'pseudonym') {
$pse_datas{pseudonym} = $pseudonym;
$pse_datas{account} = $rec->prop('Account') || '';
$pse_datas{internal} = is_pseudonym_internal($pseudonym);
} ## end if ($rec and $rec->prop...)
} ## end if ($trt eq 'DEL')
}
if ($trt eq 'LST') {
my @pseudonyms;
if ($adb) {
@pseudonyms = $adb->pseudonyms();
}
if ( $trt eq 'LST' ) {
my @pseudonyms;
if ($adb) {
@pseudonyms = $adb->pseudonyms();
}
$c->stash( pseudonyms => \@pseudonyms );
}
$c->stash( title => $title, pse_datas => \%pse_datas );
$c->render( template => 'pseudonyms' );
};
$c->stash(pseudonyms => \@pseudonyms);
} ## end if ($trt eq 'LST')
$c->stash(title => $title, pse_datas => \%pse_datas);
$c->render(template => 'pseudonyms');
} ## end sub do_display
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LST');
my $title = $c->l('pse_FORM_TITLE');
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LST');
my $title = $c->l('pse_FORM_TITLE');
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
my %pse_datas = ();
$pse_datas{'trt'} = $trt;
my ($res, $result) = '';
#my $pseudonym = uri_unescape($c->param('Pseudonym'));
my $pseudonym = $c->param('Pseudonym');
$pse_datas{'pseudonym'} = $pseudonym;
if ( $trt eq 'ADD' ) {
if ($trt eq 'ADD') {
my $account = $c->param('Account');
# controls
$res = $c->validate_new_pseudonym_name( $pseudonym, $account );
$result .= $res unless $res eq 'OK';
# controls
$res = $c->validate_new_pseudonym_name($pseudonym, $account);
$result .= $res unless $res eq 'OK';
#$result .= ' blocked';
$res = '';
if ( ! $result ) {
$adb->new_record( $pseudonym, { type => 'pseudonym',
Account => $account} )
or $result .= "Error occurred while creating pseudonym in database.";
# Untaint $pseudonym before use in system()
($pseudonym) = ($pseudonym =~ /(.+)/);
system( "/sbin/e-smith/signal-event", "pseudonym-create", "$pseudonym",)
== 0 or $result .= 'pse_CREATE_ERROR.';
}
if ( ! $result ) {
$res = 'OK';
$result = $c->l('pse_CREATE_SUCCEEDED') . ' ' . $pseudonym;
}
}
#$result .= ' blocked';
$res = '';
if ( $trt eq 'UPD' ) {
if (!$result) {
$adb->new_record(
$pseudonym,
{ type => 'pseudonym',
Account => $account
}
) or $result .= "Error occurred while creating pseudonym in database.";
my $account = $c->param('Account');
my $internal = $c->param ('Internal') || 'NO';
my $removable = $adb->get($pseudonym)->prop('Removable') || 'yes';
# Untaint $pseudonym before use in system()
($pseudonym) = ($pseudonym =~ /(.+)/);
system("/sbin/e-smith/signal-event", "pseudonym-create", "$pseudonym",) == 0
or $result .= 'pse_CREATE_ERROR.';
} ## end if (!$result)
my %props = ('Account' => $account);
if (!$result) {
$res = 'OK';
$result = $c->l('pse_CREATE_SUCCEEDED') . ' ' . $pseudonym;
}
} ## end if ($trt eq 'ADD')
if ($removable eq 'yes') {
if ($internal eq "YES") { $props{'Visible'} = 'internal'; }
else { $adb->get($pseudonym)->delete_prop('Visible'); }
}
if ($trt eq 'UPD') {
my $account = $c->param('Account');
my $internal = $c->param('Internal') || 'NO';
my $removable = $adb->get($pseudonym)->prop('Removable') || 'yes';
my %props = ('Account' => $account);
# controls
#$res = '';
#$res = validate_description( $c, $account );
#$result .= $res unless $res eq 'OK';
if ($removable eq 'yes') {
if ($internal eq "YES") { $props{'Visible'} = 'internal'; }
else { $adb->get($pseudonym)->delete_prop('Visible'); }
}
#$result .= 'blocked';
# controls
#$res = '';
#$res = validate_description( $c, $account );
#$result .= $res unless $res eq 'OK';
#$result .= 'blocked';
$res = '';
$res = '';
if ( ! $result ) {
$adb->get($pseudonym)->merge_props(%props)
or $result .= "Error occurred while modifying pseudonym in database.";
# Untaint $pseudonym before use in system()
($pseudonym) = ($pseudonym =~ /(.+)/);
system( "/sbin/e-smith/signal-event", "pseudonym-modify", "$pseudonym",)
== 0 or $result .= "Error occurred while modifying pseudonym.";
}
if ( ! $result ) {
$res = 'OK';
$result = $c->l('pse_MODIFY_SUCCEEDED') . ' ' . $pseudonym;
}
}
if (!$result) {
$adb->get($pseudonym)->merge_props(%props)
or $result .= "Error occurred while modifying pseudonym in database.";
if ( $trt eq 'DEL' ) {
# Untaint $pseudonym before use in system()
($pseudonym) = ($pseudonym =~ /(.+)/);
system("/sbin/e-smith/signal-event", "pseudonym-modify", "$pseudonym",) == 0
or $result .= "Error occurred while modifying pseudonym.";
} ## end if (!$result)
# controls
$res = '';
$res = validate_is_pseudonym($c, $pseudonym);
$result .= $res unless $res eq 'OK';
#$result .= 'blocked';
$res = '';
if ( ! $result ) {
$res = $c->delete_pseudonym( $pseudonym );
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$res = 'OK';
$result = $c->l('pse_REMOVE_SUCCEEDED') . ' ' . $pseudonym;
}
}
}
if (!$result) {
$res = 'OK';
$result = $c->l('pse_MODIFY_SUCCEEDED') . ' ' . $pseudonym;
}
} ## end if ($trt eq 'UPD')
if ($trt eq 'DEL') {
# controls
$res = '';
$res = validate_is_pseudonym($c, $pseudonym);
$result .= $res unless $res eq 'OK';
#$result .= 'blocked';
$res = '';
if (!$result) {
$res = $c->delete_pseudonym($pseudonym);
$result .= $res unless $res eq 'OK';
if (!$result) {
$res = 'OK';
$result = $c->l('pse_REMOVE_SUCCEEDED') . ' ' . $pseudonym;
}
} ## end if (!$result)
} ## end if ($trt eq 'DEL')
# common parts
if ( $res ne 'OK' ) {
$c->stash( error => $result);
$c->stash( title => $title, pse_datas => \%pse_datas );
return $c->render('pseudonyms');
if ($res ne 'OK') {
$c->stash(error => $result);
$c->stash(title => $title, pse_datas => \%pse_datas);
return $c->render('pseudonyms');
}
my $message = "'Pseudonyms' updates $trt DONE";
$c->app->log->info($message);
$c->flash( success => $result );
$c->flash(success => $result);
$c->redirect_to('/pseudonyms');
};
} ## end sub do_update
sub delete_pseudonym {
my ($c, $pseudonym) = @_;
my $msg = '';
#------------------------------------------------------------
# Make the pseudonym inactive, signal pseudonym-delete event
# and then delete it
#------------------------------------------------------------
my @pseudonyms = $adb->pseudonyms();
foreach my $p_rec (@pseudonyms) {
if ($p_rec->prop("Account") eq $pseudonym) {
$adb->get($p_rec->key)->set_prop('type','pseudonym-deleted')
$adb->get($p_rec->key)->set_prop('type', 'pseudonym-deleted')
or $msg .= "Error occurred while changing pseudonym type.";
}
}
$adb->get($pseudonym)->set_prop('type','pseudonym-deleted')
} ## end foreach my $p_rec (@pseudonyms)
$adb->get($pseudonym)->set_prop('type', 'pseudonym-deleted')
or $msg .= "Error occurred while changing pseudonym type.";
# Untaint $pseudonym before use in system()
($pseudonym) = ($pseudonym =~ /(.+)/);
system( "/sbin/e-smith/signal-event", "pseudonym-delete", "$pseudonym") == 0
system("/sbin/e-smith/signal-event", "pseudonym-delete", "$pseudonym") == 0
or $msg .= "Error occurred while removing pseudonym.";
#TODO: is it ->delete or get()->delete
foreach my $p_rec (@pseudonyms) {
if ($p_rec->prop("Account") eq $pseudonym) {
$adb->get($p_rec->key)->delete()
or $msg .= "Error occurred while deleting pseudonym from database.";
}
}
} ## end foreach my $p_rec (@pseudonyms)
$adb->get($pseudonym)->delete()
or $msg .= "Error occurred while deleting pseudonym from database.";
return $msg unless $msg;
return $msg unless $msg;
return 'OK';
}
} ## end sub delete_pseudonym
sub existing_accounts_list {
my $c = shift;
my @existingAccounts = ( ['Administrator' => 'admin']);
my @existingAccounts = ([ 'Administrator' => 'admin' ]);
foreach my $a ($adb->get_all) {
if ($a->prop('type') =~ /(user|group)/) {
push @existingAccounts, [ $a->key => $a->key ];
}
if ($a->prop('type') eq "pseudonym") {
my $target = $adb->get($a->prop('Account'));
unless ($target)
{
warn "WARNING: pseudonym (" . $a->key . ") => missing Account("
. $a->prop('Account') . ")\n";
unless ($target) {
warn "WARNING: pseudonym (" . $a->key . ") => missing Account(" . $a->prop('Account') . ")\n";
next;
}
push @existingAccounts, [ $a->key, $a->key ]
unless ($target->prop('type') eq "pseudonym");
}
}
return(\@existingAccounts);
}
} ## end if ($a->prop('type') eq...)
} ## end foreach my $a ($adb->get_all)
return (\@existingAccounts);
} ## end sub existing_accounts_list
=head2 get_pseudonym_account
@@ -301,17 +264,17 @@ Returns the current Account property for this pseudonym
=cut
sub get_pseudonym_account {
my $c = shift;
my $c = shift;
my $pseudonym = shift;
my $a = $adb->get($pseudonym)->prop('Account');
my $a = $adb->get($pseudonym)->prop('Account');
if ($a eq "admin") {
$a = "Administrator";
} elsif ($a eq "shared") {
$a = $c->l("EVERYONE");
$a = $c->l("EVERYONE");
}
return($a);
}
return ($a);
} ## end sub get_pseudonym_account
=head2 is_pseudonym_not_removable
@@ -320,13 +283,12 @@ Returns 1 if the current Account is not removable, 0 otherwise
=cut
sub is_pseudonym_not_removable {
my $c = shift;
my $c = shift;
my $pseudonym = shift;
my $removable = $adb->get($pseudonym)->prop('Removable') || 'yes';
return 1 if ($removable eq 'yes');
return 1 if ($removable eq 'yes');
return 0;
}
} ## end sub is_pseudonym_not_removable
=head2 is_pseudonym_internal
@@ -335,13 +297,13 @@ Returns YES if the current Account property Visible is 'internal'
=cut
sub is_pseudonym_internal {
# my $c = shift;
my $pseudonym = shift;
# my $c = shift;
my $pseudonym = shift;
my $visible = $adb->get($pseudonym)->prop('Visible') || '';
return 'YES' if ($visible eq 'internal');
return 'YES' if ($visible eq 'internal');
return 'NO';
}
} ## end sub is_pseudonym_internal
=head2 validate_new_pseudonym_name FM PSEUDONYM
@@ -355,30 +317,24 @@ Returns "NAME_IN_USE" if this pseudonym is taken.
=cut
sub validate_new_pseudonym_name {
my ($c, $pseudonym, $account) = @_;
my $acct = $adb->get($pseudonym);
if (defined $acct) {
return($c->l('pse_NAME_IN_USE'));
return ($c->l('pse_NAME_IN_USE'));
} elsif ($pseudonym =~ /@/) {
use esmith::DomainsDB;
my $ddb = esmith::DomainsDB->open_ro
or die "Couldn't open DomainsDB\n";
my $ddb = esmith::DomainsDB::UTF8->open_ro
or die "Couldn't open DomainsDB\n";
my ($lhs, $rhs) = split /@/, $pseudonym;
return ($c->l('pse_PSEUDONYM_INVALID_DOMAIN')) unless ($ddb->get($rhs));
return ($c->l('pse_PSEUDONYM_INVALID_SAMEACCT')) if ($lhs eq $account);
return ('OK'); # p:' . $pseudonym . ' a:' . $account);
} elsif ( $pseudonym !~ /^([a-z0-9][a-z0-9\.\-_!#\?~\$\^\+&`%\/\*]*)$/ ) {
return($c->l('pse_VALID_PSEUDONYM_NAMES'));
return ('OK'); # p:' . $pseudonym . ' a:' . $account);
} elsif ($pseudonym !~ /^([a-z0-9][a-z0-9\.\-_!#\?~\$\^\+&`%\/\*]*)$/) {
return ($c->l('pse_VALID_PSEUDONYM_NAMES'));
} else {
return('OK');
return ('OK');
}
}
} ## end sub validate_new_pseudonym_name
=head2 validate_is_pseudonym FM NAME
@@ -388,19 +344,15 @@ returns "NOT_A_PSEUDONYM" if the name in question isn't an existing pseudonym
=cut
sub validate_is_pseudonym {
my $c = shift;
my $c = shift;
my $pseudonym = shift;
$pseudonym = $adb->get($pseudonym);
return($c->l('pse_NOT_A_PSEUDONYM')) unless $pseudonym;
return ($c->l('pse_NOT_A_PSEUDONYM')) unless $pseudonym;
my $type = $pseudonym->prop('type');
unless (defined $type && ($type eq 'pseudonym') ) {
return($c->l('NOT_A_PSEUDONYM'));
unless (defined $type && ($type eq 'pseudonym')) {
return ($c->l('NOT_A_PSEUDONYM'));
}
return ('OK');
}
} ## end sub validate_is_pseudonym
1;

View File

@@ -10,143 +10,352 @@ package SrvMngr::Controller::Qmailanalog;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use esmith::FormMagick qw(gen_locale_date_string);
use SrvMngr qw(gen_locale_date_string);
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use List::Util qw(sum);
#use Mail::Log::Trace::Postfix;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('qma_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('qma_INITIAL_DESC'));
$c->stash( title => $title, modul => $modul );
$c->stash(title => $title, modul => $modul);
$c->render(template => 'qmailanalog');
};
} ## end sub main
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $result = "";
my $result = "";
my $report_type = $c->param('report_type');
if ($report_type =~ /^(\S+)$/)
{
$report_type = $1;
if ($report_type =~ /^(\S+)$/) {
$report_type = $1;
} elsif ($report_type =~ /^\s*$/) {
$report_type = "zoverall";
} else {
$result = $c->l('INVALID_REPORT_TYPE') . $report_type;
$report_type = undef;
}
elsif ($report_type =~ /^\s*$/)
{
$report_type = "zoverall";
} else {
$result = $c->l('INVALID_REPORT_TYPE') . $report_type;
$report_type = undef;
}
my $title = $c->l('qma_FORM_TITLE');
$result = $c->render_to_string(inline => generateReport($c, $report_type)) if $report_type;
$c->stash( title => $title, modul => $result );
$c->stash(title => $title, modul => $result);
$c->render(template => 'module');
};
} ## end sub do_update
sub generateReport {
my $c = shift;
my $report_type = shift;
my $out = '';
#------------------------------------------------------------
# Go ahead and generate the report.
#------------------------------------------------------------
my $now_string = $c->gen_locale_date_string();
my $log_path = '/var/log/maillog';
$out .= sprintf("<h3>%s %s </h3>", $c->l('REPORT_GENERATED'), $now_string);
$out .= sprintf "<pre>";
# Get the selected report from the form submission
my $selected_report = $report_type;
my $c = shift;
my $report_type = shift;
my $out = '';
#------------------------------------------------------------
# Looks good; go ahead and generate the report.
#------------------------------------------------------------
# $| = 1;
my $now_string = $c->gen_locale_date_string();
$out .= sprintf("<h3>%s %s </h3>", $c->l('REPORT_GENERATED'), $now_string);
if ($report_type =~ /^qmail-q/)
{
open(QMAILQUEUEREPORT, "/var/qmail/bin/$report_type |");
$out .= sprintf "<pre>";
while (<QMAILQUEUEREPORT>)
{
$out .= sprintf("%s", $_);
}
close QMAILQUEUEREPORT;
$out .= sprintf "</pre>";
$out .= sprintf("<h3>%s</h3>", $c->l('END_OF_REPORT'));
return '';
}
chdir "/var/log/qmail";
open(QMAILANALOG,
"/bin/cat \@* current 2>/dev/null"
. "| /usr/local/bin/tai64nunix"
. "| /usr/local/qmailanalog/bin/matchup 5>/dev/null"
. "| /usr/local/qmailanalog/bin/$report_type |"
);
$out .= sprintf "<pre>";
while (<QMAILANALOG>)
{
# Cook any special HTML characters
s/\&/\&amp;/g;
s/\"/\&quot;/g;
s/\>/\&gt;/g;
s/\</\&lt;/g;
$out .= sprintf("%s", $_);
}
close QMAILANALOG;
$out .= sprintf "</pre>";
$out .= sprintf("<h3>%s</h3>", $c->l('END_OF_REPORT'));
return $out;
}
# Call the relevant report sub based on the selection
if ($selected_report eq 'daily_summary') {
$out .= daily_summary_report($log_path);
}
elsif ($selected_report eq 'daily_summary_today') {
$out .= daily_summary_report_today($log_path);
}
elsif ($selected_report eq 'daily_summary_all') {
$out .= daily_summary_report_all($log_path);
}
elsif ($selected_report eq 'top_senders') {
$out .= top_senders_and_recipients($log_path);
}
elsif ($selected_report eq 'bounce_analysis') {
$out .= bounce_rate_analysis($log_path);
}
elsif ($selected_report eq 'spam_and_virus') {
$out .= spam_and_virus_filter_report($log_path);
}
elsif ($selected_report eq 'delivery_status') {
$out .= delivery_status_report($log_path);
}
elsif ($selected_report eq 'geo_analysis') {
$out .= geographical_analysis_of_email($log_path);
}
elsif ($selected_report eq 'traffic_analysis') {
$out .= traffic_analysis($log_path);
}
elsif ($selected_report eq 'auth_analysis') {
$out .= authentication_analysis($log_path);
}
elsif ($selected_report eq 'user_activity') {
$out .= user_activity_report($log_path);
}
elsif ($selected_report eq 'error_reporting') {
$out .= error_reporting($log_path);
}
elsif ($selected_report eq 'comparison_reports') {
$out .= comparison_reports($log_path, '/var/log/mail.log.1');
}
elsif ($selected_report eq 'customized_reports') {
$out .= customized_reports($log_path);
}
else {
$out .= 'Invalid report selected';
}
# The $output variable now contains the generated report output.
# Further processing can be done here, or you can render it later.
$out .= sprintf "</pre>";
$out .= sprintf("<h3>%s</h3>", $c->l('END_OF_REPORT'));
return $out;
} ## end sub generateReport
sub reportType_list {
my $c = shift;
my $c = shift;
my @array = (
# [ $c->l('qma_LIST_OUTGOING') => 'qmail-qread' ],
# [ $c->l('qma_SUMMARIZE_QUEUE') => 'qmail-qstat' ],
[ $c->l('qma_SUCCESSFUL_DELIVERY_DELAY') => 'zddist' ],
[ $c->l('qma_REASONS_DEFERRAL') => 'zdeferrals' ],
[ $c->l('qma_REASONS_FAILURE') => 'zfailures' ],
[ $c->l('qma_BASIC_STATS') => 'zoverall' ],
[ $c->l('qma_RECIP_STATS') => 'zrecipients' ],
[ $c->l('qma_RECIP_HOSTS') => 'zrhosts' ],
[ $c->l('qma_RECIP_ORDERED') => 'zrxdelay' ],
[ $c->l('qma_SENDER_STATS') => 'zsenders' ],
[ $c->l('qma_SENDMAIL_STYLE') => 'zsendmail' ],
[ $c->l('qma_REASONS_SUCCESS') => 'zsuccesses' ],
[ $c->l('qma_SENDER_UIDS') => 'zsuids' ]
);
[$c->l('qma_Daily_Summary_Report_yesterday') => 'daily_summary'],
[$c->l('qma_Daily_Summary_Report_today') => 'daily_summary_today'],
[$c->l('qma_Daily_Summary_Report_all') => 'daily_summary_all'],
#[$c->l('qma_Top Senders and Recipients') => 'top_senders'],
#[$c->l('qma_Bounce Rate Analysis') => 'bounce_analysis'],
#[$c->l('qma_Spam and Virus Filtering Report') => 'spam_and_virus'],
#[$c->l('qma_Delivery Status Report') => 'delivery_status'],
#[$c->l('qma_Geographic Analysis of Email') => 'geo_analysis'],
#[$c->l('qma_Traffic Analysis') => 'traffic_analysis'],
#[$c->l('qma_Authentication Analysis') => 'auth_analysis'],
#[$c->l('qma_User Activity Report') => 'user_activity'],
#[$c->l('qma_Error Reporting') => 'error_reporting'],
#[$c->l('qma_Comparison Reports') => 'comparison_reports'],
#[$c->l('qma_Customized Reports') => 'customized_reports'],
);
my @sorted_array = sort { $a->[0] cmp $b->[0] } @array;
return \@sorted_array;
} ## end sub reportType_list
sub daily_summary_report {
my $log_file = shift; # Path to log file
my $output = qx(ls -1 /var/log/maillog* | xargs cat |pflogsumm -d yesterday --detail 0 --no-no-msg-size);
return format_as_html("Daily Summary Report", $output);
}
1;
sub daily_summary_report_today {
my $log_file = shift; # Path to log file
my $output = qx(ls -1 /var/log/maillog* | xargs cat |pflogsumm -d today --detail 0 --no-no-msg-size);
return format_as_html("Daily Summary Report", $output);
}
sub daily_summary_report_all {
my $log_file = shift; # Path to log file
my $output = qx(ls -1 /var/log/maillog* | xargs cat |pflogsumm --detail 0 --no-no-msg-size);
return format_as_html("Summary Report across all logs", $output);
}
sub top_senders_and_recipients {
my $log_file = shift;
my $output = qx(pflogsumm --smtpd-stats $log_file);
return format_as_html("Top Senders and Recipients", $output);
}
sub bounce_rate_analysis {
my $log_file = shift;
my $output = qx(pflogsumm --bounce-detail 10 $log_file); # Show up to 10 bounce details
return format_as_html("Bounce Rate Analysis", $output);
}
sub spam_and_virus_filter_report {
my $log_file = shift;
my $output = qx(pflogsumm -u 10 $log_file); # User report with up to 10 entries
return format_as_html("Spam and Virus Filtering Report", $output);
}
sub delivery_status_report {
my $log_file = shift;
my $output = qx(pflogsumm --deferral-detail 10 $log_file); # Show deferral details
return format_as_html("Delivery Status Report", $output);
}
sub geographical_analysis_of_email {
my $log_file = shift;
# `pflogsumm` doesn't have a specific option for geographic analysis in the help text;
# It's assumed this could be replaced with something relevant, like a SMTP detail.
my $output = qx(pflogsumm --smtp-detail 10 $log_file); # Show up to 10 SMTP details
return format_as_html("Geographic Analysis of Email", $output);
}
sub traffic_analysis {
my $log_file = shift;
my $output = qx(pflogsumm --verbose-msg-detail $log_file); # Request verbose detail
return format_as_html("Traffic Analysis", $output);
}
sub authentication_analysis {
my $log_file = shift;
my $output = qx(pflogsumm -u 10 --verbose-msg-detail $log_file); # User detailed report
return format_as_html("Authentication Analysis", $output);
}
sub user_activity_report {
my $log_file = shift;
my $output = qx(pflogsumm -u 20 $log_file); # Show user activity for up to 20 users
return format_as_html("User Activity Report", $output);
}
sub error_reporting {
my $log_file = shift;
my $output = qx(pflogsumm --problems-first $log_file); # This will show problems first
return format_as_html("Error Reporting", $output);
}
sub comparison_reports {
my ($log_file1, $log_file2) = @_; # Comparing two log files
my $output = qx(pflogsumm $log_file1 $log_file2); # Standard comparison without special flags
return format_as_html("Comparison Reports", $output);
}
sub customized_reports {
my $log_file = shift;
# Because we don't have a concrete custom flag, we'll consider using -d with specific detail.
my $output = qx(pflogsumm --detail 10 $log_file); # Generally show detailed summary
return format_as_html("Customized Reports", $output);
}
sub format_as_html {
my ($title, $content) = @_;
return <<HTML;
<h2>$title</h2>
<pre>$content</pre>
HTML
}
### 1. Message Tracking
#sub trace_message {
#my ($log_path, $message_id) = @_;
##my $tracer = Mail::Log::Trace::Postfix->new({log_file => $log_path});
##$tracer->set_message_id($message_id);
#my $output = "Message Tracking Report for ID: $message_id\n";
##$output .= "=" x 50 . "\n";
##$output .= sprintf "%-12s: %s\n", 'From', $tracer->get_from_address;
##$output .= sprintf "%-12s: %s\n", 'Status', $tracer->get_final_status;
##$output .= "\nRecipients:\n";
##$output .= join("\n", map { "- $_" } $tracer->get_recipient_addresses);
##$output .= "\n\nTimeline:\n";
##my $timeline = $tracer->get_timestamps;
##while (my ($stage, $time) = each %$timeline) {
##$output .= sprintf "%-10s: %s\n", ucfirst($stage), $time;
##}
#return $output || "No records found for message ID: $message_id";
#}
#### 2. Queue Analysis
#sub get_queue_stats {
#my $spool_dir = '/var/spool/postfix';
#my %queues = map { $_ => 0 } qw(active deferred bounce hold corrupt);
#foreach my $q (keys %queues) {
#opendir(my $dh, "$spool_dir/$q");
#$queues{$q} = scalar(grep { -f "$spool_dir/$q/$_" } readdir($dh));
#closedir($dh);
#}
#my $output = "Current Postfix Queue Status\n";
#$output .= "=" x 30 . "\n";
#$output .= sprintf "%-10s: %3d messages\n", ucfirst($_), $queues{$_}
#for sort keys %queues;
#$output .= "\nTotal: " . sum(values %queues) . " messages in queue";
#return $output;
#}
#### 3. Message Statistics
#sub get_message_stats {
#my ($log_path) = @_;
#my %stats = (received => 0, rejected => 0, delivered => 0,
#deferred => 0, bounced => 0, held => 0);
#open(my $fh, '<', $log_path);
#while(<$fh>) {
#$stats{received}++ if /qmgr.*: [A-Z0-9]+: from=/;
#$stats{delivered}++ if /status=sent/;
#$stats{rejected}++ if /NOQUEUE: reject/;
#$stats{deferred}++ if /status=deferred/;
#$stats{bounced}++ if /status=bounced/;
#$stats{held}++ if /status=hold/;
#}
#close($fh);
#my $output = "Message Statistics for " . localtime . "\n";
#$output .= "=" x 40 . "\n";
#$output .= sprintf "%-12s: %6d\n", 'Received', $stats{received};
#$output .= sprintf "%-12s: %6d (%.1f%%)\n", 'Delivered', $stats{delivered},
#($stats{received} ? ($stats{delivered}/$stats{received}*100) : 0);
#$output .= sprintf "%-12s: %6d\n", 'Rejected', $stats{rejected};
#$output .= sprintf "%-12s: %6d\n", 'Deferred', $stats{deferred};
#$output .= sprintf "%-12s: %6d\n", 'Bounced', $stats{bounced};
#$output .= sprintf "%-12s: %6d\n", 'Held', $stats{held};
#return $output;
#}
#### 4. User Activity Audit
#sub get_user_activity {
#my ($log_path, $email) = @_;
##my $tracer = Mail::Log::Trace::Postfix->new({log_file => $log_path});
##my $sent = scalar $tracer->find_messages_by_sender($email);
##my $received = scalar $tracer->find_messages_by_recipient($email);
#my $output = "Activity Report for: $email\n";
##$output .= "=" x (length($email) + 18) . "\n";
##$output .= "Messages sent: $sent\n";
##$output .= "Messages received: $received\n\n";
##$output .= "Last week's activity:\n";
##$output .= join("\n", map { sprintf "- %s: %d messages", $_->[0], $_->[1] }
##$tracer->get_weekly_stats($email));
#return $output || "No activity found for $email";
#}
#### 5. Security Monitoring
#sub detect_auth_failures {
#my ($log_path) = @_;
#my %failures;
#open(my $fh, '<', $log_path);
#while(<$fh>) {
#if(/SASL (?:LOGIN|PLAIN) authentication failed.*?\[([0-9.]+)\]/) {
#$failures{$1}++;
#}
#}
#close($fh);
#return "No authentication failures found" unless keys %failures;
#my $output = "Authentication Failure Report\n";
#$output .= "=" x 30 . "\n";
#$output .= sprintf "%-15s %s\n", 'IP Address', 'Attempts';
#$output .= sprintf "%-15s %s\n", '-' x 15, '-' x 7;
#foreach my $ip (sort { $failures{$b} <=> $failures{$a} } keys %failures) {
#$output .= sprintf "%-15s %5d\n", $ip, $failures{$ip};
#}
#$output .= "\nTotal failures: " . sum(values %failures);
#return $output;
#}
1;

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Quota;
#----------------------------------------------------------------------
# heading : User management
# description : Quotas
# navigation : 2000 300
# navigation : 2000 500
#----------------------------------------------------------------------
#
# routes : end
@@ -12,182 +12,199 @@ use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use esmith::FormMagick::Panel::quota;
#use esmith::TestUtils;
use Scalar::Util qw(looks_like_number);
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::AccountsDB::UTF8;
#our $db = esmith::ConfigDB->open || die "Couldn't open config db";
our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
my $adb;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %quo_datas = ();
my $title = $c->l('quo_FORM_TITLE');
my $title = $c->l('quo_FORM_TITLE');
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$quo_datas{'trt'} = 'LIST';
my @userAccounts;
if ($adb) {
@userAccounts = $adb->users();
}
$c->stash( title => $title, quo_datas => \%quo_datas, userAccounts => \@userAccounts );
$c->stash(title => $title, quo_datas => \%quo_datas, userAccounts => \@userAccounts);
$c->render(template => 'quota');
};
} ## end sub main
sub do_display {
my $c = shift;
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $c = shift;
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $user = $c->param('user') || '';
$trt = 'UPD' if ( $user );
$trt = 'UPD' if ($user);
my %quo_datas = ();
my $title = $c->l('quo_FORM_TITLE');
my $title = $c->l('quo_FORM_TITLE');
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$quo_datas{'trt'} = $trt;
if ( $trt eq 'UPD' ) {
my $rec = $adb->get($user);
if ($rec and $rec->prop('type') eq 'user') {
$quo_datas{user} = $user;
$quo_datas{userRec} = $rec;
my $max = esmith::FormMagick::Panel::quota->toBestUnit($rec->prop('MaxBlocks'));
$quo_datas{hardlim} = $max;
$max = esmith::FormMagick::Panel::quota->toBestUnit($rec->prop('MaxBlocksSoftLim'));
$quo_datas{softlim} = $max;
}
}
$c->stash( title => $title, quo_datas => \%quo_datas );
$c->render( template => 'quota' );
};
if ($trt eq 'UPD') {
my $rec = $adb->get($user);
if ($rec and $rec->prop('type') eq 'user') {
$quo_datas{user} = $user;
$quo_datas{userRec} = $rec;
my $max = $c->toBestUnit($rec->prop('MaxBlocks'));
$quo_datas{hardlim} = $max;
$max = $c->toBestUnit($rec->prop('MaxBlocksSoftLim'));
$quo_datas{softlim} = $max;
} ## end if ($rec and $rec->prop...)
} ## end if ($trt eq 'UPD')
$c->stash(title => $title, quo_datas => \%quo_datas);
$c->render(template => 'quota');
} ## end sub do_display
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('quo_FORM_TITLE');
my $title = $c->l('quo_FORM_TITLE');
my %quo_datas = ();
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
$quo_datas{trt} = $trt;
my $result = '';
my $res;
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
if ( $trt eq 'UPD' ) {
$quo_datas{user} = ($c->param('user') || '');
$quo_datas{softlim} = ($c->param('Soft') || '');
if ($trt eq 'UPD') {
$quo_datas{user} = ($c->param('user') || '');
$quo_datas{softlim} = ($c->param('Soft') || '');
$quo_datas{hardlim} = ($c->param('Hard') || '');
# controls
$res = validate_quota( $c, $quo_datas{user}, $quo_datas{softlim}, $quo_datas{hardlim} );
$result .= $res unless $res eq 'OK';
# controls
$res = validate_quota($c, $quo_datas{user}, $quo_datas{softlim}, $quo_datas{hardlim});
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$result = $c->l('quo_SUCCESSFULLY_MODIFIED') . ' ' . $quo_datas{user};
} else {
$quo_datas{userRec} = $adb->get($quo_datas{user}) || undef;
}
}
if (!$result) {
$result = $c->l('quo_SUCCESSFULLY_MODIFIED') . ' ' . $quo_datas{user};
} else {
$quo_datas{userRec} = $adb->get($quo_datas{user}) || undef;
}
} ## end if ($trt eq 'UPD')
# common parts
if ($res ne 'OK') {
$c->stash( error => $result );
$c->stash( title => $title, quo_datas => \%quo_datas );
return $c->render('quota');
$c->stash(error => $result);
$c->stash(title => $title, quo_datas => \%quo_datas);
return $c->render('quota');
}
my $message = "'Quota' updates ($trt) DONE";
$c->app->log->info($message);
$c->flash( success => $result );
$c->flash(success => $result);
$c->redirect_to('/quota');
};
} ## end sub do_update
sub validate_quota {
my ($c, $acct, $softlim, $hardlim ) = @_;
my ($c, $acct, $softlim, $hardlim) = @_;
my $msg;
my $rec = $adb->get($acct);
return $c->l('quo_ERR_NO_SUCH_ACCT') . ' : ' . $acct unless (defined $rec);
return $c->l('quo_ERR_NO_SUCH_ACCT') . ' : ' . $acct unless (defined $rec);
my $type = $rec->prop('type');
unless ($type eq "user") {
$msg = $c->l('quo_ERR_NOT_A_USER_ACCT').$acct.$c->l('quo_ACCOUNT_IS_TYPE').$type;
return $msg;
$msg = $c->l('quo_ERR_NOT_A_USER_ACCT') . $acct . $c->l('quo_ACCOUNT_IS_TYPE') . $type;
return $msg;
}
my $uid = getpwnam($acct);
return $c->l('COULD_NOT_GET_UID').$acct unless ($uid);
return $c->l('COULD_NOT_GET_UID') . $acct unless ($uid);
if (($softlim !~ /^(.+?)\s*([KMGT])?$/ ) || (!looks_like_number ($1))) {
return $c->l('quo_SOFT_VAL_MUST_BE_NUMBER');
if (($softlim !~ /^(.+?)\s*([KMGT])?$/) || (!looks_like_number($1))) {
return $c->l('quo_SOFT_VAL_MUST_BE_NUMBER');
}
my $exponent = 1; # Entries with no suffix are assumed to be in megabytes.
if (defined ($2)) {
$exponent = index("KMGT",$2);
}
$softlim = ($1 * 1024 ** $exponent);
my $exponent = 1; # Entries with no suffix are assumed to be in megabytes.
if (($hardlim !~ /^(.+?)\s*([KMGT])?$/ ) || (!looks_like_number ($1))) {
return $c->l('quo_HARD_VAL_MUST_BE_NUMBER');
if (defined($2)) {
$exponent = index("KMGT", $2);
}
$exponent = 1; # Entries with no suffix are assumed to be in megabytes.
if (defined ($2))
{
$exponent = index("KMGT",$2);
}
$hardlim = ($1 * 1024 ** $exponent);
$softlim = ($1 * 1024**$exponent);
if (($hardlim !~ /^(.+?)\s*([KMGT])?$/) || (!looks_like_number($1))) {
return $c->l('quo_HARD_VAL_MUST_BE_NUMBER');
}
$exponent = 1; # Entries with no suffix are assumed to be in megabytes.
if (defined($2)) {
$exponent = index("KMGT", $2);
}
$hardlim = ($1 * 1024**$exponent);
#------------------------------------------------------------
# Make sure that soft limit is less than hard limit.
#------------------------------------------------------------
unless ($hardlim == 0 or $hardlim > $softlim) {
return $c->l('quo_ERR_HARD_LT_SOFT');
return $c->l('quo_ERR_HARD_LT_SOFT');
}
#------------------------------------------------------------
# Update accounts database and signal the user-modify event.
#------------------------------------------------------------
$rec->set_prop('MaxBlocks', $hardlim);
$rec->set_prop('MaxBlocks', $hardlim);
$rec->set_prop('MaxBlocksSoftLim', $softlim);
# Untaint $acct before using in system().
$acct =~ /^(\w[\-\w_\.]*)$/; $acct = $1;
system ("/sbin/e-smith/signal-event", "user-modify", "$acct") == 0
or die ($c->l('quo_ERR_MODIFYING')."\n");
$acct =~ /^(\w[\-\w_\.]*)$/;
$acct = $1;
system("/sbin/e-smith/signal-event", "user-modify", "$acct") == 0
or die($c->l('quo_ERR_MODIFYING') . "\n");
return 'OK';
} ## end sub validate_quota
sub toMB
{
my ($self,$kb) = @_;
return sprintf("%.2f", $kb / 1024);
}
sub toMBNoDecimalPlaces
{
my ($self,$kb) = @_;
return sprintf("%.0f", $kb / 1024);
}
sub toGBNoDecimalPlaces
{
my ($self,$kb) = @_;
return sprintf("%.0f", $kb / 1024 / 1024);
}
sub toKB
{
my ($self,$mb) = @_;
return sprintf("%.0f", $mb * 1024);
}
sub GBtoKB
{
my ($self,$gb) = @_;
return sprintf("%.0f", $gb * 1024 * 1024);
}
sub MBtoKB
{
my ($self,$mb) = @_;
return sprintf("%.0f", $mb * 1024);
}
sub toBestUnit
{
my ($self,$kb) = @_;
return 0 if($kb == 0);
return $kb."K" if($kb < 1024);
return $kb."K" if($kb > 1024 && $kb < 1048576 && $kb % 1024 != 0);
return $self->toMBNoDecimalPlaces($kb)."M" if($kb < 1048576);
return $self->toMBNoDecimalPlaces($kb)."M" if($kb > 1048576
&& ($kb % 1048576 != 0));
return $self->toGBNoDecimalPlaces($kb)."G";
}
1

View File

@@ -1,87 +1,78 @@
package SrvMngr::Controller::Reboot;
#----------------------------------------------------------------------
# heading : System
# heading : System
# description : Reboot or shutdown
# navigation : 4000 700
# navigation : 4000 700
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('rbo_FORM_TITLE');
my $modul = '';
$c->stash( title => $title, modul => $modul );
$c->stash(title => $title, modul => $modul);
$c->render(template => 'reboot');
};
} ## end sub main
sub do_action {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('rbo_FORM_TITLE');
my $result = "";
my $function = $c->param ('function');
my $debug = $c->param('debug');
my $title = $c->l('rbo_FORM_TITLE');
my $result = "";
my $function = $c->param('function');
my $debug = $c->param('debug');
if ($function eq "reboot") {
$result = $c->l('rbo_REBOOT_SUCCEEDED') . '<br>' . $c->l('rbo_DESC_REBOOT');
$result = $c->l('rbo_REBOOT_SUCCEEDED') . '<br>' . $c->l('rbo_DESC_REBOOT');
unless ($debug) {
esmith::util::backgroundCommand( 1, "/sbin/e-smith/signal-event", "reboot" );
# system( "/sbin/e-smith/signal-event", "reboot" ) == 0
# or die ("Error occurred while rebooting.\n");
}
esmith::util::backgroundCommand(1, "/sbin/e-smith/signal-event", "reboot");
# system( "/sbin/e-smith/signal-event", "reboot" ) == 0
# or die ("Error occurred while rebooting.\n");
} ## end unless ($debug)
} elsif ($function eq 'shutdown') {
$result = $c->l('rbo_SHUTDOWN_SUCCEEDED') . '<br>' . $c->l('rbo_DESC_SHUTDOWN');
$result = $c->l('rbo_SHUTDOWN_SUCCEEDED') . '<br>' . $c->l('rbo_DESC_SHUTDOWN');
unless ($debug) {
esmith::util::backgroundCommand( 1, "/sbin/e-smith/signal-event", "halt" );
# system( "/sbin/e-smith/signal-event", "halt" ) == 0
# or die ("Error occurred while halting.\n");
}
esmith::util::backgroundCommand(1, "/sbin/e-smith/signal-event", "halt");
# system( "/sbin/e-smith/signal-event", "halt" ) == 0
# or die ("Error occurred while halting.\n");
} ## end unless ($debug)
} elsif ($function eq 'reconfigure') {
$result = $c->l('rbo_RECONFIGURE_SUCCEEDED') . '<br>' . $c->l('rbo_DESC_RECONFIGURE');
$result = $c->l('rbo_RECONFIGURE_SUCCEEDED') . '<br>' . $c->l('rbo_DESC_RECONFIGURE');
unless ($debug) {
# esmith::util::backgroundCommand( 1, "/sbin/e-smith/signal-event", "post-upgrade",
# "; ", "/sbin/e-smith/signal-event", "reboot" );
system( "/sbin/e-smith/signal-event", "post-upgrade" ) == 0
or die ("Error occurred while running post-upgrade.\n");
system( "/sbin/e-smith/signal-event", "reboot" ) == 0
or die ("Error occurred while rebooting.\n");
}
}
$c->stash( title => $title, modul => $result );
# esmith::util::backgroundCommand( 1, "/sbin/e-smith/signal-event", "post-upgrade",
# "; ", "/sbin/e-smith/signal-event", "reboot" );
esmith::util::backgroundCommand( 1, "/sbin/e-smith/signal-event", "post-upgrade-and-reboot");
#system("/sbin/e-smith/signal-event", "post-upgrade") == 0
#or die("Error occurred while running post-upgrade.\n");
#system("/sbin/e-smith/signal-event", "reboot") == 0
#or die("Error occurred while rebooting.\n");
} ## end unless ($debug)
} ## end elsif ($function eq 'reconfigure')
$c->stash(title => $title, modul => $result);
$c->render(template => 'module');
};
} ## end sub do_action
sub rebootFunction_list {
my $c = shift;
return [[ $c->l('rbo_REBOOT') => 'reboot' ],
[ $c->l('RECONFIGURE') => 'reconfigure' ],
[ $c->l('SHUTDOWN') => 'shutdown' ]];
}
return [
[ $c->l('rbo_REBOOT') => 'reboot' ],
[ $c->l('RECONFIGURE') => 'reconfigure' ],
[ $c->l('SHUTDOWN') => 'shutdown' ]
];
} ## end sub rebootFunction_list
1;

View File

@@ -11,13 +11,10 @@ package SrvMngr::Controller::Remoteaccess;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session ip_number subnet_mask get_reg_mask);
use esmith::ConfigDB;
use esmith::ConfigDB::UTF8;
use esmith::util;
use File::Basename;
use Exporter;
@@ -25,165 +22,149 @@ use Carp;
use Socket qw( inet_aton );
#our @ISA = qw(esmith::FormMagick Exporter);
our @EXPORT = qw( networkAccess_list passwordLogin_list get_ssh_permit_root_login get_ssh_access get_telnet_mode
get_ftp_access get_ftp_password_login_access
get_value get_prop get_ssh_password_auth
validate_network_and_mask ip_number_or_blank subnet_mask_or_blank
get_ipsecrw_sessions pptp_and_dhcp_range
get_ftp_access get_ftp_password_login_access
get_value get_prop get_ssh_password_auth
validate_network_and_mask ip_number_or_blank subnet_mask_or_blank
get_ipsecrw_sessions pptp_and_dhcp_range
);
# get_pptp_sessions
our $db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
our $db;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('rma_FORM_TITLE');
my $notif = '';
my $title = $c->l('rma_FORM_TITLE');
my $notif = '';
my %rma_datas = ();
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
#$rma_datas{ipsecrwSess} = $c->get_ipsecrw_sessions();
#$rma_datas{pptpSessions} = $c->get_pptp_sessions();
$rma_datas{sshAccess} = $c->get_ssh_access();
$rma_datas{sshPermitRootLogin} = $c->get_ssh_permit_root_login();
$rma_datas{sshAccess} = $c->get_ssh_access();
$rma_datas{sshPermitRootLogin} = $c->get_ssh_permit_root_login();
$rma_datas{sshPasswordAuthentication} = $c->get_ssh_password_auth();
$rma_datas{sshTCPPort} = $c->get_ssh_port();
$rma_datas{ftpAccess} = $c->get_ftp_access();
$rma_datas{ftpPasswordAccess} = $c->get_ftp_password_login_access();
$rma_datas{sshTCPPort} = $c->get_ssh_port();
$rma_datas{ftpAccess} = $c->get_ftp_access();
$rma_datas{ftpPasswordAccess} = $c->get_ftp_password_login_access();
#$rma_datas{telnetAccess} = $c->get_telnet_access;
$c->stash( title => $title, notif => $notif, rma_datas => \%rma_datas );
$c->stash(title => $title, notif => $notif, rma_datas => \%rma_datas);
$c->render(template => 'remoteaccess');
};
} ## end sub main
sub do_action {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('rma_FORM_TITLE');
my ($result, $res, $trt) = '';
my %rma_datas = ();
$rma_datas{ipsecrwSess} = ($c->param ('IpsecrwSess') || '');
$rma_datas{ipsecrwReset} = ($c->param ('IpsecrwReset') || '');
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
$rma_datas{ipsecrwSess} = ($c->param('IpsecrwSess') || '');
$rma_datas{ipsecrwReset} = ($c->param('IpsecrwReset') || '');
#$rma_datas{pptpSessions} = ($c->param ('PptpSessions') || '0');
$rma_datas{validFromNetwork} = ($c->param ('ValidFromNetwork') || '');
$rma_datas{validFromMask} = ($c->param ('ValidFromMask') || '');
$rma_datas{validFromNetwork} = ($c->param('ValidFromNetwork') || '');
$rma_datas{validFromMask} = ($c->param('ValidFromMask') || '');
## my @remove = $q->param('validFromRemove'); ???????? the first one only !!
my @vals = $c->param ('Remove_nets');
my @vals = $c->param('Remove_nets');
$rma_datas{remove_nets} = join ',', @vals;
$rma_datas{sshaccess} = ($c->param ('SshAccess') || 'off');
$rma_datas{sshPermitRootLogin} = ($c->param ('SshPermitRootLogin') || 'no');
$rma_datas{sshPasswordAuthentication} = ($c->param ('SshPasswordAuthentication') || 'no');
$rma_datas{sshTCPPort} = ($c->param ('SshTCPPort') || '22');
$rma_datas{ftpAccess} = ($c->param ('FtpAccess') || 'off');
$rma_datas{ftpPasswordAccess} = ($c->param ('FtpPasswordAccess') || 'private');
$rma_datas{telnetAccess} = ($c->param ('TelnetAccess') || 'off');
$rma_datas{sshaccess} = ($c->param('SshAccess') || 'off');
$rma_datas{sshPermitRootLogin} = ($c->param('SshPermitRootLogin') || 'no');
$rma_datas{sshPasswordAuthentication} = ($c->param('SshPasswordAuthentication') || 'no');
$rma_datas{sshTCPPort} = ($c->param('SshTCPPort') || '22');
$rma_datas{ftpAccess} = ($c->param('FtpAccess') || 'off');
$rma_datas{ftpPasswordAccess} = ($c->param('FtpPasswordAccess') || 'private');
$rma_datas{telnetAccess} = ($c->param('TelnetAccess') || 'off');
# validate
my $v = $c->validation;
return $c->render('remoteaccess') unless $v->has_data;
#$v->optional('PptpSessions')->num(0, 999)->is_valid;
$v->optional('ValidFromNetwork')->size(7, 15)->is_valid;
$v->optional('ValidFromMask')->size(7, 15)->is_valid;
$v->required('SshTCPPort')->num(1, 65535)->is_valid;
$result .= 'field validation error' if $v->has_error;
if ( ! $result ) {
# controls
#$res = pptp_and_dhcp_range( $c, $rma_datas{pptpSessions} );
#$result .= $res . ' ' unless $res eq 'OK';
$res = ip_number_or_blank( $c, $rma_datas{validFromNetwork} );
$result .= $res . ' ' unless $res eq 'OK';
$res = subnet_mask_or_blank( $c, $rma_datas{validFromMask} );
$result .= $res . ' ' unless $res eq 'OK';
$res = validate_network_and_mask( $c, $rma_datas{validFromNetwork}, $rma_datas{validFromMask} );
$result .= $res . ' ' unless $res eq 'OK';
#$result .= ' blocked for testing !' . $rma_datas{remove_nets};
if ($c->param('ValidFromNetwork') ne "") {
$v->optional('ValidFromNetwork')->size(7, 15)->is_valid;
}
if ( ! $result ) {
$res = change_settings( $c, %rma_datas );
if ($c->param('ValidFromMask') ne "") {
$v->optional('ValidFromMask')->size(7, 15)->is_valid;
}
$v->required('SshTCPPort')->num(1, 65535)->is_valid;
$result .= 'field validation error' if $v->has_error;
if (!$result) {
# controls
#$res = pptp_and_dhcp_range( $c, $rma_datas{pptpSessions} );
#$result .= $res . ' ' unless $res eq 'OK';
$res = ip_number_or_blank($c, $rma_datas{validFromNetwork});
$result .= $res . ' ' unless $res eq 'OK';
$res = subnet_mask_or_blank($c, $rma_datas{validFromMask});
$result .= $res . ' ' unless $res eq 'OK';
$res = validate_network_and_mask($c, $rma_datas{validFromNetwork}, $rma_datas{validFromMask});
$result .= $res . ' ' unless $res eq 'OK';
#$result .= ' blocked for testing !' . $rma_datas{remove_nets};
} ## end if (!$result)
if (!$result) {
$res = change_settings($c, %rma_datas);
$result .= $res unless $res eq 'OK';
}
if ( ! $result ) {
$result = $c->l('rma_ACTION_SUCCEEDED');
$trt = 'SUC';
if ($result eq "") {
$result = $c->l('rma_SUCCESS');
$trt = 'SUC';
}
$c->stash(title => $title, notif => $result, rma_datas => \%rma_datas);
$c->stash( title => $title, notif => $result, rma_datas => \%rma_datas );
if ( $trt ne 'SUC' ) {
return $c->render(template => 'remoteaccess');
#return $c->render( template => 'remoteaccess' );
if ($trt eq 'SUC') {
$c->stash(title => $title, modul => $result);
return $c->render(template => 'module');
}
return $c->render(template => 'remoteaccess');
$c->redirect_to('/remoteaccess');
};
#$c->redirect_to('/remoteaccess');
} ## end sub do_action
sub networkAccess_list {
my $c = shift;
return [[ $c->l('rma_NO_ACCESS') => 'off'],
[ $c->l('NETWORKS_ALLOW_LOCAL') => 'private'],
[ $c->l('NETWORKS_ALLOW_PUBLIC') => 'public']];
}
return [
[ $c->l('rma_NO_ACCESS') => 'off' ],
[ $c->l('NETWORKS_ALLOW_LOCAL') => 'private' ],
[ $c->l('NETWORKS_ALLOW_PUBLIC') => 'public' ]
];
} ## end sub networkAccess_list
sub passwordLogin_list {
my $c = shift;
return [[$c->l('rma_PASSWORD_LOGIN_PRIVATE') => 'private'],
[$c->l('rma_PASSWORD_LOGIN_PUBLIC') => 'public']];
return [ [ $c->l('rma_PASSWORD_LOGIN_PRIVATE') => 'private' ], [ $c->l('rma_PASSWORD_LOGIN_PUBLIC') => 'public' ] ];
}
sub get_prop {
my ($c, $item, $prop) = @_;
warn "You must specify a record key" unless $item;
warn "You must specify a property name" unless $prop;
my $record = $db->get($item) or warn "Couldn't get record for $item";
return $record ? $record->prop($prop) : undef;
}
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my ($c, $item, $prop) = @_;
warn "You must specify a record key" unless $item;
warn "You must specify a property name" unless $prop;
my $record = $db->get($item) or warn "Couldn't get record for $item";
return $record ? $record->prop($prop) : undef;
} ## end sub get_prop
sub get_value {
my $c = shift;
my $item = shift;
return ($db->get($item)->value());
}
my $c = shift;
my $item = shift;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
return ($db->get($item)->value());
} ## end sub get_value
sub get_ftp_access {
my $status = get_prop('','ftp','status') || 'disabled';
my $status = get_prop('', 'ftp', 'status') || 'disabled';
return 'off' unless $status eq 'enabled';
my $access = get_prop('','ftp','access') || 'private';
return ($access eq 'public') ? 'normal' : 'private';
}
my $access = get_prop('', 'ftp', 'access') || 'private';
return ($access eq 'public') ? 'normal' : 'private';
} ## end sub get_ftp_access
#sub get_pptp_sessions {
# my $status = get_prop('','pptpd','status');
@@ -191,315 +172,270 @@ sub get_ftp_access {
# return(get_prop('','pptpd','sessions') || 'no');
# return '0';
#}
sub get_ssh_permit_root_login {
return(get_prop('','sshd','PermitRootLogin') || 'no');
return (get_prop('', 'sshd', 'PermitRootLogin') || 'no');
}
sub get_ssh_password_auth {
return(get_prop('','sshd','PasswordAuthentication') || 'yes');
return (get_prop('', 'sshd', 'PasswordAuthentication') || 'yes');
}
sub get_ssh_access {
my $status = get_prop('','sshd','status');
if (defined($status) && ($status eq 'enabled')) {
my $access = get_prop('','sshd','access');
$access = ($access eq 'public') ? 'public' : 'private';
return($access);
}
else {
return('off');
}
}
my $c = shift;
my $status = $c->get_prop('sshd', 'status');
if (defined($status) && ($status eq 'enabled')) {
my $access = get_prop('', 'sshd', 'access');
$access = ($access eq 'public') ? 'public' : 'private';
return ($access);
} else {
return ('off');
}
} ## end sub get_ssh_access
sub get_ssh_port {
return(get_prop('$c','sshd','TCPPort') || '22');
return (get_prop('$c', 'sshd', 'TCPPort') || '22');
}
sub get_ftp_password_login_access {
my $status = get_prop('','ftp','status') || 'disabled';
my $status = get_prop('', 'ftp', 'status') || 'disabled';
return 'private' unless $status eq 'enabled';
my $access = get_prop('','ftp','LoginAccess') || 'private';
return ($access eq 'public') ? 'public' : 'private';
}
my $access = get_prop('', 'ftp', 'LoginAccess') || 'private';
return ($access eq 'public') ? 'public' : 'private';
} ## end sub get_ftp_password_login_access
sub get_telnet_mode {
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $telnet = $db->get('telnet');
return ('off') unless $telnet;
my $status = $telnet->prop('status') || 'disabled';
return ('off') unless $status eq 'enabled';
my $access = $telnet->prop('access') || 'private';
return ($access eq "public") ? "public" : "private";
} ## end sub get_telnet_mode
my $telnet = $db->get('telnet');
return('off') unless $telnet;
my $status = $telnet->prop('status') || 'disabled';
return('off') unless $status eq 'enabled';
my $access = $telnet->prop('access') || 'private';
return ($access eq "public") ? "public" : "private";
}
sub get_ipsecrw_sessions {
my $status = $db->get('ipsec')->prop('RoadWarriorStatus');
if (defined($status) && ($status eq 'enabled')) {
return($db->get('ipsec')->prop('RoadWarriorSessions') || '0');
}
else {
return('0');
}
}
sub get_ipsecrw_sessions {
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $status = $db->get('ipsec')->prop('RoadWarriorStatus');
if (defined($status) && ($status eq 'enabled')) {
return ($db->get('ipsec')->prop('RoadWarriorSessions') || '0');
} else {
return ('0');
}
} ## end sub get_ipsecrw_sessions
sub get_ipsecrw_status {
return undef unless ( $db->get('ipsec'));
return $db->get('ipsec')->prop('RoadWarriorStatus');
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
return undef unless ($db->get('ipsec'));
return $db->get('ipsec')->prop('RoadWarriorStatus');
}
sub pptp_and_dhcp_range {
my $c = shift;
my $val = shift || 0;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $dhcp_status = $db->get_prop('dhcpd', 'status') || 'disabled';
my $dhcp_end = $db->get_prop('dhcpd', 'end') || '';
my $dhcp_start = $db->get_prop('dhcpd', 'start') || '';
my $c = shift;
my $val = shift || 0;
my $dhcp_status = $db->get_prop('dhcpd','status') || 'disabled';
my $dhcp_end = $db->get_prop('dhcpd','end') || '';
my $dhcp_start = $db->get_prop('dhcpd','start') || '';
if ( $dhcp_status eq 'enabled' ) {
my $ip_start = unpack 'N', inet_aton($dhcp_start);
my $ip_end = unpack 'N', inet_aton($dhcp_end);
my $ip_count = $ip_end - $ip_start;
return 'OK' if( $val < $ip_count );
if ($dhcp_status eq 'enabled') {
my $ip_start = unpack 'N', inet_aton($dhcp_start);
my $ip_end = unpack 'N', inet_aton($dhcp_end);
my $ip_count = $ip_end - $ip_start;
return 'OK' if ($val < $ip_count);
return $c->l('rma_NUMBER_OF_PPTP_CLIENTS_MUST_BE_LESSER_THAN_NUMBER_OF_IP_IN_DHCP_RANGE');
} else {
return 'OK';
}
}
} ## end sub pptp_and_dhcp_range
sub _get_valid_from {
my $c = shift;
my $rec = $db->get('httpd-admin');
return undef unless($rec);
my @vals = (split ',', ($rec->prop('ValidFrom') || ''));
return @vals;
}
my $c = shift;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $rec = $db->get('httpd-admin');
return undef unless ($rec);
my @vals = (split ',', ($rec->prop('ValidFrom') || ''));
return @vals;
} ## end sub _get_valid_from
sub ip_number_or_blank {
my $c = shift;
my $c = shift;
my $ip = shift;
if (!defined($ip) || $ip eq "") {
return 'OK';
return 'OK';
}
return ip_number($c, $ip);
}
} ## end sub ip_number_or_blank
sub subnet_mask_or_blank {
my $c = shift;
my $c = shift;
my $mask = shift;
if (!defined($mask) || $mask eq "") {
return "OK";
}
chomp $mask ;
return ( subnet_mask( $mask ) ne 'OK' ) ? $c->l('rma_INVALID_SUBNET_MASK') . " (" . $mask . ")" : 'OK';
}
chomp $mask;
return (subnet_mask($mask) ne 'OK')
? $c->l('rma_INVALID_SUBNET_MASK') . " (" . $mask . ")"
: 'OK';
} ## end sub subnet_mask_or_blank
sub validate_network_and_mask {
my $c = shift;
my $net = shift || "";
my $mask = shift || "";
my $c = shift;
my $net = shift || "";
my $mask = shift || "";
if ($net xor $mask) {
return $c->l('rma_ERR_INVALID_PARAMS' . " (" . $net."/".$mask . ")");
}
return 'OK';
}
if ($net xor $mask) {
return $c->l('rma_ERR_INVALID_PARAMS' . " (" . $net . "/" . $mask . ")");
}
return 'OK';
} ## end sub validate_network_and_mask
sub change_settings {
my ($c, %rma_datas) = @_;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
#------------------------------------------------------------
# good; go ahead and change the access.
#------------------------------------------------------------
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $rec = $db->get('telnet');
if($rec) {
if ($rma_datas{telnetAccess} eq "off") {
$rec->set_prop('status','disabled');
} else {
$rec->set_prop('status','enabled');
$rec->set_prop('access', $rma_datas{telnetAccess});
}
}
$rec = $db->get('sshd') || $db->new_record('sshd', {type => 'service'});
if ($rec) {
if ($rma_datas{telnetAccess} eq "off") {
$rec->set_prop('status', 'disabled');
} else {
$rec->set_prop('status', 'enabled');
$rec->set_prop('access', $rma_datas{telnetAccess});
}
} ## end if ($rec)
$rec = $db->get('sshd') || $db->new_record('sshd', { type => 'service' });
$rec->set_prop('TCPPort', $rma_datas{sshTCPPort});
$rec->set_prop('status', ( $rma_datas{sshaccess} eq "off" ? 'disabled' : 'enabled'));
$rec->set_prop('access', $rma_datas{sshaccess});
$rec->set_prop('PermitRootLogin', $rma_datas{sshPermitRootLogin});
$rec->set_prop('status', ($rma_datas{sshaccess} eq "off" ? 'disabled' : 'enabled'));
$rec->set_prop('access', $rma_datas{sshaccess});
$rec->set_prop('PermitRootLogin', $rma_datas{sshPermitRootLogin});
$rec->set_prop('PasswordAuthentication', $rma_datas{sshPasswordAuthentication});
$rec = $db->get('ftp');
if($rec) {
if ($rma_datas{ftpAccess} eq "off") {
$rec->set_prop('status', 'disabled');
$rec->set_prop('access', 'private');
$rec->set_prop('LoginAccess', 'private');
} elsif ($rma_datas{ftpAccess} eq "normal") {
$rec->set_prop('status', 'enabled');
$rec->set_prop('access', 'public');
$rec->set_prop('LoginAccess', $rma_datas{ftpPasswordAccess});
} else {
$rec->set_prop('status', 'enabled');
$rec->set_prop('access', 'private');
$rec->set_prop('LoginAccess', $rma_datas{ftpPasswordAccess});
}
}
# if ($rma_datas{pptpSessions} == 0) {
# $db->get('pptpd')->set_prop('status', 'disabled');
# } else {
# $db->get('pptpd')->set_prop('status', 'enabled');
# $db->get('pptpd')->set_prop('sessions', $rma_datas{pptpSessions});
# }
if ($rec) {
if ($rma_datas{ftpAccess} eq "off") {
$rec->set_prop('status', 'disabled');
$rec->set_prop('access', 'private');
$rec->set_prop('LoginAccess', 'private');
} elsif ($rma_datas{ftpAccess} eq "normal") {
$rec->set_prop('status', 'enabled');
$rec->set_prop('access', 'public');
$rec->set_prop('LoginAccess', $rma_datas{ftpPasswordAccess});
} else {
$rec->set_prop('status', 'enabled');
$rec->set_prop('access', 'private');
$rec->set_prop('LoginAccess', $rma_datas{ftpPasswordAccess});
}
} ## end if ($rec)
if ( $rma_datas{validFromNetwork} && $rma_datas{validFromMask} ) {
unless (add_new_valid_from( $c, $rma_datas{validFromNetwork}, $rma_datas{validFromMask} )) {
return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'new net';
}
}
# if ($rma_datas{pptpSessions} == 0) {
# $db->get('pptpd')->set_prop('status', 'disabled');
# } else {
# $db->get('pptpd')->set_prop('status', 'enabled');
# $db->get('pptpd')->set_prop('sessions', $rma_datas{pptpSessions});
# }
if ($rma_datas{validFromNetwork} && $rma_datas{validFromMask}) {
unless (add_new_valid_from($c, $rma_datas{validFromNetwork}, $rma_datas{validFromMask})) {
return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'new net';
}
} ## end if ($rma_datas{validFromNetwork...})
if ($rma_datas{remove_nets}) {
unless (remove_valid_from($c, $rma_datas{remove_nets})) {
return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'del net';
}
} ## end if ($rma_datas{remove_nets...})
if ( $rma_datas{remove_nets} ) {
unless (remove_valid_from( $c, $rma_datas{remove_nets} )) {
return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'del net';
}
}
# reset ipsec roadwarrior CA,server,client certificates
if ($rma_datas{ipsecrwReset}) {
system('/sbin/e-smith/roadwarrior', 'reset_certs') == 0 or
return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'rst ipsec';
system('/sbin/e-smith/roadwarrior', 'reset_certs') == 0
or return $c->l('rma_ERROR_UPDATING_CONFIGURATION') . 'rst ipsec';
}
if ( $rma_datas{ipsecrwSess} ) {
set_ipsecrw_sessions( $c, $rma_datas{ipsecrwSess} );
if ($rma_datas{ipsecrwSess}) {
set_ipsecrw_sessions($c, $rma_datas{ipsecrwSess});
}
unless ( system( "/sbin/e-smith/signal-event", "remoteaccess-update" ) == 0 ) {
unless (system("/sbin/e-smith/signal-event", "remoteaccess-update") == 0) {
return $c->l('rma_ERROR_UPDATING_CONFIGURATION');
}
return 'OK';
}
} ## end sub change_settings
sub set_ipsecrw_sessions {
my $c = shift;
my $c = shift;
my $sessions = shift;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
if (defined $sessions) {
$db->get('ipsec')->set_prop('RoadWarriorSessions', $sessions);
if (int($sessions) > 0) {
$db->get('ipsec')->set_prop('RoadWarriorStatus', 'enabled');
}
}
return '';
}
$db->get('ipsec')->set_prop('RoadWarriorSessions', $sessions);
if (int($sessions) > 0) {
$db->get('ipsec')->set_prop('RoadWarriorStatus', 'enabled');
}
} ## end if (defined $sessions)
return '';
} ## end sub set_ipsecrw_sessions
sub add_new_valid_from {
my $c = shift;
my $net = shift;
my $mask = shift;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $c = shift;
my $net = shift;
my $mask = shift;
# we transform bit mask to regular mask
$mask = get_reg_mask( $net, $mask );
my $rec = $db->get('httpd-admin');
return $c->error('ERR_NO_RECORD') unless $rec;
my $prop = $rec->prop('ValidFrom') || '';
my @vals = split /,/, $prop;
return '' if (grep /^$net\/$mask$/, @vals); # already have this entry
if ($prop ne '') {
$prop .= ",$net/$mask";
} else {
$prop = "$net/$mask";
}
$rec->set_prop('ValidFrom', $prop);
return 1;
}
# we transform bit mask to regular mask
$mask = get_reg_mask($net, $mask);
my $rec = $db->get('httpd-admin');
return $c->error('ERR_NO_RECORD') unless $rec;
my $prop = $rec->prop('ValidFrom') || '';
my @vals = split /,/, $prop;
return '' if (grep /^$net\/$mask$/, @vals); # already have this entry
if ($prop ne '') {
$prop .= ",$net/$mask";
} else {
$prop = "$net/$mask";
}
$rec->set_prop('ValidFrom', $prop);
return 1;
} ## end sub add_new_valid_from
sub remove_valid_from {
my $c = shift;
my $remove_nets = shift;
my @remove = split /,/, $remove_nets;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $c = shift;
my $remove_nets = shift;
# my @remove = $c->param('Remove_nets');
my @vals = $c->_get_valid_from();
my @remove = split /,/, $remove_nets;
foreach my $entry (@remove) {
return undef unless $entry;
my ($net, $mask) = split(/\//, $entry);
# my @remove = $c->param('Remove_nets');
my @vals = $c->_get_valid_from();
foreach my $entry (@remove) {
return undef unless $entry;
my ($net, $mask) = split (/\//, $entry);
unless (@vals) {
print STDERR "ERROR: unable to load ValidFrom property from conf db\n";
return undef;
}
# what if we don't have a mask because someone added an entry from
# the command line? by the time we get here, the panel will have
# added a 32 bit mask, so we don't know for sure if the value in db
# is $net alone or $net/255.255.255.255. we have to check for both
# in this special case...
@vals = (grep { $entry ne $_ && $net ne $_ } @vals);
}
my $prop;
if (@vals) {
$prop = join ',',@vals;
} else {
$prop = '';
}
$db->get('httpd-admin')->set_prop('ValidFrom', $prop);
return 1;
}
unless (@vals) {
print STDERR "ERROR: unable to load ValidFrom property from conf db\n";
return undef;
}
# what if we don't have a mask because someone added an entry from
# the command line? by the time we get here, the panel will have
# added a 32 bit mask, so we don't know for sure if the value in db
# is $net alone or $net/255.255.255.255. we have to check for both
# in this special case...
@vals = (grep { $entry ne $_ && $net ne $_ } @vals);
} ## end foreach my $entry (@remove)
my $prop;
if (@vals) {
$prop = join ',', @vals;
} else {
$prop = '';
}
$db->get('httpd-admin')->set_prop('ValidFrom', $prop);
return 1;
} ## end sub remove_valid_from
1;

View File

@@ -1,56 +1,46 @@
package SrvMngr::Controller::Request;
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::ConfigDB::UTF8 qw(open_ro);
use esmith::AccountsDB::UTF8 qw(open_ro);
# retrieve a configuration db record
sub getconfig {
my $c = shift;
my $c = shift;
my $key = $c->param('key');
$c->app->log->info($c->log_req . ' ' . $key);
if ($key) {
use esmith::ConfigDB qw(open_ro);
my $cdb = esmith::ConfigDB->open_ro;
return getdb( $c, $cdb, $key);
}
}
my $cdb = esmith::ConfigDB::UTF8->open_ro;
return getdb($c, $cdb, $key);
} ## end if ($key)
} ## end sub getconfig
# retrieve an accounts db record, given its name
sub getaccount {
my $c = shift;
my $c = shift;
my $key = $c->param('key');
$c->app->log->info($c->log_req . ' ' . $key);
if ($key) {
use esmith::AccountsDB qw(open_ro);
my $adb = esmith::AccountsDB->open_ro;
return getdb( $c, $adb, $key);
}
}
my $adb = esmith::AccountsDB::UTF8->open_ro;
return getdb($c, $adb, $key);
} ## end if ($key)
} ## end sub getaccount
sub getdb {
my ($c, $db, $key) = @_;
if ( my $rec = $db->get($key) ) {
return $c->render(json => { $key => { $rec->props }} );
if (my $rec = $db->get($key)) {
return $c->render(json => { $key => { $rec->props } });
}
return undef;
}
} ## end sub getdb
1;

View File

@@ -1,82 +1,64 @@
package SrvMngr::Controller::Review;
#----------------------------------------------------------------------
# heading : Support
# heading : Investigation
# description : Review configuration
# navigation : 000 500
# menu : N
# navigation : 7000 400
# routes : end
#----------------------------------------------------------------------
# heading-o : Configuration
# description-o : Review configuration
# navigation-o : 6000 6800
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use SrvMngr qw(gen_locale_date_string);
use esmith::ConfigDB::UTF8;
use esmith::DomainsDB::UTF8;
use esmith::NetworksDB::UTF8;
#use SrvMngr::Review_sub qw(print_page);
#use smeserver::Panel::review;
use esmith::FormMagick::Panel::review;
our $db = esmith::ConfigDB->open_ro || die "Couldn't open config db";
our $domains = esmith::DomainsDB->open_ro || die "Couldn't open domains";
our $networks = esmith::NetworksDB->open_ro || die "Couldn't open networks";
our $db;
our $domains ;
our $networks;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('rvw_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('rvw_DESCRIPTION'));
$db = esmith::ConfigDB::UTF8->open_ro || die "Couldn't open config db";
my $title = $c->l('rvw_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('rvw_DESCRIPTION'));
my %rvw_datas = ();
$rvw_datas{'servermode'} = (get_value('','SystemMode' )|| '');
$rvw_datas{'localip'} = get_value('$c','LocalIP' )
.'/'.get_value('$c','LocalNetmask');
$rvw_datas{'publicip'} =
esmith::FormMagick::Panel::review->get_public_ip_address($c);
$rvw_datas{'gateway'} =
$c->render_to_string(inline => print2_gateway_stanza($c));
$rvw_datas{'serveronly'} =
$c->render_to_string(inline => print2_serveronly_stanza($c));
$rvw_datas{'servermode'} = (get_value('', 'SystemMode') || '');
$rvw_datas{'localip'} = get_value('$c', 'LocalIP') . '/' . get_value('$c', 'LocalNetmask');
$rvw_datas{'publicip'} = $c->get_public_ip_address($c);
$rvw_datas{'gateway'} = $c->render_to_string(inline => print2_gateway_stanza($c));
$rvw_datas{'serveronly'} = $c->render_to_string(inline => print2_serveronly_stanza($c));
$rvw_datas{'addlocalnetworks'} = get_local_networks($c);
$rvw_datas{'dhcpserver'} =
$c->render_to_string(inline => print2_dhcp_stanza($c));
$rvw_datas{'dnsserver'} = (get_value('','LocalIP' )|| '');
$rvw_datas{'webserver'} = 'www.'.(get_local_domain());
$rvw_datas{'dhcpserver'} = $c->render_to_string(inline => print2_dhcp_stanza($c));
$rvw_datas{'dnsserver'} = (get_value('', 'LocalIP') || '');
$rvw_datas{'webserver'} = 'www.' . (get_local_domain());
my $port = $db->get_prop("squid", "TransparentPort") || 3128;
$rvw_datas{'proxyserver'} = 'proxy.'.get_local_domain().":$port";
$rvw_datas{'ftpserver'} = 'ftp.'.get_local_domain();
$rvw_datas{'smtpserver'} = 'mail.'.get_local_domain();
$rvw_datas{'domainname'} = (get_value('','DomainName' )|| '');
$rvw_datas{'virtualdomains'} =
$c->render_to_string(inline => gen2_domains($c));
$rvw_datas{'primarywebsite'} = 'http://www.'.get_value('','DomainName');
$rvw_datas{'servermanager'} = 'https://'. (get_value('','SystemName') || 'localhost').'/server-manager/';
$rvw_datas{'usermanager'} = 'https://'. (get_value('','SystemName') || 'localhost').'/user-password/';
$rvw_datas{'emailaddresses'} =
$c->render_to_string(inline => gen2_email_addresses($c));
$rvw_datas{'proxyserver'} = 'proxy.' . get_local_domain() . ":$port";
$rvw_datas{'ftpserver'} = 'ftp.' . get_local_domain();
$rvw_datas{'smtpserver'} = 'mail.' . get_local_domain();
$rvw_datas{'domainname'} = (get_value('', 'DomainName') || '');
$rvw_datas{'virtualdomains'} = $c->render_to_string(inline => gen2_domains($c));
$rvw_datas{'primarywebsite'} = 'http://www.' . get_value('', 'DomainName');
$rvw_datas{'servermanager'} = 'https://' . (get_value('', 'SystemName') || 'localhost') . '/server-manager/';
$rvw_datas{'usermanager'} = 'https://' . (get_value('', 'SystemName') || 'localhost') . '/user-password/';
$rvw_datas{'emailaddresses'} = $c->render_to_string(inline => gen2_email_addresses($c));
#$c->stash( releaseVersion => $c->session->{releaseVersion}, copyRight => $c->session->{copyRight},
#PwdSet => $c->session->{PwdSet}, Unsafe => $c->session->{Unsafe},
$c->stash( title => $title, modul => $modul, rvw_datas => \%rvw_datas,
);
#PwdSet => $c->session->{PwdSet}, Unsafe => $c->session->{Unsafe},
$c->stash(
title => $title,
modul => $modul,
rvw_datas => \%rvw_datas,
);
$c->render(template => 'review');
}
} ## end sub main
=head2 gen2_email_addresses
@@ -86,20 +68,28 @@ sub main {
=cut
sub gen2_email_addresses {
my $c = shift;
my $domain = get_value($c,'DomainName');
my $c = shift;
my $domain = get_value($c, 'DomainName');
my $useraccount = $c->l("rvw_EMAIL_USERACCOUNT");
my $firstname = $c->l("rvw_EMAIL_FIRSTNAME");
my $lastname = $c->l("rvw_EMAIL_LASTNAME");
my $out = "<I>" . $useraccount . "</I>\@" . $domain . "<BR>"
. "<I>" . $firstname . "</I>.<I>" . $lastname . "</I>\@" . $domain . "<BR>"
. "<I>" . $firstname . "</I>_<I>" . $lastname . "</I>\@" . $domain . "<BR>";
return $out;
}
my $firstname = $c->l("rvw_EMAIL_FIRSTNAME");
my $lastname = $c->l("rvw_EMAIL_LASTNAME");
my $out
= "<I>"
. $useraccount
. "</I>\@"
. $domain . "<BR>" . "<I>"
. $firstname
. "</I>.<I>"
. $lastname
. "</I>\@"
. $domain . "<BR>" . "<I>"
. $firstname
. "</I>_<I>"
. $lastname
. "</I>\@"
. $domain . "<BR>";
return $out;
} ## end sub gen2_email_addresses
=head2 gen2_domains
@@ -109,26 +99,26 @@ sub gen2_email_addresses {
=cut
sub gen2_domains {
my $c = shift;
my @virtual = $domains->get_all_by_prop( type => 'domain');
my $c = shift;
$domains = esmith::DomainsDB::UTF8->open_ro || die "Couldn't open domains";
my @virtual = $domains->get_all_by_prop(type => 'domain');
my $numvirtual = @virtual;
if ($numvirtual == 0) {
$c->localise("NO_VIRTUAL_DOMAINS");
}
else {
} else {
my $out = "";
my $domain;
foreach $domain (sort @virtual) {
if ($out ne "") {
$out .= "<BR>";
}
$out .= $domain->key;
}
} ## end foreach $domain (sort @virtual)
return $out;
}
}
} ## end else [ if ($numvirtual == 0) ]
} ## end sub gen2_domains
=head2 get2_local_networks
@@ -138,13 +128,54 @@ serving. (mojo ver)
=cut
sub get2_local_networks {
my $c = shift;
my $c = shift;
$networks = esmith::NetworksDB::UTF8->open_ro || die "Couldn't open networks";
my @nets = $networks->get_all_by_prop('type' => 'network');
my $numNetworks = @nets;
if ($numNetworks == 0) {
return $c->l('rvw_NO_NETWORKS');
} else {
my $out = "";
foreach my $network (sort @nets) {
if ($out ne "") {
$out .= "<BR>";
}
$out .= $network->key . "/" . get_net_prop($c, $network->key, 'Mask');
if (defined get_net_prop($c, $network->key, 'Router')) {
$out .= " via " . get_net_prop($c, $network->key, 'Router');
}
} ## end foreach my $network (sort @nets)
return $out;
} ## end else [ if ($numNetworks == 0)]
} ## end sub get2_local_networks
sub get_net_prop {
my $fm = shift;
my $item = shift;
my $prop = shift;
$networks = esmith::NetworksDB::UTF8->open_ro || die "Couldn't open networks";
my $record = $networks->get($item);
if ($record) {
return $record->prop($prop);
}
else {
return '';
}
}
sub get_local_networks {
my $fm = shift;
$networks = esmith::NetworksDB::UTF8->open_ro || die "Couldn't open networks";
my @nets = $networks->get_all_by_prop('type' => 'network');
my $numNetworks = @nets;
if ($numNetworks == 0) {
return $c->l('rvw_NO_NETWORKS');
return $fm->localise('NO_NETWORKS');
}
else {
my $out = "";
@@ -153,10 +184,10 @@ sub get2_local_networks {
$out .= "<BR>";
}
$out .= $network->key."/" . get_net_prop($c, $network->key, 'Mask');
$out .= $network->key."/" . get_net_prop($fm, $network->key, 'Mask');
if ( defined get_net_prop($c, $network->key, 'Router') ) {
$out .= " via " . get_net_prop ($c, $network->key, 'Router');
if ( defined get_net_prop($fm, $network->key, 'Router') ) {
$out .= " via " . get_net_prop ($fm, $network->key, 'Router');
}
}
return $out;
@@ -164,6 +195,10 @@ sub get2_local_networks {
}
sub get_local_domain
{
return (get_value('','DomainName'));
}
=head2 print2_gateway_stanza
@@ -172,28 +207,28 @@ If this system is a server gateway, show the external ip and gateway ip (mojo ve
=cut
sub print2_gateway_stanza
{
sub print2_gateway_stanza {
my $c = shift;
if (get_value($c,'SystemMode') =~ /servergateway/)
{
my $ip = get_value($c,'ExternalIP');
my $static =
(get_value($c, 'AccessType') eq 'dedicated') &&
(get_value($c, 'ExternalDHCP') eq 'off') &&
(get_prop($c, 'pppoe', 'status') eq 'disabled');
if ($static)
{
$ip .= "/".get_value($c,'ExternalNetmask');
}
my $out = $c->l('rvw_EXTERNAL_IP_ADDRESS_SUBNET_MASK').':'.$ip;
if ($static)
{
$out .= $c->l('rvw_GATEWAY').':'.get_value($c,'GatewayIP');
}
return $out
}
}
if (get_value($c, 'SystemMode') =~ /servergateway/) {
my $ip = get_value($c, 'ExternalIP');
my $static
= (get_value($c, 'AccessType') eq 'dedicated')
&& (get_value($c, 'ExternalDHCP') eq 'off')
&& (get_prop($c, 'pppoe', 'status') eq 'disabled');
if ($static) {
$ip .= "/" . get_value($c, 'ExternalNetmask');
}
my $out = $c->l('rvw_EXTERNAL_IP_ADDRESS_SUBNET_MASK') . ':' . $ip;
if ($static) {
$out .= $c->l('rvw_GATEWAY') . ':' . get_value($c, 'GatewayIP');
}
return $out;
} ## end if (get_value($c, 'SystemMode'...))
} ## end sub print2_gateway_stanza
=head2 print2_serveronly_stanza
If this system is a standalone server with net access, show the external
@@ -202,14 +237,15 @@ gateway IP (mojo ver)
=cut
sub print2_serveronly_stanza {
my $c = shift;
if ( (get_value($c,'SystemMode') eq 'serveronly') &&
get_value($c,'AccessType') &&
(get_value($c,'AccessType') ne "off")) {
return ( get_value($c,'GatewayIP') );
}
}
my $c = shift;
if ( (get_value($c, 'SystemMode') eq 'serveronly')
&& get_value($c, 'AccessType')
&& (get_value($c, 'AccessType') ne "off"))
{
return (get_value($c, 'GatewayIP'));
} ## end if ((get_value($c, 'SystemMode'...)))
} ## end sub print2_serveronly_stanza
=head2 print2_dhcp_stanza
@@ -220,15 +256,62 @@ Prints out the current state of dhcp service (mojo ver)
sub print2_dhcp_stanza {
my $c = shift;
my $out = (get_prop($c,'dhcpd','status') || 'disabled' );
my $out = (get_prop($c, 'dhcpd', 'status') || 'disabled');
if (get_prop($c,'dhcpd', 'status') eq 'enabled') {
$out .= '<br>'.$c->l('rvw_BEGINNING_OF_DHCP_ADDRESS_RANGE').':';
$out .= (get_prop($c,'dhcpd','start') || '' ).'<br>';
$out .= $c->l('rvw_END_OF_DHCP_ADDRESS_RANGE').':';
$out .= (get_prop($c,'dhcpd','end') || '' );
}
if (get_prop($c, 'dhcpd', 'status') eq 'enabled') {
$out .= '<br>' . $c->l('rvw_BEGINNING_OF_DHCP_ADDRESS_RANGE') . ':';
$out .= (get_prop($c, 'dhcpd', 'start') || '') . '<br>';
$out .= $c->l('rvw_END_OF_DHCP_ADDRESS_RANGE') . ':';
$out .= (get_prop($c, 'dhcpd', 'end') || '');
} ## end if (get_prop($c, 'dhcpd'...))
return $out;
} ## end sub print2_dhcp_stanza
sub get_value {
my $fm = shift;
my $item = shift;
$db = esmith::ConfigDB::UTF8->open_ro || die "Couldn't open config db";
my $record = $db->get($item);
if ($record) {
return $record->value();
}
else {
return '';
}
}
sub get_prop {
my $fm = shift if (ref($_[0]) ); # If we're being called in a formmagick context
# The first argument will always be a fm.
#otherwise, we don't want to grab it
my $item = shift;
my $prop = shift;
$db = esmith::ConfigDB::UTF8->open_ro || die "Couldn't open config db";
my $record = $db->get($item);
if ($record) {
return $record->prop($prop);
}
else {
return '';
}
}
sub get_public_ip_address
{
my $self = shift;
$db = esmith::ConfigDB::UTF8->open_ro || die "Couldn't open config db";
my $sysconfig = $db->get('sysconfig');
if ($sysconfig)
{
my $publicIP = $sysconfig->prop('PublicIP');
if ($publicIP)
{
return $publicIP;
}
}
return undef;
}

View File

@@ -0,0 +1,35 @@
package SrvMngr::Controller::Roundcubepanel;
#----------------------------------------------------------------------
# heading : Network
# description : Webmail
# navigation : 6000 900
#----------------------------------------------------------------------
#----------------------------------------------------------------------
# name : roundcubepanel, method : get, url : /roundcubepanel, ctlact : Roundcubepanel#main
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
#use SrvMngr::Model::Main;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('Webmail');
my $roundcube_url = $c->param('url');
$c->stash(title => $title, modul => $roundcube_url);
$c->render(template => 'roundcube');
} ## end sub main
sub getroundcubeurl {
my $c = shift;
my $url = shift;
return "/smanager/roundcube?url=$url";
} ## end sub getroundcubeurl
1;

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Support;
#----------------------------------------------------------------------
# heading : Support
# description : Support and licensing
# navigation : 0000 200
# navigation : 0 400
# menu : N
#
# routes : end
@@ -11,34 +11,25 @@ package SrvMngr::Controller::Support;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use SrvMngr qw(theme_list init_session);
use esmith::util;
sub display_licenses {
my $lang = shift;
my $lic = '';
my $lang = shift;
my $lic = '';
foreach my $license (esmith::util::getLicenses($lang)) {
$lic .= $license . '<br>';
}
return $lic;
}
foreach my $license (esmith::util::getLicenses($lang)) {
$lic .= $license . '<br>';
}
return $lic;
} ## end sub display_licenses
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('support_FORM_TITLE');
my $modul = $c->render_to_string(inline => display_licenses($c->session->{lang}));
$c->stash( title => $title, modul => $modul );
$c->stash(title => $title, modul => $modul);
$c->render(template => 'module');
};
} ## end sub main
1;

View File

@@ -1,51 +1,38 @@
package SrvMngr::Controller::Swttheme;
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use esmith::ConfigDB::UTF8;
#use SrvMngr qw(theme_list init_session);
our $db = esmith::ConfigDB->open() || die "Couldn't open config db";
sub main {
my $c = shift;
my $from = $c->param('From') || '/';
my $c = shift;
my $db = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $from = $c->param('From') || '/';
my $theme = $c->param('Theme');
$c->app->log->info(" swt theme '$from' '$theme' ");
my $oldTheme = $c->session->{CurrentTheme};
if ( $theme ne $oldTheme ) {
# $c->app->renderer->paths([$c->app->home->rel_file('themes/default/templates')]);
# $c->app->static->paths([$c->app->home->rel_file('themes/default/public')]);
# if ( $theme ne 'default' ) {
# # Put the new theme first
# my $t_path = $c->app->home->rel_file('themes/'.$theme);
# unshift @{$c->app->renderer->paths}, $t_path.'/templates' if -d $t_path.'/templates';
# unshift @{$c->app->static->paths}, $t_path.'/public' if -d $t_path.'/public';
# }
if ($theme ne $oldTheme) {
# $c->app->renderer->paths([$c->app->home->rel_file('themes/default/templates')]);
# $c->app->static->paths([$c->app->home->rel_file('themes/default/public')]);
# if ( $theme ne 'default' ) {
# # Put the new theme first
# my $t_path = $c->app->home->rel_file('themes/'.$theme);
# unshift @{$c->app->renderer->paths}, $t_path.'/templates' if -d $t_path.'/templates';
# unshift @{$c->app->static->paths}, $t_path.'/public' if -d $t_path.'/public';
# }
$c->session->{CurrentTheme} = $theme;
$db->get('smanager')->set_prop('Theme', $theme);
system ("/sbin/e-smith/signal-event smanager-theme-change") == 0
or warn "$c->l('ERROR_UPDATING')";
}
## (not sure) $c->flash( warning => $c->l('swt_LOGIN_AGAIN') );
$from = '/initial' if $from eq '/';
$from = '/' . $from if ( $from !~ m|^\/| );
$c->redirect_to( $from);
}
$db->get('smanager')->set_prop('Theme', $theme);
system("/sbin/e-smith/signal-event smanager-theme-change") == 0
or warn "$c->l('ERROR_UPDATING')";
} ## end if ($theme ne $oldTheme)
## (not sure) $c->flash( warning => $c->l('swt_LOGIN_AGAIN') );
$from = '/initial' if $from eq '/';
$from = '/' . $from if ($from !~ m|^\/|);
$c->redirect_to($from);
} ## end sub main
1;

View File

@@ -1,38 +0,0 @@
package SrvMngr::Controller::Userpanelaccess;
#----------------------------------------------------------------------
# heading : User management
# description : User Panel Access
# navigation : 2000 150
# menu :
#----------------------------------------------------------------------
# name : userpanelaccess, method : get, url : /userpanelaccess, ctlact : Userpanelaccess#main
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
#use SrvMngr::Model::Main;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('User panel access');
$c->stash( title => $title, modul => 'https://mailserver.bjsystems.co.uk/server-manager/cgi-bin/userpanelaccess', height => 600 );
$c->render(template => 'embedded');
}
1;

View File

@@ -8,250 +8,196 @@ package SrvMngr::Controller::Userpassword;
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use esmith::util;
use esmith::ConfigDB;
use esmith::AccountsDB;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB::UTF8;
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw( theme_list init_session is_normal_password );
our $cdb = esmith::ConfigDB->open_ro || die "Couldn't open configuration db";
use SrvMngr qw( theme_list init_session validate_password );
sub main {
my $c = shift;
my $c = shift;
my %pwd_datas = ();
my $title = $c->l("pwd_ACCOUNT_PASSWORD_CHANGE");
if ( $c->is_logged_in ) {
$pwd_datas{Account} = $c->session->{username};
$pwd_datas{trt} = 'NORM';
if ($c->is_logged_in) {
$pwd_datas{Account} = $c->session->{username};
$pwd_datas{trt} = 'NORM';
} else {
my $rt = $c->current_route;
my $mess = '';
my $jwt = $c->param('jwt') || '';
my $name = $c->jwt->decode($jwt)->{username} || '';
my $rt = $c->current_route;
my $mess = '';
my $jwt = $c->param('jwt') || '';
my $name = $c->jwt->decode($jwt)->{username} || '';
$mess = 'Invalid state' unless ($jwt and $name and $rt eq 'upwdreset');
$mess = 'Invalid state' unless ($jwt and $name and $rt eq 'upwdreset');
# request already treated or outdated
if ( $c->pwdrst->{$name}{confirmed} != 1 or $c->pwdrst->{$name}{date} < time() ) {
$mess = $c->l('use_INVALID_REQUEST').' -step 1-';
}
if ($c->pwdrst->{$name}{confirmed} != 1 or $c->pwdrst->{$name}{date} < time()) {
$mess = $c->l('pwd_INVALID_REQUEST') . ' -step 1-';
}
if ($mess) {
$c->stash(error => $mess);
return $c->redirect_to($c->home_page);
}
if ( $mess ) {
$c->stash( error => $mess );
return $c->redirect_to ( $c->home_page );
}
# ok for reset password for this account - step 2
$c->pwdrst->{$name}{confirmed} = 2;
$pwd_datas{Account} = $name;
$pwd_datas{trt} = 'RESET';
$pwd_datas{jwt} = $jwt;
$c->flash( success => $c->l('use_OK_FOR_RESET') );
}
$c->stash( pwd_datas => \%pwd_datas );
$c->render( 'userpassword' );
}
$c->pwdrst->{$name}{confirmed} = 2;
$pwd_datas{Account} = $name;
$pwd_datas{trt} = 'RESET';
$pwd_datas{jwt} = $jwt;
$c->flash(success => $c->l('pwd_OK_FOR_RESET'));
} ## end else [ if ($c->is_logged_in) ]
$c->stash(pwd_datas => \%pwd_datas);
$c->render('userpassword');
} ## end sub main
sub change_password {
my $c = shift;
my $result;
my $res;
my %pwd_datas = ();
my $trt = $c->param('Trt');
my $acctName = $c->param('User');
my $oldPass = $c->param('Oldpass') || '';
my $pass = $c->param('Pass');
my %pwd_datas = ();
my $trt = $c->param('Trt');
my $acctName = $c->param('User');
my $oldPass = $c->param('Oldpass') || '';
my $pass = $c->param('Pass');
my $passVerify = $c->param('Passverify');
my $jwt = $c->param('jwt') || '';
my $rt = $c->current_route;
my $mess = ''; my $name = '';
my $jwt = $c->param('jwt') || '';
my $rt = $c->current_route;
my $mess = '';
my $name = '';
$name = $c->jwt->decode($jwt)->{username} if $jwt;
if ( $trt eq 'RESET' ) {
$mess = 'Invalid state' unless ($jwt and $name and ($rt eq 'upwdreset2'));
# request already treated or outdated
if ( $c->pwdrst->{$name}{confirmed} != 2 or $c->pwdrst->{$name}{date} < time() ) {
$mess = $c->l('use_INVALID_REQUEST').' -step 2-';
}
if ( ! $name or $c->is_logged_in or $name ne $acctName ) {
$mess = 'Invalid reset state';
if ($trt eq 'RESET') {
$mess = 'Invalid state' unless ($jwt and $name and ($rt eq 'upwdreset2'));
# request already treated or outdated
if ($c->pwdrst->{$name}{confirmed} != 2 or $c->pwdrst->{$name}{date} < time()) {
$mess = $c->l('pwd_INVALID_REQUEST') . ' -step 2-';
}
if (!$name or $c->is_logged_in or $name ne $acctName) {
$mess = 'Invalid reset state';
}
} else {
if ( $name or $jwt or ! $c->is_logged_in ) {
$mess = 'Invalid update state';
}
}
if ( $mess ) {
$c->stash( error => $mess );
return $c->redirect_to ( $c->home_page );
}
if ($name or $jwt or !$c->is_logged_in) {
$mess = 'Invalid update state';
}
} ## end else [ if ($trt eq 'RESET') ]
if ($mess) {
$c->stash(error => $mess);
return $c->redirect_to($c->home_page);
}
$pwd_datas{Account} = $acctName;
$pwd_datas{trt} = $trt;
$pwd_datas{trt} = $trt;
# common controls
if ( $acctName eq 'admin' ) {
if ($acctName eq 'admin') {
$result .= "Admin password should not be reset here !";
} else {
unless ( $pass && $passVerify ) {
$result .= $c->l('pwd_FIELDS_REQUIRED') . "<br>";
} else {
$result .= $c->l('pwd_PASSWORD_INVALID_CHARS') . "<br>" unless (($pass) = ($pass =~ /^([ -~]+)$/ ));
$result .= $c->l('pwd_PASSWORD_VERIFY_ERROR') . "<br>" unless ( $pass eq $passVerify );
}
}
if ( $result ne '' ) {
$c->stash( error => $result, pwd_datas => \%pwd_datas );
return $c->render( 'userpassword' );
unless ($pass && $passVerify) {
$result .= $c->l('pwd_FIELDS_REQUIRED') . "<br>";
} else {
$result .= $c->l('pwd_PASSWORD_INVALID_CHARS') . "<br>" unless (($pass) = ($pass =~ /^([ -~]+)$/));
$result .= $c->l('pwd_PASSWORD_VERIFY_ERROR') . "<br>" unless ($pass eq $passVerify);
}
} ## end else [ if ($acctName eq 'admin')]
if ($result ne '') {
$c->stash(error => $result, pwd_datas => \%pwd_datas);
return $c->render('userpassword');
}
# validate new password
$res = $c->check_password( $pass );
$result .= $res . "<br>" unless ( $res eq 'OK' );
$res = $c->check_password($pass);
$result .= $res . "<br>" unless ($res eq 'OK');
# controls old password
if ( $trt ne 'RESET' ) {
unless ( $oldPass ) {
$result .= $c->l('pwd_FIELDS_REQUIRED') . "<br>" unless $trt eq 'RESET';
if ($trt ne 'RESET') {
unless ($oldPass) {
$result .= $c->l('pwd_FIELDS_REQUIRED') . "<br>" unless $trt eq 'RESET';
} else {
$result .= $c->l('pwd_PASSWORD_OLD_INVALID_CHARS') . "<br>" unless (($oldPass) = ($oldPass =~ /^(\S+)$/ ));
$result .= $c->l('pwd_PASSWORD_OLD_INVALID_CHARS') . "<br>" unless (($oldPass) = ($oldPass =~ /^(\S+)$/));
}
if ( $result ne '' ) {
$c->stash( error => $result, pwd_datas => \%pwd_datas );
return $c->render( 'userpassword' );
if ($result ne '') {
$c->stash(error => $result, pwd_datas => \%pwd_datas);
return $c->render('userpassword');
}
# verify old password
if ( $trt ne 'RESET') {
$result .= $c->l('pwd_ERROR_PASSWORD_CHANGE') . "<br>"
unless (SrvMngr::Model::Main->check_credentials($acctName, $oldPass));
}
}
if ($trt ne 'RESET') {
$result .= $c->l('pwd_ERROR_PASSWORD_CHANGE') . "<br>"
unless (SrvMngr::Model::Main->check_credentials($acctName, $oldPass));
}
} ## end if ($trt ne 'RESET')
# $result .= 'Blocked for test (prevents updates)<br>';
if ( ! $result ) {
my $res = $c->reset_password( $trt, $acctName, $pass, $oldPass );
if (!$result) {
my $res = $c->reset_password($trt, $acctName, $pass, $oldPass);
$result .= $res unless $res eq 'OK';
}
if ( $result ) {
record_password_change_attempt($c, 'FAILED');
$c->stash( error => $result, pwd_datas => \%pwd_datas );
return $c->render( 'userpassword' );
}
if ($result) {
record_password_change_attempt($c, 'FAILED');
$c->stash(error => $result, pwd_datas => \%pwd_datas);
return $c->render('userpassword');
} ## end if ($result)
$c->pwdrst->{$name}{confirmed} = 9 if $trt eq 'RESET';
record_password_change_attempt($c, 'SUCCESS');
$result .= $c->l('pwd_PASSWORD_CHANGE_SUCCESS');
$c->flash( success => $result );
$c->redirect_to( $c->home_page );
}
$c->flash(success => $result);
$c->redirect_to($c->home_page);
} ## end sub change_password
sub reset_password {
my ($c, $trt, $user, $password, $oldpassword) = @_;
my $ret;
return $c->l('usr_TAINTED_USER') unless (($user) = ($user =~ /^(\w[\-\w_\.]*)$/));
return $c->l('pwd_TAINTED_USER') unless (($user) = ($user =~ /^(\w[\-\w_\.]*)$/));
$user = $1;
my $adb = esmith::AccountsDB->open();
my $adb = esmith::AccountsDB::UTF8->open();
my $acct = $adb->get($user);
return $c->l('NO_SUCH_USER', $user) unless ( $acct->prop('type') eq 'user' );
$ret = esmith::util::setUserPasswordRequirePrevious( $user, $oldpassword, $password ) if $trt ne 'RESET';
$ret = esmith::util::setUserPassword( $user, $password ) if $trt eq 'RESET';
return $c->l('pwd_ERROR_PASSWORD_CHANGE') .' '. $trt unless $ret;
return $c->l('NO_SUCH_USER', $user) unless ($acct->prop('type') eq 'user');
$ret = esmith::util::setUserPasswordRequirePrevious($user, $oldpassword, $password) if $trt ne 'RESET';
$ret = esmith::util::setUserPassword($user, $password) if $trt eq 'RESET';
return $c->l('pwd_ERROR_PASSWORD_CHANGE') . ' ' . $trt unless $ret;
$acct->set_prop("PasswordSet", "yes");
undef $adb;
if (system("/sbin/e-smith/signal-event", "password-modify", $user)) {
$adb = esmith::AccountsDB->open();
return $c->l("usr_ERR_OCCURRED_MODIFYING_PASSWORD");
$adb = esmith::AccountsDB::UTF8->open();
return $c->l("pwd_ERR_OCCURRED_MODIFYING_PASSWORD");
}
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
return 'OK';
}
} ## end sub reset_password
sub record_password_change_attempt {
my ($c, $result) = @_;
my $user = $c->param('User');
my $ip_address = $c->tx->remote_address;
my ($c, $result) = @_;
my $user = $c->param('User');
my $ip_address = $c->tx->remote_address;
if ($result eq 'SUCCESS') {
$c->app->log->info(join "\t", "Password change succeeded: $user", $ip_address);
} else {
$c->app->log->info(join "\t", "Password change FAILED: $user", $ip_address);
}
}
if ($result eq 'SUCCESS') {
$c->app->log->info(join "\t", "Password change succeeded: $user", $ip_address);
} else {
$c->app->log->info(join "\t", "Password change FAILED: $user", $ip_address);
}
} ## end sub record_password_change_attempt
sub check_password {
my $c = shift;
my $password = shift;
my $strength;
my $rec = $cdb->get('passwordstrength');
$strength = ($rec ? ($rec->prop('Users') || 'none') : 'none');
return validate_password( $c, $strength, $password );
}
my $c = shift;
my $password = shift;
my $strength;
my $cdb = esmith::ConfigDB::UTF8->open_ro || die "Couldn't open configuration db";
my $rec = $cdb->get('passwordstrength');
$strength = ($rec ? ($rec->prop('Users') || 'none') : 'none');
return validate_password($c, $strength, $password);
} ## end sub check_password
sub validate_password {
my ($c, $strength, $pass) = @_;
use Crypt::Cracklib;
if ($strength eq "none") {
return $c->l("Passwords must be at least 7 characters long") unless ( length( $pass ) > 6 );
return "OK";
}
my $reason = is_normal_password($c, $pass, undef);
return $reason unless ($reason eq "OK");
return "OK" unless ($strength eq "strong");
if ( -f '/usr/lib64/cracklib_dict.pwd' ) {
$reason = fascist_check($pass, '/usr/lib64/cracklib_dict');
} else {
$reason = fascist_check($pass, '/usr/lib/cracklib_dict');
}
$reason ||= "Software error: password check failed";
return "OK" if ($reason eq "ok");
return $c->l("Bad Password Choice") . ": "
. $c->l("The password you have chosen is not a good choice, because")
. " " . $c->($reason) . ".";
}
1;
1;

View File

@@ -12,146 +12,125 @@ use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
#use esmith::FormMagick qw(gen_locale_date_string);
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::ConfigDB;
use Time::TAI64;
use File::Basename;
use HTML::Entities;
use esmith::FormMagick qw(gen_locale_date_string);
use SrvMngr qw(gen_locale_date_string);
use File::Temp qw(tempfile);
use constant TRUE => 1;
use constant FALSE => 0;
use esmith::ConfigDB::UTF8;
our $cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
our @logfiles = (); # with array
our $cdb;
our @logfiles = (); # with array
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %log_datas = ();
my $title = $c->l('log_FORM_TITLE');
my $notif = '';
$log_datas{default_op} =
($cdb->get('viewlogfiles')->prop('DefaultOperation')) || 'view';
$c->stash( title => $title, notif => $notif, log_datas => \%log_datas);
my $title = $c->l('log_FORM_TITLE');
my $notif = '';
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $viewlog = $cdb->get('viewlogfiles');
$log_datas{default_op} = ($viewlog ? $viewlog->prop('DefaultOperation') : undef) || 'view';
$c->stash(title => $title, notif => $notif, log_datas => \%log_datas);
$c->render(template => 'viewlogfiles');
};
} ## end sub main
sub do_action {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('log_FORM_TITLE');
my $notif = '';
my $result = "";
my $title = $c->l('log_FORM_TITLE');
my $notif = '';
my $result = "";
my %log_datas = ();
$log_datas{filename} = $c->param('Filename');
$log_datas{matchpattern} = $c->param('Matchpattern');
$log_datas{filename} = $c->param('Filename');
$log_datas{matchpattern} = $c->param('Matchpattern');
$log_datas{highlightpattern} = $c->param('Highlightpattern');
$log_datas{operation} = $c->param('Operation');
if ($log_datas{operation} eq 'download') {
$log_datas{'trt'} = "DOWN"
} else {
$log_datas{'trt'} = "SHOW"
}
$log_datas{operation} = $c->param('Operation');
if ($log_datas{operation} eq 'download') {
$log_datas{'trt'} = "DOWN";
} else {
$log_datas{'trt'} = "SHOW";
}
if ($log_datas{filename} =~ /^([\S\s]+)$/) {
$log_datas{filename} = $1;
$log_datas{filename} = $1;
} elsif ($log_datas{filename} =~ /^$/) {
$log_datas{filename} = "messages";
$log_datas{filename} = "messages";
} else {
$result .= $c->l("log_FILENAME_ERROR", $log_datas{filename} )
. " ";
}
if ($log_datas{matchpattern} =~ /^(\S+)$/) {
$log_datas{matchpattern} = $1;
} else {
$log_datas{matchpattern} = ".";
}
if ($log_datas{highlightpattern} =~ /^(\S+)$/) {
$log_datas{highlightpattern} = $1;
} else {
$log_datas{highlightpattern} = '';
$result .= $c->l("log_FILENAME_ERROR", $log_datas{filename}) . " ";
}
if ($log_datas{matchpattern} =~ /^(\S+)$/) {
$log_datas{matchpattern} = $1;
} else {
$log_datas{matchpattern} = ".";
}
if ($log_datas{highlightpattern} =~ /^(\S+)$/) {
$log_datas{highlightpattern} = $1;
} else {
$log_datas{highlightpattern} = '';
}
my $fullpath = "/var/log/$log_datas{filename}";
if (-z $fullpath) {
$result .= $c->l("log_LOG_FILE_EMPTY", "$log_datas{filename}" );
$result .= $c->l("log_LOG_FILE_EMPTY", "$log_datas{filename}");
}
if ($log_datas{trt} eq "SHOW") {
if ( ! $result ) {
$result = $c->render_to_string(inline => showlogFile( $c, %log_datas ));
}
if (!$result) {
$result = $c->render_to_string(inline => showlogFile($c, %log_datas));
}
if ( $result ) {
$c->stash(title => $title, modul => $result, log_datas => \%log_datas);
return $c->render(template => 'viewlogfiles2');
}
}
if ($result) {
$c->stash(title => $title, modul => $result, log_datas => \%log_datas);
return $c->render(template => 'viewlogfiles2');
}
} ## end if ($log_datas{trt} eq...)
if ( $log_datas{trt} eq 'DOWN' ) {
my $modul = 'Log file download';
$notif = download_logFile( $c, %log_datas );
return undef unless defined $notif;
}
$c->stash( title => $title, notif => $notif, log_datas => \%log_datas);
if ($log_datas{trt} eq 'DOWN') {
my $modul = 'Log file download';
$notif = download_logFile($c, %log_datas);
return undef unless defined $notif;
} ## end if ($log_datas{trt} eq...)
$c->stash(title => $title, notif => $notif, log_datas => \%log_datas);
$c->render(template => 'viewlogfiles');
} ## end sub do_action
};
sub timestamp2local
{
sub timestamp2local {
$_ = shift;
if (/^(\@[0-9a-f]{24})(.*)/s)
{
return Time::TAI64::tai64nlocal($1) . $2;
}
elsif (/^([0-9]{10}\.[0-9]{3})(.*)/s)
{
return localtime($1) . $2;
#if (/^(\@[0-9a-f]{24})(.*)/s) {
# return Time::TAI64::tai64nlocal($1) . $2;
#} els
if (/^([0-9]{10}\.[0-9]{3})(.*)/s) {
return localtime($1) . $2;
}
return $_;
}
} ## end sub timestamp2local
sub findlogFiles {
my $c = shift;
use File::Find;
sub findlogfiles
{
sub findlogfiles {
my $path = $File::Find::name;
if (-f)
{
if (-f) {
# Remove leading /var/log/messages
$path =~ s:^/var/log/::;
# don't bother to collect files known to be non-text
# or not log files
foreach (qw(
foreach (
qw(
journal
lastlog
btmp$
wtmp
@@ -161,176 +140,161 @@ sub findlogFiles {
httpd/ssl_scache.pag
httpd/ssl_scache.dir
\/config$
))
)
)
{
return if $path =~ /$_/;
}
} ## end foreach (qw( lastlog btmp$ wtmp...))
my ($file_base, $file_path, $file_type) = fileparse($path);
if ( $file_base =~ /@.*/ )
{
if ($file_base =~ /@.*/) {
#$logfiles{$path} = $file_path . timestamp2local($file_base);
push @logfiles, [ $file_path . timestamp2local($file_base), $path ];
}
else
{
push @logfiles, [ $file_path . timestamp2local($file_base), $path ];
} else {
#$logfiles{$path} = $path;
push @logfiles, [ $path, $path ];
push @logfiles, [ $path, $path ];
}
}
}
} ## end if (-f)
} ## end sub findlogfiles
@logfiles = ();
# Now go and find all the files under /var/log
find({wanted => \&findlogfiles, no_chdir => 1}, '/var/log');
find({ wanted => \&findlogfiles, no_chdir => 1 }, '/var/log');
my @logf = sort { $a->[0] cmp $b->[0] } @logfiles;
return \@logf;
}
} ## end sub findlogFiles
sub showlogFile {
my ($c, %log_datas) = @_;
my $fullpath = "/var/log/$log_datas{filename}";
my $out = '';
my $out = '';
$out .= sprintf("$fullpath: \n");
$out .= sprintf($c->l("log_VIEWING_TIME", $c->gen_locale_date_string()));
$out .= sprintf($c->l("log_VIEWING_TIME", $c->gen_locale_date_string() ));
unless ($log_datas{matchpattern} eq '.') {
unless ( $log_datas{matchpattern} eq '.' )
{
#$out .= sprintf("<p>\n");
$out .= sprintf($c->l("log_MATCH_HEADER", $log_datas{matchpattern} ));
}
$out .= sprintf($c->l("log_MATCH_HEADER", $log_datas{matchpattern}));
} ## end unless ($log_datas{matchpattern...})
if ($log_datas{highlightpattern}) {
if ( $log_datas{highlightpattern} )
{
#$out .= sprintf("<p>\n");
$out .= sprintf($c->l("log_HIGHLIGHT_HEADER", "$log_datas{highlightpattern}" ));
}
$out .= sprintf($c->l("log_HIGHLIGHT_HEADER", "$log_datas{highlightpattern}"));
} ## end if ($log_datas{highlightpattern...})
if ($log_datas{filename} =~ /\.gz$/) {
my $pid = open(LOGFILE, "-|");
die "Couldn't fork: $!" unless defined $pid;
unless ($pid) {
# Child
exec("/bin/zcat", $fullpath)
|| die "Can't exec zcat: $!";
|| die "Can't exec zcat: $!";
# NOTREACHED
}
} ## end unless ($pid)
} else {
open(LOGFILE, "$fullpath");
}
my $somethingMatched = 0;
my $fileEmpty = 1;
my $fileEmpty = 1;
$out .= sprintf("<PRE>");
while(<LOGFILE>)
{
while (<LOGFILE>) {
$fileEmpty = 0;
next unless /$log_datas{matchpattern}/;
$somethingMatched = 1;
$_ = timestamp2local($_);
$_ = HTML::Entities::encode_entities($_);
$_ = timestamp2local($_);
$_ = HTML::Entities::encode_entities($_);
($log_datas{highlightpattern} && /$log_datas{highlightpattern}/)
? $out .= sprintf( "<b>$_</b>" )
: $out .= sprintf("$_");
}
? $out .= sprintf("<b>$_</b>")
: $out .= sprintf("$_");
} ## end while (<LOGFILE>)
$out .= sprintf("</PRE>");
if ($fileEmpty) {
$out .= sprintf("<p>\n");
$out .= sprintf($c->l("log_LOG_FILE_EMPTY"));
} else {
unless ($somethingMatched)
{
unless ($somethingMatched) {
$out .= sprintf("<p>\n");
$out .= sprintf($c->l("log_NO_MATCHING_LINES"));
}
}
} ## end else [ if ($fileEmpty) ]
close LOGFILE;
return $out;
}
} ## end sub showlogFile
sub download_logFile {
my ($c, %log_datas) = @_;
my $fullpath = "/var/log/$log_datas{filename}";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
# Save this information for later.
$cdb->get('viewlogfiles')->merge_props('DefaultOperation', $log_datas{operation});
# If the client is on windows, we must handle this a little differently.
my $win32 = FALSE;
my $mac = FALSE;
my $agent = $ENV{HTTP_USER_AGENT} || "";
if ($agent =~ /win32|windows/i) {
$win32 = TRUE;
} elsif ($agent =~ /mac/i) {
} elsif ($agent =~ /mac/i) {
$mac = TRUE;
}
# Check for errors first. Once we start sending the file it's too late to
# report them.
my $error = "";
unless (-f $fullpath) {
unless (-f $fullpath) {
$error = $c->l("log_ERR_NOEXIST_FILE") . $fullpath;
}
local *FILE;
open(FILE, "<$fullpath")
or $error = $c->l("log_ERR_NOOPEN_FILE");
# Put other error checking here.
# Put other error checking here.
return $error if $error;
# Fix the filename, as it might have a directory prefixed to it.
# Fix the filename, as it might have a directory prefixed to it.
my $filename = $log_datas{filename};
if ( $filename =~ m#/# ) {
if ($filename =~ m#/#) {
$filename = (split /\//, $filename)[-1];
}
# And send the file.
my $nl = "\n";
if ($win32) { $nl = "\r\n" }
elsif ($mac) { $nl = "\r" }
if ($win32) { $nl = "\r\n" }
elsif ($mac) { $nl = "\r" }
# Otherwise, send the file. Start with the headers.
# Note: The Content-disposition must be attachment, or IE will view the
# file inline like it's told. It ignores the Content-type, but it likes
# the Content-disposition (an officially unsupported header) for some
# reason. Yay Microsoft.
my $file2 = new File::Temp( UNLINK => 0 );
my $file2 = new File::Temp(UNLINK => 0);
while (my $line = <FILE>) {
chomp $line;
my $linew = timestamp2local($line) . $nl;
print $file2 $linew;
}
} ## end while (my $line = <FILE>)
close(FILE);
$c->render_file(
'filepath' => "$file2",
'filename' => "$filename",
'format' => 'x-download',
'content_disposition' => 'attachment',
'cleanup' => 1,
'filepath' => "$file2",
'filename' => "$filename",
'format' => 'x-download',
'content_disposition' => 'attachment',
'cleanup' => 1,
);
return undef;
}
} ## end sub download_logFile
1;

View File

@@ -10,94 +10,73 @@ package SrvMngr::Controller::Workgroup;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::FormMagick::Panel::workgroup;
our $db = esmith::ConfigDB->open || die "Couldn't open config db";
use esmith::ConfigDB::UTF8;
our $db ;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$db = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my %wkg_datas = ();
my $title = $c->l('wkg_FORM_TITLE');
my $modul = '';
$wkg_datas{'Workgroup'} = ($db->get_prop('smb','Workgroup')) || '';
$wkg_datas{'ServerName'} = ($db->get_prop('smb','ServerName')) || '';
$wkg_datas{'ServerRole'} = ($db->get_prop('smb','ServerRole')) || '';
$wkg_datas{'RoamingProfiles'} = ($db->get_prop('smb','RoamingProfiles')) || '';
$c->stash( title => $title, modul => $modul, wkg_datas => \%wkg_datas );
my $title = $c->l('wkg_FORM_TITLE');
my $modul = '';
$wkg_datas{'Workgroup'} = ($db->get_prop('smb', 'Workgroup')) || '';
$wkg_datas{'ServerName'} = ($db->get_prop('smb', 'ServerName')) || '';
$wkg_datas{'ServerRole'} = ($db->get_prop('smb', 'ServerRole')) || '';
$wkg_datas{'RoamingProfiles'} = ($db->get_prop('smb', 'RoamingProfiles')) || '';
$c->stash(title => $title, modul => $modul, wkg_datas => \%wkg_datas);
$c->render(template => 'workgroup');
};
} ## end sub main
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $result = "";
my $workgroup = ($c->param('Workgroup') || 'no');
my $servername = ($c->param('ServerName') || 'WS');
$db = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my $result = "";
my $workgroup = ($c->param('Workgroup') || 'no');
my $servername = ($c->param('ServerName') || 'WS');
my $roamingprofiles = ($c->param('RoamingProfiles') || 'no');
my $serverrole = ($c->param('ServerRole') || 'WS');
my $serverrole = ($c->param('ServerRole') || 'WS');
# controls
my $res = validate2_workgroup($c, $workgroup, $servername);
$result .= $res unless $res eq 'OK';
$res = validate2_servername($c, $servername);
$result .= $res unless $res eq 'OK';
if ($result eq '') {
$db->get('smb')->set_prop('Workgroup', $workgroup);
$db->get('smb')->set_prop('ServerRole', $serverrole);
$db->get('smb')->set_prop('ServerName', $servername);
$db->get('smb')->set_prop('Workgroup', $workgroup);
$db->get('smb')->set_prop('ServerRole', $serverrole);
$db->get('smb')->set_prop('ServerName', $servername);
$db->get('smb')->set_prop('RoamingProfiles', $roamingprofiles);
}
system( "/sbin/e-smith/signal-event", "workgroup-update" ) == 0
or $result = $c->l('ERROR_UPDATING') . " system";
} ## end if ($result eq '')
system("/sbin/e-smith/signal-event", "workgroup-update") == 0
or $result = $c->l('ERROR_UPDATING') . " system";
my $title = $c->l('wkg_FORM_TITLE');
if ( $result eq '' ) { $result = $c->l('wkg_SUCCESS'); }
$c->stash( title => $title, modul => $result );
if ($result eq '') { $result = $c->l('wkg_SUCCESS'); }
$c->stash(title => $title, modul => $result);
$c->render(template => 'module');
};
} ## end sub do_update
sub validate2_servername {
my $c = shift;
my $c = shift;
my $servername = shift;
return ('OK') if ( $servername =~ /^([a-zA-Z][\-\w]*)$/ );
return ('OK') if ($servername =~ /^([a-zA-Z][\-\w]*)$/);
return $c->l('INVALID_SERVERNAME');
}
} ## end sub validate2_servername
sub validate2_workgroup {
my $c = shift;
my $workgroup = lc(shift);
my $c = shift;
my $workgroup = lc(shift);
my $servername = lc(shift);
# my $workgroup = $c->l(shift);
# my $servername = $c->l(shift);
return $c->l('INVALID_WORKGROUP') unless ( $workgroup =~ /^([a-zA-Z0-9][\-\w\.]*)$/ );
return $c->l('INVALID_WORKGROUP_MATCHES_SERVERNAME') if ( $servername eq $workgroup);
return ('OK');
}
1;
# my $workgroup = $c->l(shift);
# my $servername = $c->l(shift);
return $c->l('INVALID_WORKGROUP') unless ($workgroup =~ /^([a-zA-Z0-9][\-\w\.]*)$/);
return $c->l('INVALID_WORKGROUP_MATCHES_SERVERNAME') if ($servername eq $workgroup);
return ('OK');
} ## end sub validate2_workgroup
1;

View File

@@ -3,277 +3,273 @@ package SrvMngr::Controller::Yum;
#----------------------------------------------------------------------
# heading : System
# description : Software installer
# navigation : 4000 300
# navigation : 4000 500
#$if_admin->get('/yum')->to('yum#main')->name('yum');
#$if_admin->post('/yum')->to('yum#do_display')->name('yumd1');
#$if_admin->get('/yumd')->to('yum#do_display')->name('yumd');
#$if_admin->post('/yumd')->to('yum#do_update')->name('yumu');
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session ip_number_or_blank);
use esmith::ConfigDB;
# dnf_* should remain ASCII; yum_repositories do not need to be UTF-8
use esmith::ConfigDB::UTF8;
use esmith::util;
use File::Basename;
our $cdb = esmith::ConfigDB->open || die "Couldn't open config db";
my $dnf_status_file = '/var/cache/dnf/dnf.status';
our $cdb;
my $dnf_status_file = '/var/cache/dnf/dnf.status';
#use File::stat;
our %dbs;
for ( qw(available installed updates) )
{
$dbs{$_} = esmith::ConfigDB->open_ro("dnf_$_") or
die "Couldn't open dnf_$_ DB\n";
}
for ( qw(repositories) )
{
$dbs{$_} = esmith::ConfigDB->open("yum_$_") or
die "Couldn't open yum_$_ DB\n";
}
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
for (qw(available installed updates)) {
$dbs{$_} = esmith::ConfigDB::UTF8->open_ro("dnf_$_")
or die "Couldn't open dnf_$_ DB\n";
}
for (qw(repositories)) {
$dbs{$_} = esmith::ConfigDB::UTF8->open("yum_$_")
or die "Couldn't open yum_$_ DB\n";
}
my %yum_datas = ();
my $title = $c->l('yum_FORM_TITLE');
my $dest = 'yum';
my $notif = '';
my $title = $c->l('yum_FORM_TITLE');
my $dest = 'yum';
my $notif = '';
$yum_datas{'trt'} = 'STAT';
if ( $c->is_dnf_running()) {
$yum_datas{'trt'} = 'LOGF';
$dest = 'yumlogfile';
if ($c->is_dnf_running()) {
$yum_datas{'trt'} = 'LOGF';
$dest = 'yumlogfile';
} elsif ($cdb->get_prop('dnf', 'LogFile')) {
$yum_datas{'trt'} = 'PSTU';
$yum_datas{'reconf'} = $cdb->get_value('UnsavedChanges', 'yes');
$dest = 'yumpostupg';
$yum_datas{'trt'} = 'PSTU';
$yum_datas{'reconf'} = $cdb->get_value('UnsavedChanges', 'yes');
$dest = 'yumpostupg';
} else {
# normal other trt
# normal other trt
}
$c->stash( title => $title, notif => $notif, yum_datas => \%yum_datas );
return $c->render( template => $dest );
}
$c->stash(title => $title, notif => $notif, yum_datas => \%yum_datas);
return $c->render(template => $dest);
} ## end sub main
sub do_display {
my $c = shift;
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'STAT');
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
for (qw(available installed updates)) {
$dbs{$_} = esmith::ConfigDB::UTF8->open_ro("dnf_$_")
or die "Couldn't open dnf_$_ DB\n";
}
my $c = shift;
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'STAT');
for (qw(repositories)) {
$dbs{$_} = esmith::ConfigDB::UTF8->open("yum_$_")
or die "Couldn't open yum_$_ DB\n";
}
my %yum_datas = ();
my $title = $c->l('yum_FORM_TITLE');
my $title = $c->l('yum_FORM_TITLE');
my ($notif, $dest) = '';
$yum_datas{'trt'} = $trt;
# force $trt if current logfile
if ( $c->is_dnf_running() ) {
$trt = 'LOGF';
if ($c->is_dnf_running()) {
$trt = 'LOGF';
} elsif ($cdb->get_prop('dnf', 'LogFile')) {
$trt = 'PSTU';
$trt = 'PSTU';
}
if ( $trt eq 'UPDT' ) {
$dest = 'yumupdate';
if ($trt eq 'UPDT') {
$dest = 'yumupdate';
}
if ($trt eq 'INST') {
$dest = 'yuminstall';
}
if ($trt eq 'REMO') {
$dest = 'yumremove';
}
if ($trt eq 'CONF') {
$dest = 'yumconfig';
}
if ($trt eq 'LOGF') {
if ($c->is_dnf_running()) {
$dest = 'yumlogfile';
}
} ## end if ($trt eq 'LOGF')
if ( $trt eq 'INST' ) {
$dest = 'yuminstall';
if ($trt eq 'PSTU') {
if ($cdb->get_prop('dnf', 'LogFile')) {
$dest = 'yumpostupg';
$yum_datas{'reconf'} = $cdb->get_value('UnsavedChanges', 'yes');
}
if ( $trt eq 'REMO' ) {
$dest = 'yumremove';
}
if ( $trt eq 'CONF' ) {
$dest = 'yumconfig';
}
if ( $trt eq 'LOGF' ) {
if ($c->is_dnf_running()) {
$dest = 'yumlogfile';
}
}
if ( $trt eq 'PSTU') {
if ($cdb->get_prop('dnf', 'LogFile')) {
$dest = 'yumpostupg';
$yum_datas{'reconf'} = $cdb->get_value('UnsavedChanges', 'yes');
}
}
if ( ! $dest ) { $dest = 'yum'; }
$c->stash( title => $title, notif => $notif, yum_datas => \%yum_datas );
return $c->render( template => $dest );
};
} ## end if ($trt eq 'PSTU')
if (!$dest) { $dest = 'yum'; }
$c->stash(title => $title, notif => $notif, yum_datas => \%yum_datas);
return $c->render(template => $dest);
} ## end sub do_display
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = $c->param('trt');
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
for (qw(available installed updates)) {
$dbs{$_} = esmith::ConfigDB::UTF8->open_ro("dnf_$_")
or die "Couldn't open dnf_$_ DB\n";
}
my $rt = $c->current_route;
my $trt = $c->param('trt');
for (qw(repositories)) {
$dbs{$_} = esmith::ConfigDB::UTF8->open("yum_$_")
or die "Couldn't open yum_$_ DB\n";
}
my %yum_datas = ();
$yum_datas{trt} = $trt;
my $title = $c->l('yum_FORM_TITLE');
my ($dest, $res, $result) = '';
if ( $trt eq 'UPDT' ) {
if ($trt eq 'UPDT') {
$dest = 'yumupdate';
$dest = 'yumupdate';
if (!$result) {
$res = $c->do_yum('update');
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$res = $c->do_yum('update');
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$yum_datas{trt} = 'SUC';
#$result = $c->l('yum_SUCCESS');
}
}
}
if (!$result) {
$yum_datas{trt} = 'SUC';
if ( $trt eq 'INST' ) {
#$result = $c->l('yum_SUCCESS');
} ## end if (!$result)
} ## end if (!$result)
} ## end if ($trt eq 'UPDT')
$dest = 'yuminstall';
if ($trt eq 'INST') {
$dest = 'yuminstall';
if ( ! $result ) {
$res = $c->do_yum('install');
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$yum_datas{trt} = 'SUC';
#$result = $c->l('yum_SUCCESS');
}
}
}
if (!$result) {
$res = $c->do_yum('install');
$result .= $res unless $res eq 'OK';
if ( $trt eq 'REMO' ) {
if (!$result) {
$yum_datas{trt} = 'SUC';
$dest = 'yumremove';
#$result = $c->l('yum_SUCCESS');
} ## end if (!$result)
} ## end if (!$result)
} ## end if ($trt eq 'INST')
if ( ! $result ) {
$res = $c->do_yum('remove');
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$yum_datas{trt} = 'SUC';
#$result = $c->l('yum_SUCCESS');
}
}
}
if ($trt eq 'REMO') {
$dest = 'yumremove';
if ( $trt eq 'CONF' ) {
if (!$result) {
$res = $c->do_yum('remove');
$result .= $res unless $res eq 'OK';
$dest = 'yumconfig';
if (!$result) {
$yum_datas{trt} = 'SUC';
if ( ! $result ) {
$res = $c->change_settings();
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_SUCCESS');
}
}
}
#$result = $c->l('yum_SUCCESS');
} ## end if (!$result)
} ## end if (!$result)
} ## end if ($trt eq 'REMO')
if ($trt eq 'CONF') {
$dest = 'yumconfig';
if ( $trt eq 'PSTU') {
if (!$result) {
$res = $c->change_settings();
$result .= $res unless $res eq 'OK';
my $reconf = $c->param('reconf') || 'yes';
$dest = 'yumpostupg';
if (!$result) {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_SUCCESS');
}
} ## end if (!$result)
} ## end if ($trt eq 'CONF')
# effective reconfigure and reboot required
if ( $reconf eq 'yes' ) {
$res = $c->post_upgrade_reboot();
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_SYSTEM_BEING_RECONFIGURED');
}
} else {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_UPDATE_SUCCESS');
}
}
if ($trt eq 'PSTU') {
my $reconf = $c->param('reconf') || 'yes';
$dest = 'yumpostupg';
# effective reconfigure and reboot required
if ($reconf eq 'yes') {
$res = $c->post_upgrade_reboot();
$result .= $res unless $res eq 'OK';
if ( $trt eq 'LOGF' ) {
$dest = 'yumlogfile';
if ( ! $c->is_dnf_running()) {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_SUCCESS');
if (!$result) {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_SYSTEM_BEING_RECONFIGURED');
}
} else {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_UPDATE_SUCCESS');
}
}
} ## end if ($trt eq 'PSTU')
if ($trt eq 'LOGF') {
$dest = 'yumlogfile';
if (!$c->is_dnf_running()) {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_SUCCESS');
}
} ## end if ($trt eq 'LOGF')
# do_yum ended (no message) --> forced to LOGFile
if ( ! $result ) {
$dest = 'yumlogfile';
$yum_datas{trt} = 'LOGF';
if (!$result) {
$dest = 'yumlogfile';
$yum_datas{trt} = 'LOGF';
}
$c->stash(title => $title, notif => $result, yum_datas => \%yum_datas);
$c->stash( title => $title, notif => $result, yum_datas => \%yum_datas );
if ($yum_datas{trt} ne 'SUC') {
return $c->render(template => $dest);
return $c->render(template => $dest);
}
my $message = "'Yum' $trt update DONE";
$c->app->log->info($message);
$c->flash(success => $result) if $result;
$c->redirect_to("/yum");
};
} ## end sub do_update
sub get_dnf_status {
#interrogate status file created and maintained by smeserver.py plugin for dnf.
my ($c) = @_;
my ($c) = @_;
my $file_name = $dnf_status_file;
my $content = "resolved";
if ( -e "$file_name") {
open my $fh, '<', $file_name or die "Can't open file: $!";
$content = <$fh>;
close $fh;
}
my $content = "resolved";
if (-e "$file_name") {
open my $fh, '<', $file_name or die "Can't open file: $!";
$content = <$fh>;
close $fh;
} ## end if (-e "$file_name")
return $content;
}
} ## end sub get_dnf_status
sub is_dnf_running {
my ($c) = @_;
my $dnf_status = $c->get_dnf_status();
return $dnf_status ne "resolved" && $dnf_status ne "config" && $dnf_status ne "sack";
}
} ## end sub is_dnf_running
sub is_empty {
my ($c, $yumdb) = @_;
my $groups = $dbs{$yumdb}->get_all_by_prop(type => 'group') || 'none';
my $groups = $dbs{$yumdb}->get_all_by_prop(type => 'group') || 'none';
my $packages = $dbs{$yumdb}->get_all_by_prop(type => 'package') || 'none';
#Show no updates if both = none
@@ -281,283 +277,194 @@ sub is_empty {
#else return here
return;
}
} ## end sub is_empty
sub non_empty {
my ($c, $yumdb, $type) = @_;
$type ||= 'both';
return 0 unless (exists $dbs{$yumdb});
my $groups = scalar $dbs{$yumdb}->get_all_by_prop(type => 'group');
my $groups = scalar $dbs{$yumdb}->get_all_by_prop(type => 'group');
return $groups if ($type eq 'group');
my $packages = scalar $dbs{$yumdb}->get_all_by_prop(type => 'package');
if ($type eq 'package')
{
return $c->package_functions_enabled ? $packages : 0;
if ($type eq 'package') {
return $c->package_functions_enabled ? $packages : 0;
}
return ($c->package_functions_enabled or $yumdb eq 'updates') ?
($groups || $packages) : $groups;
}
return ($c->package_functions_enabled or $yumdb eq 'updates') ? ($groups || $packages) : $groups;
} ## end sub non_empty
sub package_functions_enabled {
my ($c) = @_;
return ($cdb->get_prop("dnf", "PackageFunctions") eq "enabled");
}
sub get_status {
my ($c, $prop, $localise) = @_;
my $status = $cdb->get_prop("dnf", $prop) || 'disabled';
return $status unless $localise;
return $c->l($status eq 'enabled' ? 'ENABLED' : 'DISABLED');
}
} ## end sub get_status
sub get_options {
my ($c, $yumdb, $type) = @_;
my %options;
for ($dbs{$yumdb}->get_all_by_prop(type => $type))
{
$options{$_->key} = $_->key . " " . $_->prop("Version") . " - " .
$_->prop("Repo");
for ($dbs{$yumdb}->get_all_by_prop(type => $type)) {
$options{ $_->key } = $_->key . " " . $_->prop("Version") . " - " . $_->prop("Repo");
}
return \%options;
}
} ## end sub get_options
sub get_options2 {
my ($c, $yumdb, $type) = @_;
my @options;
for ($dbs{$yumdb}->get_all_by_prop(type => $type))
{
push @options, [ $_->key . " " . $_->prop("Version") . " - " .
$_->prop("Repo") => $_->key ];
for ($dbs{$yumdb}->get_all_by_prop(type => $type)) {
push @options, [ $_->key . " " . $_->prop("Version") . " - " . $_->prop("Repo") => $_->key ];
}
return \@options;
}
} ## end sub get_options2
sub get_names {
return [ keys %{get_options(@_)} ];
return [ keys %{ get_options(@_) } ];
}
sub get_names2 {
my ($c, $yumdb, $type) = @_;
my @selected;
for ($dbs{$yumdb}->get_all_by_prop(type => $type)) {
push @selected, $_->key;
}
return \@selected;
# return [ values @{get_options2(@_)} ];
}
# return [ values @{get_options2(@_)} ];
} ## end sub get_names2
sub get_repository_options2 {
my $c = shift;
my @options;
foreach my $repos (
$dbs{repositories}->get_all_by_prop(type => "repository") )
{
next unless ($repos->prop('Visible') eq 'yes'
or $repos->prop('status') eq 'enabled');
foreach my $repos ($dbs{repositories}->get_all_by_prop(type => "repository")) {
next unless ($repos->prop('Visible') eq 'yes'
or $repos->prop('status') eq 'enabled');
push @options, [ $repos->prop('Name') => $repos->key ];
}
} ## end foreach my $repos ($dbs{repositories...})
my @opts = sort { $a->[0] cmp $b->[0] } @options;
return \@opts;
}
} ## end sub get_repository_options2
sub get_repository_current_options
{
sub get_repository_current_options {
my $c = shift;
my @selected;
foreach my $repos (
$dbs{repositories}->get_all_by_prop( type => "repository" ) )
{
next unless ($repos->prop('Visible') eq 'yes'
or $repos->prop('status') eq 'enabled');
foreach my $repos ($dbs{repositories}->get_all_by_prop(type => "repository")) {
next unless ($repos->prop('Visible') eq 'yes'
or $repos->prop('status') eq 'enabled');
push @selected, $repos->key if ($repos->prop('status') eq 'enabled');
}
} ## end foreach my $repos ($dbs{repositories...})
return \@selected;
}
} ## end sub get_repository_current_options
sub get_avail2 {
my ($c, $yumdb, $type) = @_;
return $c->get_options2("available", "package");
}
sub get_check_freq_opt {
my ($c) = @_;
return [[ $c->l('DISABLED') => 'disabled'],
[ $c->l('yum_1DAILY') => 'daily'],
[ $c->l('yum_2WEEKLY') => 'weekly'],
[ $c->l('yum_3MONTHLY') => 'monthly']];
}
return [
[ $c->l('DISABLED') => 'disabled' ],
[ $c->l('yum_1DAILY') => 'daily' ],
[ $c->l('yum_2WEEKLY') => 'weekly' ],
[ $c->l('yum_3MONTHLY') => 'monthly' ]
];
} ## end sub get_check_freq_opt
sub print_skip_header {
my ($c) = shift;
return "<INPUT TYPE=\"hidden\" NAME=\"skip_header\" VALUE=\"1\">\n";
}
sub change_settings {
my ($c) = @_;
for my $param ( qw(
PackageFunctions
) )
for my $param (
qw(
PackageFunctions
)
)
{
$cdb->set_prop("dnf", $param, $c->param("yum_$param"));
}
$cdb->set_prop("dnf", $param, $c->param("yum_$param"));
} ## end for my $param (qw( PackageFunctions...))
my $check4updates = $c->param("yum_check4updates");
my $status = 'disabled';
my $status = 'disabled';
if ($check4updates ne 'disabled') { $status = 'enabled'; }
$cdb->set_prop("dnf", 'check4updates', $check4updates);
my $deltarpm = $c->param("yum_DeltaRpmProcess");
$cdb->set_prop("dnf", 'DeltaRpmProcess', $deltarpm);
my $downloadonly = $c->param("yum_DownloadOnly");
if ($downloadonly ne 'disabled') { $status = 'enabled'; }
$cdb->set_prop("dnf", 'DownloadOnly', $downloadonly);
my $AutoInstallUpdates = $c->param("yum_AutoInstallUpdates");
if ($AutoInstallUpdates ne 'disabled') { $status = 'enabled'; }
$cdb->set_prop("dnf", 'AutoInstallUpdates', $AutoInstallUpdates);
$cdb->set_prop("dnf", 'status', $status);
my %selected = map {$_ => 1} @{$c->every_param('SelectedRepositories')};
foreach my $repos (
$dbs{repositories}->get_all_by_prop(type => "repository") )
{
$repos->set_prop("status",
exists $selected{$repos->key} ? 'enabled' : 'disabled');
$cdb->set_prop("dnf", 'status', $status);
my %selected = map { $_ => 1 } @{ $c->every_param('SelectedRepositories') };
foreach my $repos ($dbs{repositories}->get_all_by_prop(type => "repository")) {
$repos->set_prop("status", exists $selected{ $repos->key } ? 'enabled' : 'disabled');
}
$dbs{repositories}->reload;
unless ( system( "/sbin/e-smith/signal-event", "dnf-modify" ) == 0 )
{
return $c->l('yum_ERROR_UPDATING_CONFIGURATION');
unless (system("/sbin/e-smith/signal-event", "dnf-modify") == 0) {
return $c->l('yum_ERROR_UPDATING_CONFIGURATION');
}
return 'OK';
}
} ## end sub change_settings
sub do_yum {
my ($c, $function) = @_;
for ( qw(SelectedGroups SelectedPackages) )
{
$cdb->set_prop("dnf", $_, join(',', (@{$c->every_param($_)} )));
for (qw(SelectedGroups SelectedPackages)) {
$cdb->set_prop("dnf", $_, join(',', (@{ $c->every_param($_) })));
}
esmith::util::backgroundCommand(0, "/sbin/e-smith/signal-event", "dnf-$function");
esmith::util::backgroundCommand(0,
"/sbin/e-smith/signal-event", "dnf-$function");
for ( qw(available installed updates) ) {
$dbs{$_}->reload;
for (qw(available installed updates)) {
$dbs{$_}->reload;
}
return 'OK';
}
} ## end sub do_yum
sub get_yum_status_page {
my ($c) = @_;
my $yum_status;
open(YUM_STATUS, "</var/run/yum.status");
$yum_status = <YUM_STATUS>;
close(YUM_STATUS);
return $yum_status;
}
} ## end sub get_yum_status_page
sub format_yum_log {
my $c = shift;
$cdb->reload;
my $filepage = $cdb->get_prop('dnf', 'LogFile');
return '' unless $filepage and ( -e "$filepage" );
return '' unless $filepage and (-e "$filepage");
my $out = sprintf "<PRE>";
open (FILE, "$filepage");
open(FILE, "$filepage");
while (<FILE>) {
$out .= sprintf("%s", $_);
$out .= sprintf("%s", $_);
}
close FILE;
$out .= sprintf "</PRE>";
undef $filepage;
return $out;
}
} ## end sub format_yum_log
sub post_upgrade_reboot {
my $c = shift;
$cdb->get_prop_and_delete('dnf', 'LogFile');
$cdb->reload;
@@ -565,17 +472,13 @@ sub post_upgrade_reboot {
exec "/sbin/e-smith/signal-event post-upgrade; /sbin/e-smith/signal-event reboot";
die "Exec failed";
}
return 'OK'
}
return 'OK';
} ## end sub post_upgrade_reboot
sub show_yum_log {
my $c = shift;
my $out = $c->format_yum_log();
my $c = shift;
my $out = $c->format_yum_log();
my $yum_log = $cdb->get_prop_and_delete('dnf', 'LogFile');
return $out;
}
1;
} ## end sub show_yum_log
1;

View File

@@ -1,5 +1,12 @@
'bac_No suitable local devices found' => 'No suitable local devices found',
'bac_BACKUP_TITLE' => 'Backup or restore server data',
#
# Lex file for Backup generated on 2025-07-17 09:52:30
#
'bac_ALL_BACKUPS' => 'All backups',
'bac_AM' => 'AM',
'bac_AM/PM' => 'AM/PM',
'bac_ANOTHER_RESTORE_IN_PROGRESS' => 'Another restore is in progress. Please try again later.',
'bac_BACKUP_CHOICE' => 'Selecting files to display',
'bac_BACKUP_CONFIG_STATUS' => 'Backup configuration and status',
'bac_BACKUP_DESC' => '<P>The server provides two ways to back up and restore
your server: using your local desktop or a tape drive.</P>
<P>The first method creates a copy of your server configuration and user
@@ -46,127 +53,125 @@ copy it to a local removable disk such as a USB disk.</P>
<P>All backup methods allow you to restore your configuration and user
data files. Workstation backup provides individual file restore. <b>Ideally,
full restore should be performed on a freshly installed server</b>.</P>',
'bac_BACKUP_CONFIG_STATUS' => 'Backup configuration and status',
'bac_BACKUP_DESKTOP_TOO_BIG' => 'Your server has too much data for a reliable backup to desktop.',
'bac_BACKUP_FILE_INCOMPLETE' => 'The backup file was incomplete',
'bac_BACKUP_TITLE' => 'Backup or restore server data',
'bac_BACKUPS_RUN_AT' => 'Regular tape backups will run at: ',
'bac_REMINDER_MESSAGE_AT' => 'Reminder messages will be sent at: ',
'bac_TAPE_BACKUPS' => 'Tape backups are ',
'bac_BETWEEN_0_AND_12' => 'Please choose an hour between 0 and 12.',
'bac_BETWEEN_0_AND_59' => 'Please choose a minute between 0 and 59.',
'bac_CHECK_INTEGRITY_WARNING' => 'Warning : For large backups, checking integrity may be a long task and should be made with daily workstation backup disabled.',
'bac_CHECK_TO_VERIFY_FULL_RESTORE' => 'Check here to test integrity of all backups needed for a full restore with the selected backup ',
'bac_cifs' => 'cifs',
'bac_COMPRESSION_LEVEL' => 'Backup compression level ~[0-9~]',
'bac_CONFIGURATION_TO_BE_DONE' => 'Please configure the backup settings.',
'bac_CONFIGURE_TAPE_BACKUP' => 'Configure tape backup',
'bac_CONFIGURE_WORKSTN_BACKUP' => 'Configure Workstation Backup',
'bac_CONFIGURE_WORKSTN_BACKUP_DESC' => 'You can set the number of
successive backup sets to keep on the workstation, with automatic rotation.
Each set may contain saved data for several consecutive days.
In this case first backup of the set is full backup, others daily backups are
incremental. You can also set a time limit for each backup session or for incremental
backups only. When this limit occurs, backup is cleanly stopped and the next
incremental backup will safely continue with unsaved and modified datas.',
'bac_COULD_NOT_DECODE' => 'Could not decode backup file: ',
'bac_COULD_NOT_EXEC_PIPELINE' => 'Could not execute backup pipeline: ',
'bac_COULD_NOT_FORK' => 'Could not fork: ',
'bac_DESKTOP_BACKUP' => 'Backup to desktop',
'bac_DESKTOP_RESTORE' => 'Restore from desktop',
'bac_DESKTOP_RESTORE_DESC' => 'This process will upload a server backup file from your local desktop to your server and restore the configuration and user data files. <B>The restore should be performed on a freshly installed server</B>.',
'bac_DESKTOP_VERIFY' => 'Verify desktop backup file',
'bac_TAPE_CONFIGURE' => 'Configure tape backup',
'bac_TAPE_RESTORE' => 'Restore from tape',
'bac_RESTORE_IN_PROGRESS_BEGAN_AT' => 'A system restore is in progress. It began at: ',
'bac_REFRESH_THIS_DISPLAY' => 'Refresh this display',
'bac_CONFIGURE_TAPE_BACKUP' => 'Configure tape backup',
'bac_RESTORE_COMPLETED' => 'A system restore has completed',
'bac_STARTED_AT' => 'It began at: ',
'bac_FINISHED_AT' => 'and finished at: ',
'bac_YOU_MUST_REBOOT' => 'You must reboot the server to activate any configuration changes that were
made as a result of this restore.',
'bac_REBOOT' => 'Reboot',
'bac_SELECT_AN_ACTION' => 'Select an action',
'bac_X_BACKUP_OR_RESTORE' => 'X Backup or restore server data',
'bac_DOW' => 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday Everyday',
'bac_ENABLE_DISABLE_TAPE' => 'Enable/Disable Nightly Tape Backup',
'bac_ENABLE_DISABLE_WORKSTN' => 'Enable/Disable Daily Workstation Backup',
'bac_ENABLE_TAPE_BACKUP' => 'Enable tape backup',
'bac_ENABLE_WORKSTN_BACKUP' => 'Enable Workstation Backup',
'bac_ERR_ALREADY_MOUNTED' => 'Backup directory is already mounted',
'bac_ERR_CONF_BACKUP' => 'Error occurred during conf-backup event.',
'bac_ERR_DAR_CATALOG' => 'Error when using Dar catalog',
'bac_ERR_EXTRACT' => 'Error when extracting with Dar',
'bac_ERR_INVALID_COMPRESSION' => 'Compression level must be set between 0 (no compression) and 9 (maximum compression)',
'bac_ERR_INVALID_FILES_IN_SET_NUMBER' => 'This number must be 1 or greater. First backup in set is <b>full</b> others are <b>incrementals</b>',
'bac_ERR_INVALID_FOLDER' => 'Invalid share name',
'bac_ERR_INVALID_HOUR' => 'Error: invalid backup hour: ',
'bac_ERR_INVALID_LOGIN' => 'Invalid Login',
'bac_ERR_INVALID_MINUTE' => 'Error: invalid backup minute: ',
'bac_ERR_INVALID_PASSWORD' => 'Invalid Password',
'bac_ERR_INVALID_REMINDER_HOUR' => 'Error: invalid reminder hour: ',
'bac_ERR_INVALID_REMINDER_MINUTE' => 'Error: invalid reminder minute: ',
'bac_ERR_INVALID_SELDATE' => 'Date format is invalid, must be ~[~[~[yyyy/~]mm/~]dd-~]hh:mm~[:ss~]. ie: 2005/12/31-08:23:32 or
10-08:32 or 08:32',
'bac_ERR_INVALID_SETS_NUMBER' => 'Sets number must be 1 or greater',
'bac_ERR_INVALID_TIMEOUT' => 'Maximum backup time must be set between 1 and 24 hours',
'bac_ERR_INVALID_WORKSTN' => 'Invalid Workstation IP or Hostname ',
'bac_ERR_MOUNTING_SMBSHARE' => 'Unable to mount workstation shared folder',
'bac_ERR_NO_FULL_BACKUP' => 'Aborting restore because needed full backup is missing or unreadable.',
'bac_ERR_NO_HOST_DIR' => 'No directory for your host in shared folder. Maybe your host name is different from backup ones',
'bac_ERR_NO_INC_BACKUP' => 'Aborting restore because the set has missing or unreadable incremental backup number',
'bac_ERR_NO_MOUNTED_DISK' => 'Error : No mounted disk available. Please mount a disk or select another type of workstation backup.',
'bac_ERR_NO_USB_DISK' => 'Error : No removable disk available. Please connect a removable disk or select another type of workstation backup.',
'bac_ERR_NOT_MOUNTED' => 'Backup directory is not mounted',
'bac_ERR_POST_BACKUP' => 'Error occurred during post-backup actions.',
'bac_ERR_PRE_BACKUP' => 'Error occurred during pre-backup actions.',
'bac_ERR_PRE_RESTORE' => 'Error occurred during pre-restore actions.',
'bac_ERR_POST_BACKUP' => 'Error occurred during post-backup actions.',
'bac_RESTORE_SERVER_CONFIG' => 'Restore server configuration',
'bac_DESKTOP_RESTORE_DESC' => 'This process will upload a server backup file from your local desktop to your server and restore the configuration and user data files. <B>The restore should be performed on a freshly installed server</B>.',
'bac_ERR_READING_FILE' => 'There was an error in reading the backup file.',
'bac_ERR_RESTORING_FROM_TAPE' => 'Error occurred restoring files from tape.',
'bac_ERR_RESTORING_FROM_WORKSTN' => 'Error occurred restoring files from workstation.',
'bac_ERR_RESTORING_GID' => 'Error occurred while restoring gid of "www"',
'bac_ERR_RESTORING_INITIAL_GRP' => 'Error occurred while restoring initial group of "www".',
'bac_ERR_UPDATING_CONF_AFTER_TAPE_RESTORE' => 'Error occurred while updating system configuration after tape
restore.',
'bac_ERR_UPDATING_CONF_AFTER_WORKSTN_RESTORE' => 'Error occurred while updating system configuration after workstation
restore.',
'bac_ERR_WHILE_UNMOUNTING' => 'Error occurs when unmounting distant share',
'bac_ERROR_READING_FILE' => 'Error while reading files from',
'bac_ERROR_WHEN_TESTING_REMOTE_SERVER' => 'The parameters have been saved, however the remote host is not reachable, please check your settings.',
'bac_FILE_TO_RESTORE' => 'Backup file to restore from',
'bac_FILES_HAVE_BEEN_RESTORED' => 'The following files and directories have been restored:',
'bac_FILES_IN_BACKUP' => 'The following files are considered in the backup :',
'bac_FILTER_EXPRESSION' => 'Names filtered by',
'bac_FINISHED_AT' => 'and finished at: ',
'bac_FREE_SPACE' => 'You have approximately [_1] free space on the server.
Check that desktop backup file is less than [_2] before
commencing the restore.',
'bac_MUST_REBOOT_AFTER_RESTORE' => 'After the restore completes you must reboot the server.',
'bac_FILE_TO_RESTORE' => 'Backup file to restore from',
'bac_VERIFY_BACKUP_DESC' => '
<p>This option will display the names of all files
in a previously created desktop backup file. You
can use this option to verify the contents of the
backup file.</p> ',
'bac_SELECT_BACKUP_FILE' => 'Select backup file',
'bac_VERIFY' => 'Verify',
'bac_RESTORE_CANNOT_PROCEED' => 'Unable to proceed with restore of server configuration',
'bac_ANOTHER_RESTORE_IN_PROGRESS' => 'Another restore is in progress. Please try again later.',
'bac_RESTORE_IN_PROGRESS' => 'Restore in progress',
'bac_RESTORE_IN_PROGRESS_DESC' => 'After the restore completes you must reboot the server. Your restore is
complete when the words "Restore complete" appear at the bottom of your screen.
',
'bac_FILES_HAVE_BEEN_RESTORED' => 'The following files and directories have been restored:',
'bac_RESTORE_FAILED_MSG' => 'Restore failed! There was an error in reading the backup file.',
'bac_RESTORE_COMPLETE' => 'Restore complete',
'bac_ERR_RESTORING_GID' => 'Error occurred while restoring gid of \'www\'',
'bac_ERR_RESTORING_INITIAL_GRP' => 'Error occurred while restoring initial group of \'www\'.',
'bac_RESTORE_FAILED' => 'Restore failed! The backup file was incomplete.',
'bac_COULD_NOT_EXEC_PIPELINE' => 'Could not execute backup pipeline: ',
'bac_COULD_NOT_DECODE' => 'Could not decode backup file: ',
'bac_FILES_IN_BACKUP' => 'The following files are considered in the backup :',
'bac_VERIFY_COMPLETE' => 'Verification is complete',
'bac_BACKUP_FILE_INCOMPLETE' => 'The backup file was incomplete',
'bac_ERR_READING_FILE' => 'There was an error in reading the backup file.',
'bac_ENABLE_DISABLE_TAPE' => 'Enable/Disable Nightly Tape Backup',
'bac_TAPE_CONFIG_DESC' => '<p>Select whether you wish to enable nightly backups. Then indicate the
desired times for the backup and the load tape reminder.</p> <p>The tape
backup requires a supported tape drive. A warning message will be sent to
the administrator at the designated reminder time if the tape drive is
empty.</p>',
'bac_ENABLE_TAPE_BACKUP' => 'Enable tape backup',
'bac_TAPE_BACKUP_TIME' => 'Tape backup time of day (hour/min)',
'bac_FULL_ONLY_ON' => 'Full backup is allowed on',
'bac_HOURS' => 'hours.',
'bac_INC_ONLY_TIMEOUT' => 'Don"t timeout full backup sessions',
'bac_LOAD_TAPE_REMINDER_TIME' => 'Load tape reminder time of day (hour/min)',
'bac_AM/PM' => 'AM/PM',
'bac_AM' => 'AM',
'bac_local removable disk' => 'Local removable disk',
'bac_LOGIN' => 'Login is ',
'bac_Mounted disk' => 'Mounted disk',
'bac_MUST_REBOOT_AFTER_RESTORE' => 'After the restore completes you must reboot the server.',
'bac_nfs' => 'nfs',
'bac_No suitable local devices found' => 'No suitable local devices found',
'bac_NO_BACKUPS_TO_RESTORE' => 'There is no backup set on configured workstation shared folder. Verify your configuration settings.',
'bac_NO_UID_FOR_NAME' => 'Could not get uid for user named: ',
'bac_NOW_RESTORING_FROM_TAPE' => 'Your server configuration and user data
files are now being restored from tape.',
'bac_NOW_RESTORING_FROM_WORKSTN' => 'Your server configuration and user data
files are now being restored from workstation shared folder.',
'bac_NUMBER_OF_FILES_IN_SET' => 'Daily backups in each set',
'bac_NUMBER_OF_SETS' => 'Number of rotating backup sets',
'bac_PAGE_REFRESH_IN' => 'This page will refresh to the status display in [_1] seconds, or
click <a href="/server-manager/cgi-bin/backup">here</a>.',
'bac_PASSWORD' => 'Password is ',
'bac_PM' => 'PM',
'bac_UPDATE_CONF' => 'Update',
'bac_UPDATING_TAPE_CONF' => 'Updating tape backup configuration',
'bac_ERR_INVALID_HOUR' => 'Error: invalid backup hour: ',
'bac_BETWEEN_0_AND_12' => 'Please choose an hour between 0 and 12.',
'bac_ERR_INVALID_MINUTE' => 'Error: invalid backup minute: ',
'bac_BETWEEN_0_AND_59' => 'Please choose a minute between 0 and 59.',
'bac_ERR_INVALID_REMINDER_HOUR' => 'Error: invalid reminder hour: ',
'bac_ERR_INVALID_REMINDER_MINUTE' => 'Error: invalid reminder minute: ',
'bac_ERR_CONF_BACKUP' => 'Error occurred during conf-backup event.',
'bac_SUCCESSFULLY_ENABLED_TAPE' => 'Successfully enabled tape backups',
'bac_WITH_BACKUP_TIME' => 'with backup time: ',
'bac_WITH_REMINDER_TIME' => 'and load tape reminder time: ',
'bac_SUCCESSFULLY_DISABLED' => 'Successfully disabled tape backups',
'bac_READ_COMPLETE' => 'You can choose all the directories and files you want to restore in the displayed list
(use ctrl or shift for multiple selection). <br/> <b>Warning :</b> If you select a directory,
all contained files and directories will be restored.<p/>
By default the most recent version of selected files is restored, but if you specify a date
in the format <i>~[~[~[yyyy/~]mm/~]dd-~]hh:mm~[:ss~]</i> the process
will restore only the most recent version modified <b>before the given date</b>.',
'bac_REFRESH_THIS_DISPLAY' => 'Refresh this display',
'bac_REMINDER_MESSAGE_AT' => 'Reminder messages will be sent at: ',
'bac_RESTORE_CANNOT_PROCEED' => 'Unable to proceed with restore of server configuration',
'bac_RESTORE_COMPLETE' => 'Restore complete',
'bac_RESTORE_COMPLETED' => 'A system restore has completed',
'bac_RESTORE_CONF_FROM_TAPE' => 'Restore server configuration from tape backup',
'bac_RESTORE_CONF_FROM_TAPE_DESC' => '<P>This process will restore the configuration and user data files from a
server tape backup. <B>The restore should be performed on a freshly installed server</B>.</P>
<P>Ensure that you have loaded the desired backup tape into the tape drive
before proceeding.</P>
<P>After the restore completes you must reboot the server.</P>',
'bac_RESTORE_FROM_TAPE' => 'Restore From Tape',
'bac_UNABLE_TO_RESTORE_CONF' => 'Unable to restore server configuration',
'bac_RESTORING_FROM_TAPE' => 'Restoring From Tape',
'bac_NOW_RESTORING_FROM_TAPE' => 'Your server configuration and user data
files are now being restored from tape.',
'bac_ERR_RESTORING_FROM_TAPE' => 'Error occurred restoring files from tape.',
'bac_ERR_UPDATING_CONF_AFTER_TAPE_RESTORE' => 'Error occurred while updating system configuration after tape
restore.',
'bac_COULD_NOT_FORK' => 'Could not fork: ',
'bac_SERVER_REBOOT' => 'Server reboot',
'bac_SERVER_WILL_REBOOT' => 'Your server will now reboot.',
'bac_NO_UID_FOR_NAME' => 'Could not get uid for user named: ',
'bac_PAGE_REFRESH_IN' => 'This page will refresh to the status display in [_1] seconds, or
click <a href="/server-manager/cgi-bin/backup">here</a>.',
'Backup or restore' => 'Backup or restore',
'bac_BACKUP_DESKTOP_TOO_BIG' => 'Your server has too much data for a reliable backup to desktop.',
'bac_WORKSTN_BACKUPS' => 'Workstation backups are ',
'bac_WKBACKUPS_RUN_AT' => 'Regular workstation backups will run at: ',
'bac_WORKSTN_CONFIGURE' => 'Configure workstation backup',
'bac_WORKSTN_VERIFY' => 'Verify workstation backup',
'bac_WORKSTN_RESTORE' => 'Restore from workstation',
'bac_CONFIGURE_WORKSTN_BACKUP' => 'Configure Workstation Backup',
'bac_ENABLE_DISABLE_WORKSTN' => 'Enable/Disable Daily Workstation Backup',
'bac_ENABLE_WORKSTN_BACKUP' => 'Enable Workstation Backup',
'bac_WORKSTN_BACKUP_TIME' => 'Workstation backup time of day (hour/min)',
'bac_UPDATING_WORKSTN_CONF' => 'Updating workstation backup configuration',
'bac_SUCCESSFULLY_ENABLED_WORKSTN' => 'Successfully enabled workstation backups',
'bac_SUCCESSFULLY_DISABLED_WORKSTN' => 'Successfully disabled workstation backups',
'bac_VERIFY_WORKSTN_BACKUP_FILE' => 'Verify workstation backup',
'bac_VERIFY_WORKSTN_BACKUP_DESC' => '<p>This option will display the names of all files
in a previously created workstation daily backup. You
can use this option to verify the contents of the
backup.<b>You must choose the backup you want to verify</b></p>
<p>Only files flagged with (Saved) are contained in the backup.</p>
<br/>Backup files are verified from shared folder :',
'bac_RESTORE_CONF_FROM_WORKSTN' => 'Restore server configuration from workstation backup',
'bac_RESTORE_CONF_FROM_WORKSTN_DESC' => '<p>This process will restore the configuration and user data files from a
Server workstation backup. <b>The restore
@@ -175,109 +180,104 @@ should be performed on a freshly installed Server</b>.</p>
before proceeding.</p>
<p>After the restore completes you must reboot the server.</p>
Backup will be restored from : ',
'bac_RESTORE_FAILED' => 'Restore failed! The backup file was incomplete.',
'bac_RESTORE_FAILED_MSG' => 'Restore failed! There was an error in reading the backup file.',
'bac_RESTORE_FROM_TAPE' => 'Restore From Tape',
'bac_RESTORE_FROM_WORKSTN' => 'Restore From Workstation',
'bac_RESTORE_IN_PROGRESS' => 'Restore in progress',
'bac_RESTORE_IN_PROGRESS_BEGAN_AT' => 'A system restore is in progress. It began at: ',
'bac_RESTORE_IN_PROGRESS_DESC' => 'After the restore completes you must reboot the server. Your restore is
complete when the words "Restore complete" appear at the bottom of your screen.
',
'bac_RESTORE_SERVER_CONFIG' => 'Restore server configuration',
'bac_RESTORE_VERIFY_FAILED' => 'Verify integrity failed',
'bac_RESTORING_FROM_TAPE' => 'Restoring From Tape',
'bac_RESTORING_FROM_WORKSTN' => 'Restoring From Workstation',
'bac_NOW_RESTORING_FROM_WORKSTN' => 'Your server configuration and user data
files are now being restored from workstation shared folder.',
'bac_ERR_RESTORING_FROM_WORKSTN' => 'Error occurred restoring files from workstation.',
'bac_ERR_UPDATING_CONF_AFTER_WORKSTN_RESTORE' => 'Error occurred while updating system configuration after workstation
restore.',
'bac_WORKSTN_NAME' => 'Workstation IP or hostname',
'bac_WORKSTN_BACKUP_SETTINGS' => 'Workstation Backup Settings',
'bac_SELECT_AN_ACTION' => 'Select an action',
'bac_SELECT_BACKUP_FILE' => 'Select backup file',
'bac_SELECT_DATE_BEFORE' => 'Restore most recent before',
'bac_SELECT_FILES_TO_RESTORE' => 'Select files to restore',
'bac_SELECT_VFS_TYPE' => 'Select the type of share for backup destination',
'bac_SERVER_REBOOT' => 'Server reboot',
'bac_SERVER_WILL_REBOOT' => 'Your server will now reboot.',
'bac_SHARED_FOLDER_NAME' => 'Backup share',
'bac_WORKSTN_LOGIN' => 'Login name',
'bac_STARTED_AT' => 'It began at: ',
'bac_SUCCESSFULLY_DISABLED' => 'Successfully disabled tape backups',
'bac_SUCCESSFULLY_DISABLED_WORKSTN' => 'Successfully disabled workstation backups',
'bac_SUCCESSFULLY_ENABLED_TAPE' => 'Successfully enabled tape backups',
'bac_SUCCESSFULLY_ENABLED_WORKSTN' => 'Successfully enabled workstation backups',
'bac_TAPE_BACKUP_TIME' => 'Tape backup time of day (hour/min)',
'bac_TAPE_BACKUPS' => 'Tape backups are ',
'bac_TAPE_CONFIG_DESC' => '<p>Select whether you wish to enable nightly backups. Then indicate the
desired times for the backup and the load tape reminder.</p> <p>The tape
backup requires a supported tape drive. A warning message will be sent to
the administrator at the designated reminder time if the tape drive is
empty.</p>',
'bac_TAPE_CONFIGURE' => 'Configure tape backup',
'bac_TAPE_RESTORE' => 'Restore from tape',
'bac_TESTED_BACKUP' => 'Testing integrity of backup',
'bac_TESTING_NEEDED_BACKUPS_FOR_RESTORE' => 'Testing all backups needed for a full restore with selected backup',
'bac_UNABLE_TO_RESTORE_CONF' => 'Unable to restore server configuration',
'bac_UPDATING_TAPE_CONF' => 'Updating tape backup configuration',
'bac_UPDATING_WORKSTN_CONF' => 'Updating workstation backup configuration',
'bac_VERIFY_BACKUP_DESC' => '
<p>This option will display the names of all files
in a previously created desktop backup file. You
can use this option to verify the contents of the
backup file.</p> ',
'bac_VERIFY_COMPLETE' => 'Verification is complete',
'bac_VERIFY_WORKSTN_BACKUP_DESC' => '<p>This option will display the names of all files
in a previously created workstation daily backup. You
can use this option to verify the contents of the
backup.<b>You must choose the backup you want to verify</b></p>
<p>Only files flagged with (Saved) are contained in the backup.</p>
<br/>Backup files are verified from shared folder :',
'bac_VERIFY_WORKSTN_BACKUP_FILE' => 'Verify workstation backup',
'bac_WITH_BACKUP_TIME' => 'with backup time: ',
'bac_WITH_REMINDER_TIME' => 'and load tape reminder time: ',
'bac_WKBACKUPS_RUN_AT' => 'Regular workstation backups will run at: ',
'bac_WORKSTATION_BACKUP_DEST' => 'Backup workstation settings',
'bac_CONFIGURE_WORKSTN_BACKUP_DESC' => 'You can set the number of
successive backup sets to keep on the workstation, with automatic rotation.
Each set may contain saved data for several consecutive days.
In this case first backup of the set is full backup, others daily backups are
incremental. You can also set a time limit for each backup session or for incremental
backups only. When this limit occurs, backup is cleanly stopped and the next
incremental backup will safely continue with unsaved and modified datas.',
'bac_ERR_INVALID_WORKSTN' => 'Invalid Workstation IP or Hostname ',
'bac_ERR_INVALID_FOLDER' => 'Invalid share name',
'bac_ERR_INVALID_LOGIN' => 'Invalid Login',
'bac_ERR_INVALID_PASSWORD' => 'Invalid Password',
'bac_ERR_ALREADY_MOUNTED' => 'Backup directory is already mounted',
'bac_ERR_MOUNTING_SMBSHARE' => 'Unable to mount workstation shared folder',
'bac_ERR_NOT_MOUNTED' => 'Backup directory is not mounted',
'bac_WORKSTATION_BACKUP_SETCONF' => 'Create or modify workstation backup configuration',
'bac_WORKSTN_BACKUP_COMPRESSION' => 'Compression level (0-9) of backup is ',
'bac_WORKSTN_BACKUP_DAYSINSET' => 'Number of daily backups contained in each set is ',
'bac_WORKSTN_BACKUP_DESC' => '<p>This panel displays the present workstation backup configuration. You can
change it in this panel and the next one.</p><p/>',
'bac_WORKSTN_BACKUP_ENABLED' => 'Backup is ',
'bac_WORKSTN_BACKUP_HOST' => 'Backup is made on LAN workstation ',
'bac_WORKSTN_BACKUP_INCONLY_TIMEOUT' => 'except full backups which are cleanly timed out after 24 hours',
'bac_WORKSTN_BACKUP_MNT' => 'Backup is made on mounted disk',
'bac_WORKSTN_BACKUP_NOT_CONFIGURED' => '<p>Presently, workstation backup is not configured. You can set this configuration
with this panel and the next one.</p><p/>',
'bac_WORKSTN_BACKUP_SETSNUM' => 'Number of rotating backup sets is ',
'bac_WORKSTN_BACKUP_SETTINGS' => 'Workstation Backup Settings',
'bac_WORKSTN_BACKUP_SHARE' => 'Destination backup share folder is ',
'bac_WORKSTN_BACKUP_TIME' => 'Workstation backup time of day (hour/min)',
'bac_WORKSTN_BACKUP_TIMEOUT' => 'Each daily backup session is cleanly timed out after ',
'bac_WORKSTN_BACKUP_TOD' => 'Daily backup occurs at ',
'bac_WORKSTN_BACKUP_USB' => 'Backup is made on local removable disk',
'bac_WORKSTN_BACKUP_VFSTYPE' => ' via ',
'bac_WORKSTN_BACKUPS' => 'Workstation backups are ',
'bac_WORKSTN_CONFIGURE' => 'Configure workstation backup',
'bac_WORKSTN_FULL_BACKUP_DAY' => 'Full backup session (new backup sets) is allowed only on',
'bac_WORKSTN_FULL_BACKUP_EVERYDAY' => 'Full backup sessions (new backup set) are allowed everyday',
'bac_WORKSTN_LOGIN' => 'Login name',
'bac_WORKSTN_NAME' => 'Workstation IP or hostname',
'bac_WORKSTN_NOT_SET' => 'You must first correctly configure your workstation backup',
'bac_NO_BACKUPS_TO_RESTORE' => 'There is no backup set on configured workstation shared folder. Verify your configuration settings.',
'bac_NUMBER_OF_SETS' => 'Number of rotating backup sets',
'bac_NUMBER_OF_FILES_IN_SET' => 'Daily backups in each set',
'bac_ERR_INVALID_SETS_NUMBER' => 'Sets number must be 1 or greater',
'bac_ERR_INVALID_FILES_IN_SET_NUMBER' => 'This number must be 1 or greater. First backup in set is <b>full</b> others are <b>incrementals</b>',
'bac_WORKSTN_TIMEOUT' => 'Optional backup session timeout (hours)',
'bac_INC_ONLY_TIMEOUT' => 'Don\'t timeout full backup sessions',
'bac_ERR_INVALID_TIMEOUT' => 'Maximum backup time must be set between 1 and 24 hours',
'bac_ERR_NO_HOST_DIR' => 'No directory for your host in shared folder. Maybe your host name is different from backup ones',
'bac_ERROR_READING_FILE' => 'Error while reading files from',
'bac_WORKSTN_SEL_RESTORE' => 'Selective file restore from workstation',
'bac_WORKSTN_SELECTIVE_RESTORE' => 'Workstation selective file restore',
'bac_ALL_BACKUPS' => 'All backups',
'bac_WORKSTN_RESTORE' => 'Restore from workstation',
'bac_WORKSTN_SEL_REST_DESC' => 'This process will restore only specified files and directories. You must first choose
the backup from which the files will be restored. If you don\'t know in which backup
are the required files, you can select \'All backups\' option. <br/><br/>
the backup from which the files will be restored. If you don"t know in which backup
are the required files, you can select "All backups" option. <br/><br/>
The next panel will display available files and directories,
so you can choose the ones to restore. To restrict the number of files and directories
displayed in this panel, you have the option to give now a filtering expression,
applied as a regular expression to the displayed names.<br/><br/>
You have the responsibility not to restore files which could break the
functioning of your server.<br/> <br/>Currently, files will be restored from :',
'bac_BACKUP_CHOICE' => 'Selecting files to display',
'bac_SELECT_DATE_BEFORE' => 'Restore most recent before',
'bac_FILTER_EXPRESSION' => 'Names filtered by',
'bac_READ_COMPLETE' => 'You can choose all the directories and files you want to restore in the displayed list
(use ctrl or shift for multiple selection). <br/> <b>Warning :</b> If you select a directory,
all contained files and directories will be restored.<p/>
By default the most recent version of selected files is restored, but if you specify a date
in the format <i>~[~[~[yyyy/~]mm/~]dd-~]hh:mm~[:ss~]</i> the process
will restore only the most recent version modified <b>before the given date</b>.',
'bac_ERR_INVALID_SELDATE' => 'Date format is invalid, must be ~[~[~[yyyy/~]mm/~]dd-~]hh:mm~[:ss~]. ie: 2005/12/31-08:23:32 or
10-08:32 or 08:32',
'bac_SELECT_FILES_TO_RESTORE' => 'Select files to restore',
'bac_ERR_WHILE_UNMOUNTING' => 'Error occurs when unmounting distant share',
'bac_ERR_DAR_CATALOG' => 'Error when using Dar catalog',
'bac_COMPRESSION_LEVEL' => 'Backup compression level ~[0-9~]',
'bac_FULL_ONLY_ON' => 'Full backup is allowed on',
'bac_ERR_INVALID_COMPRESSION' => 'Compression level must be set between 0 (no compression) and 9 (maximum compression)',
'bac_DOW' => 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday Everyday',
'bac_CONFIGURATION_TO_BE_DONE' => 'Please configure the backup settings.',
'bac_WORKSTN_BACKUP_DESC' => '<p>This panel displays the present workstation backup configuration. You can
change it in this panel and the next one.</p><p/>',
'bac_WORKSTN_BACKUP_NOT_CONFIGURED' => '<p>Presently, workstation backup is not configured. You can set this configuration
with this panel and the next one.</p><p/>',
'bac_WORKSTN_BACKUP_ENABLED' => 'Backup is ',
'bac_WORKSTN_BACKUP_USB' => 'Backup is made on local removable disk',
'bac_WORKSTN_BACKUP_MNT' => 'Backup is made on mounted disk',
'bac_WORKSTN_BACKUP_HOST' => 'Backup is made on LAN workstation ',
'bac_WORKSTN_BACKUP_VFSTYPE' => ' via ',
'bac_WORKSTN_BACKUP_SHARE' => 'Destination backup share folder is ',
'bac_WORKSTN_BACKUP_TOD' => 'Daily backup occurs at ',
'bac_LOGIN' => 'Login is ',
'bac_PASSWORD' => 'Password is ',
'bac_WORKSTN_BACKUP_SETSNUM' => 'Number of rotating backup sets is ',
'bac_WORKSTN_BACKUP_DAYSINSET' => 'Number of daily backups contained in each set is ',
'bac_WORKSTN_BACKUP_COMPRESSION' => 'Compression level (0-9) of backup is ',
'bac_WORKSTN_BACKUP_TIMEOUT' => 'Each daily backup session is cleanly timed out after ',
'bac_WORKSTN_BACKUP_INCONLY_TIMEOUT' => 'except full backups which are cleanly timed out after 24 hours',
'bac_WORKSTN_FULL_BACKUP_EVERYDAY' => 'Full backup sessions (new backup set) are allowed everyday',
'bac_WORKSTN_FULL_BACKUP_DAY' => 'Full backup session (new backup sets) is allowed only on',
'bac_WORKSTATION_BACKUP_SETCONF' => 'Create or modify workstation backup configuration',
'bac_SELECT_VFS_TYPE' => 'Select the type of share for backup destination',
'bac_ERR_NO_USB_DISK' => 'Error : No removable disk available. Please connect a removable disk or select another type of workstation backup.',
'bac_ERR_NO_MOUNTED_DISK' => 'Error : No mounted disk available. Please mount a disk or select another type of workstation backup.',
'bac_HOURS' => 'hours.',
'bac_ERR_NO_FULL_BACKUP' => 'Aborting restore because needed full backup is missing or unreadable.',
'bac_ERR_NO_INC_BACKUP' => 'Aborting restore because the set has missing or unreadable incremental backup number',
'bac_CHECK_TO_VERIFY_FULL_RESTORE' => 'Check here to test integrity of all backups needed for a full restore with the selected backup ',
'bac_TESTING_NEEDED_BACKUPS_FOR_RESTORE' => 'Testing all backups needed for a full restore with selected backup',
'bac_TESTED_BACKUP' => 'Testing integrity of backup',
'bac_RESTORE_VERIFY_FAILED' => 'Verify integrity failed',
'bac_CHECK_INTEGRITY_WARNING' => 'Warning : For large backups, checking integrity may be a long task and should be made with daily workstation backup disabled.',
'bac_cifs' => 'cifs',
'bac_nfs' => 'nfs',
'bac_local removable disk' => 'Local removable disk',
'bac_Mounted disk' => 'Mounted disk',
'bac_ERROR_WHEN_TESTING_REMOTE_SERVER' => 'The parameters have been saved, however the remote host is not reachable, please check your settings.',
'bac_ERR_EXTRACT' => 'Error when extracting with Dar',
'bac_WORKSTN_SEL_RESTORE' => 'Selective file restore from workstation',
'bac_WORKSTN_SELECTIVE_RESTORE' => 'Workstation selective file restore',
'bac_WORKSTN_TIMEOUT' => 'Optional backup session timeout (hours)',
'bac_WORKSTN_VERIFY' => 'Verify workstation backup',
'bac_X_BACKUP_OR_RESTORE' => 'X Backup or restore server data',
'bac_YOU_MUST_REBOOT' => 'You must reboot the server to activate any configuration changes that were
made as a result of this restore.',
'Backup or restore' => 'Backup or restore',

View File

@@ -1,24 +1,27 @@
'bugr_FORM_TITLE' => 'Report a Bug',
'bugr_DO_NOT_PANIC' => 'Don\'t Panic!',
'bugr_SME_EXPERIENCE' => 'Unfortunately there is no software without bugs, and you probably came to this page because of an issue you are experiencing with your SME-server installation.',
'bugr_PLEASE_REPORT_HERE' => 'In order to help developers to diagnose and fix your issue, please download one of the following text templates, fill it out and paste it into your bug report at',
'bugr_USE_TEMPLATE' => 'Please refer to the following link on how to report efficiency a bug and use its template',
'bugr_FOLLOWING_REPORT_MIGHT_HELP' => 'It will also help if you provide some vital information on the configuration of your SME-server in your bug report. By clicking on the "Create configuration report" button below, you can create and download a text file containing this information. Please attach this file to your bug report as well.',
'bugr_REPORT_CONTENT' => 'The report will contain the following information',
'bugr_SME_VERSION' => 'Koozali SME Server version',
'bugr_SERVER_MODE' => 'Server mode',
'bugr_PREVIOUS_SERVER_MODE' => 'Previous server mode',
'bugr_KERNEL_AND_ARCH' => 'Current running kernel version and architecture',
'bugr_INSTALLED_RPMS' => 'A list of additional RPMs installed on your server',
'bugr_ALTERED_TEMPLATES' => 'A list of SME templates that have been altered on your server from a base install',
#
# Lex file for Bugreport generated on 2025-07-17 09:52:30
#
'bugr_ALTERED_EVENTS' => 'A list of SME events that have been altered on your server from a base install',
'bugr_YUM_REPOS' => 'A list of additional software repositories configured on your server',
'bugr_PRIVACY' => 'No privacy related data (ie. users, passwords, IP addresses) will be included in the report.',
'bugr_CREATE_REPORT' => 'Create configuration report',
'bugr_DONATING' => 'Have you considered donating?',
'bugr_ALTERED_TEMPLATES' => 'A list of SME templates that have been altered on your server from a base install',
'bugr_AWARE_SME' => 'You are probaly aware that SME server is developed and supported by a collaborative community of volunteers from all over the world. While SME server is free to download and use, maintaining the infrastructure behind the project (eg. hosting the forums and wiki, providing repositories and build servers etc.) costs real money in the real world.',
'bugr_YOUR_HELP' => 'In very much the same way you need us to address your current issue, we need YOUR help to keep this project alive!',
'bugr_CONSIDER_DONATING' => 'Please consider donating to the project by clicking on the image link below:',
'bugr_THANK_YOU' => 'Thank you for your support!',
'bugr_CREATE_REPORT' => 'Create configuration report',
'bugr_DO_NOT_PANIC' => 'Don"t Panic!',
'bugr_DONATING' => 'Have you considered donating?',
'bugr_Download this report' => 'Download this report !',
'bugr_FOLLOWING_REPORT_MIGHT_HELP' => 'It will also help if you provide some vital information on the configuration of your SME-server in your bug report. By clicking on the "Create configuration report" button below, you can create and download a text file containing this information. Please attach this file to your bug report as well.',
'bugr_FORM_TITLE' => 'Report a Bug',
'bugr_INSTALLED_RPMS' => 'A list of additional RPMs installed on your server',
'bugr_KERNEL_AND_ARCH' => 'Current running kernel version and architecture',
'bugr_PLEASE_REPORT_HERE' => 'In order to help developers to diagnose and fix your issue, please download one of the following text templates, fill it out and paste it into your bug report at',
'bugr_PREVIOUS_SERVER_MODE' => 'Previous server mode',
'bugr_PRIVACY' => 'No privacy related data (ie. users, passwords, IP addresses) will be included in the report.',
'bugr_REPORT_CONTENT' => 'The report will contain the following information',
'bugr_SERVER_MODE' => 'Server mode',
'bugr_SME_EXPERIENCE' => 'Unfortunately there is no software without bugs, and you probably came to this page because of an issue you are experiencing with your SME-server installation.',
'bugr_SME_VERSION' => 'Koozali SME Server version',
'bugr_THANK_YOU' => 'Thank you for your support!',
'bugr_USE_TEMPLATE' => 'Please refer to the following link on how to report efficiency a bug and use its template',
'bugr_YOUR_HELP' => 'In very much the same way you need us to address your current issue, we need YOUR help to keep this project alive!',
'bugr_YUM_REPOS' => 'A list of additional software repositories configured on your server',
'Report a bug' => 'Report a bug',

View File

@@ -1,12 +1,12 @@
'clm_FORM_TITLE' => 'Antivirus settings',
'clm_LABEL_FILESYSTEM_SCAN_PERIOD' => 'Scan filesystem',
#
# Lex file for Clamav generated on 2025-07-17 09:52:30
#
'clm_DESC_FILESYSTEM_SCAN_PERIOD' => '<h2>General Settings</h2>
If this option is enabled then the filesystem will be
scanned for viruses.A report of any found viruses will be
scanned for viruses. A report of any found viruses will be
emailed to the administrator.',
'clm_LABEL_QUARANTINE' => 'Quarantine infected files',
'clm_FORM_TITLE' => 'Antivirus settings',
'clm_LABEL_CLAM_VERSIONS' => 'ClamAV and db versions',
'clm_WEEKLY' => 'Weekly',
'clm_NEVER' => 'Never',
'clm_DAILY' => 'Daily',
'clm_LABEL_FILESYSTEM_SCAN_PERIOD' => 'Scan filesystem',
'clm_LABEL_QUARANTINE' => 'Quarantine infected files',
'clm_SUCCESS' => 'The new clamav antivirus settings have been saved.',

View File

@@ -1,59 +1,65 @@
#
# Lex file for Datetime generated on 2025-07-17 09:52:31
#
'dat_APRIL' => 'April',
'dat_AUGUST' => 'August',
'dat_BETWEEN_0_AND_59' => 'Please choose a minute between 0 and 59.',
'dat_BETWEEN_1_AND_12' => 'Please choose an hour between 1 and 12.',
'dat_BETWEEN_1_AND_31' => 'Please choose a day between 1 and 31.',
'dat_COULD_NOT_OPEN_TZ_FILE' => 'Error: Could not open timezone file for reading: ',
'dat_CURRENT_SETTING' => 'Current setting',
'dat_DECEMBER' => 'December',
'dat_ERR_CHANGING_TS' => 'Error while changing network time server setting',
'dat_ERR_SETTING_CLOCK' => 'Error occurred while setting system time and hardware clock.',
'dat_FEBRUARY' => 'February',
'dat_FORM_TITLE' => 'Date and time configuration',
'dat_FOUR_DIGIT_YEAR' => 'Please choose a four-digit year between 1900 and 2200.',
'dat_INITIAL_DESC' => 'This is where you configure the date and time of this server. You may use an existing network time server or
manually set the date and time for your time zone.',
'dat_SET_DATE_TITLE' => 'Set Date and Time',
'dat_COULD_NOT_OPEN_TZ_FILE' => 'Error: Could not open timezone file for reading: ',
'dat_Invalid_date' => 'Invalid date',
'dat_INVALID_DAY' => 'Error: invalid day of month: ',
'dat_INVALID_HOUR' => 'Error: invalid hour: ',
'dat_INVALID_MINUTE' => 'Error: invalid minute: ',
'dat_INVALID_MONTH' => 'Error: invalid month',
'dat_INVALID_NTP_ADDR' => 'Invalid NTP server address: ',
'dat_INVALID_NTP_SERVER' => 'Invalid NTP server, the server <b>will not</b> try to synchronize from a time server.',
'dat_INVALID_SECOND' => 'Error: invalid second',
'dat_INVALID_YEAR' => 'Error: invalid year: ',
'dat_JANUARY' => 'January',
'dat_FEBRUARY' => 'February',
'dat_MARCH' => 'March',
'dat_APRIL' => 'April',
'dat_MAY' => 'May',
'dat_JUNE' => 'June',
'dat_JULY' => 'July',
'dat_AUGUST' => 'August',
'dat_SEPTEMBER' => 'September',
'dat_OCTOBER' => 'October',
'dat_NOVEMBER' => 'November',
'dat_DECEMBER' => 'December',
'dat_NEW_M/D/Y' => 'New month/day/year:',
'dat_JUNE' => 'June',
'dat_manually_set' => 'Set manually',
'dat_MARCH' => 'March',
'dat_MAY' => 'May',
'dat_MONTH_BETWEEN_1_AND_12' => 'Please choose a month value between 1 and 12.',
'dat_NETWORK_TIME_SERVER' => 'Network Time Server',
'dat_NEW_DATE_AND_TIME' => 'New date and time setting:',
'dat_NEW_H/M/S' => 'New hour/min/sec:',
'dat_AM/PM_AND_TZ' => 'AM/PM and time zone:',
'dat_NTP_ENABLE_DESC' => 'The server can periodically synchronize the system clock to a network time protocol (NTP) server. If you select this option, enter the hostname or IP address of the NTP server below.',
'dat_NEW_M/D/Y' => 'New month/day/year:',
'dat_NOVEMBER' => 'November',
'dat_NTP_CONFIGURE_DESC' => 'The server is periodically synchronizing the system clock to the network time protocol (NTP) server specified below. To synchronize to a different NTP server, enter a different hostname or IP address in the field below.',
'dat_NTP_CONFIGURE_TITLE' => 'Configure Network Time Server',
'dat_NTP_DISABLE_DESC' => 'Choose this option to stop syncronizing the system clock to the NTP
server.When the NTP service is disabled, you can set the system date and time manually from this page.',
'dat_NTP_DISABLE_TITLE' => 'Disable Network Time Server',
'dat_NTP_ENABLE_DESC' => 'The server can periodically synchronize the system clock to a network time protocol (NTP) server. If you select this option, enter the hostname or IP address of the NTP server below.',
'dat_NTP_ENABLE_TITLE' => 'Enable Network Time Server',
'dat_NTP_SERVER' => 'NTP Server',
'dat_VERIFY_DATE_AND_TIME' => 'Verify date and time',
'dat_NEW_DATE_AND_TIME' => 'New date and time setting:',
'dat_SETTING_DATE_AND_TIME' => 'Setting date and time',
'dat_INVALID_DAY' => 'Error: invalid day of month: ',
'dat_BETWEEN_1_AND_31' => 'Please choose a day between 1 and 31.',
'dat_INVALID_YEAR' => 'Error: invalid year: ',
'dat_FOUR_DIGIT_YEAR' => 'Please choose a four-digit year between 1900 and 2200.',
'dat_INVALID_HOUR' => 'Error: invalid hour: ',
'dat_BETWEEN_1_AND_12' => 'Please choose an hour between 1 and 12.',
'dat_INVALID_MINUTE' => 'Error: invalid minute: ',
'dat_BETWEEN_0_AND_59' => 'Please choose a minute between 0 and 59.',
'dat_INVALID_SECOND' => 'Error: invalid second',
'dat_MONTH_BETWEEN_1_AND_12' => 'Please choose a month value between 1 and 12.',
'dat_INVALID_MONTH' => 'Error: invalid month',
'dat_UPDATING_CLOCK' => 'System clock is being updated. Please wait for a few seconds,
then click <A HREF="datetime?page=1&wherenext=Verify" TARGET="main">here</A>
to verify changes.',
'dat_ERR_SETTING_CLOCK' => 'Error occurred while setting system time and hardware clock.',
'dat_ntp_server' => 'NTP server',
'dat_NTP_Server_URL' => 'NTP Server URL:',
'dat_OCTOBER' => 'October',
'dat_SEPTEMBER' => 'September',
'dat_SERVER_DISABLED' => 'Network time server disabled successfully',
'dat_SERVER_DISABLED_DESC' => 'You have disabled this service: The server will rely on its internal
clock, and <b>will not</b> try to synchronize from a time server.',
'dat_ERR_CHANGING_TS' => 'Error while changing network time server setting',
'dat_INVALID_NTP_ADDR' => 'Invalid NTP server address: ',
'dat_SET_DATE_TITLE' => 'Set Date and Time',
'dat_set_manually' => 'Set Date and Time:',
'dat_SETTING_DATE_AND_TIME' => 'Setting date and time',
'dat_SETTINGS_CHANGED' => 'Network time server setting changed successfully',
'dat_SYNC_WITH' => 'This server is now configured to synchronize periodically
(via the Internet) with:',
'dat_INVALID_NTP_SERVER' => 'Invalid NTP server, the server <b>will not</b> try to synchronize from a time server.',
'dat_NETWORK_TIME_SERVER' => 'Network Time Server',
'dat_NTP_CONFIGURE_TITLE' => 'Configure Network Time Server',
'dat_NTP_ENABLE_TITLE' => 'Enable Network Time Server',
'dat_NTP_DISABLE_TITLE' => 'Disable Network Time Server',
'dat_CURRENT_SETTING' => 'Current setting',
'dat_The_time_is_currently' => 'The time is currently:',
'dat_TZ' => 'Time zone:',
'dat_UPDATING_CLOCK' => 'System clock is being updated',
'dat_VERIFY_DATE_AND_TIME' => 'Verify date and time',
'Date and time' => 'Date and time',

View File

@@ -1,28 +1,30 @@
'dir_FORM_TITLE' => 'Change LDAP directory settings',
'dir_LABEL_ROOT' => 'Server root',
'dir_DESCRIPTION' => 'The LDAP server provides a network-available listing of the user accounts
and groups on your server, and can be accessed using an LDAP client such as the Address Book feature
in Netscape Communicator. Configure your LDAP client with the local IP address of your server,
port number 389, and the server root parameter shown below.',
'dir_DESC_DIRECTORY_ACCESS' => ' You can control access to your LDAP directory:
the private setting allows access only from your local network, and the public setting allows access from anywhere on the Internet. ',
'dir_DIRECTORY_ACCESS' => 'LDAP directory access',
#
# Lex file for Directory generated on 2025-07-17 09:52:31
#
'dir_CITY' => 'Default City',
'dir_COMPANY' => 'Default company',
'dir_DEPARTMENT' => 'Default department',
'dir_DESC_DEPARTMENT' => 'These fields are the LDAP defaults for your organization.
Whenever you create a new user account, you will be prompted
to enter all of these fields (they can be different for each
user) but the values you set here
will show up as defaults. This is a convenience to make it
faster to create user accounts.',
'dir_DEPARTMENT' => 'Default department',
'dir_COMPANY' => 'Default company',
'dir_STREET' => 'Default Street address',
'dir_CITY' => 'Default City',
'dir_PHONENUMBER' => 'Default Phone Number',
'dir_DESC_DIRECTORY_ACCESS' => ' You can control access to your LDAP directory:
the private setting allows access only from your local network, and the public setting allows access from anywhere on the Internet. ',
'dir_DESC_EXISTING' => 'You can either leave existing user accounts as they are, using the above defaults only for
new users, or you can apply the above defaults to all existing users as well.',
'dir_DESCRIPTION' => 'The LDAP server provides a network-available listing of the user accounts
and groups on your server, and can be accessed using an LDAP client such as the Address Book feature
in Netscape Communicator. Configure your LDAP client with the local IP address of your server,
port number 389, and the server root parameter shown below.',
'dir_DIRECTORY_ACCESS' => 'LDAP directory access',
'dir_EXISTING' => 'Existing users',
'dir_SUCCESS' => 'The new LDAP default settings have been saved.',
'dir_FORM_TITLE' => 'Change LDAP directory settings',
'dir_LABEL_ROOT' => 'Server root',
'dir_LEAVE' => 'Leave as they are',
'dir_PHONENUMBER' => 'Default Phone Number',
'dir_STREET' => 'Default Street address',
'dir_SUCCESS' => 'The new LDAP default settings have been saved.',
'dir_UPDATE' => 'Update with new defaults',
'Directory' => 'Directory',

View File

@@ -1,59 +1,60 @@
#
# Lex file for Domains generated on 2025-07-17 09:52:31
#
'dom_ABOUT_TO_REMOVE' => 'Are you sure you wish to remove this domain ?',
'dom_ADD_DOMAIN' => 'Add domain',
'dom_FORM_TITLE' => 'Manage domains',
'dom_FORM_DESCRIPTION' => 'When you create a domain, your server will be able to
receive e-mail for that domain and will also be able to host a
web site for that domain.',
'dom_ADD_DOMAIN' => 'Add domain',
'dom_NO_VIRTUAL_DOMAINS' => 'There are no domains in the system',
'dom_CURRENT_DOMAINS' => 'Current list of domains',
'dom_PRIMARY_SITE' => 'primary site',
'dom_CONTENT' => '[_1] i-bay',
'dom_CREATE_TITLE' => 'Create a new domain',
'dom_CONTENT_FIELD_DESCRIPTION' => 'For the web site, you may choose your primary web site or any
i-bay as the content.',
'dom_DOMAIN_NAME_VALIDATION_ERROR' => 'Error: unexpected or missing characters in domain name
[_1].The domain name should contain one or more
letters, numbers, periods and minus signs.Did not create new domain.',
'dom_DOMAIN_DESCRIPTION_VALIDATION_ERROR' => 'Error: unexpected or missing characters in domain description
[_1]. Did not create new domain.',
'dom_DOMAIN_IN_USE_ERROR' => 'Error: domain [_1] is already in use.Did not create
new domain.',
'dom_SYSTEM_DOMAIN_ERROR' => 'Error: domain [_1] is your system domain name.You
cannot have a domain with the same name.Did not create new domain.',
'dom_SUCCESSFULLY_CREATED' => 'Successfully created domain [_1].Your web
server is now being restarted.The links on this page will be
inactive until the web server restart is complete.',
'dom_MODIFY_TITLE' => 'Modify domain',
'dom_NONEXISTENT_DOMAIN_ERROR' => 'Error: [_1] is not an existing domain.',
'dom_SUCCESSFULLY_MODIFIED' => 'Successfully modified domain [_1].Your web
server is now being restarted.The links on this page will be inactive until the web server restart is complete.',
'dom_REMOVE_TITLE' => 'Remove domain',
'dom_REMOVE_DESCRIPTION' => 'You are about to remove the domain "[_1]" ([_2]).',
'dom_ABOUT_TO_REMOVE' => 'Are you sure you wish to remove this domain ?',
'dom_ERROR_WHILE_REMOVING_DOMAIN' => 'Error: internal failure while removing domain [_1].',
'dom_SUCCESSFULLY_DELETED' => 'Successfully deleted domain [_1]. Your web server
is now being restarted.The links on this page will be inactive
until the web server restart is complete.',
'dom_DESC_CORPORATE_DNS_CURRENT' => 'Corporate DNS Settings',
'dom_DOMAINS_PAGE_CORPORATE_DNS' => 'Modify corporate DNS settings',
'dom_corporate' => 'Corporate DNS servers',
'dom_CREATE_TITLE' => 'Create a new domain',
'dom_CURRENT_DOMAINS' => 'Current list of domains',
'dom_DESC_CORPORATE_DNS' => 'If this server does not have access to the Internet, or
you have special requirements for DNS resolution,
enter the DNS server IP addresses here.
These fields should be left blank unless
you have a specific reason to configure other DNS servers.
You should not enter the address of your ISP\'s DNS servers
You should not enter the address of your ISP"s DNS servers
here, as the server is capable of resolving all
Internet DNS names without this additional configuration.',
'dom_LABEL_CORPORATE_DNS_PRIMARY' => 'Primary corporate DNS server',
'dom_LABEL_CORPORATE_DNS_SECONDARY' => 'Secondary corporate DNS server',
'dom_DESC_CORPORATE_DNS_CURRENT' => 'Corporate DNS Settings',
'dom_DESC_NAMESERVERS' => 'You can select whether this domain is resolved locally,
passed to the corporate DNS servers, or resolved by
the Internet DNS servers. The default will be correct
for most networks.',
'dom_DOMAIN_DESCRIPTION_VALIDATION_ERROR' => 'Error: unexpected or missing characters in domain description
[_1]. Did not create new domain.',
'dom_DOMAIN_IN_USE_ERROR' => 'Error: domain [_1] is already in use. Did not create
new domain.',
'dom_DOMAIN_NAME_VALIDATION_ERROR' => 'Error: unexpected or missing characters in domain name
[_1].The domain name should contain one or more
letters, numbers, periods and minus signs. Did not create new domain.',
'dom_DOMAINS_PAGE_CORPORATE_DNS' => 'Modify corporate DNS settings',
'dom_ERROR_WHILE_REMOVING_DOMAIN' => 'Error: internal failure while removing domain [_1].',
'dom_FORM_DESCRIPTION' => 'When you create a domain, your server will be able to
receive e-mail for that domain and will also be able to host a
web site for that domain.',
'dom_FORM_TITLE' => 'Manage domains',
'dom_internet' => 'Internet DNS servers',
'dom_LABEL_CORPORATE_DNS_PRIMARY' => 'Primary corporate DNS server',
'dom_LABEL_CORPORATE_DNS_SECONDARY' => 'Secondary corporate DNS server',
'dom_LABEL_NAMESERVERS' => 'Domain DNS servers',
'dom_localhost' => 'Resolve locally',
'dom_internet' => 'Internet DNS servers',
'dom_corporate' => 'Corporate DNS servers',
'dom_MODIFY_TITLE' => 'Modify domain',
'dom_NO_VIRTUAL_DOMAINS' => 'There are no domains in the system',
'dom_NONEXISTENT_DOMAIN_ERROR' => 'Error: [_1] is not an existing domain.',
'dom_PRIMARY_SITE' => 'primary site',
'dom_REMOVE_DESC' => 'You are about to remove the domain ',
'dom_REMOVE_DESC2' => ' Are you sure you wish to remove this Domain ? ',
'dom_REMOVE_DESCRIPTION' => 'You are about to remove the domain "[_1]" ([_2]).',
'dom_REMOVE_TITLE' => 'Remove domain',
'dom_SUCCESSFULLY_CREATED' => 'Successfully created domain [_1].Your web
server is now being restarted. The links on this page will be
inactive until the web server restart is complete.',
'dom_SUCCESSFULLY_DELETED' => 'Successfully deleted domain [_1]. Your web server
is now being restarted. The links on this page will be inactive
until the web server restart is complete.',
'dom_SUCCESSFULLY_MODIFIED' => 'Successfully modified domain [_1].Your web
server is now being restarted. The links on this page will be inactive until the web server restart is complete.',
'dom_SYSTEM_DOMAIN_ERROR' => 'Error: domain [_1] is your system domain name. You
cannot have a domain with the same name. Did not create new domain.',

View File

@@ -1,129 +1,60 @@
'mai_FORM_TITLE' => 'E-mail settings',
'E-mail' => 'E-mail',
'mai_SUCCESS' => 'The new e-mail settings have been saved.',
'mai_NEVER' => 'not at all',
'mai_EVERY5MIN' => 'Every 5 minutes',
'mai_EVERY15MIN' => 'Every 15 minutes',
'mai_EVERY30MIN' => 'Every 30 minutes',
'mai_EVERYHOUR' => 'Every hour',
'mai_EVERY2HRS' => 'Every 2 hours',
'mai_STANDARD' => 'Standard (SMTP)',
'mai_ETRN' => 'ETRN (SMTP with client request)',
'mai_DEFAULT' => 'Default',
'mai_SPECIFY_BELOW' => 'Specify below',
'mai_MULTIDROP' => 'multi-drop',
'mai_LABEL_MODE' => 'E-mail retrieval mode',
#
# Lex file for Emailsettings generated on 2025-07-17 09:52:31
#
'mai_ACC_panel_action_was_successful' => 'Email access settings saved sucessfully',
'mai_ALLOW_PRIVATE' => 'Allow private',
'mai_AUTO' => 'Automatic',
'mai_DEL_panel_action_was_successful' => 'Email delivery settings saved sucessfully',
'mai_DESC_BLOCK_EXECUTABLE_CONTENT' => 'You can block executable content in e-mail attachments
by highlighting the executable attachment types you wish to
block. E-mail containing these attachment types will
be automatically returned to the sender.',
'mai_DESC_DELEGATE' => 'Your server includes a complete, full-featured e-mail server. However,
if for some reason you wish to delegate e-mail processing to
another system, specify the IP address of the delegate system
here. For normal operation, leave this field blank.',
'mai_DESC_FETCH_PERIOD' => 'For ETRN or multi-drop, you can control how frequently this server
contacts your secondary e-mail server to fetch e-mail. More
frequent connections mean that you receive your e-mail more
quickly, but also cause Internet requests to be sent more often,
possibly increasing your phone and Internet charges.',
'mai_DESC_IMAP_ACCESS_CONTROL' => 'You can control IMAP server access. The setting "Allow access
only from local networks" allows IMAP access only from your
local network(s). The IMAPS setting can be used to provide
encrypted external access to your IMAP server. We recommend
leaving this setting "Allow access only from local networks"
unless you have a specific reason to do otherwise.',
'mai_DESC_MODE' => 'The e-mail retrieval mode can be set to
standard (for dedicated Internet connections), ETRN (recommended
for dialup connections), or multi-drop (for dialup connections if
ETRN is not supported by your Internet provider). Note that
multi-drop mode is the only option available when the server is
configured in private server and gateway mode.',
'mai_LABEL_DELEGATE' => 'Address of internal mail server',
'mai_TITLE_DELEGATE' => 'Delegate mail servers',
'mai_DESC_DELEGATE' => 'Your server includes a complete, full-featured e-mail server. However,
if for some reason you wish to delegate e-mail processing to
another system, specify the IP address of the delegate system
here. For normal operation, leave this field blank.',
'mai_LABEL_SECONDARY' => 'Secondary mail server',
'mai_TITLE_SECONDARY' => 'ETRN or multi-drop settings',
'mai_DESC_SECONDARY' => 'For ETRN or multi-drop, specify the hostname or IP address of your
secondary mail server. (If using the standard e-mail setup, this
field can be left blank.)',
'mai_DESC_FETCH_PERIOD' => 'For ETRN or multi-drop, you can control how frequently this server
contacts your secondary e-mail server to fetch e-mail. More
frequent connections mean that you receive your e-mail more
quickly, but also cause Internet requests to be sent more often,
possibly increasing your phone and Internet charges.',
'mai_LABEL_FETCH_PERIOD' => 'During office hours (8:00 AM to 6:00 PM) on weekdays',
'mai_LABEL_FETCH_PERIOD_NIGHTS' => 'Outside office hours (6:00 PM to 8:00 AM) on weekdays',
'mai_LABEL_FETCH_PERIOD_WEEKENDS' => 'During the weekend',
'mai_DESC_POP_ACCESS_CONTROL' => 'You can control POP3 server access. The setting "Allow access
only from local networks" allows POP3 access only from your
local network(s). The POP3S setting can be used to provide
encrypted external access to your POP3 server. We recommend
leaving this setting "Allow access only from local networks"
unless you have a specific reason to do otherwise.',
'mai_DESC_POP_ACCOUNT' => 'For multi-drop e-mail, specify the POP user account and password.
(If using standard or ETRN e-mail, these fields can be blank.)
Also, for multi-drop, you can either use the default mail sorting
method, or you can specify a particular message header to use for
mail sorting.',
'mai_LABEL_POP_PASS' => 'POP user password (for multi-drop)',
'mai_LABEL_POP_ACCOUNT' => 'POP user account (for multi-drop)',
'mai_LABEL_SORT_METHOD' => 'Select sort method (for multi-drop)',
'mai_LABEL_SORT_HEADER' => 'Select sort header (for multi-drop)',
'mai_LABEL_FETCH_PROTO' => 'Protocol (for multi-drop)',
'mai_LABEL_FETCH_SECURE' => 'Tunnel over SSL (for multi-drop)',
'mai_AUTO' => 'Automatic',
'mai_ENABLED_BOTH' => 'Allow both HTTP and HTTPS',
'mai_ENABLED_SECURE_ONLY' => 'Allow HTTPS (secure)',
'mai_ONLY_LOCAL_NETWORK_SSL' => 'Allow HTTPS (secure) from local networks',
'mai_INSECURE_POP3' => 'Allow both POP3 and POP3S',
'mai_ALLOW_PRIVATE' => 'Allow private',
'mai_SECURE_POP3' => 'Allow private and public (secure POP3S)',
'mai_INSECURE_IMAP' => 'Allow both IMAP and IMAPS',
'mai_SECURE_IMAP' => 'Allow private and public (secure IMAPS)',
'mai_INSECURE_SMTP' => 'Allow both SMTP and SSMTP',
'mai_SECURE_SMTP' => 'Allow SSMTP (secure)',
'mai_LABEL_POP_ACCESS_CONTROL' => 'POP3 server access',
'mai_LABEL_IMAP_ACCESS_CONTROL' => 'IMAP server access',
'mai_LABEL_SMTP_AUTH_CONTROL' => 'SMTP authentication',
'mai_FORWARD_TO_ADMIN' => 'Send to administrator',
'mai_FORWARD_TO' => 'Send to',
'mai_RETURN_TO_SENDER' => 'Reject',
'mai_LABEL_UNKNOWN' => 'E-mail to unknown users',
'mai_TITLE_UNKNOWN' => 'Unknown Users',
'mai_DESC_UNKNOWN' => 'Selecting Reject (recommended setting) will configure the server to only
accept mail for valid email addresses (for example users, groups, pseudonyms).
Mail for other addresses will be rejected.',
'mai_LABEL_SMARTHOST' => 'Address of Internet provider\'s mail server',
'mai_TITLE_SMARTHOST' => 'SMTP server',
'mai_DESC_SECONDARY' => 'For ETRN or multi-drop, specify the hostname or IP address of your
secondary mail server. (If using the standard e-mail setup, this
field can be left blank.)',
'mai_DESC_SMARTHOST' => 'The server can deliver outgoing messages directly to their
destination (recommended in most cases) or can deliver them via
your Internet provider\'s SMTP server (recommended if you have an
your Internet provider"s SMTP server (recommended if you have an
unreliable Internet connection or are using a residential Internet
service). If using your Internet provider\'s SMTP server, specify
its hostname or IP address below. Otherwise leave this field
blank.',
'mai_INVALID_SMARTHOST' => 'The smarthost name you entered is not a valid internet domain name
and is not blank',
'mai_DESC_POP_ACCESS_CONTROL' => 'You can control POP3 server access. The setting \'Allow access
only from local networks\' allows POP3 access only from your
local network(s). The POP3S setting can be used to provide
encrypted external access to your POP3 server. We recommend
leaving this setting \'Allow access only from local networks\'
unless you have a specific reason to do otherwise.',
'mai_DESC_IMAP_ACCESS_CONTROL' => 'You can control IMAP server access. The setting \'Allow access
only from local networks\' allows IMAP access only from your
local network(s). The IMAPS setting can be used to provide
encrypted external access to your IMAP server. We recommend
leaving this setting \'Allow access only from local networks\'
unless you have a specific reason to do otherwise.',
service). If using your Internet provider"s SMTP server, specify
its hostname or IP address below. Otherwise leave this field blank.',
'mai_DESC_SMTP_AUTH_CONTROL' => 'You can provide authenticated access to your SMTP server, or
set it to Disabled.
The SSMTP setting requires <b>all</b> users to use SSL/TLS
authentication. The SMTP and SSMTP option additionally allows
STARTTLS to be used to ensure secure authentication.',
'mai_DESC_WEBMAIL' => 'You can enable or disable webmail on this system. Webmail allows
users to access their mail through a regular web browser by
pointing the browser to https://[_1]/webmail,and
logging in to their account.',
'mai_LABEL_WEBMAIL' => 'Webmail access',
'mai_LABEL_BLOCK_EXECUTABLE_CONTENT' => 'Executable content blocking',
'mai_LABEL_CONTENT_TO_BLOCK' => 'Content to block',
'mai_DESC_BLOCK_EXECUTABLE_CONTENT' => 'You can block executable content in e-mail attachments
by highlighting the executable attachment types you wish to
block. E-mail containing these attachment types will
be automatically returned to the sender.',
'mai_UNACCEPTABLE_CHARS' => 'This field requires a valid e-mail address, which must include
the @ symbol and a domain name.',
'mai_DESC_STATE_ACCESS' => 'E-mail access',
'mai_DESC_STATE_ACCESS_BUTTON' => 'Change e-mail access settings',
'mai_DESC_STATE_RECEPTION' => 'E-mail reception',
'mai_DESC_STATE_RECEPTION_BUTTON' => 'Change e-mail reception settings',
'mai_DESC_STATE_DELIVERY' => 'E-mail delivery',
'mai_DESC_STATE_DELIVERY_BUTTON' => 'Change e-mail delivery settings',
'mai_DESC_STATE_FILTERING_BUTTON' => 'Change e-mail filtering settings',
'mai_LABEL_VIRUS_SCAN' => 'Virus scanning',
'mai_DESC_VIRUS_SCAN' => 'You can scan incoming and outgoing e-mail for viruses. If scanning is enabled and a virus is detected, the e-mail will be rejected and returned to the
sender.',
'mai_LABEL_SPAM_SCAN' => 'Spam filtering',
'mai_DESC_SPAM_SCAN' => 'You can scan e-mail for spam. If Spam filtering is
enabled, an X-Spam-Status: header is added to each
message, which can be used for filtering spam.
@@ -132,23 +63,98 @@ process from the default of medium. For fine-grained
control, you can set the Spam sensitivity to Custom
and then choose a custom tagging level, and
optionally a level at which to reject the message.',
'mai_LABEL_SPAM_SUBJECT' => 'SPAM subject prefix',
'mai_DESC_SPAM_SUBJECT' => 'You can enable to add a tag to the subject of each
message that is classified as SPAM.
The value for this tag can be defined below.',
'mai_LABEL_SPAM_SENSITIVITY' => 'Spam sensitivity',
'mai_LABEL_SPAM_TAGLEVEL' => 'Custom spam tagging level',
'mai_LABEL_SPAM_REJECTLEVEL' => 'Custom spam rejection level',
'mai_LABEL_SPAM_SUBJECTTAG' => 'Modify subject of spam messages',
'mai_LABEL_SORTSPAM' => 'Sort spam into junkmail folder',
'mai_VERYHIGH' => 'Very high',
'mai_HIGH' => 'High',
'mai_MEDIUM' => 'Medium',
'mai_LOW' => 'Low',
'mai_VERYLOW' => 'Very low',
'mai_CUSTOM' => 'Custom',
'mai_DESC_STATE_ACCESS' => 'E-mail access',
'mai_DESC_STATE_ACCESS_BUTTON' => 'Change e-mail access settings',
'mai_DESC_STATE_DELIVERY' => 'E-mail delivery',
'mai_DESC_STATE_DELIVERY_BUTTON' => 'Change e-mail delivery settings',
'mai_DESC_STATE_FILTERING_BUTTON' => 'Change e-mail filtering settings',
'mai_DESC_STATE_RECEPTION' => 'E-mail reception',
'mai_DESC_STATE_RECEPTION_BUTTON' => 'Change e-mail reception settings',
'mai_DESC_UNKNOWN' => 'Selecting Reject (recommended setting) will configure the server to only
accept mail for valid email addresses (for example users, groups, pseudonyms).
Mail for other addresses will be rejected.',
'mai_DESC_VIRUS_SCAN' => 'You can scan incoming and outgoing e-mail for viruses. If scanning is enabled and a virus is detected, the e-mail will be rejected and returned to the
sender.',
'mai_DESC_WEBMAIL' => 'You can enable or disable webmail on this system. Webmail allows
users to access their mail through a regular web browser by
pointing the browser to https://[_1]/webmail,and
logging in to their account.',
'mai_E-Mail' => 'E-mail',
'mai_ENABLED_BOTH' => 'Allow both HTTP and HTTPS',
'mai_ENABLED_SECURE_ONLY' => 'Allow HTTPS (secure)',
'mai_ETRN' => 'ETRN (SMTP with client request)',
'mai_EVERY15MIN' => 'Every 15 minutes',
'mai_EVERY2HRS' => 'Every 2 hours',
'mai_EVERY30MIN' => 'Every 30 minutes',
'mai_EVERY5MIN' => 'Every 5 minutes',
'mai_EVERYHOUR' => 'Every hour',
'mai_FIL_panel_action_was_successful' => 'Email filtering settings saved sucessfully',
'mai_FORM_TITLE' => 'E-mail settings',
'mai_FORWARD_TO' => 'Send to',
'mai_FORWARD_TO_ADMIN' => 'Send to administrator',
'mai_INSECURE_IMAP' => 'Allow both IMAP and IMAPS',
'mai_INSECURE_POP3' => 'Allow both POP3 and POP3S',
'mai_INSECURE_SMTP' => 'Allow both SMTP and SSMTP',
'mai_INVALID_DELEGATE' => 'The delegate host name you entered is not a valid IP Address and is not blank',
'mai_INVALID_SMARTHOST' => 'The smarthost name you entered is not a valid internet domain name and is not blank',
'mai_LABEL_BLOCK_EXECUTABLE_CONTENT' => 'Executable content blocking',
'mai_LABEL_CONTENT_TO_BLOCK' => 'Content to block',
'mai_LABEL_DELEGATE' => 'IP Address of internal mail server',
'mai_LABEL_FETCH_PERIOD' => 'During office hours (8:00 AM to 6:00 PM) on weekdays',
'mai_LABEL_FETCH_PERIOD_NIGHTS' => 'Outside office hours (6:00 PM to 8:00 AM) on weekdays',
'mai_LABEL_FETCH_PERIOD_WEEKENDS' => 'During the weekend',
'mai_LABEL_FETCH_PROTO' => 'Protocol (for multi-drop)',
'mai_LABEL_FETCH_SECURE' => 'Tunnel over SSL (for multi-drop)',
'mai_LABEL_IMAP_ACCESS_CONTROL' => 'IMAP server access',
'mai_LABEL_MODE' => 'E-mail retrieval mode',
'mai_LABEL_POP_ACCESS_CONTROL' => 'POP3 server access',
'mai_LABEL_POP_ACCOUNT' => 'POP user account (for multi-drop)',
'mai_LABEL_POP_PASS' => 'POP user password (for multi-drop)',
'mai_LABEL_SECONDARY' => 'Secondary mail server',
'mai_LABEL_SMARTHOST' => 'Address of Internet provider"s mail server',
'mai_LABEL_SMARTHOST_SMTPAUTH_PASSWD' => 'Mail server password',
'mai_LABEL_SMARTHOST_SMTPAUTH_STATUS' => 'SMTP Authentication for Internet provider',
'mai_LABEL_SMARTHOST_SMTPAUTH_USERID' => 'Mail server user id',
'mai_LABEL_SMARTHOST_SMTPAUTH_PASSWD' => 'Mail server password',
'mai_VALIDATION_SMTPAUTH_NONBLANK' => 'This field cannot be left blank if SMTP Authentication is
'mai_LABEL_SMTP_AUTH_CONTROL' => 'SMTP authentication',
'mai_LABEL_SORT_HEADER' => 'Select sort header (for multi-drop)',
'mai_LABEL_SORT_METHOD' => 'Select sort method (for multi-drop)',
'mai_LABEL_SORTSPAM' => 'Sort spam into junkmail folder',
'mai_LABEL_SPAM_REJECTLEVEL' => 'Custom spam rejection level',
'mai_LABEL_SPAM_SCAN' => 'Spam filtering',
'mai_LABEL_SPAM_SENSITIVITY' => 'Spam sensitivity',
'mai_LABEL_SPAM_SUBJECT' => 'SPAM subject prefix',
'mai_LABEL_SPAM_SUBJECTTAG' => 'Modify subject of spam messages',
'mai_LABEL_SPAM_TAGLEVEL' => 'Custom spam tagging level',
'mai_LABEL_UNKNOWN' => 'E-mail to unknown users',
'mai_LABEL_VIRUS_SCAN' => 'Virus scanning',
'mai_LABEL_WEBMAIL' => 'Webmail access',
'mai_MULTIDROP' => 'multi-drop',
'mai_NEVER' => 'not at all',
'mai_ONLY_LOCAL_NETWORK_SSL' => 'Allow HTTPS (secure) from local networks',
'mai_REC_panel_action_was_successful' => 'Email receive settings saved sucessfully',
'mai_SECURE_IMAP' => 'Allow private and public (secure IMAPS)',
'mai_SECURE_POP3' => 'Allow private and public (secure POP3S)',
'mai_SECURE_SMTP' => 'Allow SSMTP (secure)',
'mai_SMTP_port_(25)' => 'Smtp port (25) main purpose is to receive emails from another server, starttls is always offered, but auth if offered is only if starttls is also used by client.',
'mai_SMTP_port_authenticate' => 'Smtp port %u allow client to authenticate:',
'mai_SMTP_Submission' => 'Smtp submission port (587) will require starttls, then authenticate to send.',
'mai_SMTPS_port_(465)' => 'Smtps port (465) will require implicit ssl/tls then authenticate to send.',
'mai_SMTPS_SSL/TLS' => 'Smtps ssl/tls auth: port %u status:',
'mai_SPECIFY_BELOW' => 'Specify below',
'mai_STANDARD' => 'Standard (SMTP)',
'mai_Submission_port' => 'Submission port %u status:',
'mai_SUCCESS' => 'The new e-mail settings have been saved.',
'mai_TITLE_DELEGATE' => 'Delegate mail servers',
'mai_TITLE_SECONDARY' => 'ETRN or multi-drop settings',
'mai_TITLE_SMARTHOST' => 'SMTP server',
'mai_TITLE_UNKNOWN' => 'Unknown Users',
'mai_UNACCEPTABLE_CHARS' => 'This field requires a valid e-mail address, which must include
the @ symbol and a domain name.',
'mai_VALIDATION_SMTPAUTH_NONBLANK' => 'The user id and password fields cannot be left blank if SMTP Authentication is
enabled.',
'mai_VERYHIGH' => 'Very high',
'mai_VERYLOW' => 'Very low',
'mai_RETURN_TO_SENDER' => 'Reject',

View File

@@ -1,154 +1,155 @@
'edit' => 'edit',
'del' => 'del',
'exit' => 'Exit',
'cancel' => 'Cancel',
'hello' => 'hello',
'All rights reserved' => 'All Rights Reserved',
'Collaboration' => 'Collaboration',
'Administration' => 'Administration',
'Security' => 'Security',
'Configuration' => 'Configuration',
'Miscellaneous' => 'Miscellaneous',
'Your Settings' => 'Your Settings',
'SAVE' => 'Save',
'CANCEL' => 'Cancel',
'ENABLED' => 'Enabled',
'DISABLED' => 'Disabled',
'NO' => 'No',
'YES' => 'Yes',
'ADD' => 'Add',
'CREATE' => 'Create',
'MODIFY' => 'Modify',
'REMOVE' => 'Remove',
'COMMENT' => 'Comment',
'NEXT' => 'Next',
'SELF' => 'Self',
'REMOTE' => 'Remote',
'LOCAL' => 'Local',
'ACTION' => 'Action',
'NETWORK' => 'Network',
'ROUTER' => 'Router',
'OPERATION_STATUS_REPORT' => 'Operation status report',
#
# Lex file for General generated on 2025-07-17 09:52:34
#
'ACCOUNT' => 'Account',
'GROUP' => 'Group',
'DESC_SECTIONBAR' => '<hr class="sectionbar"/>',
'NO_PIPES_ALLOWED' => 'Pipe symbols (|) are not permitted in this field',
'ERROR_BELOW' => 'ERROR: There was an error in the validation of this page. Please scroll down and find the specific problem.',
'ACCESS' => 'Access',
'ACCOUNT_LOCKED' => 'Account is locked',
'GROUP_ADD' => 'Add group',
'NETWORKS_ALLOW_LOCAL' => 'Allow access only from local networks',
'NETWORKS_ALLOW_PUBLIC' => 'Allow public access (entire Internet)',
'ERROR_PASSWORD_CHANGE' => 'An error occurred while attempting to change your password. Please make sure that the old password entered is correct.',
'BACK' => 'Back',
'BACKUP' => 'Backup',
'DESCRIPTION_BRIEF' => 'Brief description',
'PASSWORD_CHANGE' => 'Change Password',
'RESET_PASSWORD_TITLE' => 'Reset user password',
'ACCOUNT_PASSWORD_CHANGE' => 'Change account password',
'CONTENT' => 'Content',
'CREATE_GROUP' => 'Create user group',
'USER_LIST_CURRENT' => 'Current list of users',
'DESCRIPTION' => 'Description',
'DESTINATION' => 'Destination',
'DOMAIN_NAME' => 'Domain name',
'DOMAIN' => 'Domain',
'DOMAINS' => 'Domains',
'DOWNLOAD' => 'Download',
'ERROR_UPDATING_CONFIGURATION' => 'Error occurred while updating system configuration.',
'GROUP_MEMBERS' => 'Group Members',
'GROUP_NAME' => 'Group Name',
'GROUPS' => 'Groups',
'IP_ADDRESS' => 'IP Address',
'IP_ADDRESS_OR_FQDN' => 'IP Address or FQDN',
'USER_INVALID' => 'Invalid user',
'LOCATION' => 'Location',
'MB' => 'Mb',
'MODIFY_USER_GROUP' => 'Modify user group',
'NAME' => 'Name',
'PASSWORD_VERIFY_NEW' => 'New password (verify):',
'PASSWORD_NEW' => 'New password:',
'OFF' => 'Off',
'OK' => 'Ok',
'PASSWORD_OLD' => 'Old password:',
'ON' => 'On',
'PASSWORD' => 'Password',
'PERFORM' => 'Perform',
'RECONFIGURE' => 'Reconfigure',
'REMOVE_USER_GROUP' => 'Remove user group',
'PASSWORD_RESET' => 'Reset password',
'RESTORE' => 'Restore',
'SHUTDOWN' => 'Shutdown',
'SUCCESS' => 'Success',
'ACCOUNT_NAME_INVALID' => 'The account name entered is invalid.',
'ACCOUNT_NAME_INVALID_CHARS' => 'The account name you entered contained invalid characters.',
'PASSWORD_OLD_INVALID_CHARS' => 'The old password you entered contained invalid characters.',
'PASSWORD_INVALID_CHARS' => 'The password you entered contained invalid characters.',
'PASSWORD_VERIFY_ERROR' => 'The passwords you entered did not match.',
'ACCOUNT_USER_NONE' => 'There are no user accounts in the system.',
'ACCOUNT_GROUP_NONE' => 'There are no user groups in the system.',
'ERROR_INVALID_CHARS' => 'Unexpected characters in description.',
'USER_NAME' => 'User Name',
'YOUR_ACCOUNT' => 'Your account:',
'YOUR_ACCOUNT_INVALID' => 'The account name entered is invalid.',
'PASSWORD_CHANGE_SUCCESS' => 'Your password has been successfully changed.',
'FM_NONBLANK' => 'This field must not be left blank',
'FM_INTEGER' => 'This field must contain a positive integer',
'FM_NUMBER' => 'This field must contain a number',
'FM_WORD' => 'This field must look like a single word.',
'FM_DATE' => 'The data entered could not be parsed as a date',
'FM_CREDIT_CARD_NUMBER1' => 'You must enter a credit card number',
'FM_CREDIT_CARD_NUMBER2' => 'Credit card numbers shouldn\'t have anything but numbers, spaces or dashes',
'FM_CREDIT_CARD_NUMBER3' => 'Must be at least 14 characters in length',
'FM_CREDIT_CARD_NUMBER4' => 'Doesn\'t appear to be a valid credit card number',
'FM_CREDIT_CARD_EXPIRY1' => 'No expiry date entered.',
'FM_CREDIT_CARD_EXPIRY2' => 'Expiry date must be in the format MM/YY or MM/YYYY',
'FM_CREDIT_CARD_EXPIRY3' => 'This expiry date appears to have already passed',
'FM_CREDIT_CARD_EXPIRY4' => 'This expiry date appears to be too far in the future',
'FM_ISO_COUNTRY_CODE1' => 'You must provide a country code',
'FM_ISO_COUNTRY_CODE2' => 'This field does not contain an ISO country code',
'FM_US_STATE' => 'This doesn\'t appear to be a valid 2-letter US state abbreviation',
'FM_US_ZIPCODE' => 'US zip codes must contain 5 or 9 numbers',
'FM_MINLENGTH1' => 'Minimum length has been specified meaninglessly as [_1]',
'FM_MINLENGTH2' => 'This field must be at least [_1] characters',
'FM_MAXLENGTH1' => 'Maximum length has been specified meaninglessly as [_1]',
'FM_MAXLENGTH2' => 'This field must be no more than [_1] characters',
'FM_EXACTLENGTH1' => 'You must specify the length for the field.',
'FM_EXACTLENGTH2' => 'You must specify the exactlength of the field with an integer',
'FM_EXACTLENGTH3' => 'This field must be exactly [_1] characters',
'FM_LENGTHRANGE1' => 'You must specify the maximum and minimum length for the field.',
'FM_LENGTHRANGE2' => 'You must specify the maximum and minimum lengths of the field with an integer',
'FM_LENGTHRANGE3' => 'This field must be between [_1] and [_2] characters',
'FM_URL' => 'This field must contain a URL starting with http:// or ftp://',
'FM_EMAIL_SIMPLE1' => 'You must enter an email address.',
'FM_EMAIL_SIMPLE2' => 'This field doesn\'t look like an RFC822-compliant email address',
'FM_DOMAIN_NAME' => 'This field doesn\'t look like a valid Internet domain name or hostname.',
'ACCOUNT_LOCKED' => 'Account is locked',
'ACCOUNT_USER_NONE' => 'There are no user accounts in the system.',
'ACTION' => 'Action',
'ADD' => 'Add',
'ALL_BACKUPS' => 'All backups',
'Allow_local_access_only' => 'Allow local access only',
'Allow_public_access' => 'Allow public access',
'AM/PM:' => 'Am/pm:',
'Apply' => 'Apply',
'Back' => 'Back',
'Blocked' => 'Blocked',
'Check' => 'Check',
'Check_Domain' => 'Check domain',
'cifs' => 'Cifs',
'City' => 'City',
'COMMENT' => 'Comment',
'Company' => 'Company',
'Config' => 'Config',
'Content' => 'Content',
'COULD_NOT_GET_UID' => 'Could not get uid',
'COULD_NOT_OPEN_TZ_FILE' => 'Could not open tz file',
'CREATE_GROUP' => 'Create user group',
'Custom' => 'Custom',
'Daily' => 'Daily',
'Date' => 'Date',
'Day:' => 'Day:',
'Default' => 'Default',
'DELETE_ERROR' => 'Delete error',
'Department' => 'Department',
'DESCRIPTION' => 'Description',
'DESCRIPTION_BRIEF' => 'Brief description',
'DISABLED' => 'Disabled',
'DOMAIN' => 'Domain',
'DOMAIN_NAME' => 'Domain name',
'DOWNLOAD' => 'Download',
'Email' => 'Email',
'ENABLED' => 'Enabled',
'END_OF_REPORT' => 'End of Report',
'ENTIRE_INTERNET_NO_PASSWORD' => 'Entire internet no password',
'ENTIRE_INTERNET_PASSWORD' => 'Entire internet password',
'ENTIRE_INTERNET_PASSWORD_REMOTE' => 'Entire internet password remote',
'Error_occurred_while_modifying_password_for_admin.' => 'Error occurred while modifying password for admin.',
'ERROR_UPDATING' => 'Error updating',
'ERROR_UPDATING_CONFIGURATION' => 'Error occurred while updating system configuration.',
'EVERYONE' => 'Everyone',
'Everyone' => 'Everyone',
'Expiry' => 'Expiry',
'files' => 'files',
'firstname' => 'firstname',
'FM_ERR_UNEXPECTED_DESC' => 'Error: unexpected or missing characters in description',
'FM_IP_NUMBER1' => 'This field must contain a valid IP number and can not be left blank.',
'FM_IP_NUMBER2' => 'Invalid IP address format (expected X.X.X.X)',
'FM_IP_NUMBER3' => '[_1] is more than 255',
'FM_USERNAME' => 'This field must look like a valid username (3 to 8 letters and numbers)',
'FM_PASSWORD1' => 'You must provide a password.',
'FM_PASSWORD2' => 'The password you provided was not a good password.A good password must contain all of the following: upper case letter, lower case letter, number, non-alphanumeric character, be at least 7 characters long.',
'FM_MAC_ADDRESS1' => 'You must provide a MAC address.',
'FM_MAC_ADDRESS2' => 'The MAC address you provided was not valid.',
'FM_ERR_UNEXPECTED_DESC' => 'Error: unexpected or missing characters in description',
swt_THEME => 'Theme',
swt_LOGIN_AGAIN => 'You may need to login again to see the choosed theme',
acs_NO => 'Not Authorized',
acs_LOGIN => 'Login required',
acs_ADMIN => 'Admin rights required',
'User password' => 'User password',
Logout => 'Logout',
Home => 'Home',
CSRF_VALIDATION_FAILURE => 'Error: CSRF token is invalid or outdated.',
Empty => 'Empty',
Active => 'Active',
MINUTE => 'Minute',
MINUTES => 'Minutes',
HOUR => 'Hour',
HOURS => 'Hours',
SMALL => 'Small',
MEDIUM => 'Medium',
LARGE => 'Large',
FIELD_INVALID_CHARS => 'A field you entered contains invalid characters.',
'FM_NONBLANK' => 'This field must not be left blank',
'Gateway' => 'Gateway',
'GROUP' => 'Group',
'GROUP_ADD' => 'Add group',
'GROUP_MEMBERS' => 'Group Members',
'GROUP_NAME' => 'Group Name',
'High' => 'High',
'Hostname' => 'Hostname',
'Hour:' => 'Hour:',
'Install' => 'Install',
'INVALID_REPORT_TYPE' => 'Invalid report type',
'INVALID_SERVERNAME' => 'Invalid servername',
'INVALID_WORKGROUP' => 'Invalid workgroup',
'INVALID_WORKGROUP_MATCHES_SERVERNAME' => 'Invalid workgroup matches servername',
'IP_ADDRESS_OR_FQDN' => 'IP Address or FQDN',
'Issuer' => 'Issuer',
'lastname' => 'lastname',
'LOCAL' => 'Local',
'LOCAL_NETWORK_NO_PASSWORD' => 'Local network no password',
'LOCAL_NETWORK_PASSWORD' => 'Local network password',
'local_removable_disk' => 'Local removable disk',
'LOCATION' => 'Location',
'Location' => 'Location',
'Lock' => 'Lock',
'Low' => 'Low',
'Medium' => 'Medium',
'megabytes' => 'megabytes',
'Minute:' => 'Minute:',
'MODIFY' => 'Modify',
'Modify' => 'Modify',
'MODIFY_USER_GROUP' => 'Modify user group',
'Month:' => 'Month:',
'Monthly' => 'Monthly',
'Mounted_disk' => 'Mounted disk',
'NAME' => 'Name',
'NETWORK' => 'Network',
'NETWORKS_ALLOW_LOCAL' => 'Allow access only from local networks',
'NETWORKS_ALLOW_PUBLIC' => 'Allow public access (entire Internet)',
'Never' => 'Never',
'NEXT' => 'Next',
'nfs' => 'Nfs',
'NO' => 'No',
'NONE' => 'None',
'NOT_A_PSEUDONYM' => 'Not a pseudonym',
'NUM_OF_HOSTS' => 'Num of hosts',
'Only_allow_insecure_access' => 'Only allow insecure access',
'Operation' => 'Operation',
'PASSWORD' => 'Password',
'PASSWORD_NEW' => 'New password:',
'PASSWORD_RESET' => 'Reset password',
'PASSWORD_VERIFY_ERROR' => 'The passwords you entered did not match.',
'PASSWORD_VERIFY_NEW' => 'New password (verify):',
'PERFORM' => 'Perform',
'PptpSessions' => 'Pptpsessions',
'Protocol' => 'Protocol',
'Pseudonym' => 'Pseudonym',
'Reboot' => 'Reboot',
'RECONFIGURE' => 'Reconfigure',
'Reject' => 'Reject',
'REMOTE' => 'Remote',
'REMOVE' => 'Remove',
'REMOVE_USER_GROUP' => 'Remove user group',
'REPORT_GENERATED' => 'Report generated',
'RESET_PASSWORD_TITLE' => 'Reset user password',
'ROUTER' => 'Router',
'SAVE' => 'Save',
'Save' => 'Save',
'Second:' => 'Second:',
'SELF' => 'Self',
'SHUTDOWN' => 'Shutdown',
'SMTP_port_%u_allow_client_to_authenticate:' => 'Smtp port %u allow client to authenticate:',
'SMTP_port_(25)_main_purpose_is_to_receive_emails_from_another_server,_STARTTLS_is_always_offered,_but_auth_if_offered_is_only_if_STARTTLS_is_also_used_by_client.' => 'Smtp port (25) main purpose is to receive emails from another server, starttls is always offered, but auth if offered is only if starttls is also used by client.',
'SMTP_Submission_port_(587)_will_require_STARTTLS,_then_authenticate_to_send.' => 'Smtp submission port (587) will require starttls, then authenticate to send.',
'SMTPS_port_(465)_will_require_implicit_SSL/TLS_then_authenticate_to_send.' => 'Smtps port (465) will require implicit ssl/tls then authenticate to send.',
'SMTPS_SSL/TLS_auth:_port_%u_status:' => 'Smtps ssl/tls auth: port %u status:',
'Submission_port_%u_status:' => 'Submission port %u status:',
'SUBNET_MASK' => 'Subnet mask',
'SUCCESS' => 'Success',
'THEME' => 'Theme',
'Time' => 'Time',
'Time_Configuration' => 'Time configuration',
'Time_Setting_Mode:' => 'Time setting mode:',
'Update' => 'Update',
'USER_DIFFERENT' => 'User different',
'USER_NAME' => 'User Name',
'useraccount' => 'useraccount',
'ValidFromMask' => 'Validfrommask',
'ValidFromNetwork' => 'Validfromnetwork',
'Verify' => 'Verify',
'WARG' => 'Warg',
'Webmail' => 'Webmail',
'Weekly' => 'Weekly',
'WGRE' => 'Wgre',
'WGRG' => 'Wgrg',
'Year:' => 'Year:',
'YES' => 'Yes',

View File

@@ -1,32 +1,33 @@
'grp_FORM_TITLE' => 'Create, modify, or remove user groups',
'grp_GROUP_TOO_LONG' => 'Error: group name is too long. The maximum is [_1] characters.',
'grp_ACCOUNT_CONFLICT' => 'Error: the group "[_1]" can\'t be created because there is
#
# Lex file for Groups generated on 2025-07-17 09:52:31
#
'grp_ACCOUNT_CONFLICT' => 'Error: the group "[_1]" can"t be created because there is
already a [_2] account of that name.',
'grp_INVALID_GROUP_DESCRIPTION' => 'Error: unexpected or missing characters in group description',
'grp_NO_MEMBERS' => 'Error: no members in group.Did not create new group.',
'grp_CREATED_GROUP' => 'Successfully created user group',
'grp_DELETED_GROUP' => 'Successfully removed user group',
'grp_MODIFIED_GROUP' => 'Successfully modifed user group',
'grp_CONFIRM_DELETE_GROUP' => 'Are you sure you wish to remove this group?',
'grp_CREATE_ERROR' => 'An error occurred while creating user group.',
'grp_CREATED_GROUP' => 'Successfully created user group',
'grp_CURRENT_LIST' => 'Current list of User Groups',
'grp_DELETE_DESCRIPTION' => 'You are about to remove the user group "[_1]."',
'grp_DELETE_ERROR' => 'An error occurred while removing user group.',
'grp_MODIFY_ERROR' => 'An error occurred while modifying user group.',
'grp_DELETED_GROUP' => 'Successfully removed user group',
'grp_FORM_TITLE' => 'Create, modify, or remove user groups',
'grp_GROUP_DESC' => 'Brief Description/Windows Group Alias',
'grp_GROUP_DESC_EXPL' => 'Input a brief group description in the field below.
This field also designates the group name viewable by
Windows clients.',
'grp_GROUP_HAS_MEMBERS' => 'This group contains the following members:',
'grp_GROUP_NAMING' => 'The group name should contain only lower-case
letters, numbers, hyphens, periods, and underscores,
and should start with a lower-case letter. For
example "sales", "beta5", and "reseller_partners" are
all valid group names, but "3rd-event", "Marketing Team"
and "lost&found" are not.',
'grp_GROUP_HAS_MEMBERS' => 'This group contains the following members:',
'grp_NOT_A_GROUP' => 'Error: That is not an existing group account.',
'grp_GROUP_DESC' => 'Brief Description/Windows Group Alias',
'grp_GROUP_DESC_EXPL' => 'Input a brief group description in the field below.
This field also designates the group name viewable by
Windows clients.',
'grp_GROUP_TOO_LONG' => 'Error: group name is too long. The maximum is [_1] characters.',
'grp_IBAYS_WILL_BE_CHANGED' => 'The following information bays were assigned to this group and
will be changed to the Administrator group (you can change them to
something else afterward):',
'grp_CONFIRM_DELETE_GROUP' => 'Are you sure you wish to remove this group?',
'grp_CURRENT_LIST' => 'Current list of User Groups',
'grp_DELETE_DESCRIPTION' => 'You are about to remove the user group "[_1]."',
'grp_INVALID_GROUP_DESCRIPTION' => 'Error: unexpected or missing characters in group description',
'grp_MODIFIED_GROUP' => 'Successfully modifed user group',
'grp_MODIFY_ERROR' => 'An error occurred while modifying user group.',
'grp_NO_MEMBERS' => 'Error: no members in group. Did not create new group.',
'grp_NOT_A_GROUP' => 'Error: That is not an existing group account.',

View File

@@ -1,74 +1,73 @@
'hos_FORM_TITLE' => 'Hostnames and addresses',
'hos_UNABLE_TO_OPEN_CONFIGDB' => 'Unable to open configuration database',
#
# Lex file for Hostentries generated on 2025-07-17 09:52:32
#
'hos_ABOUT_TO_REMOVE' => 'Are you sure you wish to remove this hostname?',
'hos_ADD_HOSTNAME' => 'Add hostname',
'hos_ADDR_IN_DHCP_RANGE' => 'Address is inside the DHCP assigned dynamic range',
'hos_CONFIRM_DESCRIPTION' => 'Please confirm the following details.',
'hos_CREATE_LOCAL_HOST_TITLE' => 'Create a new hostname referring to a local host.',
'hos_CREATE_REMOTE_HOST_TITLE' => 'Create a new hostname referring to a remote host',
'hos_CREATE_TITLE' => 'Create or modify hostname',
'hos_CURRENT_HOSTNAMES_FOR_DOMAIN' => 'Current list of hostnames for [_1].',
'hos_CURRENT_HOSTNAMES_FOR_LOCAL_DOMAIN' => 'Current list of hostnames for [_1]',
'hos_DIDNT_ENTER_LOCAL_IP' => 'Error: You did not specify a Local IP address. IP
addresses must contain only numbers and periods and
be in the form "aaa.bbb.ccc.ddd".Did not create hostname.',
'hos_DNS_FORWARDER_ENABLED' => 'A DNS forwarder has been configured. This means that all DNS
lookups will be handled by the DNS forwarder. Hostnames
and addresses cannot be modified on this server while
a DNS forwarder is configured.',
'hos_ADD_HOSTNAME' => 'Add hostname',
'hos_HOSTNAME' => 'Hostname',
'hos_HOSTTYPE' => 'Location',
'hos_LOCAL_IP' => 'Local IP',
'hos_ETHERNET_ADDRESS' => 'Ethernet address',
'hos_CURRENT_HOSTNAMES_FOR_DOMAIN' => 'Current list of hostnames for [_1].',
'hos_NO_HOSTNAMES_FOR_SERVICENAME' => 'There are no hostnames in the system for [_1].',
'hos_CURRENT_HOSTNAMES_FOR_LOCAL_DOMAIN' => 'Current list of hostnames for [_1]',
'hos_NO_HOSTNAMES_FOR_LOCAL_DOMAIN' => 'There are no hostnames in the system for [_1].',
'hos_STATIC_HOST_MESSAGE' => '- This host represents your system name and cannot be modifiedor removed.',
'hos_CREATE_LOCAL_HOST_TITLE' => 'Create a new hostname for this server',
'hos_HOSTNAME_VALIDATION_ERROR' => 'Error: unexpected characters in host name: "[_1]".
The host name should contain only
letters, numbers, and hyphens and must start
with a letter or a number.',
'hos_HOSTNAME_LENGTH_ERROR' => 'Error: account name [_1] is too long. The
maximum is 32 characters.',
'hos_DOMAIN_VALIDATION_ERROR' => 'Error: unexpected or missing characters in domain name
[_1]. The domain name should contain one or more
letters, numbers, periods and minus signs. Did not create new
domain.',
'hos_HOSTNAME_EXISTS_ERROR' => 'Error: account [_1] hostname.',
'hos_SUCCESSFULLY_CREATED' => 'Successfully created hostname.',
'hos_ERR_IP_IS_LOCAL_OR_GATEWAY' => 'Error: IP cannot be server IP or Gateway IP.',
'hos_ERR_IP_NOT_LOCAL' => 'Error: This IP address is not on any of our local networks.',
'hos_ERROR_WHILE_CREATING_HOST' => 'Error occurred while creating hostname.',
'hos_ERROR_WHILE_DELETING_HOST' => 'Error occurred while deleting hostname.',
'hos_ERROR_WHILE_MODIFYING_HOST' => 'Error occurred while modifying hostname.',
'hos_ETHERNET_ADDRESS' => 'Ethernet address',
'hos_ETHERNET_ADDRESS_DESCRIPTION' => 'The ethernet address is optional and causes the DHCP server to
statically bind the local IP address to the computer with this
ethernet address. If specified, it must be of the form
"AA:BB:CC:DD:EE:FF" and must contain only the numbers 0-9 and
the letters A-F.',
'hos_FORM_TITLE' => 'Hostnames and addresses',
'hos_HOSTNAME_COMMENT_ERROR' => 'Error: unexpected characters in the comment of "[_1]".
The comment must contain only letters, spaces, numbers, dots, commas, undescores, hyphens and must start with a letter or number.',
'hos_HOSTNAME_DESCRIPTION' => 'The hostname must contain only letters, numbers, and hyphens, and must start with a letter or number. ',
'hos_HOSTNAME_EXISTS_ERROR' => 'Error: account [_1] hostname.',
'hos_HOSTNAME_LENGTH_ERROR' => 'Error: account name [_1] is too long. The
maximum is 32 characters.',
'hos_HOSTNAME_VALIDATION_ERROR' => 'Error: unexpected characters in host name: "[_1]".
The host name should contain only
letters, numbers, and hyphens and must start
with a letter or a number.',
'hos_HOSTNAME_VALIDATOR_ERROR' => 'Error: unexpected characters in host name: "[_1]". The host name should contain only
letters, numbers, and hyphens and must start with a letter or a number. ',
'hos_IP_VALIDATION_ERROR' => 'Error: IP Address [_1] is
invalid. IP Addresses must contain only numbers and periodsand be in the form "aaa.bbb.ccc.ddd". Did not create hostname.',
'hos_LOCAL_IP' => 'Local IP',
'hos_LOCAL_IP_DESCRIPTION' => 'The Local IP address is the IP address of another machine on
the local network. Please enter a valid IP address in the
format "aaa.bbb.ccc.ddd".',
'hos_ETHERNET_ADDRESS_DESCRIPTION' => 'The ethernet address is optional and causes the DHCP server to
statically bind the local IP address to the computer with this
ethernet address.If specified, it must be of the form
"AA:BB:CC:DD:EE:FF" and must contain only the numbers 0-9 and
the letters A-F.',
'hos_CREATE_LOCAL_HOST_TITLE' => 'Create a new hostname referring to a local host.',
'hos_DIDNT_ENTER_LOCAL_IP' => 'Error: You did not specify a Local IP address.IP
addresses must contain only numbers and periods and
be in the form "aaa.bbb.ccc.ddd".Did not create hostname.',
'hos_IP_VALIDATION_ERROR' => 'Error: IP Address [_1] is
invalid. IP Addresses must contain only numbers and periodsand be in the form "aaa.bbb.ccc.ddd". Did not create hostname.',
'hos_LOCAL_PAGE_DESCRIPTION' => 'Please enter the following additional details for a localhost:',
'hos_MAC_ADDRESS_VALIDATION_ERROR' => 'Error: Ethernet address [_1]
is invalid.Ethernet addresses must be in the
is invalid. Ethernet addresses must be in the
form "AA:BB:CC:DD:EE:FF" and only contain the
numbers 0-9 and the letters A-F. Did not create
hostname.',
'hos_CREATE_REMOTE_HOST_TITLE' => 'Create a new hostname referring to a remote host',
'hos_CREATE_TITLE' => 'Create or modify hostname',
'hos_MODIFY_TITLE' => 'Modify hostname',
'hos_LOCAL_PAGE_DESCRIPTION' => 'Please enter the following additional details for a localhost:',
'hos_MUST_BE_VALID_HOSTNAME_OR_IP' => 'Must be a valid hostname or IP number',
'hos_NO_HOSTNAMES_FOR_LOCAL_DOMAIN' => 'There are no hostnames in the system for [_1].',
'hos_NO_HOSTNAMES_FOR_SERVICENAME' => 'There are no hostnames in the system for [_1].',
'hos_NO_HOSTS_FOR_THIS_DOMAIN' => 'There are no hosts for this domain.',
'hos_REMOTE_PAGE_DESCRIPTION' => 'Please enter the following additional details for a remotehost:',
'hos_REMOVE_PAGE_DESCRIPTION' => 'You are about to remove the hostname "[_1]"',
'hos_REMOVE_TITLE' => 'Remove hostname',
'hos_STATIC_HOST_MESSAGE' => '- This host represents your system name and cannot be modifiedor removed.',
'hos_SUCCESSFULLY_CREATED' => 'Successfully created hostname.',
'hos_SUCCESSFULLY_DELETED' => 'Successfully deleted host.',
'hos_SUCCESSFULLY_MODIFIED' => 'Successfully modified host.',
'hos_REMOVE_TITLE' => 'Remove hostname',
'hos_REMOVE_PAGE_DESCRIPTION' => 'You are about to remove the hostname "[_1]"',
'hos_ABOUT_TO_REMOVE' => 'Are you sure you wish to remove this hostname?',
'hos_CONFIRM_DESCRIPTION' => 'Please confirm the following details.',
'hos_NO_HOSTS_FOR_THIS_DOMAIN' => 'There are no hosts for this domain.',
'hos_ADDR_IN_DHCP_RANGE' => 'Address is inside the DHCP assigned dynamic range',
'hos_ERROR_WHILE_CREATING_HOST' => 'Error occurred while creating hostname.',
'hos_ERROR_WHILE_MODIFYING_HOST' => 'Error occurred while modifying hostname.',
'hos_ERROR_WHILE_DELETING_HOST' => 'Error occurred while deleting hostname.',
'hos_ERR_IP_IS_LOCAL_OR_GATEWAY' => 'Error: IP cannot be server IP or Gateway IP.',
'hos_ERR_IP_NOT_LOCAL' => 'Error: This IP address is not on any of our local networks.',
'hos_MUST_BE_VALID_HOSTNAME_OR_IP' => 'Must be a valid hostname or IP number',
'hos_HOSTNAME_COMMENT_ERROR' => 'Error: unexpected characters in the comment of "[_1]".
The comment must contain only letters, spaces, numbers, dots, commas, undescores, hyphens and must start with a letter or number.',
'hos_HOSTNAME_VALIDATOR_ERROR' => 'Error: unexpected characters in host name: "[_1]". The host name should contain only
letters, numbers, and hyphens and must start with a letter or a number. ',
'hos_UNABLE_TO_OPEN_CONFIGDB' => 'Unable to open configuration database',
'Hostnames and addresses' => 'Hostnames and addresses',

View File

@@ -1,13 +1,37 @@
'iba_FORM_TITLE' => 'Create, modify, or remove i-bays',
#
# Lex file for Ibays generated on 2025-07-17 09:52:32
#
'ENTIRE_INTERNET_NO_PASSWORD' => 'Entire Internet (no password required)',
'ENTIRE_INTERNET_PASSWORD' => 'Entire Internet (password required)',
'ENTIRE_INTERNET_PASSWORD_REMOTE' => 'Entire Internet (password required outside local network)',
'iba_ACCOUNT_EXISTS' => 'The account "[_1]" is an existing [_2] account.',
'iba_ACCT_CLASHES_WITH_PSEUDONYM' => 'The account "[_1]" clashes with pseudonym
details for [_2] account "[_3]".
<p>[_1] is a pseudonym for [_2].</p>',
'iba_ACCT_NAME_HAS_INVALID_CHARS' => 'The i-bay name "[_1]" contains invalid characters.
I-bay names must start with a lower case letter and contain
only lower case letters, numbers, and hyphens.',
'iba_ADD_IBAY' => 'Add ibay',
'iba_ADD_TITLE' => 'Create or modify an i-bay',
'iba_ALLOW_DYNAMIC_CONTENT' => 'Execution of dynamic content (CGI, PHP, SSI)',
'iba_CANT_CREATE_IBAY' => 'Can"t create new account for [_1] (does it already exist?)',
'iba_CANT_FIND_IBAY' => 'Can"t find account for [_1] (does it exist?)',
'iba_ERROR_WHILE_CREATING_IBAY' => 'An error occurred while creating the i-bay.',
'iba_ERROR_WHILE_DELETING_IBAY' => 'An error occurred while deleting the i-bay.',
'iba_ERROR_WHILE_MODIFYING_IBAY' => 'An error occurred while modifying the i-bay.',
'iba_ERROR_WHILE_RESETTING_PASSWORD' => 'Error while resetting password.',
'iba_FIRSTPAGE_DESC' => 'You can remove any information bay or reset its password by
clicking on the corresponding command
next to the information bay. If the information bay shows up
in red, that means that the password has not
yet been changed from the default, and should be changed
soon.',
'iba_ADD_TITLE' => 'Create or modify an i-bay',
'iba_FORM_TITLE' => 'Create, modify, or remove i-bays',
'iba_HTTPS_Only' => 'Force secure connections',
'iba_IBAY_PASSWD_VALIDATION_ERROR' => 'The password may contain only letters and numbers.',
'iba_IBAY_PASSWD_VERIFY_ERROR' => 'The passwords do not match.',
'iba_MAX_IBAY_NAME_LENGTH_ERROR' => 'The i-bay name "[_1]" is too long. The maximum is
[_2] characters.',
'iba_NAME_FIELD_DESC' => 'The information bay name should contain only lower-case
letters, numbers, periods, hyphens and underscores, and
should start with a lower-case letter. For example
@@ -15,57 +39,35 @@ should start with a lower-case letter. For example
names, but "3associates", "John Smith" and
"Bus!Partner" are not. The name is limited to [_1] characters.',
'iba_NAME_LABEL' => 'Information bay name',
'iba_USER_ACCESS' => 'User access via file sharing or user ftp',
'iba_NO_IBAYS' => 'There are no i-bays currently configured.',
'iba_PASSWORD_DESC' => 'You are about to change the password for the i-bay [_1].',
'iba_PUBLIC_ACCESS' => 'Public access via web or anonymous ftp',
'iba_PUBLIC_ACCESS_DESCRIPTION' => 'The public access mode "password required outside local
network" is not supported by the FTP server component. If
you select this mode, the FTP server will require a
password both inside and outside the local network for this
i-bay.',
'iba_ALLOW_DYNAMIC_CONTENT' => 'Execution of dynamic content (CGI, PHP, SSI)',
'iba_HTTPS_Only' => 'Force secure connections',
'iba_REMOVE_TITLE' => 'Remove information bay',
'iba_REMOVE_DESC' => '<p>You are about to remove the information bay [_1] ([_2]).
</p><p>All files belonging to this information bay will be deleted.
</p><p>Are you sure you wish to remove this information bay?
</p>',
'iba_ERROR_WHILE_CREATING_IBAY' => 'An error occurred while creating the i-bay.',
'iba_REMOVE_TITLE' => 'Remove information bay',
'iba_SUCCESSFULLY_CREATED_IBAY' => 'Successfully created i-bay.',
'iba_NO_IBAYS' => 'There are no i-bays currently configured.',
'iba_CANT_FIND_IBAY' => 'Can\'t find account for [_1] (does it exist?)',
'iba_CANT_CREATE_IBAY' => 'Can\'t create new account for [_1] (does it already exist?)',
'iba_ERROR_WHILE_MODIFYING_IBAY' => 'An error occurred while modifying the i-bay.',
'iba_SUCCESSFULLY_MODIFIED_IBAY' => 'Successfully modified i-bay.',
'iba_VIRTUAL_HOST_MESSAGE' => 'The following virtual domains were using this information
bay as their content and will be changed to the primary web
site (you can change them to something else afterward).',
'iba_SUCCESSFULLY_DELETED_IBAY' => 'Successfully deleted i-bay.',
'iba_ERROR_WHILE_DELETING_IBAY' => 'An error occurred while deleting the i-bay.',
'iba_PASSWORD_DESC' => 'You are about to change the password for the i-bay [_1].',
'iba_IBAY_PASSWD_VALIDATION_ERROR' => 'The password may contain only letters and numbers.',
'iba_IBAY_PASSWD_VERIFY_ERROR' => 'The passwords do not match.',
'iba_SUCCESSFULLY_MODIFIED_IBAY' => 'Successfully modified i-bay.',
'iba_SUCCESSFULLY_RESET_PASSWORD' => 'Successfully reset password.',
'iba_ERROR_WHILE_RESETTING_PASSWORD' => 'Error while resetting password.',
'iba_USER_ACCESS' => 'User access via file sharing or user ftp',
'iba_VHOST_MESSAGE' => '<P>The following virtual domains were using this information bay
as their content and will be changed to the primary web site
(you can change them to something else afterward):</P>',
'iba_VIRTUAL_HOST_MESSAGE' => 'The following virtual domains were using this information
bay as their content and will be changed to the primary web
site (you can change them to something else afterward).',
'Information bays' => 'Information bays',
'WGRG' => 'Write = group, Read = group',
'WGRE' => 'Write = group, Read = everyone',
'WARG' => 'Write = admin, Read = group',
'NONE' => 'No access',
'INVALID_IBAY_DESCRIPTION' => 'Error: unexpected or missing characters in i-bay description',
'LOCAL_NETWORK_NO_PASSWORD' => 'Local network (no password required)',
'LOCAL_NETWORK_PASSWORD' => 'Local network (password required)',
'ENTIRE_INTERNET_NO_PASSWORD' => 'Entire Internet (no password required)',
'ENTIRE_INTERNET_PASSWORD' => 'Entire Internet (password required)',
'ENTIRE_INTERNET_PASSWORD_REMOTE' => 'Entire Internet (password required outside local network)',
'INVALID_IBAY_DESCRIPTION' => 'Error: unexpected or missing characters in i-bay description',
'iba_ACCT_NAME_HAS_INVALID_CHARS' => 'The i-bay name "[_1]" contains invalid characters.
I-bay names must start with a lower case letter and contain
only lower case letters, numbers, and hyphens.',
'iba_MAX_IBAY_NAME_LENGTH_ERROR' => 'The i-bay name "[_1]" is too long. The maximum is
[_2] characters.',
'iba_ACCT_CLASHES_WITH_PSEUDONYM' => 'The account "[_1]" clashes with pseudonym
details for [_2] account "[_3]".
<p>[_1] is a pseudonym for [_2].</p>',
'iba_ACCOUNT_EXISTS' => 'The account "[_1]" is an existing [_2] account.',
'NONE' => 'No access',
'WARG' => 'Write = admin, Read = group',
'WGRE' => 'Write = group, Read = everyone',
'WGRG' => 'Write = group, Read = group',

View File

@@ -1,30 +1,34 @@
'ln_LOCAL NETWORKS' => 'Local networks',
'Local networks' => 'Local networks',
'ln_FIRSTPAGE_DESC' => 'For security reasons, several services on your server are available only to your local network. However you can grant these local access privileges to additional networks by listing them below. Most installations should leave this list empty.',
#
# Lex file for Localnetworks generated on 2025-07-17 09:52:32
#
'ln_ADD_DESC' => 'Each parameter must be in the form #.#.#.# (each # is a number from 0 to 255). The server software will zero out the ending (host identifier) part of the network address according to the subnet mask, to ensure that the network address is valid. </P><P> "Router" should be the IP address of the router on your local network via which the additional network is reached.',
'ln_ADD_TITLE' => 'Add a local network ',
'ln_ADD_DESC' =>'Each parameter must be in the form #.#.#.# (each # is a number from 0 to 255). The server software will zero out the ending (host identifier) part of the network address according to the subnet mask, to ensure that the network address is valid. </P><P> "Router" should be the IP address of the router on your local network via which the additional network is reached.',
'ln_NETWORK_ADDRESS' => 'Network address',
'ln_SUBNET_MASK' => 'Subnet mask',
'ln_DEFAULT' => 'default',
'ln_ERROR_CREATING_NETWORK' => 'Error occurred while creating network.',
'ln_ERROR_DELETING_NETWORK' => 'Error occurred while deleting network.',
'ln_extra' => '[_1]/[_2] via router $networkRouter}.',
'ln_Failed to find network in Db' => 'Failed to find network in Db',
'ln_FIRSTPAGE_DESC' => 'For security reasons, several services on your server are available only to your local network. However you can grant these local access privileges to additional networks by listing them below. Most installations should leave this list empty.',
'ln_INVALID_IP_ADDRESS' => 'Invalid IP address - [_1]',
'ln_INVALID_SUBNET_MASK' => 'Invalid subnet mask',
'ln_REMOVE_TITLE' => 'Remove local network',
'ln_REMOVE_DESC' => 'You are about to remove the following local network.',
'ln_REMOVE_CONFIRM' => 'Are you sure you wish to remove this network?',
'ln_DEFAULT' => 'default',
'ln_NUMBER_OF_HOSTS' => 'Number of hosts',
'ln_NOT_ACCESSIBLE_FROM_LOCAL_NETWORK' => 'Error: router address {$networkRouter} is not accessible from local network. Did not add network.',
'ln_LOCALNETWORK_ADD'=>'Add network',
'ln_NETWORK_ALREADY_LOCAL' => ' Error: network {$network} (derived from network {$networkAddress} and subnet mask {$networkMask}) is already considered local. Did not add new network. ',
'ln_NETWORK_ALREADY_ADDED' => 'Error: network {$network} (derived from network {$networkAddress} and subnet mask {$networkMask}) has already been added. Did not add new network.',
'ln_ERROR_CREATING_NETWORK' => 'Error occurred while creating network.',
'ln_SUCCESS' =>'Successfully added network [_1]/[_2] via router [_3].',
'ln_SUCCESS_SINGLE_ADDRESS' =>'Successfully added network {$network}/{$networkMask} via router {$networkRouter}. Your server will grant local access privileges to the single IP address {$network}. ',
'ln_SUCCESS_NETWORK_RANGE' =>'Successfully added network [_1]/[_2] via router [_3]. Your server will grant local access privileges to [_4] IP addresses in the range [_5] to [_6]. ',
'ln_NO_SUCH_NETWORK' =>'Network not found in network db',
'ln_SUCCESS_REMOVED_NETWORK' =>'Successfully removed network [_1]/[_2] via router [_3].',
'ln_ERROR_DELETING_NETWORK' => 'Error occurred while deleting network.',
'ln_LOCAL NETWORKS' => 'Local networks',
'ln_LOCALNETWORK_ADD' => 'Add network',
'ln_NETWORK_ADDRESS' => 'Network address',
'ln_NETWORK_ALREADY_ADDED' => 'Error: network [_1] (derived from network [_1] and subnet mask [_2]) has already been added. Did not add new network.',
'ln_NETWORK_ALREADY_LOCAL' => ' Error: network [_1] (derived from network [_1] and subnet mask [_2]) is already considered local. Did not add new network. ',
'ln_NO_ADDITIONAL_NETWORKS' => 'No additional networks',
'ln_NO_SUCH_NETWORK' => 'Network not found in network db',
'ln_NOT_ACCESSIBLE_FROM_LOCAL_NETWORK' => 'Error: router address [_3] is not accessible from local network. Did not add network.',
'ln_NUMBER_OF_HOSTS' => 'Number of hosts',
'ln_REMOVE_CONFIRM' => 'Are you sure you wish to remove this network?',
'ln_REMOVE_DESC' => 'You are about to remove the following local network.',
'ln_REMOVE_HOSTS_DESC' => 'Local hosts configured on the network you are about to remove have been detected. By default, they will also be removed. Uncheck this box if, for some reason, you do not wish this to happen. Note that they will not be treated as local, and may not even be reachable, after this network is removed. ',
'ln_REMOVE_HOSTS_LABEL' => 'Remove hosts on network',
'ln_extra' => '{$network}/{$networkMask} via router $networkRouter}.',
'ln_SUCCESS_NONSTANDARD_RANGE' =>'<p>Successfully added network [_1]/[_2] via router [_3].</p><p> Your server will grant local access privileges to [_4] IP addresses in the range [_5] to [_6].</p><p> Warning: the ProFTPd FTP server cannot handle this nonstandard subnet mask. The simpler specification <b>[_7]</b> will be used instead.</p>',
'ln_REMOVE_TITLE' => 'Remove local network',
'ln_SUBNET_MASK' => 'Subnet mask',
'ln_SUCCESS' => 'Successfully added network [_1]/[_2] via router [_3].',
'ln_SUCCESS_NETWORK_RANGE' => 'Successfully added network [_1]/[_2] via router [_3]. Your server will grant local access privileges to [_4] IP addresses in the range [_5] to [_6]. ',
'ln_SUCCESS_NONSTANDARD_RANGE' => '<p>Successfully added network [_1]/[_2] via router [_3].</p><p> Your server will grant local access privileges to [_4] IP addresses in the range [_5] to [_6].</p><p> Warning: the ProFTPd FTP server cannot handle this nonstandard subnet mask. The simpler specification <b>[_7]</b> will be used instead.</p>',
'ln_SUCCESS_REMOVED_NETWORK' => 'Successfully removed network [_1]/[_2] via router [_3].',
'ln_SUCCESS_SINGLE_ADDRESS' => 'Successfully added network [_1]/[_2] via router [_3]. Your server will grant local access privileges to the single IP address [_1]. ',
'Local networks' => 'Local networks',

View File

@@ -1,56 +1,55 @@
'pf_FORM_TITLE' => 'Configure Port Forwarding',
'pf_FIRST_PAGE_DESCRIPTION' => '<p>
You can use this panel to modify your firewall rules so
as to open a specific port on this server and forward it
to another port on another host. Doing so will permit
incoming traffic to directly access a private host on
your LAN.
</p><p>
WARNING: Misuse of this feature can seriously compromise the
security of your network. Do not use this feature
lightly, or without fully understanding the implications
of your actions.
</p>',
'pf_CREATE_RULE' => 'Create portforwarding rule',
'pf_SUMMARY_ADD_DESC' => 'The following summarizes the port-forwarding rule
that you are about to add. If you are satisfied with the rule,
click the \'Add\' button.',
'pf_SUMMARY_REMOVE_DESC' => 'The following summarizes the port-forwarding rule
that you are about to remove. If you are sure you want to
remove the rule, click the \'Remove\' button.',
'pf_SHOW_FORWARDS' => 'Below you will find a table summarizing the current
port-forwarding rules installed on this server. Click on the
\'Remove\' link to remove the corresponding rule.',
'pf_NO_FORWARDS' => 'There are currently no forwarded ports on the system.',
'pf_CREATE_PAGE_DESCRIPTION' => '<p>Select the protocol, the port you wish to forward, the
#
# Lex file for Portforwarding generated on 2025-07-17 09:52:32
#
'pf_ALLOW_HOSTS' => 'Allow Hosts',
'pf_CREATE_PAGE_DESCRIPTION' => 'Select the protocol, the port you wish to forward, the
destination host, and the port on the destination host
that you wish to forward to. If you wish to specify a port
range, enter the lower and upper boundaries separated by a
hyphen. The destination port may be left blank, which will
instruct the firewall to leave the source port
unaltered.</p>',
'pf_LABEL_SOURCE_PORT' => 'Source Port(s)',
'pf_LABEL_PROTOCOL' => 'Protocol',
'pf_LABEL_DESTINATION_PORT' => 'Destination Port(s)',
'pf_LABEL_DESTINATION_HOST' => 'Destination Host IP Address',
'pf_LABEL_RULE_COMMENT' => 'Rule Comment',
'pf_LABEL_ALLOW_HOSTS' => 'Allow Hosts',
'Port forwarding' => 'Port forwarding',
'pf_SUCCESS' => 'Your change to the port forwarding rules has been successfully saved.',
'pf_RULE_COMMENT' => 'Rule Comment',
'pf_ALLOW_HOSTS' => 'Allow Hosts',
'pf_ERR_NO_MASQ_RECORD' => 'Cannot retrieve masq record from the configuration database.',
'pf_ERR_UNSUPPORTED_MODE' => 'Unsupported mode.',
'pf_ERR_CANNOT_REMOVE_NORULE' => 'Cannot remove non-existant rule.',
'pf_ERR_NONZERO_RETURN_EVENT' => 'Event returned a non-zero return value.',
'pf_ERR_BADPORT' => 'The ports must be a positive integer less than 65536.',
unaltered',
'pf_CREATE_RULE' => 'Create portforwarding rule',
'pf_ERR_BADAHOST' => 'This does not appear to be a valid IP address list.
ie: 192.168.0.1,192.168.1.1/24',
'pf_ERR_BADIP' => 'This does not appear to be an IP address. You must use
dotted-quad notation, and each of the four numbers should be less
than 256. ie: 192.168.0.5',
'pf_ERR_BADPORT' => 'The ports must be a positive integer less than 65536.',
'pf_ERR_CANNOT_REMOVE_NORULE' => 'Cannot remove non-existant rule.',
'pf_ERR_DUPRULE' => 'This rule has already been added, it cannot be added twice.',
'pf_ERR_NO_MASQ_RECORD' => 'Cannot retrieve masq record from the configuration database.',
'pf_ERR_NONZERO_RETURN_EVENT' => 'Event returned a non-zero return value.',
'pf_ERR_PORT_COLLISION' => 'ERROR: This port or port range conflicts with an existing
rule. Please modify this new rule, or remove the old rule.',
'pf_ERR_BADAHOST' => 'This does not appear to be a valid IP address list.
ie: 192.168.0.1,192.168.1.1/24',
'pf_ERR_UNSUPPORTED_MODE' => 'Unsupported mode.',
'pf_FIRST_PAGE_DESCRIPTION' => 'You can use this panel to modify your firewall rules so
as to open a specific port on this server and forward it
to another port on another host. Doing so will permit
incoming traffic to directly access a private host on
your LAN.
WARNING: Misuse of this feature can seriously compromise the
security of your network. Do not use this feature
lightly, or without fully understanding the implications
of your actions.',
'pf_FORM_TITLE' => 'Configure Port Forwarding',
'pf_IN_SERVERONLY' => 'This server is currently in serveronly mode and portforwarding
is possible only to localhost.',
'pf_LABEL_ALLOW_HOSTS' => 'Allow Hosts',
'pf_LABEL_DESTINATION_HOST' => 'Destination Host IP Address',
'pf_LABEL_DESTINATION_PORT' => 'Destination Port(s)',
'pf_LABEL_RULE_COMMENT' => 'Rule Comment',
'pf_LABEL_SOURCE_PORT' => 'Source Port(s)',
'pf_NO_FORWARDS' => 'There are currently no forwarded ports on the system.',
'pf_RULE_COMMENT' => 'Rule Comment',
'pf_SHOW_FORWARDS' => 'Below you will find a table summarizing the current
port-forwarding rules installed on this server. Click on the
"Remove" link to remove the corresponding rule.',
'pf_SUCCESS' => 'Your change to the port forwarding rules has been successfully saved.',
'pf_SUMMARY_ADD_DESC' => 'The following summarizes the port-forwarding rule
that you are about to add. If you are satisfied with the rule,
click the "Add" button.',
'pf_SUMMARY_REMOVE_DESC' => 'The following summarizes the port-forwarding rule
that you are about to remove. If you are sure you want to
remove the rule, click the "Remove" button.',
'Port forwarding' => 'Port forwarding',

View File

@@ -1,12 +1,11 @@
'prt_FORM_TITLE' => 'Add or remove printers',
'prt_INITIAL_BTN' => 'Add printer',
'prt_INITIAL_DESC' => '<P><A class="button-like" HREF="printers?page=0&Next=Add">Add printer</A></P>',
'prt_NO_PRINTERS' => 'There are no printers in the system.',
'prt_CURRENT_LIST' => 'Current List of printers',
'prt_REMOTE_ADDRESS' => 'Remote address',
'prt_REMOTE_NAME' => 'Remote name',
'prt_CREATE_NEW_PRINTER' => 'Create a new printer',
#
# Lex file for Printers generated on 2025-07-17 09:52:33
#
'Printers' => 'Printers',
'prt_ABOUT_TO_REMOVE' => 'You are about to remove the printer: ',
'prt_ARE_YOU_SURE' => 'Are you sure you wish to remove this printer?',
'prt_CREATE_NETWORK_DESC' => 'Please enter the address and name of the network printer',
'prt_CREATE_NETWORK_PRINTER' => 'Create a new network printer',
'prt_CREATE_NEW_DESC' => 'Please choose a unique name for the printer and enter a brief
description. The printer name should contain only lower-case
letters and numbers, and should start with a lower-case
@@ -17,36 +16,39 @@ letter. For example "hplaser", "epsonlp", and
Avoid names and descriptions that contain these terms,
"offline", "disabled", "down", "off", "waiting", "jam",
"paper", "error" and "responding". ',
'prt_PRINTER_NAME' => 'Printer name',
'prt_LOCAL_PRINTER_0' => 'Local printer port 0 (LPT1)',
'prt_LOCAL_PRINTER_1' => 'Local printer port 1 (LPT2)',
'prt_LOCAL_PRINTER_2' => 'Local printer port 2 (LPT3)',
'prt_NET_PRINTER' => 'Network printer ...',
'prt_FIRST_USB_PRINTER' => 'First USB attached printer',
'prt_SECOND_USB_PRINTER' => 'Second USB attached printer',
'prt_CREATE_NEW_PRINTER' => 'Create a new printer',
'prt_CREATED_SUCCESSFULLY' => 'Successfully created printer: ',
'prt_CURRENT_LIST' => 'Current List of printers',
'prt_DELETED_SUCCESSFULLY' => 'Successfully deleted printer: ',
'prt_ERR_CREATING' => 'Error occurred while creating printer.',
'prt_ERR_DELETING' => 'Error occurred while deleting printer.',
'prt_ERR_EXISTS' => 'Error: An account with the same name exists with type: ',
'prt_ERR_INTERNAL_FAILURE' => 'Error: internal failure while removing printer: ',
'prt_ERR_INVALID_ADDRESS' => 'Error: invalid network address. Did not create new printer.',
'prt_ERR_INVALID_REMOTE_NAME' => 'Error: invalid network printer name. Did not create new printer.',
'prt_ERR_OPENING_DB' => 'Error occurred while opening accounts database.',
'prt_ERR_UNEXPECTED_DESC' => 'Error: unexpected or missing characters in description.
Did not create new printer.',
'prt_ERR_UNEXPECTED_NAME' => '<P>Error: unexpected characters in printer name.</P>
<P>The printer name should contain only lower-case
letters and numbers, and should start with a lower-case
letter. For example "hplaser", "epsonlp", and
"canonbj" are valid names.</P>',
'prt_ERR_UNEXPECTED_DESC' => 'Error: unexpected or missing characters in description.
Did not create new printer.',
'prt_ERR_EXISTS' => 'Error: An account with the same name exists with type: ',
'prt_ERR_INVALID_ADDRESS' => 'Error: invalid network address. Did not create new printer.',
'prt_ERR_INVALID_REMOTE_NAME' => 'Error: invalid network printer name. Did not create new printer.',
'prt_ERR_CREATING' => 'Error occurred while creating printer.',
'prt_CREATED_SUCCESSFULLY' => 'Successfully created printer: ',
'prt_CREATE_NETWORK_PRINTER' => 'Create a new network printer',
'prt_ERR_OPENING_DB' => 'Error occurred while opening accounts database.',
'prt_CREATE_NETWORK_DESC' => 'Please enter the address and name of the network printer',
'prt_FIRST_USB_PRINTER' => 'First USB attached printer',
'prt_FORM_TITLE' => 'Add or remove printers',
'prt_HOSTNAME_OR_IP' => 'Hostname or IP address of the network printer',
'prt_INITIAL_BTN' => 'Add printer',
'prt_INITIAL_DESC' => '<P><A class="button-like" HREF="printers?page=0&Next=Add">Add printer</A></P>',
'prt_LOCAL_PRINTER_0' => 'Local printer port 0 (LPT1)',
'prt_LOCAL_PRINTER_1' => 'Local printer port 1 (LPT2)',
'prt_LOCAL_PRINTER_2' => 'Local printer port 2 (LPT3)',
'prt_MUST_BE_VALID_HOSTNAME_OR_IP' => 'Must be a valid hostname or IP number',
'prt_NET_PRINTER' => 'Network printer ...',
'prt_NO_PRINTERS' => 'There are no printers in the system.',
'prt_PRINTER_NAME' => 'Printer name',
'prt_REMOTE_ADDRESS' => 'Remote address',
'prt_REMOTE_NAME' => 'Remote name',
'prt_REMOTE_NAME_DESC' => 'Network printer name (enter raw if not sure)',
'prt_REMOVE_PRINTER' => 'Remove printer',
'prt_ABOUT_TO_REMOVE' => 'You are about to remove the printer: ',
'prt_SECOND_USB_PRINTER' => 'Second USB attached printer',
'prt_SPOOL_FILE_WARNING' => 'All the spool files for this printer will be deleted.',
'prt_ARE_YOU_SURE' => 'Are you sure you wish to remove this printer?',
'prt_ERR_INTERNAL_FAILURE' => 'Error: internal failure while removing printer: ',
'prt_ERR_DELETING' => 'Error occurred while deleting printer.',
'prt_DELETED_SUCCESSFULLY' => 'Successfully deleted printer: ',
'prt_MUST_BE_VALID_HOSTNAME_OR_IP' => 'Must be a valid hostname or IP number',
'Printers' => 'Printers',

View File

@@ -1,6 +1,10 @@
'prx_TITLE' => 'Proxy settings',
'prx_FIRST_PAGE_DESCRIPTION' => 'This page allows configuration of the server\'s
#
# Lex file for Proxy generated on 2025-07-17 09:52:33
#
'Proxy settings' => 'Proxy settings',
'prx_ERR_NO_SQUID_REC' => 'ERROR: There is no squid record in the configuration database.',
'prx_ERR_PROXY_UPDATE_FAILED' => 'ERROR: The proxy-update event returned an error.',
'prx_FIRST_PAGE_DESCRIPTION' => 'This page allows configuration of the server"s
proxy settings.
The server includes a transparent proxy and cache for
HTTP traffic. This is enabled by default, but not enforced
@@ -8,12 +12,12 @@ if the server is in &quot;serveronly&quot; mode.
If this server is acting as an e-mail server, connections
from local network clients to external SMTP servers
will default to being redirected to the local e-mail server.',
'prx_HTTP_PROXY_STATUS_DESCRIPTION' => 'The server\'s HTTP proxy works to reduce overall uplink usage by
'prx_HTTP_PROXY_STATUS_DESCRIPTION' => 'The server"s HTTP proxy works to reduce overall uplink usage by
caching recently-visited pages. It is transparent to web browsers
using this server as their gateway. Enable or disable this proxy
with the following toggle.',
'prx_HTTP_PROXY_STATUS_LABEL' => 'HTTP proxy status',
'prx_SMTP_PROXY_STATUS_DESCRIPTION' => 'The server\'s transparent SMTP proxy works to reduce virus traffic
'prx_SMTP_PROXY_STATUS_DESCRIPTION' => 'The server"s transparent SMTP proxy works to reduce virus traffic
from infected client hosts by forcing all outgoing SMTP traffic
through this server if set to "enabled".
If you wish to use an alternate SMTP server, and this server is
@@ -22,9 +26,5 @@ proxy to "blocked" prevents all SMTP traffic to other servers,
this is the default. The proxy only intercepts/blocks normal smtp
(port 25) traffic.',
'prx_SMTP_PROXY_STATUS_LABEL' => 'SMTP proxy status',
'prx_ERR_PROXY_UPDATE_FAILED' => 'ERROR: The proxy-update event returned an error.',
'prx_ERR_NO_SQUID_REC' => 'ERROR: There is no squid record in the configuration database.',
'prx_SUCCESS' => 'The new proxy settings were applied successfully.',
'prx_BLOCKED' => 'Blocked',
'Proxy settings' => 'Proxy settings',
'prx_TITLE' => 'Proxy settings',

View File

@@ -1,9 +1,12 @@
'pse_NO_PSEUDONYMS' => ' <b>There are no pseudonyms in the system.</b> ',
'pse_REMOVE_PSEUDONYM' => 'Remove pseudonym',
#
# Lex file for Pseudonyms generated on 2025-07-17 09:52:33
#
'pse_ABOUT_TO_REMOVE' => 'You are about to remove the pseudonym: [_1]<br>
<b>Are you sure you wish to continue?</b>',
'pse_FORM_TITLE' => 'Create, modify, or remove pseudonyms',
'pse_CLICK_TO_CREATE' => 'Add pseudonym',
'pse_CREATE_SUCCEEDED' => 'Successfully created pseudonym',
'pse_CURRENT_PSEUDONYMS' => 'Current List of Pseudonyms',
'pse_DESC_PSEUDONYM_NAME' => ' Please select an existing account or group for the pseudonym from the pulldown menu below',
'pse_DESCRIPTION' => '<p>The server automatically creates
an e-mail alias for each group. If you want to define an e-mail
alias for a list of users, simply create a group and the
@@ -14,7 +17,7 @@ For example, you may wish to create a pseudonym
"webmaster" for your "webdevelopers" group or a
pseudonym "joe" for the user "joseph".</p>
<p>The server automatically creates pseudonyms of the form
firstname.lastname and firstname_lastname for every user
firstname. lastname and firstname_lastname for every user
on the system and a pseudonym "everyone" which contains
all users on the system.</p>
<p>Pseudonyms also allow you to create e-mail aliases for valid
@@ -28,22 +31,28 @@ is limited to one further level. For example the pseudonym
"webmaster" can forward to the pseudonym "techsupport" which
then forwards to a specified user "ray". This is useful where
one user is responsiblefor multiple roles and saves having
to change the pseudonym\'s associated with that user many times
to change the pseudonym"s associated with that user many times
in the event that the user departs the organisation.</p>
<p>You can modify or remove a
pseudonym by clicking on the corresponding
command next to the pseudonym.</p>',
'pse_FORM_TITLE' => 'Create, modify, or remove pseudonyms',
'pse_LOCAL_ONLY' => '(local network only)',
'pse_MODIFY_PSEUDONYM' => 'Modify Pseudonym',
'pse_MODIFY_SUCCEEDED' => 'Successfully modified pseudonym',
'pse_NAME_IN_USE' => 'Error: That name is in use You cannot create a pseudonym with that name.',
'pse_NO_PSEUDONYMS' => ' <b>There are no pseudonyms in the system.</b> ',
'pse_NOT_A_PSEUDONYM' => 'That account is not a pseudonym',
'pse_PSEUDONYM_INVALID_DOMAIN' => 'That domain is not hosted on this server',
'pse_PSEUDONYM_INVALID_NOACCT' => 'That account is not hosted on this server',
'pse_PSEUDONYM_INVALID_SAMEACCT' => 'A pseudonym cannot point to the same account',
'pse_PSEUDONYM_NAME' => 'Pseudonym name',
'pse_REMOVE_PSEUDONYM' => 'Remove pseudonym',
'pse_REMOVE_SUCCEEDED' => 'Successfully removed pseudonym',
'pse_SELECT_ACCOUNT' => 'Select account or group',
'pse_SELECT_INTERNAL' => 'Local network only',
'pse_CLICK_TO_CREATE' => 'Add pseudonym',
'pse_PSEUDONYM' => 'Pseudonym',
'pse_USER_OR_GROUP' => 'User or group',
'pse_CURRENT_PSEUDONYMS' => 'Current List of Pseudonyms',
'pse_TITLE_CREATE' => 'Create a pseudonym',
'pse_DESC_PSEUDONYM_NAME' => ' Please select an existing account or group for the pseudonym from the pulldown menu below',
'pse_MODIFY_PSEUDONYM' => 'Modify Pseudonym',
'pse_PSEUDONYM_NAME' => 'Pseudonym name',
'pse_USER_OR_GROUP' => 'User or group',
'pse_VALID_PSEUDONYM_NAMES' => ' The pseudonym
should contain only lower-case letters, numbers, period,
hyphen and underscore
@@ -55,13 +64,4 @@ command next to the pseudonym.</p>',
domains that are valid on this server. For example
"fred@virtualdomain.com" can be forwarded to "mary"
(or to another valid user account).</p> ',
'pse_NAME_IN_USE' => 'Error: That name is in use You cannot create a pseudonym with that name.',
'pse_NOT_A_PSEUDONYM' => 'That account is not a pseudonym',
'pse_PSEUDONYM_INVALID_DOMAIN' => 'That domain is not hosted on this server',
'pse_PSEUDONYM_INVALID_NOACCT' => 'That account is not hosted on this server',
'pse_PSEUDONYM_INVALID_SAMEACCT' => 'A pseudonym cannot point to the same account',
'pse_CREATE_SUCCEEDED' => 'Successfully created pseudonym',
'pse_MODIFY_SUCCEEDED' => 'Successfully modified pseudonym',
'pse_REMOVE_SUCCEEDED' => 'Successfully removed pseudonym',
'pse_EVERYONE' => 'Everyone',
'Pseudonyms' => 'Pseudonyms',

View File

@@ -1,28 +1,32 @@
#
# Lex file for Qmailanalog generated on 2025-07-17 09:52:33
#
'Mail log file analysis' => 'Mail log file analysis',
'qma_BASIC_STATS' => 'Basic statistics',
'qma_Daily_Summary_Report_all' => 'Summary report for all time up to now',
'qma_Daily_Summary_Report_today' => 'Summary report for today up to now',
'qma_Daily_Summary_Report_yesterday' => 'Summary report for yesterday',
'qma_END_OF_REPORT' => 'End of Report',
'qma_FORM_TITLE' => 'Mail Log File Analysis',
'qma_GENERATE_REPORT' => 'Generate report',
'qma_INITIAL_DESC' => '<P>Analysing the mail system log files can aid both in
understanding how your system is performing and in
diagnosing delivery problems. Several different
reports are available.</P>
<P>Please note that it may take several minutes to generate
these reports</P>',
'qma_REPORT_TYPE' => 'Choose a report type',
'qma_GENERATE_REPORT' => 'Generate report',
'qma_INVALID_REPORT_TYPE' => 'Invalid report type: ',
'qma_LIST_OUTGOING' => 'List outgoing messages and recipients',
'qma_SUMMARIZE_QUEUE' => 'Summarize status of mail queue',
'qma_SUCCESSFUL_DELIVERY_DELAY' => 'Successful delivery delay distribution',
'qma_REASONS_DEFERRAL' => 'Reasons for deferral',
'qma_REASONS_FAILURE' => 'Reasons for failure',
'qma_BASIC_STATS' => 'Basic statistics',
'qma_RECIP_STATS' => 'Recipients statistics',
'qma_REASONS_SUCCESS' => 'Reasons for success',
'qma_RECIP_HOSTS' => 'Recipient hosts',
'qma_RECIP_ORDERED' => 'Recipients in best order for mailing lists',
'qma_SENDER_STATS' => 'Sender statistics',
'qma_SENDMAIL_STYLE' => 'Sendmail style log',
'qma_REASONS_SUCCESS' => 'Reasons for success',
'qma_SENDER_UIDS' => 'Sender uids',
'qma_INVALID_REPORT_TYPE' => 'Invalid report type: ',
'qma_RECIP_STATS' => 'Recipients statistics',
'qma_REPORT_GENERATED' => 'Report generated: ',
'qma_END_OF_REPORT' => 'End of Report',
'Mail log file analysis' => 'Mail log file analysis',
'qma_REPORT_TYPE' => 'Choose a report type',
'qma_SENDER_STATS' => 'Sender statistics',
'qma_SENDER_UIDS' => 'Sender uids',
'qma_SENDMAIL_STYLE' => 'Sendmail style log',
'qma_SUCCESSFUL_DELIVERY_DELAY' => 'Successful delivery delay distribution',
'qma_SUMMARIZE_QUEUE' => 'Summarize status of mail queue',

View File

@@ -1,40 +1,39 @@
#
# Lex file for Quota generated on 2025-07-17 09:52:33
#
'quo_ABS_LIMIT' => 'Absolute limit',
'quo_ABS_LIMIT_MB' => 'Absolute limit (MB)',
'quo_ACCOUNT_IS_TYPE' => 'It is an account of type: ',
'quo_COULD_NOT_GET_UID' => 'Could not determine the uid for user: ',
'quo_CURRENT_USAGE' => 'Current usage (MB)',
'quo_CURRENT_USAGE_AND_SETTINGS' => 'Current Quota Usage and Settings',
'quo_CURRENTLY_HAS' => 'currently has: ',
'quo_ERR_HARD_LT_SOFT' => ' Error: absolute limit must be greater than limit with grace time. ',
'quo_ERR_MODIFYING' => 'Error occurred while modifying user.',
'quo_ERR_NO_SUCH_ACCT' => 'Error: there is no account named: ',
'quo_ERR_NOT_A_USER_ACCT' => 'Error: the account is not a user account: ',
'quo_FORM_TITLE' => 'Create, modify, or remove user account quotas',
'quo_UNABLE_TO_OPEN_ACCOUNTS' => 'Unable to open accounts db',
'quo_HARD_VAL_MUST_BE_NUMBER' => 'Error: absolute limit must be a number, optionally followed by one of the unit suffixes K, M, G, or T.',
'quo_INSTRUCTIONS' => 'Enter the quota with optional unit suffix of "K" for kilobytes, "M" for megabytes,
"G" for gigabytes or "T" for terabytes.
Entries with no suffix are assumed to be in megabytes. A setting of "0"
for either limit disables that limit for the corresponding user.',
'quo_LIMIT_WITH_GRACE' => 'Limit with grace period',
'quo_LIMIT_WITH_GRACE_MB' => 'Limit with grace period (MB)',
'quo_MODIFY_USER_TITLE' => 'Modify user quota limits',
'quo_OCCUPYING' => 'occupying: ',
'quo_QUOTA_DESC' => '<p>You can set filesystem quotas for users on your system by clicking
the "Modify" button next to the user you wish to update.
<p>If the user exceeds the "Limit with grace period", warnings will be
generated. If this limit is exceeded for longer than a week or if the
"Absolute limit" is reached, the user will be unable to store any more
files or receive any more e-mail.
<p>A setting of \'0\' for either limit disables that limit for the
<p>A setting of "0" for either limit disables that limit for the
corresponding user.
<p>The disk space for each user includes the user\'s home directory,
<p>The disk space for each user includes the user"s home directory,
e-mail, and any files owned by the user in information bays.',
'quo_CURRENT_USAGE_AND_SETTINGS' => 'Current Quota Usage and Settings',
'quo_LIMIT_WITH_GRACE' => 'Limit with grace period',
'quo_LIMIT_WITH_GRACE_MB' => 'Limit with grace period (MB)',
'quo_ABS_LIMIT' => 'Absolute limit',
'quo_ABS_LIMIT_MB' => 'Absolute limit (MB)',
'quo_CURRENT_USAGE' => 'Current usage (MB)',
'quo_COULD_NOT_GET_UID' => 'Could not determine the uid for user: ',
'quo_ERR_NO_SUCH_ACCT' => 'Error: there is no account named: ',
'quo_ERR_NOT_A_USER_ACCT' => 'Error: the account is not a user account: ',
'quo_ACCOUNT_IS_TYPE' => 'It is an account of type: ',
'quo_MODIFY_USER_TITLE' => 'Modify user quota limits',
'quo_USER' => 'User: ',
'quo_CURRENTLY_HAS' => 'currently has: ',
'quo_FILES' => 'files',
'quo_OCCUPYING' => 'occupying: ',
'quo_MEGABYTES' => 'megabytes',
'quo_INSTRUCTIONS' => 'Enter the quota with optional unit suffix of \'K\' for kilobytes, \'M\' for megabytes,
\'G\' for gigabytes or \'T\' for terabytes.
Entries with no suffix are assumed to be in megabytes. A setting of \'0\'
for either limit disables that limit for the corresponding user.',
'quo_SOFT_VAL_MUST_BE_NUMBER' => 'Error: limit with grace period must be a number, optionally followed by one of the unit suffixes K, M, G, or T.',
'quo_HARD_VAL_MUST_BE_NUMBER' => 'Error: absolute limit must be a number, optionally followed by one of the unit suffixes K, M, G, or T.',
'quo_ERR_HARD_LT_SOFT' => ' Error: absolute limit must be greater than limit with grace time. ',
'quo_ERR_MODIFYING' => 'Error occurred while modifying user.',
'quo_SUCCESSFULLY_MODIFIED' => 'Successfully modified quota for user account: ',
'quo_UNABLE_TO_OPEN_ACCOUNTS' => 'Unable to open accounts db',
'quo_USER' => 'User: ',
'Quotas' => 'Quotas',

View File

@@ -1,19 +1,20 @@
'rbo_FORM_TITLE' => 'Shutdown or reboot',
'rbo_REBOOT' => 'Reboot',
'rbo_REBOOT_SUCCEEDED' => 'Reboot request initiated successfully.',
#
# Lex file for Reboot generated on 2025-07-17 09:52:33
#
'rbo_DESC_REBOOT' => 'Your server has initiated the reboot process.',
'rbo_RECONFIGURE_SUCCEEDED' => 'Reconfiguration request initiated successfully.',
'rbo_DESC_RECONFIGURE' => 'Your server has initiated a full system reconfiguration and reboot.',
'rbo_SHUTDOWN_SUCCEEDED' => 'Shutdown request initiated successfully.',
'rbo_DESC_SHUTDOWN' => 'Your server has initiated the shutdown process.
The process will take several minutes to complete, after which
you can switch off the power.',
'rbo_LABEL_REBOOT' => 'Select Shutdown, Reboot or Reconfigure',
'rbo_DESCRIPTION' => 'You can reboot, shut down your server or perform a full system
reconfiguration from this screen. You must perform a shutdown
before switching the power off. All of these functions take
several minutes to complete.
When you click <b>perform</b> the operation will be initiated immediately, so be ready!',
'rbo_FORM_TITLE' => 'Shutdown or reboot',
'rbo_LABEL_REBOOT' => 'Select Shutdown, Reboot or Reconfigure',
'rbo_REBOOT_SUCCEEDED' => 'Reboot request initiated successfully.',
'rbo_RECONFIGURE_SUCCEEDED' => 'Reconfiguration request initiated successfully.',
'rbo_SHUTDOWN_SUCCEEDED' => 'Shutdown request initiated successfully.',
'Reboot or shutdown' => 'Reboot or shutdown',
'rbo_REBOOT'=> 'Reboot',

View File

@@ -1,35 +1,9 @@
'rma_FORM_TITLE' => 'Change remote access settings',
'rma_DESCRIPTION' => 'For each of the options below, the private setting allows anyone
from your local network to access your server. The
public setting allows access from anywhere on the Internet. The no
access setting disables access. To understand the security
implications of changing these options from the default settings, you
should read the user\'s guide section on remote access.',
'rma_SUCCESS' => 'The new remote access settings have been saved.',
'rma_NO_ACCESS' => 'No Access',
'rma_PASSWORD_LOGIN_PRIVATE' => 'Accept passwords only from local networks',
'rma_PASSWORD_LOGIN_PUBLIC' => 'Accept passwords from anywhere',
'rma_LABEL_TELNET_ACCESS' => 'Telnet access',
'rma_LABEL_FTP_ACCESS' => 'FTP access',
'rma_LABEL_FTP_LOGIN' => 'FTP password access',
'rma_LABEL_PPTP' => 'Number of PPTP clients',
'rma_NUMBER_OF_PPTP_CLIENTS_MUST_BE_LESSER_THAN_NUMBER_OF_IP_IN_DHCP_RANGE' => 'The number of pptp clients is greater than the number of reserved IP for DHCP. You should take a smaller number.',
'rma_LABEL_SSH_PORT' => 'TCP Port for secure shell access',
'rma_LABEL_SSH' => 'Secure shell access',
'rma_LABEL_SSH_ADMIN' => 'Allow administrative command line access over secure shell',
'rma_LABEL_SSH_PASSWORD_ACCESS' => 'Allow secure shell access using standard passwords',
'rma_TITLE_SSH' => 'Secure Shell Settings',
'rma_DESC_SSH' => 'You can control Secure Shell access to your server.
The public setting should only be enabled by
experienced administrators
for remote problem diagnosis and resolution.
We recommend leaving this
parameter set to "No Access"
unless you have a specific reason to do otherwise.',
'rma_TITLE_FTP_ACCESS' => 'FTP Settings',
#
# Lex file for Remoteaccess generated on 2025-07-17 09:52:33
#
'Remote access' => 'Remote access',
'rma_DESC_FTP_ACCESS' => 'You can also control <b>FTP</b> access to your server. We
recommend leaving this parameter set to \'no access\' unless you
recommend leaving this parameter set to "no access" unless you
have a specific reason to do otherwise.
<p>
Note: these settings limit access to the server and override other
@@ -44,50 +18,80 @@ server, if remote access via the secure shell is enabled.
This method of access protects the
passwords and data of the FTP session, whereas standard FTP
provides no protection.</p>',
'rma_TITLE_PPTP' => 'PPTP Settings',
'rma_DESC_IPSECRW' => 'You can allow IPSEC client access to your server, authenticated by
digital certificates. You should leave this feature disabled by setting the value
to the number 0 unless you require IPSEC client access.',
'rma_DESC_IPSECRW_RESET' => 'If you wish to reset all digital certificates, you
can do so here.<br>Any old certificates will no longer
authenticate against the server, so <b><i>all IPSEC clients will
need to import a new certificate!</i></b>.',
'rma_DESC_PPTP' => 'You can allow PPTP access to your server.
You should leave this feature disabled by setting the value
to the number 0 unless you require PPTP access.',
'rma_VALUE_ZERO_OR_POSITIVE' => 'Value must be zero or a positive integer',
'rma_DESC_SERIAL_CONSOLE_ACCESS' => ' <hr class="sectionbar" /><h2>Serial console</h2>
You can allow access to the server console from a terminal
connected to a server serial port.',
'rma_DESC_SSH' => 'You can control Secure Shell access to your server.
The public setting should only be enabled by
experienced administrators
for remote problem diagnosis and resolution.
We recommend leaving this
parameter set to "No Access"
unless you have a specific reason to do otherwise.
Note that an "Autoblock" feature is enabled by default when public access is enabled; to disable or tune this feature, refer to the manual at https://wiki.koozali.org/AutoBlock
',
'rma_DESC_TELNET_ACCESS' => 'WARNING:Telnet is currently enabled, but this feature is
no longer supported. Telnet is inherently insecure and should only
be used in circumstances where no practical alternative exists. You
should change option to [_1] and use
secure shell if remote access is
required. Once disabled, telnet will no longer appear on this
screen. ',
'rma_DESC_VALID_FROM_ENTRIES' => 'To add a new remote management network,
enter the details below.',
'rma_DESCRIPTION' => 'For each of the options below, the private setting allows anyone
from your local network to access your server. The
public setting allows access from anywhere on the Internet. The no
access setting disables access. To understand the security
implications of changing these options from the default settings, you
should read the user"s guide section on remote access.',
'rma_ERR_INVALID_PARAMS' => 'Either provide both a network and subnet mask, or leave both
fields blank.',
'rma_ERR_NO_RECORD' => 'Unable to locate httpd-admin record in configuration db',
'rma_FORM_TITLE' => 'Change remote access settings',
'rma_INVALID_SUBNET_MASK' => 'Invalid subnet mask',
'rma_LABEL_FTP_ACCESS' => 'FTP access',
'rma_LABEL_FTP_LOGIN' => 'FTP password access',
'rma_LABEL_IPSECRW_RESET' => 'Reset digital certificates',
'rma_LABEL_IPSECRW_SESS' => 'Number of IPSEC clients',
'rma_LABEL_PPTP' => 'Number of PPTP clients',
'rma_LABEL_PPTP_ACCESS' => 'PPTP default user access',
'rma_LABEL_SERIAL_CONSOLE_ACCESS' => 'Serial console',
'rma_LABEL_SSH' => 'Secure shell access',
'rma_LABEL_SSH_ADMIN' => 'Allow administrative command line access over secure shell',
'rma_LABEL_SSH_PASSWORD_ACCESS' => 'Allow secure shell access using standard passwords',
'rma_LABEL_SSH_PORT' => 'TCP Port for secure shell access',
'rma_LABEL_TELNET_ACCESS' => 'Telnet access',
'rma_NO_ACCESS' => 'No Access',
'rma_NO_ENTRIES_YET' => 'There are no entries yet',
'rma_NUM_OF_HOSTS' => 'Number of hosts',
'rma_NUMBER_OF_PPTP_CLIENTS_MUST_BE_LESSER_THAN_NUMBER_OF_IP_IN_DHCP_RANGE' => 'The number of pptp clients is greater than the number of reserved IP for DHCP. You should take a smaller number.',
'rma_PASSWORD_LOGIN_PRIVATE' => 'Accept passwords only from local networks',
'rma_PASSWORD_LOGIN_PUBLIC' => 'Accept passwords from anywhere',
'rma_PORT1_ENABLED' => 'Enabled on serial port 1',
'rma_PORT2_ENABLED' => 'Enabled on serial port 2',
'rma_REMOTE_MANAGEMENT' => 'Remote Management',
'rma_VALIDFROM_TITLE' => '[_1]',
'rma_SUBNET_MASK' => 'Subnet mask',
'rma_SUCCESS' => 'The new remote access settings have been saved.',
'rma_TITLE_FTP_ACCESS' => 'FTP Settings',
'rma_TITLE_IPSECRW' => 'IPSEC Client (Roadwarrior) Settings',
'rma_TITLE_PPTP' => 'PPTP Settings',
'rma_TITLE_SSH' => 'Secure Shell Settings',
'rma_TITLE_TELNET_ACCESS' => 'Telnet Settings',
'rma_VALIDFROM_DESC' => 'It is possible to allow hosts on remote networks to access the
server manager by entering those networks here. Use a subnet
mask of 255.255.255.255 to limit the access to the specified host.
Any hosts within the specified range will be able to access the
server manager using HTTPS.',
'rma_DESC_VALID_FROM_ENTRIES' => 'To add a new remote management network,
enter the details below.',
'rma_SUBNET_MASK' => 'Subnet mask',
'rma_NUM_OF_HOSTS' => 'Number of hosts',
'rma_NO_ENTRIES_YET' => 'There are no entries yet',
'rma_INVALID_SUBNET_MASK' => 'Invalid subnet mask',
'rma_ERR_INVALID_PARAMS' => 'Either provide both a network and subnet mask, or leave both
fields blank.',
'rma_ERR_NO_RECORD' => 'Unable to locate httpd-admin record in configuration db',
'Remote access' => 'Remote access',
'rma_LABEL_SERIAL_CONSOLE_ACCESS' => 'Serial console',
'rma_DESC_SERIAL_CONSOLE_ACCESS' => ' <hr class="sectionbar" /><h2>Serial console</h2>
You can allow access to the server console from a terminal
connected to a server serial port.',
'rma_PORT1_ENABLED' => 'Enabled on serial port 1',
'rma_PORT2_ENABLED' => 'Enabled on serial port 2',
'rma_LABEL_PPTP_ACCESS' => 'PPTP default user access',
'rma_TITLE_TELNET_ACCESS' => 'Telnet Settings',
'rma_DESC_TELNET_ACCESS' => 'WARNING:Telnet is currently enabled, but this feature is
no longer supported.Telnet is inherently insecure and should only
be used in circumstances where no practical alternative exists. You
should change option to [_1] and use
secure shell if remote access is
required.Once disabled, telnet will no longer appear on this
screen. ',
'rma_TITLE_IPSECRW' => 'IPSEC Client (Roadwarrior) Settings',
'rma_DESC_IPSECRW' => 'You can allow IPSEC client access to your server, authenticated by
digital certificates. You should leave this feature disabled by setting the value
to the number 0 unless you require IPSEC client access.',
'rma_LABEL_IPSECRW_SESS' => 'Number of IPSEC clients',
'rma_DESC_IPSECRW_RESET' => 'If you wish to reset all digital certificates, you
can do so here.<br>Any old certificates will no longer
authenticate against the server, so <b><i>all IPSEC clients will
need to import a new certificate!</i></b>.',
'rma_LABEL_IPSECRW_RESET' => 'Reset digital certificates',
'rma_VALIDFROM_TITLE' => '[_1]',
'rma_VALUE_ZERO_OR_POSITIVE' => 'Value must be zero or a positive integer',

View File

@@ -1,37 +1,37 @@
'rvw_FORM_TITLE' => 'Review configuration',
#
# Lex file for Review generated on 2025-07-17 09:52:34
#
'Review configuration' => 'Review configuration',
'rvw_ADDITIONAL_LOCAL_NETWORKS' => 'Additional local networks',
'rvw_BEGINNING_OF_DHCP_ADDRESS_RANGE' => 'Beginning of DHCP address range',
'rvw_DESCRIPTION' => 'This report summarizes the networking, server, and domain
parameters on this server relevant to configuring
the client computers on your network.You may wish to print this
the client computers on your network. You may wish to print this
page and use it as a reference.',
'rvw_NETWORKING_PARAMS' => 'Networking Parameters',
'rvw_SERVER_MODE' => 'Server Mode',
'rvw_LOCAL_IP_ADDRESS_SUBNET_MASK' => 'Local IP address / subnet mask',
'rvw_EXTERNAL_IP_ADDRESS_SUBNET_MASK' => 'External IP address / subnet mask',
'rvw_GATEWAY' => 'Gateway',
'rvw_ADDITIONAL_LOCAL_NETWORKS' => 'Additional local networks',
'rvw_DHCP_SERVER' => 'DHCP server',
'rvw_BEGINNING_OF_DHCP_ADDRESS_RANGE' => 'Beginning of DHCP address range',
'rvw_END_OF_DHCP_ADDRESS_RANGE' => 'End of DHCP address range',
'rvw_SERVER_NAMES' => 'Server names',
'rvw_DNS_SERVER' => 'DNS server',
'rvw_WEB_SERVER' => 'Web server',
'rvw_PROXY_SERVER' => 'Proxy server',
'rvw_FTP_SERVER' => 'FTP server',
'rvw_SMTP_POP_AND_IMAP_MAIL_SERVERS' => 'SMTP, POP, and IMAP mail servers',
'rvw_HOSTS' => 'Hosts',
'rvw_DOMAIN_INFORMATION' => 'Domain information',
'rvw_PRIMARY_DOMAIN' => 'Primary domain',
'rvw_VIRTUAL_DOMAINS' => 'Virtual domains',
'rvw_PRIMARY_WEB_SITE' => 'Primary web site',
'rvw_SERVER_MANAGER' => 'Server manager',
'rvw_USER_PASSWORD_PANEL' => 'User password panel',
'rvw_EMAIL_ADDRESSES' => 'Email Addresses',
'rvw_EMAIL_USERACCOUNT' => 'useraccount',
'rvw_EMAIL_FIRSTNAME' => 'firstname',
'rvw_EMAIL_LASTNAME' => 'lastname',
'rvw_NO_VIRTUAL_DOMAINS' => 'No virtual domains defined',
'rvw_NO_NETWORKS' => 'No additional networks defined',
'rvw_END_OF_DHCP_ADDRESS_RANGE' => 'End of DHCP address range',
'rvw_EXTERNAL_IP_ADDRESS_SUBNET_MASK' => 'External IP address / subnet mask',
'rvw_FORM_TITLE' => 'Review configuration',
'rvw_FTP_SERVER' => 'FTP server',
'rvw_HOSTS' => 'Hosts',
'rvw_INTERNET_VISIBLE_ADDRESS' => 'Internet Visible IP Address',
'Review configuration' => 'Review configuration',
'rvw_LOCAL_IP_ADDRESS_SUBNET_MASK' => 'Local IP address / subnet mask',
'rvw_NETWORKING_PARAMS' => 'Networking Parameters',
'rvw_NO_NETWORKS' => 'No additional networks defined',
'rvw_NO_VIRTUAL_DOMAINS' => 'No virtual domains defined',
'rvw_PRIMARY_DOMAIN' => 'Primary domain',
'rvw_PRIMARY_WEB_SITE' => 'Primary web site',
'rvw_PROXY_SERVER' => 'Proxy server',
'rvw_SERVER_MANAGER' => 'Server manager',
'rvw_SERVER_MODE' => 'Server Mode',
'rvw_SERVER_NAMES' => 'Server names',
'rvw_SMTP_POP_AND_IMAP_MAIL_SERVERS' => 'SMTP, POP, and IMAP mail servers',
'rvw_USER_PASSWORD_PANEL' => 'User password panel',
'rvw_VIRTUAL_DOMAINS' => 'Virtual domains',
'rvw_WEB_SERVER' => 'Web server',

View File

@@ -1,62 +1,60 @@
'usr_FORM_TITLE' => 'Create, modify, or remove user accounts',
'usr_FIRSTPAGE_DESC' => '<p>You can modify, lock or remove any account or reset the account\'s password by clicking on the corresponding command next to the account. </p><p>If the account is marked as locked, that means that the user\'s password needs to be reset. Please note that newly created accounts are automatically locked until the password is changed. </p>',
'usr_P2_TITLE' => 'Create or modify',
'usr_CREATE_MODIFY_DESC' => '<p>The account name should contain only lower-case letters, numbers, hyphens, periods, underscores and should start with a lower-case letter. For example "betty","hjohnson", and "mary-jane" are all valid account names, but "3friends", "John Smith", and "henry:miller" are not. </p><p>Note that two special pseudonyms will be created for each new account. These pseudonyms provide the ability to have alternative mail accounts for that user which include their first name and last name separated with a period (.) and underscore (_). So, for the account "betty" with first name "Betty" and last name "Rubble" two pseudonyms are created as betty.rubble and betty_rubble. </p><p>The directory information (department, company, etc.) can be changed from the defaults shown below. The changes will apply only to this user. </p>',
'usr_ADD_USER' => 'Add user account',
'usr_MODIFY_ADMIN_TITLE' => 'Modify the admin account',
'usr_USER_CREATED' => 'Successfully created user account. ',
'usr_USER_MODIFIED' => 'Successfully modified user account. ',
'usr_CANNOT_MODIFY_USER' => 'Error: an internal error occurred while attempting to modify the user "[_1]".',
'usr_CANNOT_MODIFY_USER_GROUPS' =>'Error: an internal error occurred while attempting to modify the group "[_1]" for user "[_2]".',
'usr_TAINTED_USER' => 'The account name "[_1]" contains invalid characters.',
#
# Lex file for Useraccounts generated on 2025-07-17 09:52:29
#
'Users' => 'Users',
'usr_ACCOUNT_CONFLICT' => 'Error: the account "[_1]" can"t be created because there is already a [_1] account of that name.',
'usr_ACCOUNT_NAME' => 'Account name',
'usr_FIRSTNAME' => 'First name',
'usr_LASTNAME' => 'Last name',
'usr_DEPARTMENT' => 'Department',
'usr_COMPANY' => 'Company',
'usr_STREET_ADDRESS' => 'Street address',
'usr_CITY' => 'City',
'usr_PHONE_NUMBER' => 'Phone number',
'usr_EMAIL_DELIVERY' => 'Email delivery',
'usr_DELIVER_EMAIL_LOCALLY' => 'Deliver email locally',
'usr_FORWARD_EMAIL' => 'Forward email to address below',
'usr_ACCOUNT_TOO_LONG' => 'Error: account name is too long. The maximum is [_1] characters.',
'usr_ACCT_NAME_HAS_INVALID_CHARS' => 'The account name "[_1]" contains invalid characters. Account names must start with a lower case letter and contain only lower case letters, numbers, hyphens, periods and underscores.',
'usr_ADD_USER' => 'Add user account',
'usr_CANNOT_CONTAIN_WHITESPACE' => 'This field cannot contain white-space',
'usr_CANNOT_MODIFY_USER' => 'Error: an internal error occurred while attempting to modify the user "[_1]".',
'usr_CANNOT_MODIFY_USER_GROUPS' => 'Error: an internal error occurred while attempting to modify the group "[_1]" for user "[_2]".',
'usr_CREATE_MODIFY_DESC' => '<p>The account name should contain only lower-case letters, numbers, hyphens, periods, underscores and should start with a lower-case letter. For example "betty","hjohnson", and "mary-jane" are all valid account names, but "3friends", "John Smith", and "henry:miller" are not. </p><p>Note that two special pseudonyms will be created for each new account. These pseudonyms provide the ability to have alternative mail accounts for that user which include their first name and last name separated with a period (.) and underscore (_). So, for the account "betty" with first name "Betty" and last name "Rubble" two pseudonyms are created as betty.rubble and betty_rubble. </p><p>The directory information (department, company, etc.) can be changed from the defaults shown below. The changes will apply only to this user. </p>',
'usr_CURRENT_SYSTEM_PASSWORD' => 'Current system password',
'usr_DELIVER_AND_FORWARD' => 'Both deliver locally and forward',
'usr_DELIVER_EMAIL_LOCALLY' => 'Deliver email locally',
'usr_EMAIL_DELIVERY' => 'Email delivery',
'usr_ERR_OCCURRED_CREATING' => 'An error occurred creating the user.',
'usr_ERR_OCCURRED_DELETING' => 'An error occurred while trying to delete the user.',
'usr_ERR_OCCURRED_MODIFYING_PASSWORD' => 'An error occurred while updating the password',
'usr_FIRSTNAME' => 'First name',
'usr_FIRSTPAGE_DESC' => '<p>You can modify, lock or remove any account or reset the account"s password by clicking on the corresponding command next to the account. </p><p>If the account is marked as locked, that means that the user"s password needs to be reset. Please note that newly created accounts are automatically locked until the password is changed. </p>',
'usr_FORM_TITLE' => 'Create, modify, or remove user accounts',
'usr_FORWARD_EMAIL' => 'Forward email to address below',
'usr_FORWARDING_ADDRESS' => 'Forwarding address',
'usr_GROUP_MEMBERSHIPS' => 'Group memberships',
'usr_RESET_DESC' => 'You are about to change the password for the user account "[_1]" ([_2])',
'usr_RESET_DESC2' => 'Enter the new password in the fields below',
'usr_ERR_OCCURRED_MODIFYING_PASSWORD' => 'An error occurred while updating the password',
'usr_PASSWORD_CHANGE_SUCCEEDED' => 'Successfully changed password for user "[_1]".',
'usr_LOCK_DESC' => 'You are about to lock the user account "[_1]" ([_2])',
'usr_LOCKED_ACCOUNT' => 'Successfully locked account for user "[_1]".',
'usr_NO_SUCH_USER' => 'Error: the user account "[_1]" does not exist.',
'usr_PSEUDONYM_CLASH' => 'Error: the pseudonym "[_1]" is already taken by the existing user account "[_1]".To differentiate, add initials to this field.',
'usr_LABEL_IPSECRW_DOWNLOAD' => 'Download digital certificate to IPSec client',
'usr_LASTNAME' => 'Last name',
'usr_LOCK_ACCOUNT' => 'Lock account',
'usr_LOCK_ACCOUNT_TITLE' => 'Lock user account',
'usr_LOCK_DESC' => 'You are about to lock the user account "[_1]" ([_2])',
'usr_LOCK_DESC2' => 'This user account will be locked. This means that this user will not be able to log in, and will not be able to collect e-mail. Any e-mail arriving will still be stored and/or forwarded to an external e-mail address, as configured. The account may be activated in the future by setting a new password. The current password will not be retained.</p><p><b>Are you sure you wish to lock this account?</b>',
'usr_LOCKED_ACCOUNT' => 'Successfully locked account for user "[_1]".',
'usr_MEMBER' => 'Member?',
'usr_MODIFY_ADMIN_TITLE' => 'Modify the admin account',
'usr_NEW_SYSTEM_PASSWORD' => 'New system password',
'usr_NEW_SYSTEM_PASSWORD_VERIFY' => 'New system password (verify)',
'usr_NO_SUCH_USER' => 'Error: the user account "[_1]" does not exist.',
'usr_NO_USER_ACCOUNTS' => 'There are no user accounts on this system.',
'usr_P2_TITLE' => 'Create or modify',
'usr_PASSWORD_CHANGE_SUCCEEDED' => 'Successfully changed password for user "[_1]".',
'usr_PHONE_NUMBER' => 'Phone number',
'usr_PSEUDONYM_CLASH' => 'Error: the pseudonym "[_1]" is already taken by the existing user account "[_1]".To differentiate, add initials to this field.',
'usr_REMOVE_ACCOUNT_TITLE' => 'Remove user account',
'usr_REMOVE_DESC' => 'You are about to remove the user account "[_1]" ([_2])',
'usr_REMOVE_DESC2' => 'All files belonging to this user account will be deleted. Also, any e-mail for this user account still remaining on the server (i.e. that has not yet been retrieved by the user) will be discarded. </p><p><b>Are you sure you wish to remove this account?</b>',
'usr_LOCK' => 'Lock',
'usr_NO_USER_ACCOUNTS' => 'There are no user accounts on this system.',
'Users' => 'Users',
'usr_ACCT_NAME_HAS_INVALID_CHARS' => 'The account name "[_1]" contains invalid characters. Account names must start with a lower case letter and contain only lower case letters, numbers, hyphens, periods and underscores.',
'usr_ACCOUNT_TOO_LONG' => 'Error: account name is too long. The maximum is [_1] characters.',
'usr_ACCOUNT_CONFLICT' => 'Error: the account "[_1]" can\'t be created because there is already a [_1] account of that name.',
'usr_ERR_OCCURRED_CREATING' => 'An error occurred creating the user.',
'usr_CANNOT_CONTAIN_WHITESPACE' => 'This field cannot contain white-space',
'usr_UNACCEPTABLE_CHARS' => 'This field must contain only letters, numbers, dots, hypens and underscores and start with a letter',
'usr_MEMBER' => 'Member?',
'usr_VPN_CLIENT_ACCESS' => 'VPN Client Access',
'usr_SYSTEM_PASSWORD_FORM_TITLE' => 'Change system password',
'usr_SYSTEM_PASSWORD_DESCRIPTION' => 'Certain services on this server installation require a username and password (for example this web page for the server manager application). The username is always admin. You can change the system password using the fields below.',
'usr_SYSTEM_PASSWORD_UNPRINTABLES_IN_PASS' => 'Password must contain only printable characters',
'usr_SYSTEM_PASSWORD_VERIFY_ERROR' => 'The two passwords are not identical.',
'usr_RESET_DESC' => 'You are about to change the password for the user account "[_1]" ([_2])',
'usr_RESET_DESC2' => 'Enter the new password in the fields below',
'usr_STREET_ADDRESS' => 'Street address',
'usr_SYSTEM_PASSWORD_AUTH_ERROR' => 'The current password is incorrect.',
'usr_SYSTEM_PASSWORD_CHANGED' => 'The system password has been changed.',
'usr_CURRENT_SYSTEM_PASSWORD' => 'Current system password',
'usr_NEW_SYSTEM_PASSWORD' => 'New system password',
'usr_NEW_SYSTEM_PASSWORD_VERIFY' => 'New system password (verify)',
'usr_LABEL_IPSECRW_DOWNLOAD' => 'Download digital certificate to IPSec client',
'usr_ERR_OCCURRED_DELETING' => 'An error occurred while trying to delete the user.',
'usr_SYSTEM_PASSWORD_DESCRIPTION' => 'Certain services on this server installation require a username and password (for example this web page for the server manager application). The username is always admin. You can change the system password using the fields below.',
'usr_SYSTEM_PASSWORD_FORM_TITLE' => 'Change system password',
'usr_SYSTEM_PASSWORD_UNPRINTABLES_IN_PASS' => 'Password must contain only printable characters',
'usr_SYSTEM_PASSWORD_VERIFY_ERROR' => 'The two passwords are not identical.',
'usr_TAINTED_USER' => 'The account name "[_1]" contains invalid characters.',
'usr_UNACCEPTABLE_CHARS' => 'This field must contain only letters, numbers, dots, hypens and underscores and start with a letter',
'usr_USER_CREATED' => 'Successfully created user account. ',
'usr_USER_MODIFIED' => 'Successfully modified user account. ',
'usr_VPN_CLIENT_ACCESS' => 'VPN Client Access',

View File

@@ -1,21 +1,26 @@
'pwd_FIELDS_REQUIRED' => 'All fields are required',
'pwd_ERROR_PASSWORD_CHANGE' => 'An error occurred while attempting to change your password. Please make sure that the old password entered is correct.',
'pwd_PASSWORD_CHANGE' => 'Change Password',
'pwd_RESET_PASSWORD_TITLE' => 'Reset user password',
'pwd_ACCOUNT_PASSWORD_CHANGE' => 'Change account password',
'pwd_PASSWORD_VERIFY_NEW' => 'New password (verify):',
'pwd_PASSWORD_NEW' => 'New password:',
'pwd_PASSWORD_OLD' => 'Old password:',
'pwd_PASSWORD_RESET' => 'Reset password',
#
# Lex file for Userpassword generated on 2025-07-17 09:52:29
#
'pwd_ACCOUNT_GROUP_NONE' => 'There are no user groups in the system.',
'pwd_ACCOUNT_NAME_INVALID' => 'The account name entered is invalid.',
'pwd_ACCOUNT_NAME_INVALID_CHARS' => 'The account name you entered contained invalid characters.',
'pwd_PASSWORD_OLD_INVALID_CHARS' => 'The old password you entered contained invalid characters.',
'pwd_PASSWORD_INVALID_CHARS' => 'The password you entered contained invalid characters.',
'pwd_PASSWORD_VERIFY_ERROR' => 'The new passwords you entered did not match.',
'pwd_ACCOUNT_PASSWORD_CHANGE' => 'Change account password',
'pwd_ACCOUNT_USER_NONE' => 'There are no user accounts in the system.',
'pwd_ACCOUNT_GROUP_NONE' => 'There are no user groups in the system.',
'pwd_YOUR_ACCOUNT' => 'Your account:',
'pwd_YOUR_ACCOUNT_INVALID' => 'The account name entered is invalid.',
'pwd_PASSWORD_CHANGE_SUCCESS' => 'Your password has been successfully changed.',
'pwd_DESCRIPTION' => '<P>To change your account password, please fill out the following form. You will need to provide the name of your account, your old password, and your desired new password. (You must type the new password twice.)</P><P>If you cannot change your password because you have forgotten the old one, your local system administrator can reset your password using the <EM>server manager</EM>.</P>',
'pwd_DESCRIPTION_RESET' => '<P>To reset your account password, please fill out the following form. You will need to provide your desired new password. (You must type it twice.)</P><P>In cas of problem, your local system administrator can reset your password using the <EM>server manager</EM>.</P>',
'pwd_ERROR_PASSWORD_CHANGE' => 'An error occurred while attempting to change your password. Please make sure that the old password entered is correct.',
'pwd_FIELDS_REQUIRED' => 'All fields are required',
'pwd_PASSWORD_CHANGE' => 'Change Password',
'pwd_PASSWORD_CHANGE_SUCCESS' => 'Your password has been successfully changed.',
'pwd_PASSWORD_DESCRIPTION' => 'The password must be composed of at least twelve characters with uppercase and lowercase letters, numbers and non-alphanumeric characters.',
'pwd_PASSWORD_INVALID_CHARS' => 'The password you entered contained invalid characters.',
'pwd_PASSWORD_NEW' => 'New password:',
'pwd_PASSWORD_OLD' => 'Old password:',
'pwd_PASSWORD_OLD_INVALID_CHARS' => 'The old password you entered contained invalid characters.',
'pwd_PASSWORD_RESET' => 'Reset password',
'pwd_PASSWORD_VERIFY_ERROR' => 'The new passwords you entered did not match.',
'pwd_PASSWORD_VERIFY_NEW' => 'New password (verify):',
'pwd_PASSWORD_WIKI' => 'If you want to know more about passwords, then please refer to the <a href="https://wiki.koozali.org/Useful_Commands#Password_strength">Wiki</a>',
'pwd_RESET_PASSWORD_TITLE' => 'Reset user password',
'pwd_YOUR_ACCOUNT' => 'Your account:',
'pwd_YOUR_ACCOUNT_INVALID' => 'The account name entered is invalid.',

View File

@@ -1,39 +1,40 @@
'log_FORM_TITLE' => 'View log files',
'log_FIRSTPAGE_DESC' => 'This panel allows you to view or download the log files generated
by the services running on your server.',
'log_LOG_FILE_SELECT_DESC' => 'Choose a log file to view',
#
# Lex file for Viewlogfiles generated on 2025-07-17 09:52:29
#
'log_DOWNLOAD_FILE' => 'Preparing to download the logfile [_1].',
'log_DOWNLOAD_PAGE_DESC' => 'Your logfile download is now prepared. It will proceed as soon
as you click on the &quot;Next&quot; button below, and instruct
your browser to accept the download via the pop-up window that
will appear.',
'log_END_DESC' => 'Please note that it may take quite some time to generate these
reports.',
'log_FILENAME_ERROR' => '<p>Error while specifying log file name.</p>
<p>Invalid report type "[_1]".</p>',
'log_FILTER_PATTERN_DESC' => 'You may optionally specify a filter pattern to display only the
lines from the log file which match this pattern.If you leave
lines from the log file which match this pattern. If you leave
this field blank, all available lines of the log file will be
displayed. Note that this option is not used if you download the
logfile.',
'log_FILTER_PATTERN_LABEL' => 'Filter Pattern (optional)',
'log_FIRSTPAGE_DESC' => 'This panel allows you to view or download the log files generated
by the services running on your server.',
'log_FORM_TITLE' => 'View log files',
'log_HIGHLIGHT_HEADER' => 'Highlighting lines matching: "[_1]".',
'log_LOG_FILE_EMPTY' => 'Log file "[_1]" is empty!',
'log_LOG_FILE_SELECT_DESC' => 'Choose a log file to view',
'log_MATCH_HEADER' => 'Displaying lines matching: "[_1]".',
'log_MATCH_PATTERN_DESC' => 'You may also optionally specify a highlight pattern to mark in bold
any lines from the log file which match the highlight pattern. The
highlight pattern is applied to any lines which have already
matched the filter pattern. Note that this option is not used if
you download the logfile.',
'log_MATCH_PATTERN_LABEL' => 'Highlight Pattern (optional)',
'log_END_DESC' => 'Please note that it may take quite some time to generate these
reports.',
'log_VIEW' => 'View log file',
'log_LOG_FILE_EMPTY' => 'Log file "[_1]" is empty!',
'log_VIEWING_TIME' => 'Viewed at [_1].',
'log_MATCH_HEADER' => 'Displaying lines matching: "[_1]".',
'log_HIGHLIGHT_HEADER' => 'Highlighting lines matching: "[_1]".',
'log_NO_MATCHING_LINES' => 'No matching lines displayed.',
'log_FILENAME_ERROR' => '<p>Error while specifying log file name.</p>
<p>Invalid report type "[_1]".</p>',
'log_REFRESH' => 'Refresh this logfile',
'log_OP_DESC' => 'You must choose between viewing the logfile in your browser, or
downloading the logfile to your computer. If the logfile is
particularly large, you may wish to download it instead of
attempting to open it in your browser, as this is a problem for
some web browsers.',
'log_OP_LABEL' => 'Operation',
'log_DOWNLOAD_PAGE_DESC' => 'Your logfile download is now prepared. It will proceed as soon
as you click on the &quot;Next&quot; button below, and instruct
your browser to accept the download via the pop-up window that
will appear.',
'log_DOWNLOAD_FILE' => 'Preparing to download the logfile [_1].',
'log_REFRESH' => 'Refresh this logfile',
'log_VIEW' => 'View log file',
'log_VIEWING_TIME' => 'Viewed at [_1].',

View File

@@ -1,28 +1,29 @@
'wkg_FORM_TITLE' => 'Change workgroup settings',
'wkg_DESC_WORKGROUP' => 'Enter the name of the Windows workgroup that this server should appear in.',
'wkg_LABEL_WORKGROUP' => 'Windows workgroup',
'wkg_DESC_SERVERNAME' => 'Enter the name that this server should use for
Windows and Macintosh file sharing.',
'wkg_LABEL_SERVERNAME' => 'Server Name',
#
# Lex file for Workgroup generated on 2025-07-17 09:52:29
#
'wkg_DESC_PDC' => 'Should this server act as the workgroup
and domain controller on your Windows network? You should leave
this set to <b>No</b> if another server is already performing this
role on your network.',
'wkg_LABEL_PDC' => 'Workgroup and Domain Controller',
'wkg_DESC_ROAM' => 'Should this server support roaming profiles?
You should leave this set to the default of <b>No</b> unless you have
experience administering server-based Windows roaming profiles and
know that this feature is required.',
'wkg_LABEL_ROAM' => 'Roaming profiles',
'wkg_SUCCESS' => 'The new workgroup settings have been saved',
'wkg_INVALID_WORKGROUP' => 'The workgroup name must begin with a letter (upper or lower
case), followed by any combination of letters, numbers,
underscores, periods and hyphens.',
'wkg_DESC_SERVERNAME' => 'Enter the name that this server should use for
Windows and Macintosh file sharing.',
'wkg_DESC_WORKGROUP' => 'Enter the name of the Windows workgroup that this server should appear in.',
'wkg_FORM_TITLE' => 'Change workgroup settings',
'wkg_INVALID_SERVERNAME' => 'The server name must begin with a letter (upper or lower case),
followed by any combination of letters, numbers, underscores and
hyphens.',
'wkg_INVALID_WORKGROUP' => 'The workgroup name must begin with a letter (upper or lower
case), followed by any combination of letters, numbers,
underscores, periods and hyphens.',
'wkg_INVALID_WORKGROUP_MATCHES_SERVERNAME' => 'The server and workgroup names match, when compared in lower case.
These values must be different in order for filesharing to be turned on. ',
'wkg_LABEL_PDC' => 'Workgroup and Domain Controller',
'wkg_LABEL_ROAM' => 'Roaming profiles',
'wkg_LABEL_SERVERNAME' => 'Server Name',
'wkg_LABEL_WORKGROUP' => 'Windows workgroup',
'wkg_SUCCESS' => 'The new workgroup settings have been saved',
'Workgroup' => 'Workgroup',

View File

@@ -1,59 +1,53 @@
'yum_FORM_TITLE' => 'Software installer',
'yum_SUCCESS' => 'The new settings have been saved.',
'yum_LABEL_YUM_STATUS' => 'Check for updates',
'yum_LABEL_YUM_AUTOINSTALLUPDATES' => 'Automatically install updates',
'yum_DESC_YUM_AUTOINSTALLUPDATES' => 'If enabled this will take precedence over the simple check for updates notification and predownload features. Instead it will install the available updates from enabled repositories. For more information refer to yum and yum-cron manual page.',
'yum_LABEL_YUM_PACKAGEFUNCTIONS' => 'Manage individual packages',
'yum_DESC_YUM_PACKAGEFUNCTIONS' => 'The software installer can manage groups of
related package or individual packages. By
default, only groups of packages are presented.
If you wish to manage individual packages,
enable this option. This should only be done
by experienced administrators.',
'yum_LABEL_ENABLED_REPOSITORIES' => 'Enabled repositories',
#
# Lex file for Yum generated on 2025-07-17 09:52:30
#
'yum_BUTTON_CONFIGURATION' => 'Change software installer settings',
'yum_BUTTON_INSTALL_AVAILABLE' => 'Install additional software',
'yum_BUTTON_INSTALL_UPDATES' => 'List available updates',
'yum_BUTTON_REMOVE' => 'Remove installed software',
'yum_DESC_AVAILABLE_GROUPS' => 'You can select software groups
to install from the list below.',
'yum_DESC_AVAILABLE_PACKAGES' => 'You can also select individual packages
to install from the list below.',
'yum_DESC_AVAILABLE_UPDATES' => 'The following updates are available for your system.
You should normally install all available updates.
If there are updates you do not wish to install, de-select
them from the list below.',
'yum_DESC_ENABLED_REPOSITORIES' => 'The software installer can install software
from any of enabled repositories. To enable
a repository, select it from the list.
To disable a repository, de-select it from the list.
By default, only stable, tested software is available
for installation.',
'yum_TITLE_UPTODATE' => 'This system is up to date.',
'yum_DESC_UPTODATE' => 'All updates have been installed.',
'yum_TITLE_UPDATES_AVAILABLE' => 'Updates Available',
'yum_DESC_INSTALLED_GROUPS' => 'You can select software groups
to remove from the list below.',
'yum_DESC_INSTALLED_PACKAGES' => 'You can also select individual packages
you wish to remove from the list below.',
'yum_DESC_UPDATES_AVAILABLE' => 'There are updates available for your system. These updates
should be installed as soon as possible.',
'yum_LABEL_AVAILABLE_UPDATES' => 'Updates available',
'yum_DESC_AVAILABLE_UPDATES' => 'The following updates are available for your system.
You should normally install all available updates.
If there are updates you do not wish to install, de-select
them from the list below.',
'yum_INSTALL_UPDATES' => 'Install selected updates',
'yum_BUTTON_INSTALL_UPDATES' => 'List available updates',
'yum_DESC_UPTODATE' => 'All updates have been installed.',
'yum_DESC_YUM_AUTOINSTALLUPDATES' => 'If enabled this will take precedence over the simple check for updates notification and predownload features. Instead it will install the available updates from enabled repositories. For more information refer to yum and yum-cron manual page.',
'yum_DESC_YUM_DELTARPMPROCESS' => 'A deltarpm contains the difference between an old and a new version of a rpm,
which can save bandwith. The drawback is that update
operations consume considerably more CPU cycles',
'yum_DESC_YUM_DOWNLOADONLY' => 'The rpm updates can be downloaded during the night,
this will ease and give faster the yum update process
(only enabled repositories will be used).',
'yum_DESC_YUM_PACKAGEFUNCTIONS' => 'The software installer can manage groups of
related package or individual packages. By
default, only groups of packages are presented.
If you wish to manage individual packages,
enable this option. This should only be done
by experienced administrators.',
'yum_FORM_TITLE' => 'Software installer',
'yum_HEADER_AVAILABLE_SOFTWARE' => 'The following software is available to be installed
onto your system. You should only install additional
software onto this system if you are aware
of the consequences of doing so.',
'yum_DESC_AVAILABLE_GROUPS' => 'You can select software groups
to install from the list below.',
'yum_LABEL_AVAILABLE_GROUPS' => 'Available groups',
'yum_DESC_AVAILABLE_PACKAGES' => 'You can also select individual packages
to install from the list below.',
'yum_LABEL_AVAILABLE_PACKAGES' => 'Available packages',
'yum_INSTALL_SOFTWARE' => 'Install',
'yum_HEADER_INSTALLED_SOFTWARE' => 'The following software is installed
on this system. You should only remove
software from this system if you are aware
of the consequences of doing so.',
'yum_DESC_INSTALLED_GROUPS' => 'You can select software groups
to remove from the list below.',
'yum_LABEL_INSTALLED_GROUPS' => 'Installed groups',
'yum_DESC_INSTALLED_PACKAGES' => 'You can also select individual packages
you wish to remove from the list below.',
'yum_LABEL_INSTALLED_PACKAGES' => 'Installed packages',
'yum_BUTTON_CONFIGURATION' => 'Change software installer settings',
'yum_BUTTON_INSTALL_AVAILABLE' => 'Install additional software',
'yum_BUTTON_REMOVE' => 'Remove installed software',
'yum_HEADER_POSTUPGRADE_REQUIRED' => ' The system needs to be reconfigured
after adding or removing software,
or applying updates.
@@ -63,17 +57,21 @@ this page to start the reconfiguration process.
<b>An automatic reboot will be
initiated as part of this reconfiguration process</b>
</p> ',
'yum_INSTALL_UPDATES' => 'Install selected updates',
'yum_LABEL_AVAILABLE_GROUPS' => 'Available groups',
'yum_LABEL_AVAILABLE_PACKAGES' => 'Available packages',
'yum_LABEL_AVAILABLE_UPDATES' => 'Updates available',
'yum_LABEL_ENABLED_REPOSITORIES' => 'Enabled repositories',
'yum_LABEL_INSTALLED_GROUPS' => 'Installed groups',
'yum_LABEL_INSTALLED_PACKAGES' => 'Installed packages',
'yum_LABEL_YUM_AUTOINSTALLUPDATES' => 'Automatically install updates',
'yum_LABEL_YUM_DELTARPMPROCESS' => 'Delta Rpm Update',
'yum_LABEL_YUM_DOWNLOADONLY' => 'Predownload updates',
'yum_LABEL_YUM_PACKAGEFUNCTIONS' => 'Manage individual packages',
'yum_LABEL_YUM_STATUS' => 'Check for updates',
'yum_SUCCESS' => 'The new settings have been saved.',
'yum_SYSTEM_BEING_RECONFIGURED' => 'Your system is being automatically rebooted to
complete the reconfiguraton process.',
'yum_1DAILY' => 'Daily',
'yum_2WEEKLY' => 'Weekly',
'yum_3MONTHLY' => 'Monthly',
'yum_LABEL_YUM_DELTARPMPROCESS' => 'Delta Rpm Update',
'yum_DESC_YUM_DELTARPMPROCESS' => 'A deltarpm contains the difference between an old and a new version of a rpm,
which can save bandwith. The drawback is that update
operations consume considerably more CPU cycles',
'yum_LABEL_YUM_DOWNLOADONLY' => 'Predownload updates',
'yum_DESC_YUM_DOWNLOADONLY' => 'The rpm updates can be downloaded during the night,
this will ease and give faster the yum update process
(only enabled repositories will be used).',
'yum_TITLE_UPDATES_AVAILABLE' => 'Updates Available',
'yum_TITLE_UPTODATE' => 'This system is up to date.',
'yum_UPDATE_SUCCESS' => 'The requested changes have been successfully implemented.',

View File

@@ -4,19 +4,19 @@ use strict;
use warnings;
use utf8;
use esmith::ConfigDB;
use esmith::AccountsDB;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB::UTF8;
use esmith::util;
use Net::LDAP qw/LDAP_INVALID_CREDENTIALS/;
our ($cdb,$adb);
sub init_data {
my %datas = ();
my $cdb = esmith::ConfigDB->open_ro() or die("can't open Config DB");
$cdb = esmith::ConfigDB::UTF8->open_ro() or die("can't open Config DB");
my $sysconfig = $cdb->get("sysconfig");
$datas{'lang'} = $sysconfig->prop('Language') || 'en_US';
@@ -42,9 +42,10 @@ sub init_data {
sub reconf_needed {
my $cdb = esmith::ConfigDB->open_ro() or die("can't open Config DB");
my $unsafe = ($cdb->get('bootstrap-console') and $cdb->get('bootstrap-console')->prop('Run') eq 'yes') ||
($cdb->get('UnsavedChanges') and $cdb->get('UnsavedChanges')->value eq 'yes') || '0';
$cdb = esmith::ConfigDB::UTF8->open_ro() or die("can't open Config DB");
#my $unsafe = ($cdb->get('bootstrap-console') and $cdb->get('bootstrap-console')->prop('Run') eq 'yes') ||
# ($cdb->get('UnsavedChanges') and $cdb->get('UnsavedChanges')->value eq 'yes') || '0';
my $unsafe = ($cdb->get('UnsavedChanges') and $cdb->get('UnsavedChanges')->value eq 'yes') || '0';
return $unsafe;
}
@@ -54,7 +55,7 @@ sub check_credentials {
my ($c, $username, $password) = @_;
return unless $username || $password;
my $cdb = esmith::ConfigDB->open_ro() or die("can't open Configuration DB");
$cdb = esmith::ConfigDB::UTF8->open_ro() or die("can't open Configuration DB");
my $l = $cdb->get('ldap');
my $status = $l->prop('status') || "disabled";
unless ($status eq "enabled" ) {
@@ -87,13 +88,13 @@ sub check_adminalias {
my $c = shift;
my $alias;
my $cdb = esmith::ConfigDB->open_ro() or die("can't open Configuration DB");
$cdb = esmith::ConfigDB::UTF8->open_ro() or die("can't open Configuration DB");
if (defined $cdb->get('AdminAlias')) {
$alias = $cdb->get('AdminAlias')->value;
}
return undef unless $alias;
my $adb = esmith::AccountsDB->open_ro() or die("can't open Accounts DB");
$adb = esmith::AccountsDB::UTF8->open_ro() or die("can't open Accounts DB");
my $arec = $adb->get( $alias );
return undef unless $arec;
@@ -105,4 +106,3 @@ sub check_adminalias {
1;

View File

@@ -0,0 +1,100 @@
# Optimized SrvMngr_Auth module using stash caching and Exporter
package SrvMngr_Auth;
use strict;
use warnings;
use Exporter qw(import); # Import the Exporter module
use esmith::AccountsDB::UTF8;
# Define functions to be exported upon request
our @EXPORT_OK = qw(check_admin_access load_user_auth_info has_panel_access get_panel_from_path);
# Helper function to extract panel name from path
sub get_panel_from_path {
my ($path) = @_;
if ($path =~ m{^/([^/]+)}) {
return $1;
}
return ''; # Return empty string if no panel found
}
# Load user authentication info and cache it in the stash
sub load_user_auth_info {
my ($c) = @_;
# Check if auth info is already cached in the stash
return if exists $c->stash->{auth_info};
my %auth_info = (
username => '', # Initialize username
is_admin => 0,
allowed_panels => [],
);
# Get username from session
$auth_info{username} = $c->session->{username} || ''; # Provide default empty string
# Check if user is admin
$auth_info{is_admin} = $c->is_admin || 0;
# If not admin, get allowed panels
if (!$auth_info{is_admin} && $auth_info{username}) {
my $accountsdb = esmith::AccountsDB::UTF8->open_ro();
if ($accountsdb) {
my $user_rec = $accountsdb->get($auth_info{username});
# Check if the property exists before trying to get its value
if (defined $user_rec && $user_rec->prop('AdminPanels')) {
# Get comma-separated list of allowed admin panels
my $admin_panels = $user_rec->prop('AdminPanels');
$auth_info{allowed_panels} = [split(/,/, $admin_panels)];
}
}
}
# Store the calculated info in the stash
$c->stash(auth_info => \%auth_info);
}
# Check if a user has access to a specific panel (uses cached info)
sub has_panel_access {
my ($c, $panel) = @_;
# Ensure auth info is loaded
load_user_auth_info($c);
my $auth_info = $c->stash->{auth_info};
# Check if requested panel is in allowed panels
foreach my $allowed_panel (@{$auth_info->{allowed_panels}}) {
return 1 if lc($panel) eq lc($allowed_panel)
|| lc(substr($panel, 0, length($allowed_panel))) eq lc($allowed_panel);
}
return 0;
}
# Main function to check admin access (uses cached info)
sub check_admin_access {
my ($c) = @_;
# Ensure auth info is loaded
load_user_auth_info($c);
my $auth_info = $c->stash->{auth_info};
# First check if user is admin
return 1 if $auth_info->{is_admin};
# If not admin, check if they have access to the specific panel
my $current_path = $c->req->url->path;
my $requested_panel = $current_path;
return 0 unless $requested_panel;
# Check if user has access to this panel using the cached info
return has_panel_access($c, $requested_panel);
}
1; # Return true value for module loading

View File

@@ -5,11 +5,11 @@
use strict;
use warnings;
use esmith::ConfigDB;
use esmith::ConfigDB::UTF8;
use constant WEBFUNCTIONS => '/usr/share/smanager/lib/SrvMngr/Controller/';
my $rtdb = esmith::ConfigDB->open('routes') or
my $rtdb = esmith::ConfigDB::UTF8->open('routes') or
die "Couldn't access Routes database\n";
my @routes = $rtdb->get_all_by_prop( type => 'route' );

View File

@@ -7,7 +7,7 @@
use strict;
use warnings;
use esmith::ConfigDB;
use esmith::ConfigDB::UTF8;
sub gen_pwd {
use MIME::Base64 qw(encode_base64);
@@ -29,7 +29,7 @@ sub gen_pwd {
return $p;
}
my $cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
my $cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $pwds = $cdb->get_prop('smanager','Secrets');

View File

@@ -9,11 +9,15 @@ use esmith::util;
BEGIN
{
$0 =~ /^(.+)$/ms; $0 = $1; # Untaint script name
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
$ENV{'PATH'} = '/usr/sbin:/usr/bin:/usr/local/bin';
$ENV{'SHELL'} = '/bin/bash';
$ENV{'HOME'} = '/usr/share/smanager';
delete $ENV{'ENV'};
esmith::util::setRealToEffective();
#to help debug UTF8, see perlrun and perlvar -CSAD or -CLSD
#print '$ENV{PERL_UNICODE}='.$ENV{'PERL_UNICODE'}."\n" if $ENV{'PERL_UNICODE'};
#print '${^UNICODE}='.${^UNICODE}.' ; ${^UTF8LOCALE}='.${^UTF8LOCALE} ."\n";
#print '${^OPEN}'.${^OPEN}."\n" if ${^OPEN} ;
}

View File

@@ -6,8 +6,8 @@ use Test::Mojo;
use FindBin;
use lib "$FindBin::Bin/../lib";
eval "use esmith::ConfigDB";
plan skip_all => 'esmith::ConfigDB (and others) required for testing 002_basic' if $@;
eval "use esmith::ConfigDB::UTF8";
plan skip_all => 'esmith::ConfigDB::UTF8 (and others) required for testing 002_basic' if $@;
plan tests => 3;

View File

@@ -6,8 +6,8 @@ use Test::Mojo;
use FindBin;
use lib "$FindBin::Bin/../lib";
eval "use esmith::ConfigDB";
plan skip_all => 'esmith::ConfigDB (and others) required for testing 004_panels' if $@;
eval "use esmith::ConfigDB::UTF8";
plan skip_all => 'esmith::ConfigDB::UTF8 (and others) required for testing 004_panels' if $@;
my $tests;
plan tests => $tests;
@@ -17,8 +17,8 @@ BEGIN { $tests += 2 * 3 };
my $t = Test::Mojo->new('SrvMngr');
$t->ua->max_redirects(1);
$t->get_ok('/')->status_is(200)->content_like(qr/SME Server 10/);
$t->get_ok('/manual')->status_is(200)->content_like(qr/SME Server 10/);
$t->get_ok('/')->status_is(200)->content_like(qr/SME Server 11/);
$t->get_ok('/manual')->status_is(200)->content_like(qr/SME Server 11/);
BEGIN { $tests += 5 * 2 };
my @panels = qw/ Initial Login Manual Support Request /;

View File

@@ -0,0 +1,38 @@
Configuration report created {$report_creation_time}
==================
Base configuration
==================
SME server version: {$releaseversion}
SME server mode: {$systemmode}
SME server previous mode: {$previoussystemmode }
Running Kernel: {$curkernel}
===========================
New RPMs not in base system
===========================
{ foreach $i (@newrpms) {
$OUT .= "$i";
}
}
===========================
Custom and modified templates
===========================
{ foreach $i (@templates) {
$OUT .= "$i";
}
}
===========================
Modified events
===========================
{ foreach $i (@events) {
$OUT .= "$i";
}
}
=======================
Additional repositories
=======================
{ foreach $r (@repositories) {
$OUT .= "$r";
}
}
DONE!

View File

@@ -0,0 +1,51 @@
.datetime-config-row {
display: flex;
align-items: stretch;
margin-bottom: 1em;
}
.datetime-label-col {
background: #e8f3e2; /* light green */
padding: 1em 0em 0em 0em;
min-width: 30%;
display: flex;
align-items: flex-start;
justify-content: flex-end;
font-weight: bold;
border-radius: 4px 0 0 4px;
}
.datetime-label {
display:inline-flex;
}
.datetime-fields-col {
background: #fff;
padding: 1em;
flex: 1;
border: 1px solid #ccc;
border-left: none;
border-radius: 0 4px 4px 0;
}
.datetime-clock {
min-width: 20em;
display:inline-flex;
border:0px;
padding:5px;
}
.datetime-clock-label {
background-color:#e8f3e2;
display:inline-flex;
width:30%;
font-weight:bold;
text-align:right;
}
.ntp-test-result { font-weight: bold; }
.ntp-test-success { color: green; }
.ntp-test-error { color: red; }
.ntp-test-wait { color: #333; }

View File

@@ -0,0 +1,14 @@
/*
Generated by: SM2Gen version:0.9(20Jan2025) Chameleon version:4.5.4 On Python:3.12.3 at 2025-06-29 08:53:20
*/
.Emailsettings-panel {}
.name {}
.rout {}
.name {}
.rout {}
.name {}
.rout {}
.name {}
.rout {}
.name {}
.rout {}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,43 @@
/* General styles for the module panel */
#module {
padding: 20px;
border: 1px solid #ccc;
border-radius: 10px;
background-color: #f9f9f9;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
/* Debug information styling */
#module p {
font-family: monospace;
color: #555;
}
#module pre {
background-color: #eee;
padding: 10px;
border-radius: 5px;
}
/* Error message styling */
.sme-error {
color: #d9534f;
font-weight: bold;
margin-bottom: 15px;
}
/* Title styling */
#module h1 {
font-family: Arial, sans-serif;
color: #333;
text-align: center;
margin-bottom: 20px;
}
/* Content styling */
.module-content {
font-family: Georgia, serif;
font-size: 13px;
line-height: 1.2;
color: #555;
}

View File

@@ -0,0 +1,505 @@
{
margin-left: 0;
}
a.alert {
color: red;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
a.item {
color: #00008b;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
a.item-current:hover, a.warn-current:hover {
border-color: #888;
}
a.item-current:link, a.warn-current:link,
a.item-current:visited, a.warn-current:visited,
a.item-current:active, a.warn-current:active,
a.item-current:hover, a.warn-current:hover {
display: block;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
color: black;
text-decoration: none;
background: #fff;
border-color: #888;
margin: 0;
border-style: solid;
border-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
a.item:active, a.item-current:active,
a.warn:active, a.warn-current:active {
display: block;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
color: white;
background: black;
text-decoration: none;
border-color: #000;
margin: 0;
border-style: solid;
border-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
a.item:hover, a.item-current:hover,
a.warn:hover, a.warn-current:hover {
display: block;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
color: black;
text-decoration: none;
background: #ccc;
border-color: #888;
margin: 0;
border-style: solid;
border-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
a.item:link, a.item-current:link,
a.warn:link, a.warn-current:link {
display: block;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
color: black;
background: #e8f3e1;
text-decoration: none;
text-align: left;
border-color: #e8f3e1;
margin: 0;
border-style: solid;
border-width: 1px;
padding: 0 10px 2px;
}
a.item:visited, a.item-current:visited,
a.warn:visited, a.warn-current:visited {
display: block;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
color: black;
background: #e8f3e1;
text-decoration: none;
border-color: #e8f3e1;
margin: 0;
border-style: solid;
border-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
a.section-title {
display: inline-block;
color: #6CA345;
padding-left: 5px;
padding-right: 5px;
line-height: 18px;
font-weight: bold;
}
a.sl {
color: green;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
a.update {
color: red;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background: #98d36e;
}
a.warn:link, a.warn-current:link,
a.warn:visited, a.warn-current:visited,
a.warn:active, a.warn-current:active,
a.warn:hover, a.warn-current:hover {
background-image: url("/server-common/warn.gif");
background-repeat: no-repeat;
background-position: 10px;
padding-left: 25px;
}
a:active {
color: #606060;
text-decoration: none;
}
a:hover {
color: #F00;
text-decoration: none;
}
a:link {
color: #006921;
text-decoration: none;
}
a:visited {
color: #063;
text-decoration: none;
}
body {
background-color: #FFF;
color: #000;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
border-width: 0;
}
body, body.main {
margin: 5px 20px 5px 5px;
}
body, body.menu {
margin: 0 0 0 2px;
}
body.header {
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background-color: #bee6a2;
margin: 0;
}
body.main {
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background-color: #fff;
color: #000;
}
body.menu {
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background-color: #e8f3e1;
}
div.error, div.sme-error, span.error, span.sme-error {
color: red;
background-color: #f9f9f9;
border-width: 1px;
border-style: solid;
border-color: red;
padding: 10px;
border-radius: 10px;
}
form {
margin-top: 2px;
margin-bottom: 2px;
}
h1, .h1 {
font-family: Verdana, Tahoma, sans-serif;
color: #333;
font-size: 18px;
margin-bottom: 4px;
margin-top: 12px;
}
h2, .h2 {
font-family: Verdana, Tahoma, sans-serif;
color: #333;
font-size: 14px;
margin-bottom: 3px;
margin-top: 12px;
}
h3, .h3 {
font-family: Verdana, Tahoma, sans-serif;
color: #333;
font-size: 12px;
margin-bottom: 2px;
margin-top: 12px;
}
h4, .h4 {
font-family: Verdana, Tahoma, sans-serif;
font-style: italic;
color: #333;
font-size: 12px;
margin-bottom: 2px;
margin-top: 10px;
}
hr.sectionbar {
color: #8ebe43;
background-color: #8ebe43;
height: 1px;
width: 80%;
border: 0;
}
hr.sme-copyrightbar {
color: #8ebe43;
background-color: #8ebe43;
height: 1px;
width: 100%;
border: 0;
}
input.action {
margin-left: 0;
background-color: #bee6a2;
color: darkgreen;
border-radius: 8px;
border: 2px solid #4CAF50;
display: flex;
justify-content: center;
align-items: center;
}
input.action2 {
margin-left: 0;
color: black;
background-color: #d4d0c8;
display: flex;
justify-content: center;
}
input.action:active {
background-color: #3e8e41;
transform: translate(-2px,2px);
}
input.action:hover {
background-color: #3e8e41;
color: white;
}
input.field-with-error {
background-color: #fd9e7e;
}
label.field-with-error {
color: #dd7e5e;
}
ol, ul, li {
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
font-weight: normal;
color: black;
}
p {
margin-top: 8px;
margin-bottom: 2px;
}
span {
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
}
span.data {
padding: 2px;
font-weight: bold;
margin-left: 0;
}
span.data2 {
padding: 2px;
}
span.label {
display: inline-block;
font-weight: bold;
background-color: #e8f3e1;
width: 30%;
text-align: right;
}
span.label2 {
display: inline-block;
font-weight: bold;
background-color: #e8f3e1;
text-align: right;
}
table, tr, td, div, p, form {
color: #000;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
}
table.sme-border {
border-collapse: collapse;
border: 2px solid #cccccc;
empty-cells: show;
margin: 5px;
}
table.sme-layout {
border-collapse: collapse;
margin-bottom: 2px;
margin-top: 2px;
}
table.sme-noborders {
padding: 0;
margin: 0 0 20px;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
}
td {
text-align: left;
}
td.darkgrey {
background-color: #888;
}
td.label {
font-weight: bold;
background-color: #e8f3e1;
width: 30%;
text-align: right;
}
td.menu-cell {
margin: 0;
padding: 0;
}
td.section {
padding-bottom: 2px;
padding-top: 8px;
background-color: #e8f3e1;
}
td.sme-border a, td.sme-border-right a, td.sme-border-center a {
font-size: 10px;
}
td.sme-border, td.sme-border-warning, td.sme-border-right, td.sme-border-center {
border: 1px solid #cccccc;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
font-weight: normal;
color: #000;
text-align: left;
padding: 3px 2px;
}
td.sme-border-center {
text-align: center;
}
td.sme-border-right {
text-align: right;
}
td.sme-border-warning {
color: red;
}
/* sme-layout* : Used for top-level layout */
table.sme-layout {
border-collapse: collapse;
margin-bottom: 2px;
margin-top: 2px;
}
tr.sme-layout {
border: 1px solid #dddddd;
}
td.sme-layout {
border: 1px solid #dddddd;
}
td.sme-noborders-content {
text-align: left;
vertical-align: top;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
}
td.sme-noborders-info, div.sme-noborders-info {
text-align: left;
vertical-align: top;
}
td.sme-noborders-label {
font-weight: bold;
text-align: right;
background-color: #e8f3e1;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
width: 33%;
}
td.sme-radiobutton {
width: 30px;
}
th.sme-border {
border: 1px;
background-color: #bee6a2;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
font-weight: bold;
color: #000;
text-align: center;
vertical-align: bottom;
padding: 3px;
}
th.sme-layout {
border: 1px;
background-color: #e8f3e1;
font-family: Verdana, Tahoma, sans-serif;
font-size: 9pt;
font-weight: bold;
color: #000;
text-align: right;
padding: 4px;
}
tr.sme-layout {
border: 1px;
}
ul {
list-style-type: circle;
}
div.success, span.success {
color: #006400;
border-width: 1px;
border-style: solid;
border-color: #006400 ;
padding: 10px;
border-radius: 10px;
}
div.roundcube #roundcube{
width:100%;
height:600px;
}

View File

@@ -0,0 +1,293 @@
/* css/sme-password.css */
.input-container {
position: relative;
display: inline-block;
}
.sme-password {
padding-right: 5px; /* Ensure space for the toggle icon */
}
.toggle-password {
position: absolute;
right: 4px; /* Position it towards the right */
top: 50%; /* Center vertically */
transform: translateY(-50%); /* Adjust for exact centering */
cursor: pointer;
width: 20px; /* Set the width of the icon */
height: 20px; /* Set the height of the icon */
}
.module {
padding: 20px;
border: 1px ;
border-radius: 10px;
background-color: #f9f9f9;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
margin-left: 10px !important;
margin-top: 10px;
}
.sme-copyright {
color: #777;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
}
.logo {
height: 142%;
width: auto;
margin-left: -16px;
}
.gradient-panel {
width: 100%;
height: 40px;
background: linear-gradient(to right, white ,#c0e7a5 );
display: flex;
align-items: center;
position: relative;
}
.sme-error {
color: #d9534f;
display: block;
background-color: #fff;
border-width: 1px;
border-style: solid;
border-color: red;
padding: 2px;
font-weight: bold;
margin-bottom: 15px;
}
.login-button {
position: absolute;
left: 7%;
transform: translateX(-50%);
background-color: #4caf50b8;
color: white !important;
border: none;
padding: 8px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
cursor: pointer;
border-radius: 4px;
margin-left: 77%;
}
.sme-warning {
color: orange;
display: block;
background-color: #fff;
border-width: 1px;
border-style: solid;
border-color: orange;
padding: 2px;
}
.infobar {
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background-color: #98d36e;
}
.module-content {
font-family: Georgia, Garamond, serif;
font-size: 13px;
line-height: 1.2;
color: #555;
}
#help-button {
text-decoration: none;
font-size: 20px;
padding: 8px;
background-color: #98d36e;
border-radius: 4px;
color: #000;
}
/*
#module {
padding: 20px;
border: 1px;
border-radius: 10px;
background-color: #f9f9f9;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
*/
#container {
max-width: 100%;
position: relative;
margin: auto;
}
#header2 {
width:96%;
margin-left: 1px;
margin-top: 4px;
}
#main {
margin-left: 200px;
padding: 10px;
}
#central {
padding: 5px;
}
#footer {
padding-left: 5px;
}
#header {
width: 100%;
margin: auto;
}
#navigation {
width: 190px;
position: absolute;
padding: 5px;
background-color: #E8F3E1;
overflow: auto;
margin-top:20px;
}
#footer img {
float: right;
position: fixed;
/*margin-left: 40%;*/
}
.flag-style {
position: absolute;
transform: translateY(-50%);
left: 95%;
/*right: 20px;
*/
width: 24px;
height: 14px;
display: inline-block;
vertical-align: middle;
}
/* flag container*/
#flag-container span {
font-size: 24px;
display: flex; /* Allows for easy centering */
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
width: 100%; /* Full width of parent */
height: 24px; /* Set a fixed height */
border: 1px solid #ccc; /* Light gray border */
border-radius: 5px; /* Rounded corners */
cursor: default; /* Prevent text cursor */
}
.fallback-box {
display: inline-block; /* Make it inline-block to fit around the content */
border: 2px solid gray; /* Change the border color as desired */
padding: 10px; /* Add some padding */
border-radius: 10px; /* Round the corners of the box */
font-size: 60px; /* Adjust size if needed */
margin-top: 10px; /* Add some margin */
text-align: center; /* Center text inside the box */
}
table.sme-border {
border-collapse: collapse;
border: 2px solid #cccccc;
empty-cells: show;
margin: 5px 5px 5px 2px;
}
td.sme-border, td.sme-border-warning, td.sme-border-right, td.sme-border-center {
border: 1px solid #cccccc;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
font-weight: normal;
color: #000000;
text-align: left;
padding-left: 2px;
padding-right: 2px;
padding-top: 3px;
padding-bottom: 3px;
}
td.sme-border-warning {
color: red;
}
td.sme-border-right {
text-align: right;
}
td.sme-border-center {
text-align: center;
}
th.sme-border {
border: 1px solid #cccccc;
background-color: #bee6a2;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
font-weight: bold;
color: #000000;
text-align: center;
vertical-align: bottom;
padding-left: 3px;
padding-right: 3px;
padding-top: 3px;
padding-bottom: 3px;
/*border-width: 1px;
border-style: solid;
border-color: #F2F0EE #75736E #75736E #F2F0EE ;
*/
}
td.sme-border a, td.sme-border-right a, td.sme-border-center a {
font-size: 10px;
}
th.sme-layout {
border: 1px solid #8ebe43;
background-color: #bee6a2;
}
table.sme-border {
border: 2px solid #dddddd;
}
td.sme-border-warning,
td.sme-border-right,
td.sme-border-center {
border: 1px solid #dddddd;
}
td.sme-border-right {text-align: right;}
td.sme-border-center {text-align: center;}
th.sme-border {
border: 1px solid #dddddd;
background-color: #e8f3e1;
}
.no-visited-state {
color: inherit;
/* Or specify the desired color */
text-decoration: none;
/* Or any other style you want to reset */
}
.no-visited-state:visited {
color: inherit;
/* Or specify the desired color */
text-decoration: none;
/* Or any other style you want to reset */
}
#busy-indicator {
display: none;
margin-top: 10px;
font-weight: bold;
color: red;
}
.busy {
cursor: wait; /* Change the cursor to a 'wait' cursor */
}

Some files were not shown because too many files have changed in this diff Show More