Compare commits
	
		
			18 Commits
		
	
	
		
			11_0_0-54_
			...
			11_0_0-67_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5be2152e89 | |||
| 63973f2bb4 | |||
| 82ff48e641 | |||
| c5d863b3a0 | |||
| 4f00dfbdb1 | |||
| f9bf8cf064 | |||
| 4f0617f6c3 | |||
| 4c94d768e2 | |||
| 1731f75cba | |||
| 5fe285f9f2 | |||
| 1c93be6e8a | |||
| ce96f72726 | |||
| 0fd7137edd | |||
| d179b06f69 | |||
| c2427189d5 | |||
| 887af04bfe | |||
| 34b85b1cde | |||
| a5758b4431 | 
							
								
								
									
										9
									
								
								root/usr/lib/systemd/system/bootsequence.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								root/usr/lib/systemd/system/bootsequence.service
									
									
									
									
									
										Normal 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 | ||||
| @@ -43,7 +43,7 @@ $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 | ||||
| @@ -788,7 +788,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 ); | ||||
|   | ||||
| @@ -32,10 +32,14 @@ use esmith::util; | ||||
| use esmith::lockfile; | ||||
| use esmith::BlockDevices; | ||||
| use constant DEBUG => $ENV{MOJO_SMANAGER_DEBUG} || 0; | ||||
| our $cdb = esmith::ConfigDB->open   || die "Couldn't open config db"; | ||||
| our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db"; | ||||
| our $rdb = esmith::ConfigDB->open('/etc/e-smith/restore') | ||||
|     || die "Couldn't open restore db"; | ||||
|  | ||||
| use constant FALSE => 0; | ||||
| use constant TRUE  => 1; | ||||
|  | ||||
| #our $cdb = esmith::ConfigDB->open   || die "Couldn't open config db"; #remove as cached gives problems | ||||
| #our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db"; | ||||
| #our $rdb = esmith::ConfigDB->open('/etc/e-smith/restore') || die "Couldn't open restore db"; | ||||
| my ($cdb,$adb,$rdb); | ||||
| my $es_backup = new esmith::Backup or die "Couldn't create Backup object\n"; | ||||
| my @directories = $es_backup->restore_list; | ||||
| @directories = grep { -e "/$_" } @directories; | ||||
| @@ -52,6 +56,9 @@ sub main { | ||||
|     my $c = shift; | ||||
|     $c->app->log->info($c->log_req); | ||||
|     my %bac_datas = (); | ||||
| 	$cdb = esmith::ConfigDB->open   || die "Couldn't open config db"; | ||||
| 	$adb = esmith::AccountsDB->open || die "Couldn't open accounts db"; | ||||
| 	$rdb = esmith::ConfigDB->open('/etc/e-smith/restore'); | ||||
|     my $title     = $c->l('bac_BACKUP_TITLE'); | ||||
|     my $notif; | ||||
|     $bac_datas{'function'} = 'desktop_backup'; | ||||
| @@ -108,6 +115,9 @@ sub do_display { | ||||
|     my $rt = $c->current_route; | ||||
|     my ($res, $result) = ''; | ||||
|     my $function = $c->param('Function'); | ||||
| 	$cdb = esmith::ConfigDB->open   || die "Couldn't open config db"; | ||||
| 	$adb = esmith::AccountsDB->open || die "Couldn't open accounts db"; | ||||
| 	$rdb = esmith::ConfigDB->open('/etc/e-smith/restore'); | ||||
|  | ||||
|     if ($function =~ /^(\S+)$/) { | ||||
|         $function = $1; | ||||
| @@ -129,7 +139,11 @@ sub do_display { | ||||
|         $c->stash(compressionlevel => $CompressionLevel, exclude => \@exclude, directories => \@directories); | ||||
|  | ||||
|         # streaming download in template | ||||
|         return $c->render("/backdown"); | ||||
|         $c->render(template=>"backdown"); | ||||
|         #sleep(30); | ||||
|         # Redirect to the front page | ||||
| 		#$c->redirect_to('/backup'); | ||||
|         return "" | ||||
|     } ## end if ($function eq 'desktop_backup') | ||||
|  | ||||
|     if ($function eq 'tape_configure') { | ||||
| @@ -265,6 +279,9 @@ sub do_update { | ||||
|     my $c = shift; | ||||
|     $c->app->log->info($c->log_req); | ||||
|     my $rt       = $c->current_route; | ||||
| 	$cdb = esmith::ConfigDB->open   || die "Couldn't open config db"; | ||||
| 	$adb = esmith::AccountsDB->open || die "Couldn't open accounts db"; | ||||
| 	$rdb = esmith::ConfigDB->open('/etc/e-smith/restore'); | ||||
|     my $function = $c->param('Function'); | ||||
|     DEBUG && warn("do_update $function"); | ||||
|     my %bac_datas = (); | ||||
| @@ -513,13 +530,13 @@ sub do_update { | ||||
|  | ||||
|     # common part for all functions | ||||
|     if ($res ne 'OK') { | ||||
|  | ||||
|         if ($res eq 'NEXT') { | ||||
|             $dest = 'back_' . $bac_datas{"function"}; | ||||
|         } else { | ||||
|             $c->stash(error => $result); | ||||
|             $dest = "back_$function"; | ||||
|         } | ||||
|         $bac_datas{vfstype}        = $c->param('VFSType'); | ||||
|         $c->stash(title => $title, bac_datas => \%bac_datas); | ||||
|         return $c->render($dest); | ||||
|     } ## end if ($res ne 'OK') | ||||
| @@ -919,7 +936,7 @@ sub workstnVerify { | ||||
|  | ||||
| sub workstnRestore { | ||||
|     my ($c) = @_; | ||||
|     my $out; | ||||
|     my $out = ''; | ||||
|     my $restoreref = $c->param('Backupset'); | ||||
|     my $set        = $restoreref; | ||||
|     $set =~ s/\/[^\/]*$//; | ||||
| @@ -1002,6 +1019,7 @@ sub workstnRestore { | ||||
|         return "$c->l('bac_OPERATION_STATUS_REPORT') $c->l('bac_ERR_PRE_RESTORE')"; | ||||
|     } | ||||
|     $| = 1; | ||||
|     my $RD; | ||||
|  | ||||
|     if (open(RD, "-|")) { | ||||
|  | ||||
| @@ -1034,8 +1052,8 @@ sub workstnRestore { | ||||
|                     or warn($c->l('bac_ERR_RESTORING_INITIAL_GRP') . "\n"); | ||||
|                 esmith::util::backgroundCommand(0, "/sbin/e-smith/signal-event", "post-upgrade"); | ||||
|  | ||||
|                 #	system("/sbin/e-smith/signal-event", "post-upgrade") == 0 | ||||
|                 #	    or die ($c->l('bac_ERROR_UPDATING_CONFIGURATION')."\n"); | ||||
|                 	#system("/sbin/e-smith/signal-event", "post-upgrade") == 0  | ||||
|                 	#    or die ($c->l('bac_ERROR_UPDATING_CONFIGURATION')."\n"); | ||||
|             } else { | ||||
|                 $message = $c->l('bac_RESTORE_FAILED'); | ||||
|             } | ||||
| @@ -1063,9 +1081,111 @@ sub workstnRestore { | ||||
|         die($error_message) if $error_message; | ||||
|         exit(0); | ||||
|     } ## end else [ if (open(RD, "-|")) ] | ||||
|     $rdb->reload; | ||||
|     $error_message .= $c->bunmount($mntdir, $VFSType); | ||||
|     return '#OK#' . $out; | ||||
|      | ||||
| 	#my $RD; | ||||
|  | ||||
| 	## Fork-safe open with explicit error handling | ||||
| 	#unless (open($RD, "-|")) { | ||||
| 		## Child process | ||||
| 		#local $SIG{__DIE__} = sub { exit 255 }; | ||||
| 		#$| = 1;  # Autoflush | ||||
|  | ||||
| 		#eval { | ||||
| 			#foreach my $file (@restorefiles) { | ||||
| 				## Security: strict filename validation | ||||
| 				#unless ($file =~ m{^[\w\/.-]+$}) { | ||||
| 					#die "Invalid filename: $file"; | ||||
| 				#} | ||||
| 				 | ||||
| 				## Check file existence | ||||
| 				#unless (-e $file) { | ||||
| 					#die "Backup file $file does not exist"; | ||||
| 				#} | ||||
|  | ||||
| 				## Execute dar with error checking | ||||
| 				#system("/usr/bin/dar", "-Q", "-x", $file, "-v", "-N", "-R", "/", "-wa"); | ||||
| 				#if ($? == -1) { | ||||
| 					#die "Failed to execute dar: $!"; | ||||
| 				#} elsif ($? & 127) { | ||||
| 					#die sprintf("dar died with signal %d, %s coredump", | ||||
| 						#($? & 127), ($? & 128) ? 'with' : 'without'); | ||||
| 				#} elsif ($? >> 8 != 0) { | ||||
| 					#die "dar exited with error code " . ($? >> 8); | ||||
| 				#} | ||||
| 			#} | ||||
|  | ||||
| 			## Unmount with error checking | ||||
| 			#if (my $unmount_err = $c->bunmount($mntdir, $VFSType)) { | ||||
| 				#die "Unmount failed: $unmount_err"; | ||||
| 			#} | ||||
| 		#}; | ||||
|  | ||||
| 		#if (my $child_err = $@) { | ||||
| 			#print STDERR "CHILD ERROR: $child_err"; | ||||
| 			#exit 254; | ||||
| 		#} | ||||
| 		#exit 0; | ||||
| 	#}  | ||||
| 	#else { | ||||
| 		## Parent process | ||||
| 		#eval { | ||||
| 			## Verify fork succeeded | ||||
| 			#unless (defined $RD) { | ||||
| 				#die "Fork failed: $!"; | ||||
| 			#} | ||||
|  | ||||
| 			#$out .= $c->l('bac_FILES_HAVE_BEEN_RESTORED') . "\n<UL>"; | ||||
| 			#my $complete = 0; | ||||
|  | ||||
| 			## Read from child process | ||||
| 			#while (<$RD>) { | ||||
| 				#$complete++ if /etc\/samba\/smbpasswd$/; | ||||
| 				#$out .= "<li>$_</li>\n"; | ||||
| 			#} | ||||
| 			#$out .= "</UL>"; | ||||
|  | ||||
| 			## Close pipe and check status | ||||
| 			#unless (close $RD) { | ||||
| 				#die "Pipe close failed: $!"; | ||||
| 			#} | ||||
|  | ||||
| 			#my $child_status = $?; | ||||
| 			#if ($child_status != 0) { | ||||
| 				#die "Child process failed with status " . ($child_status >> 8); | ||||
| 			#} | ||||
|  | ||||
| 			## Post-restore actions | ||||
| 			#if ($complete) { | ||||
| 				#system("/usr/sbin/groupmod", "-g", $www_gid, "www"); | ||||
| 				#if ($? != 0) { | ||||
| 					#die $c->l('bac_ERR_RESTORING_GID') . ": $! (status $?)"; | ||||
| 				#} | ||||
|  | ||||
| 				#system("/usr/sbin/usermod", "-g", $www_gid, "www"); | ||||
| 				#if ($? != 0) { | ||||
| 					#die $c->l('bac_ERR_RESTORING_INITIAL_GRP') . ": $! (status $?)"; | ||||
| 				#} | ||||
|  | ||||
| 				#my $bg_result = esmith::util::backgroundCommand(0, "/sbin/e-smith/signal-event", "post-upgrade"); | ||||
| 				#unless ($bg_result) { | ||||
| 					#die "Failed to schedule post-upgrade event"; | ||||
| 				#} | ||||
| 			#} else { | ||||
| 				#die $c->l('bac_RESTORE_FAILED'); | ||||
| 			#} | ||||
| 		#}; | ||||
|  | ||||
| 		## Error handling | ||||
| 		#if (my $err = $@) { | ||||
| 			#$rec->set_prop('state', 'failed'); | ||||
| 			#$rec->set_prop('error', "$err"); | ||||
| 			#esmith::lockfile::UnlockFile($file_handle); | ||||
| 			#return $c->l('bac_RESTORE_FAILED_MSG') . ": $err"; | ||||
| 		#} | ||||
| 	#}        | ||||
| 	$rdb->reload; | ||||
| 	$error_message .= $c->bunmount($mntdir, $VFSType); | ||||
| 	return '#OK#' . $out; | ||||
| } ## end sub workstnRestore | ||||
|  | ||||
| sub workstnSelRestore() { | ||||
| @@ -1442,6 +1562,7 @@ sub performReboot { | ||||
|  | ||||
|     #print "$c->l('bac_SERVER_REBOOT')"; | ||||
|     #print "$c->l('bac_SERVER_WILL_REBOOT')"; | ||||
|     warn "reboot coming"; | ||||
|     esmith::util::backgroundCommand(2, "/sbin/e-smith/signal-event", "reboot"); | ||||
|     return "#OK#" . $c->l('bac_SERVER_WILL_REBOOT'); | ||||
| } ## end sub performReboot | ||||
| @@ -1847,7 +1968,7 @@ sub showSize { | ||||
| } ## end sub showSize | ||||
|  | ||||
| sub desktopBackupRecordStatus { | ||||
|     my ($backup, $phase, $status) = @_; | ||||
|     my ($c,$backup, $phase, $status) = @_; | ||||
|     my $now = time(); | ||||
|     warn("Backup terminated: $phase failed - status: $status\n"); | ||||
|     $backup->set_prop('EndEpochTime', "$now"); | ||||
| @@ -1972,7 +2093,7 @@ sub bunmount { | ||||
|         system('/bin/umount', '-f', $mount) == 0 | ||||
|             or return ($c->l('bac_ERR_WHILE_UNMOUNTING')); | ||||
|     } | ||||
|     return; | ||||
|     return ""; | ||||
| } ## end sub bunmount | ||||
|  | ||||
| sub findmnt { | ||||
| @@ -2011,4 +2132,4 @@ sub vmount { | ||||
|         return (qx(/bin/mount -t nfs -o nolock,timeo=30,retrans=1,retry=0 "$host:/$share" $mountdir 2>&1)); | ||||
|     } | ||||
| } ## end sub vmount | ||||
| 1; | ||||
| 1; | ||||
| @@ -17,6 +17,9 @@ use File::Basename; | ||||
| use SrvMngr qw( gen_locale_date_string ); | ||||
| 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; | ||||
| @@ -78,7 +81,7 @@ sub create_configuration_report { | ||||
|     # create the reporting template | ||||
|     my $configreport_template = Text::Template->new( | ||||
|         TYPE    => 'FILE', | ||||
|         SOURCE  => '/etc/e-smith/web/common/configuration_report.tmpl', | ||||
|         SOURCE  => '/usr/share/smanager/themes/default/public/configuration_report.tmpl', | ||||
|         UNTAINT => 1 | ||||
|     ); | ||||
|     my $report_creation_time = gen_locale_date_string; | ||||
| @@ -114,13 +117,40 @@ sub create_configuration_report { | ||||
|  | ||||
|     # 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!"; | ||||
|     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 $out = ''; | ||||
| @@ -143,4 +173,4 @@ sub download_config_report { | ||||
|         'cleanup'             => 1, | ||||
|     ); | ||||
| } ## end sub download_config_report | ||||
| 1; | ||||
| 1; | ||||
| @@ -13,7 +13,7 @@ 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; | ||||
| use esmith::ConfigDB; | ||||
| use esmith::DomainsDB; | ||||
| @@ -385,31 +385,6 @@ sub check_password { | ||||
|     return validate_password($c, $strength, $password); | ||||
| } ## end sub check_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) . "."; | ||||
| } ## end sub validate_password | ||||
|  | ||||
| =head2 group_list() | ||||
|  | ||||
|   | ||||
| @@ -14,6 +14,9 @@ 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; | ||||
| @@ -48,44 +51,63 @@ sub generateReport { | ||||
|     my $c           = shift; | ||||
|     my $report_type = shift; | ||||
|     my $out         = ''; | ||||
|  | ||||
|     #------------------------------------------------------------ | ||||
|     # Looks good; go ahead and generate the report. | ||||
|     # Go ahead and generate the report. | ||||
|     #------------------------------------------------------------ | ||||
|     #	$| = 1; | ||||
|     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); | ||||
|  | ||||
|     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 ''; | ||||
|     } ## end if ($report_type =~ /^qmail-q/) | ||||
|     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>"; | ||||
|     # Get the selected report from the form submission | ||||
|     my $selected_report = $report_type; | ||||
|  | ||||
|     while (<QMAILANALOG>) { | ||||
|     # 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 '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'; | ||||
|     } | ||||
|  | ||||
|         # Cook any special HTML characters | ||||
|         s/\&/\&/g; | ||||
|         s/\"/\"/g; | ||||
|         s/\>/\>/g; | ||||
|         s/\</\</g; | ||||
|         $out .= sprintf("%s", $_); | ||||
|     } ## end while (<QMAILANALOG>) | ||||
|     close QMAILANALOG; | ||||
|     # 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; | ||||
| @@ -94,22 +116,236 @@ sub generateReport { | ||||
| sub reportType_list { | ||||
|     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_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 | ||||
| 1; | ||||
|  | ||||
| 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); | ||||
| } | ||||
|  | ||||
| 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 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; | ||||
| @@ -134,7 +134,7 @@ sub networkAccess_list { | ||||
|     return [ | ||||
|         [ $c->l('rma_NO_ACCESS')         => 'off' ], | ||||
|         [ $c->l('NETWORKS_ALLOW_LOCAL')  => 'private' ], | ||||
|         [ $c->l('NETWORKS_ALLOW_PUBLIC') => 'public' ] | ||||
|         [ $c->l('NETWORKS_ALLOW_PUBLIC') => 'normal' ] | ||||
|     ]; | ||||
| } ## end sub networkAccess_list | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ use Mojo::Base 'Mojolicious::Controller'; | ||||
| use Locale::gettext; | ||||
| use SrvMngr::I18N; | ||||
| use SrvMngr qw(theme_list init_session | ||||
|     is_normal_password email_simple); | ||||
|     validate_password email_simple); | ||||
|  | ||||
| #use esmith::FormMagick qw( validate_password ); | ||||
| #use CGI::FormMagick::Validator qw( call_fm_validation ); | ||||
| @@ -434,31 +434,6 @@ sub check_password { | ||||
|     return validate_password($c, $check_type, $pass1); | ||||
| } ## end sub check_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->l($reason) . "."; | ||||
| } ## end sub validate_password | ||||
|  | ||||
| sub emailForward_list { | ||||
|     my $c = shift; | ||||
|     return [ | ||||
|   | ||||
| @@ -16,7 +16,7 @@ use esmith::ConfigDB; | ||||
| use esmith::AccountsDB; | ||||
| 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 ); | ||||
| #our $cdb = esmith::ConfigDB->open_ro || die "Couldn't open configuration db"; | ||||
|  | ||||
| sub main { | ||||
| @@ -200,28 +200,4 @@ sub check_password { | ||||
|     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) . "."; | ||||
| } ## end sub validate_password | ||||
| 1; | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| 'clm_LABEL_FILESYSTEM_SCAN_PERIOD' => 'Scan filesystem', | ||||
| '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_LABEL_CLAM_VERSIONS' => 'ClamAV and db versions', | ||||
|   | ||||
| @@ -14,26 +14,26 @@ web site for that domain.', | ||||
| 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.', | ||||
| 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 | ||||
| '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_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 | ||||
| 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.', | ||||
| 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 | ||||
| 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', | ||||
|   | ||||
| @@ -128,7 +128,7 @@ | ||||
| '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_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', | ||||
| @@ -151,4 +151,4 @@ SMALL => 'Small', | ||||
| MEDIUM => 'Medium', | ||||
| LARGE => 'Large', | ||||
| FIELD_INVALID_CHARS => 'A field you entered contains invalid characters.', | ||||
|  | ||||
| 'REPORT_GENERATED' => "Report generated", | ||||
| @@ -4,7 +4,7 @@ | ||||
| '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_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', | ||||
|   | ||||
| @@ -34,17 +34,17 @@ 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 | ||||
| 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 | ||||
| '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_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.', | ||||
|   | ||||
| @@ -14,7 +14,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 | ||||
|   | ||||
| @@ -8,6 +8,14 @@ reports are available.</P> | ||||
| these reports</P>', | ||||
| 'qma_REPORT_TYPE' => 'Choose a report type', | ||||
| 'qma_GENERATE_REPORT' => 'Generate report', | ||||
| 'qma_INVALID_REPORT_TYPE' => 'Invalid report type: ', | ||||
| 'qma_REPORT_GENERATED' => 'Report generated: ', | ||||
| 'qma_END_OF_REPORT' => 'End of Report', | ||||
| 'Mail log file analysis' => 'Mail log file analysis', | ||||
|  | ||||
| 'qma_Daily_Summary_Report_yesterday' => 'Summary report for yesterday', | ||||
| 'qma_Daily_Summary_Report_today' => 'Summary report for today up to now', | ||||
|  | ||||
| 'qma_LIST_OUTGOING' => 'List outgoing messages and recipients', | ||||
| 'qma_SUMMARIZE_QUEUE' => 'Summarize status of mail queue', | ||||
| 'qma_SUCCESSFUL_DELIVERY_DELAY' => 'Successful delivery delay distribution', | ||||
| @@ -20,9 +28,4 @@ these reports</P>', | ||||
| '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_REPORT_GENERATED' => 'Report generated: ', | ||||
| 'qma_END_OF_REPORT' => 'End of Report', | ||||
| 'Mail log file analysis' => 'Mail log file analysis', | ||||
|  | ||||
| 'qma_SENDER_UIDS' => 'Sender uids', | ||||
| @@ -26,7 +26,9 @@ 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.', | ||||
| 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_TITLE_FTP_ACCESS' => 'FTP Settings', | ||||
| '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 | ||||
| @@ -75,11 +77,11 @@ connected to a server serial port.', | ||||
| '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 | ||||
| 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  | ||||
| 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 | ||||
| @@ -90,4 +92,4 @@ to the number 0 unless you require IPSEC client access.', | ||||
| 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_LABEL_IPSECRW_RESET' => 'Reset digital certificates', | ||||
| @@ -2,7 +2,7 @@ | ||||
| 'rvw_FORM_TITLE' => 'Review configuration', | ||||
| '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', | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| by the services running on your server.', | ||||
| 'log_LOG_FILE_SELECT_DESC' => 'Choose a log file to view', | ||||
| '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.', | ||||
|   | ||||
| @@ -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! | ||||
							
								
								
									
										43
									
								
								root/usr/share/smanager/themes/default/public/css/module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								root/usr/share/smanager/themes/default/public/css/module.css
									
									
									
									
									
										Normal 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; | ||||
| } | ||||
| @@ -0,0 +1,25 @@ | ||||
| document.addEventListener('DOMContentLoaded', function() { | ||||
|     const analysisType = document.getElementById('analysis_type'); | ||||
|     const messageIdGroup = document.getElementById('message_id_group'); | ||||
|     const emailAddressGroup = document.getElementById('email_address_group'); | ||||
|  | ||||
|     // Initially hide both controls | ||||
|     messageIdGroup.style.display = 'none'; | ||||
|     emailAddressGroup.style.display = 'none'; | ||||
|  | ||||
|     analysisType.addEventListener('change', function() { | ||||
|         // Hide both controls first | ||||
|         messageIdGroup.style.display = 'none'; | ||||
|         emailAddressGroup.style.display = 'none'; | ||||
|  | ||||
|         // Show the relevant control based on the selected option | ||||
|         switch(this.value) { | ||||
|             case 'trace_message': | ||||
|                 messageIdGroup.style.display = 'block'; | ||||
|                 break; | ||||
|             case 'user_activity': | ||||
|                 emailAddressGroup.style.display = 'block'; | ||||
|                 break; | ||||
|         } | ||||
|     }); | ||||
| }); | ||||
| @@ -74,10 +74,8 @@ | ||||
| 	</p><br> | ||||
|  | ||||
| 	%= hidden_field 'Function' => $bac_datas->{'function'} | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('bac_UPDATE_CONF'), class => 'action' | ||||
|     </div> | ||||
|  | ||||
|     % end | ||||
| </div> | ||||
| % end | ||||
| % end | ||||
| @@ -30,10 +30,8 @@ | ||||
|  | ||||
| 	%= hidden_field 'Function' => $bac_datas->{'function'} | ||||
|  | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('bac_RESTORE_FROM_TAPE'), class => 'action' | ||||
|     </div> | ||||
|  | ||||
|     % end | ||||
| </div> | ||||
| % end | ||||
| % end | ||||
| @@ -44,12 +44,10 @@ | ||||
| 	</span></p> | ||||
|  | ||||
| 	%= hidden_field 'Function' => $bac_datas->{'function'} . '1' | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('NEXT'), class => 'action' | ||||
|     </div> | ||||
|  | ||||
|     % end | ||||
|  | ||||
| </div> | ||||
|  | ||||
| % end | ||||
| % end | ||||
| @@ -148,9 +148,7 @@ | ||||
|  | ||||
| 	%= hidden_field 'Function' => $bac_datas->{function} | ||||
| 	%= hidden_field 'VFSType' => $bac_datas->{vfstype} | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('bac_UPDATE_CONF'), class => 'action' | ||||
|     </div> | ||||
|     % end | ||||
| </div> | ||||
| % end | ||||
| % end | ||||
| @@ -38,9 +38,7 @@ | ||||
| 	</span><br><br> | ||||
|  | ||||
| 	%= hidden_field 'Function' => $bac_datas->{'function'} | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('bac_RESTORE_FROM_WORKSTN'), class => 'action' | ||||
|     </div> | ||||
|     % end | ||||
| </div> | ||||
| % end | ||||
| % end | ||||
| @@ -29,9 +29,7 @@ | ||||
| 	%=l 'bac_YOU_MUST_REBOOT' | ||||
| 	</p> | ||||
| 	%= hidden_field 'Function' => $bac_datas->{'function'} | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('bac_REBOOT'), class => 'action' | ||||
|     </div> | ||||
|     % end | ||||
| </div> | ||||
|  | ||||
|   | ||||
| @@ -39,12 +39,10 @@ | ||||
| 	</span><br> | ||||
| 	<br> | ||||
| 	%= hidden_field 'Function' => $bac_datas->{'function'} | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('PERFORM'), class => 'action' | ||||
|     </div> | ||||
|  | ||||
|     % end | ||||
|  | ||||
| </div> | ||||
|  | ||||
| % end | ||||
| % end | ||||
| @@ -41,9 +41,7 @@ | ||||
| 	%= hidden_field 'Backupset' => $bac_datas->{'backupset'} | ||||
| 	%= hidden_field 'Filterexp' => $bac_datas->{'filterexp'} | ||||
|  | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('PERFORM'), class => 'action' | ||||
|     </div> | ||||
|  | ||||
|     % end | ||||
|  | ||||
|   | ||||
| @@ -24,9 +24,7 @@ | ||||
|  | ||||
|     %= form_for '/backupd' => (method => 'POST') => begin | ||||
| 	%= hidden_field 'Function' => $bac_datas->{'function'} | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('NEXT'), class => 'action' | ||||
|     </div> | ||||
|  | ||||
|     % end | ||||
|  | ||||
|   | ||||
| @@ -44,10 +44,8 @@ | ||||
|  | ||||
| 	<br><br> | ||||
| 	%= hidden_field 'Function' => $bac_datas->{'function'} . '1' | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('bac_VERIFY'), class => 'action' | ||||
|     </div> | ||||
|  | ||||
|     % end | ||||
| </div> | ||||
| % end | ||||
| % end | ||||
| @@ -28,10 +28,8 @@ | ||||
|  | ||||
|     %= hidden_field 'Function' => $bac_datas->{'function'} | ||||
|  | ||||
|     <div class='center'> | ||||
|     %= submit_button $c->l('NEXT'), class => 'action' | ||||
|     </div> | ||||
|  | ||||
|     % end | ||||
| </div> | ||||
| % end | ||||
| % end | ||||
| @@ -11,42 +11,52 @@ | ||||
|     # The events handle cases where mysqld is not enabled, and/or is not running. | ||||
|     my $status = system("/sbin/e-smith/signal-event", "pre-backup", "desktop"); | ||||
|     if ($status) { | ||||
| 	desktopBackupRecordStatus($backup_rec, 'pre-backup', $status); | ||||
| 	return ($c->l('bac_OPERATION_STATUS_REPORT'). | ||||
| 		$c->l('bac_ERR_PRE_BACKUP')); | ||||
| 		$c->desktopBackupRecordStatus($backup_rec, 'pre-backup', $status); | ||||
| 		return ($c->l('bac_OPERATION_STATUS_REPORT').$c->l('bac_ERR_PRE_BACKUP')); | ||||
|     } | ||||
|  | ||||
|     my $clvl = $c->stash('compressionlevel'); | ||||
|     my $cmd = "/bin/tar --directory / --create @{$c->stash('directories')} --file=-" | ||||
|         . "@{$c->stash('exclude')} | /usr/bin/gzip $clvl "; | ||||
|     my $cmd = "/bin/tar --create --file=- --directory / @{$c->stash('exclude')}  " | ||||
|         . "@{$c->stash('directories')} | /usr/bin/gzip $clvl "; | ||||
|  | ||||
|     my $success = open my $fh, '-|', $cmd; | ||||
|     unless ($success) { return "Error dowload command."; }; | ||||
|   | ||||
|   # Write chunk | ||||
|   $c->res->headers->content_type('application/x-tar'); | ||||
|   $c->res->headers->content_disposition(qq/attachment; filename="smeserver.tgz"/); | ||||
|  | ||||
|   my $cb; | ||||
|   $cb = sub { | ||||
|     my $c = shift; | ||||
|     my $size = 500 * 1024; | ||||
|     my $length = sysread($fh, my $buffer, $size); | ||||
|     unless ($length) { | ||||
|       close $fh; | ||||
|       undef $cb; | ||||
|       $c->finish; | ||||
|       return; | ||||
|     } | ||||
|     $c->write_chunk($buffer, $cb); | ||||
|   }; | ||||
|   $c->$cb; | ||||
|     #unless ($success) { return "Error download command."; }; | ||||
|     if ($success) { | ||||
| 		# Try with download plugin - seems to fail to complete download and also  | ||||
| 		# name of file deposited is not as required. | ||||
| 		#my $output = do { local $/; <$fh> }; | ||||
| 		#close $fh; | ||||
| 		#$c->render_file( | ||||
| 			#data => $output, | ||||
| 			#filename => 'output.txt', | ||||
| 			#content_type => 'text/plain' | ||||
| 		#); | ||||
| 		# So organise it ourselves. | ||||
| 		$c->res->headers->content_type('application/x-tar'); | ||||
| 		$c->res->headers->content_disposition(qq/attachment; filename="smeserver.tgz"/); | ||||
| 		my $cb; | ||||
| 		$cb = sub { | ||||
| 		my $c = shift; | ||||
| 		my $size = 500 * 1024; | ||||
| 		my $length = sysread($fh, my $buffer, $size); | ||||
| 		unless ($length) { | ||||
| 		  close $fh; | ||||
| 		  undef $cb; | ||||
| 		  $c->finish; | ||||
| 		  return; | ||||
| 		} | ||||
| 		$c->write_chunk($buffer, $cb); | ||||
| 		}; | ||||
| 		$c->$cb; | ||||
| 	} else { | ||||
| 		$c->render(text => "Failed to execute command: $!", status => 500); | ||||
| 	} | ||||
|  | ||||
|     # Remove the dumped tables. | ||||
|     $status = system("/sbin/e-smith/signal-event", "post-backup", "desktop"); | ||||
|     if ($status) { | ||||
| 	desktopBackupRecordStatus($backup_rec, 'post-backup', $status); | ||||
| 	die ($c->l('bac_ERR_POST_BACKUP'),"\n"); | ||||
| 		$c->desktopBackupRecordStatus($backup_rec, 'post-backup', $status); | ||||
| 		die ($c->l('bac_ERR_POST_BACKUP'),"\n"); | ||||
|     } | ||||
|  | ||||
|     $now = time(); | ||||
| @@ -54,3 +64,4 @@ | ||||
|     $backup_rec->set_prop('Result', "0"); | ||||
|  | ||||
| %> | ||||
| 1; | ||||
| @@ -70,12 +70,10 @@ | ||||
| 	</span></p> | ||||
|  | ||||
| 	<br> | ||||
|     <div class='center'> | ||||
| 	%= submit_button $c->l('PERFORM'), class => 'action' | ||||
|     </div> | ||||
|  | ||||
|  	%= submit_button $c->l('PERFORM'), class => 'action' | ||||
|   | ||||
|     % end | ||||
|  | ||||
| </div> | ||||
|  | ||||
| % end | ||||
| % end | ||||
| @@ -18,9 +18,16 @@ | ||||
|     <% my $btn = l('bugr_Download this report'); %> | ||||
|  | ||||
|     %= form_for 'bugreportD' => (method => 'POST') => begin | ||||
| 	%= submit_button "$btn", class => 'action' | ||||
| 	%= hidden_field 'trt' => $bugr_datas->{trt} | ||||
|     % end     | ||||
| 		%= submit_button "$btn", class => 'action' | ||||
| 		%= hidden_field 'trt' => $bugr_datas->{trt} | ||||
|     % end    | ||||
|      | ||||
|     % my $out = "================== <br />"; | ||||
|     % $out .= "Boot anaysis image (right click and save image to download)<br />"; | ||||
|     % $out .= "================== <br />"; | ||||
|     % $out .= "<img src='images/boot.svg' alt='boot timing image' width=95% >"; | ||||
|      | ||||
|    <br><%= $c->render_to_string(inline=>$out) %><br> | ||||
|  | ||||
| </div> | ||||
|  | ||||
|   | ||||
| @@ -1,20 +1,27 @@ | ||||
| % layout 'default', title => "Sme server 2 - module"; | ||||
|  | ||||
| % content_for 'module' => begin | ||||
|  | ||||
| %= stylesheet '/css/module.css' | ||||
| <div id='module' class='module module-panel'> | ||||
|     % if (config->{debug} == 1) { | ||||
| 	<p> | ||||
| 	%= dumper $c->current_route | ||||
| 	</p> | ||||
|         <p> | ||||
|             <strong>Debug Info:</strong> | ||||
|             <pre><%= dumper $c->current_route %></pre> | ||||
|         </p> | ||||
|     % } | ||||
|     % if ( stash 'error' ) { | ||||
|     	<br><div class=sme-error> | ||||
|     	%= $c->render_to_string(inline => stash 'error')  | ||||
| 	</div> | ||||
|     %} | ||||
|     <h1> <%=$title %></h1><br> | ||||
|     %= $c->render_to_string( inline => stash 'modul' ) | ||||
|      | ||||
|     % if (stash 'error') { | ||||
|         <div class="sme-error"> | ||||
|             <strong>Error:</strong><br> | ||||
|             <%= $c->render_to_string(inline => stash 'error') %> | ||||
|         </div> | ||||
|     % } | ||||
|      | ||||
|     <h1><%= $title %></h1> | ||||
|      | ||||
|     <div class="module-content"> | ||||
|         <%= $c->render_to_string(inline => stash 'modul') %> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| %end | ||||
| % end | ||||
| @@ -2,7 +2,7 @@ | ||||
| <HR class="sme-copyrightbar"> | ||||
| <a href="https://mojolicious.org" target="_blank"><img src="images/sme-mojo-logo-white.png" style="position:relative;"></a> | ||||
| <font class="sme-copyright"> | ||||
| %	if ( $c->is_logged_in ) { | ||||
| %	if ( $c->is_logged_in && $c->is_admin) { | ||||
| 	SME Server <%= session 'releaseVersion' %>-<%= $c->app->VERSION %> Manager II | ||||
| 	% my $mode; | ||||
| 	% if (config->{mode} eq 'development'){ $mode = '-dev';} else { $mode = '';} | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| <%     use POSIX qw(strftime); %> | ||||
| <div id="info"> | ||||
|     <% if (! $c->session->{PwdSet} ) { %> | ||||
| 	<div class="sme-error"><h5> | ||||
| @@ -13,4 +14,12 @@ | ||||
|         Warning: Development or debug mode enabled AND public access is offered ! | ||||
|         </h5></div> | ||||
|     <% } %> | ||||
|     <% my $curdate = strftime '%Y%m%d', localtime; %> | ||||
|     <% if ( "$curdate"  >= "20290531" ) { %> | ||||
| 	<div class="sme-error"><h5> | ||||
|       URGENT NOTICE: As per May 31st 2029, SME Server 11 is obsolete, and potentially INSECURE. NO support will be offered for any issue found with this installed version. | ||||
|       Please migrate IMMEDIATELY to Koozali SME Server 12 or higher version. Failure to upgrade may lead to the compromise of this server. | ||||
|       </br>Please, consult <a href="https://wiki.koozali.org/SME_Server:Download" target="_blank">https://wiki.koozali.org/SME_Server:Download</a> to get the latest version | ||||
|      </h5></div> | ||||
|     <% } %> | ||||
| </div> | ||||
| @@ -1,6 +1,6 @@ | ||||
| % layout 'default', title => "Sme server 2 - qmailanalog"; | ||||
|  | ||||
| % content_for 'module' => begin | ||||
| %= javascript '/js/qmailanalog.js' | ||||
| <div id='module' class='module qmailanalog-panel'> | ||||
|     %if (config->{debug} == 1) { | ||||
| 	<p> | ||||
| @@ -11,17 +11,34 @@ | ||||
|     <br> | ||||
|     <%= $modul %> | ||||
|     <% 	my $btn = l('qma_GENERATE_REPORT'); %> | ||||
|  | ||||
|     %= form_for 'qmailanalog' => (method => 'POST') => begin | ||||
| 	<p> | ||||
| 	<span class=label> | ||||
| 	%=l 'qma_REPORT_TYPE' | ||||
| 	</span><span class=data> | ||||
| 	<!-- (to be sorted) --> | ||||
| 	%= select_field 'report_type' => $c->reportType_list() | ||||
| 	</span> | ||||
| 	</p> | ||||
| 	%= submit_button "$btn", class => 'action' | ||||
| 		<p> | ||||
| 		<span class=label> | ||||
| 		%=l 'qma_REPORT_TYPE' | ||||
| 		</span><span class=data> | ||||
| 		<!-- (to be sorted) --> | ||||
| 		%= select_field 'report_type' => $c->reportType_list(), id => 'analysis_type' | ||||
| 		</span> | ||||
| 		</p> | ||||
|  | ||||
| 		<!--And optional parameters, depending on the choice.--> | ||||
| 		<div id="message_id_group"> | ||||
| 			<span class=label> | ||||
| 			%= label_for message_id => 'Message ID:' | ||||
| 			</span><span class=data> | ||||
| 			%= text_field 'message_id', placeholder => 'Enter Postfix Message ID', id => 'message_id_group' | ||||
| 			</span> | ||||
| 		</div> | ||||
|  | ||||
| 		<div id="email_address_group"> | ||||
| 			<span class=label> | ||||
| 			%= label_for email_address => 'Email Address:' | ||||
| 			</span><span class=data> | ||||
| 			%= email_field 'email_address', placeholder => 'Enter email address', id => 'email_address_group' | ||||
| 			</span> | ||||
| 		</div> | ||||
|  | ||||
| 		%= submit_button "$btn", class => 'action' | ||||
|     % end | ||||
| </div> | ||||
| %end | ||||
| @@ -2,7 +2,7 @@ Summary: Sme server  navigation module : manager 2 | ||||
| %define name smeserver-manager | ||||
| Name: %{name} | ||||
| %define version 11.0.0 | ||||
| %define release 54 | ||||
| %define release 66 | ||||
| Version: %{version} | ||||
| Release: %{release}%{?dist} | ||||
| License: GPL | ||||
| @@ -143,6 +143,47 @@ true | ||||
| %defattr(-,root,root) | ||||
|  | ||||
| %changelog | ||||
| * 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. | ||||
|  | ||||
| * 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] | ||||
|  | ||||
| * Sat Mar 08 2025 Brian Read <brianr@koozali.org> 11.0.0-64.sme | ||||
| - Add code to check for boot phase completion [SME: 12953] | ||||
|  | ||||
| * 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 | ||||
|  | ||||
| * Tue Mar 04 2025 Brian Read <brianr@koozali.org> 11.0.0-62.sme | ||||
| - Update *_en.lex files to conform to standard english punctuation  [SME: 11809] | ||||
|  | ||||
| * 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] | ||||
|  | ||||
| * 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] | ||||
|  | ||||
| * 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] | ||||
|  | ||||
| * 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] | ||||
|  | ||||
| * 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 | ||||
|  | ||||
| * 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: 12934] | ||||
|  | ||||
| * Tue Feb 18 2025 Brian Read <brianr@koozali.org> 11.0.0-55.sme | ||||
| - fix public ftp access not showing on panel [SME: 12927] | ||||
|  | ||||
| * 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] | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user