opt
/
kaspersky
/
kav4fs
/
lib
/
perl
/
KL
➕ New
📤 Upload
✎ Editing:
AppSamba.pm
← Back
package KL::AppSamba; use strict; use KL::Utils; use File::Basename; #--- my $HEADER_SETUP_SAMBA = <<EOT; Setting up the Samba server real-time protection EOT my $MSG_SAMBA_FOUND = <<EOT; The installer found the following Samba server installed on your computer: Samba server version: %1 Samba server binaries located in %2 Samba server configuration file: %3 Samba server libs: %4 VFS module to be installed: %5 Enter 'yes', if you want to protect this Samba server by %6. Enter 'no', if Samba server has been detected incorrectly, or if you don\'t want to protect it. EOT my $MSG_SAMBA_AUTO = <<EOT; Configuring Samba server using parameters: Samba server configuration file: %1 Samba server libs: %2 VFS module to be installed: %3 EOT my $MSG_SAMBA_FOUND_VFSDIR_LOCATED_AT = "located in"; my $MSG_SAMBA_FOUND_VFSDIR_NOT_MATTER = "does not matter"; my $MSG_SAMBA_NOT_FOUND = <<EOT; The installer couldn\'t find a Samba server on your computer. Either it is not installed, or is installed to an unknown location. EOT my $MSG_SAMBA_CONFIRM_CUSTOM = <<EOT; If the Samba server is installed, specify the server installation details and enter 'yes'. Otherwise, enter 'no' (the Samba server configuration step will be interrupted): EOT my $MSG_SAMBA_RECONFIG_HINT = <<EOT; You can configure Samba server protection later by running the initial configuration script again by executing <B>%1</B> EOT my $MSG_SAMBA_ASK_SMBD_PATH = <<EOT; Please enter the full path (without the filename) to your smbd binary (or <B>enter 'cancel' to interrupt</B> the Samba server configuration step). EOT my $SETUPMSG_3b = <<EOT; The real-time protection of Samba server was not setup because the path to Samba binaries was not specified. You can run the initial configuration script again by executing <B>%1</B> EOT my $MSG_SAMBA_CANNOT_EXECUTE = <<EOT; Unable to execute %1: %2. EOT my $MSG_SAMBA_NOFILE = "No such file"; my $MSG_SAMBA_NODIR = "The %1 directory doesn't exist"; my $MSG_SAMBA_ASK_CONF_PATH = <<EOT; Please enter the full path to your smbd configuration file (or <B>enter 'cancel' to interrupt</B> the Samba server configuration step). EOT my $MSG_SAMBA_SETUP_CANCELED = <<EOT; The real-time protection of Samba server was not setup. You can run the initial configuration script again by executing <B>%1</B> EOT my $MSG_SAMBA_INVALID_CONFIG = <<EOT; The %1 file is not a correct Samba server configuration file. EOT my $MSG_SAMBA_ASK_VFS_PATH = <<EOT; Please enter the full path to your Samba server vfs libs (usually a directory named vfs/, containing files with the .so extension, such as readonly.so). Enter 'cancel' to interrupt the Samba server configuration step. EOT my $MSG_SAMBA_BAD_VFS_PATH = <<EOT; The %1 path is not a correct Samba Server vfs libs path. EOT my $MSG_COMMAND_FAILED = <<EOT; Couldn\'t execute the command %1: %2. EOT my $MSG_SAMBA_VFS_CONFIGURED = <<EOT; The Samba server vfs module has been configured successfully. EOT my $MSG_SAMBA_SETUP_SUCCESS = <<EOT; The configuration file of Samba server was changed. Restart the Samba daemon manually to apply these changes. EOT my $MSG_DELETE_FAILED = <<EOT; Couldn\'t delete the %1 file: %2. EOT my $MSG_CANT_WRITE = <<EOT; Couldn\'t write %1: %2. EOT my $MSG_CANT_READ = <<EOT; Couldn\'t read %1: %2. EOT #--- ### Samba module setup routines ### sub _parse_samba_config { my $filename = shift; my %smbconf = KL::IniFile::load($filename); return if !%smbconf || !$smbconf{"sections"} || !$smbconf{"sections"}->{"global"}; return %smbconf; } sub _cmp_samba_version { my $ver1 = shift; my $ver2 = shift; return undef if ($ver1 !~ /^(\d+)\.(\d+)\.(\d+)([a-z])?/); my @v1 = ($1, $2, $3, $4); return undef if ($ver2 !~ /^(\d+)\.(\d+)\.(\d+)([a-z])?/); my @v2 = ($1, $2, $3, $4); for (my $i = 0; $i < 4; $i++ ) { my $vv1 = defined $v1[$i] ? $v1[$i] : ''; my $vv2 = defined $v2[$i] ? $v2[$i] : ''; if ($i < 3) { $vv1 = int($vv1); $vv2 = int($vv2); return -1 if ($vv1 < $vv2); return 1 if ($vv1 > $vv2); } else { return -1 if ($vv1 lt $vv2); return 1 if ($vv1 gt $vv2); } } return 0; } sub _find_vfs_module { my $self = shift; my $ver = shift; my @smb_interfaces_special = ( [ '22-sles', '3.0.28-*-*-SUSE-CODE10' ], [ '22-sles', '3.0.36-*-*-SUSE-CODE10' ], ); my @smb_interfaces = ( [ '36', '4.6.0' ], [ '35', '4.5.0' ], [ '34', '4.4.0' ], [ '33', '4.3.0' ], [ '32', '4.2.0' ], [ '31', '4.1.0' ], [ '30', '4.0.0' ], [ '28', '3.6.0' ], [ '27', '3.5.0' ], [ '25', '3.4.0' ], [ '24', '3.3.0' ], [ '22', '3.2.0' ], [ '21', '3.0.25' ], [ '16', '3.0.23' ], [ '15', '3.0.21' ], [ '14', '3.0.20a' ], [ '13', '3.0.20' ], [ '11', '3.0.11' ], [ '10a', '3.0.2a' ], [ '10', '3.0.2' ], [ '09', '3.0.0' ], ); my $if_ver; if (not defined $if_ver) { SPECIALIF: foreach my $smbif (@smb_interfaces_special) { my @masks = @{$smbif}; my $smbif = shift @masks; foreach my $mask (@masks) { $mask = quotemeta($mask); $mask =~ s/\\\*/\.\*/g; if ($ver =~ /$mask/) { $if_ver = $smbif; last SPECIALIF; } } } } if (not defined $if_ver) { foreach my $smbif (@smb_interfaces) { my ($smbif, $minver) = @{$smbif}; if (_cmp_samba_version($ver, $minver) >= 0) { $if_ver = $smbif; last; } } } return undef if not defined $if_ver; return sprintf('%s-smb-vfs%s', $self->appinfo('product', 'name'), $if_ver); } sub _get_smbd_version { my $smbd = shift; # execute smbd and parse its version my ($ret, $version) = KL::Utils::execute('env', 'LANG=C', $smbd, '-V'); return if $ret != 0; $version =~ s/(^Version |\s+$)//g; if (!$version || $version !~ /^\d+\.([\d\.]+[a-z]?)/) { return; } return $version; } sub _get_smbd_info { my $self = shift; my $smbd = shift; my $ret; my $version = _get_smbd_version($smbd); if (!$version) { return; } my $smbdinfo = { 'bin' => $smbd, 'version' => $version, 'conf' => undef, 'vfsdir' => undef, 'type' => undef, 'vfsmodule' => undef, }; ($ret, $_) = KL::Utils::execute('env', 'LANG=C', $smbd, '-b'); if (!$_) { return; } $smbdinfo->{'conf'} = $1 if /^\s*CONFIGFILE:\s+(.*)/m; $smbdinfo->{'vfsdir'} = "$1/vfs" if /^\s*MODULESDIR:\s+(.*)/m; if ( (not defined $smbdinfo->{'vfsdir'}) or (!-d $smbdinfo->{'vfsdir'}) ) { $smbdinfo->{'vfsdir'} = (-d "$1/vfs" ? "$1/vfs" : "$1/samba/vfs") if /^\s*LIBDIR:\s+(.*)/m; } my $bintype; ($ret, $bintype) = KL::Utils::execute('env', 'LANG=C', 'file', '-b', $smbd); if ($ret == 0) { if ($bintype =~ /^ELF 32/) { $smbdinfo->{'type'} = 'elf32'; } elsif ($bintype =~ /^ELF 64/) { $smbdinfo->{'type'} = 'elf64'; } } if (not defined $smbdinfo->{'type'}) { # detect arch from build host info if ( /^\s*Build host:\s+.*(i[3-6]86|x86_64|amd64)/mi ) { my $buildhost = $1; if ( $buildhost =~ /amd64|x86_64/i ) { $smbdinfo->{'type'} = 'elf64'; } elsif ( $buildhost =~ /i[3-6]86/i ) { $smbdinfo->{'type'} = 'elf32'; } } } my $smbdtype = $smbdinfo->{'type'}; my $libspath; if ($smbdtype eq 'elf32') { $libspath = $self->get_path('libs'); } elsif ($smbdtype eq 'elf64') { $libspath = $self->get_path('libs64'); } else { return; } $libspath .= '/samba/'; my $vfsmodule = $self->_find_vfs_module($version); if (!$vfsmodule) { return; } $smbdinfo->{'vfsmodule'} = $libspath . $vfsmodule . '.so'; return $smbdinfo; } sub _find_samba { my $self = shift; my @samba_setup = ( { # default Samba installation from sources "smbd" => "/usr/local/samba/sbin/smbd", "conf" => "/usr/local/samba/lib/smb.conf", "vfs" => "/usr/local/samba/lib/vfs" }, { # FreeBSD/OpenBSD packages "smbd" => "/usr/local/sbin/smbd", "conf" => "/usr/local/etc/smb.conf", "vfs" => "/usr/local/lib/samba/vfs" }, { # Most Linux packages (RedHat, SuSE, etc) "smbd" => "/usr/sbin/smbd", "conf" => "/etc/samba/smb.conf", "vfs" => "/usr/lib/samba/vfs" }, { # A very old Solaris package "smbd" => "/opt/samba/bin/smbd", "conf" => "/opt/samba/lib/smb.conf", "vfs" => "/opt/samba/lib/vfs" } ); # Try to detect Samba automatically foreach (@samba_setup) { my $smbdinfo; my %rec = %{$_}; next if ! -f $rec{'smbd'}; $smbdinfo = $self->_get_smbd_info($rec{'smbd'}); next if ! $smbdinfo; return $smbdinfo; } return undef; } ### sub _ask_samba_paths { my $self = shift; my $setup_cmd = $self->{'SETUP'} . " --samba"; my $smbdinfo = $self->_find_samba(); my $smbdpath = $smbdinfo ? dirname($smbdinfo->{'bin'}) . '/' : ''; if ($smbdinfo) { my @args = ( $smbdinfo->{"version"}, # %1 $smbdpath, # %2 $smbdinfo->{"conf"}, #3 $smbdinfo->{"vfsdir"} ? "$MSG_SAMBA_FOUND_VFSDIR_LOCATED_AT $smbdinfo->{vfsdir}/" : $MSG_SAMBA_FOUND_VFSDIR_NOT_MATTER, #4 $smbdinfo->{"vfsmodule"}, #5 $self->appinfo('product', 'title'), #6 ); my $confirmed = KL::Utils::ask_boolean ('yes', $MSG_SAMBA_FOUND, @args); if ($confirmed) { return $smbdinfo; } } else { KL::Utils::error ($MSG_SAMBA_NOT_FOUND); if ( KL::Utils::ask_boolean ('no', $MSG_SAMBA_CONFIRM_CUSTOM) == 0 ) { KL::Utils::output ($MSG_SAMBA_RECONFIG_HINT, $setup_cmd); return; } } # # Auto-detection failed or not confirmed # # (1) Ask user for smbd binary while ( 1 ) { $smbdpath = KL::Utils::ask_question ($smbdpath, $MSG_SAMBA_ASK_SMBD_PATH); if ($smbdpath =~ /^s*cancel\s*$/i) { KL::Utils::output ($SETUPMSG_3b, $setup_cmd); return; } if (!-d $smbdpath) { KL::Utils::output ($MSG_SAMBA_CANNOT_EXECUTE, "smbd", KL::Utils::translate_string($MSG_SAMBA_NODIR, $smbdpath) ); next; } # exists? if (! -f "$smbdpath/smbd") { KL::Utils::output ($MSG_SAMBA_CANNOT_EXECUTE, "$smbdpath/smbd", $MSG_SAMBA_NOFILE); next; } $smbdinfo = $self->_get_smbd_info("$smbdpath/smbd"); # does it execute successfully? abort if it doesn't if (!$smbdinfo) { KL::Utils::output ($MSG_SAMBA_CANNOT_EXECUTE, "$smbdpath/smbd", $!); next; } last; } # (2) Ask user for Samba config file binary. while ( 1 ) { my $confpath = KL::Utils::ask_question ($smbdinfo->{'conf'}, $MSG_SAMBA_ASK_CONF_PATH); if ($confpath =~ /^s*cancel\s*$/i) { KL::Utils::output ($MSG_SAMBA_SETUP_CANCELED, $setup_cmd); return; } $confpath .= "/smb.conf" if -d $confpath; if (_parse_samba_config ($confpath)) { $smbdinfo->{'conf'} = $confpath; last; } KL::Utils::output ($MSG_SAMBA_INVALID_CONFIG, $confpath); } # (3) Ask user of Samba 3.x.x for lib path while ( 1 ) { my $libpath = KL::Utils::ask_question ($smbdinfo->{'vfsdir'}, $MSG_SAMBA_ASK_VFS_PATH); if ($libpath =~ /^s*cancel\s*$/i) { KL::Utils::output ($MSG_SAMBA_SETUP_CANCELED, $setup_cmd); return; } if ( -d $libpath && -f "$libpath/readonly.so" ) { $smbdinfo->{'vfsdir'} = $libpath; last; } KL::Utils::output ($MSG_SAMBA_BAD_VFS_PATH, $libpath); } return $smbdinfo; } sub _setup_samba_module { my $self = shift; my $smbdinfo = shift; my $smbdconf_path = $smbdinfo->{'conf'}; my $vfsmodule = $smbdinfo->{'vfsmodule'}; my $vfsmodule_name = basename($smbdinfo->{'vfsmodule'}); my $copiedvfsmodule = ""; # For 3.x we also need to copy the module my $vfsmodule_dest = "$smbdinfo->{vfsdir}/$vfsmodule_name"; my $msg = KL::Utils::copy_file ($vfsmodule, $vfsmodule_dest); if ($msg) { KL::Utils::error ($msg); return 0; } chmod 0755, $vfsmodule_dest; $self->settings('SAMBA_VFSMODULE', $vfsmodule_dest); # Modify the config file, checking for already registered unknown VFS modules my $configure_shares_mode; my $marker = uc($self->{'TITLE'}); $vfsmodule_name = basename($vfsmodule_name, '.so'); my %smbconf = _parse_samba_config ($smbdconf_path); foreach my $name (@{$smbconf{'order'}}) { # Do not add share on these sections next if $name eq "printers" || !defined $smbconf{"sections"}->{$name}; my $newcfgdata = undef; foreach my $line (split (/\n/, $smbconf{"sections"}->{$name}, -1)) { if ( $line =~ /^\s*vfs object\s*=\s*(.*)\s*$/ ) { my $curr_module = $1; if ( $curr_module eq $vfsmodule and $name eq 'global') { # Already added for this share - stop scanning $newcfgdata = undef; last; } if ($curr_module =~ /kavsamba5-smb-/) { # skip to remove usage old module versions next; } else { # disable 3rd party vfs module $line =~ s/^\s+//; $newcfgdata .= "\t# COMMENTED-OUT BY $marker\n\t# $line\n"; next; } } next if $line =~ /# ADDED BY KASPERSKY ANTI-VIRUS/; $newcfgdata .= "$line\n"; } if ( defined $newcfgdata ) { $newcfgdata =~ s/\n$//; if ($name eq "global") { $newcfgdata = "\t# ADDED BY $marker\n" . "\tvfs object = $vfsmodule_name\n" . $newcfgdata; } $smbconf{"sections"}->{$name} = $newcfgdata; } } # Make a backup if (!open FILE, "<$smbdconf_path") { KL::Utils::error( "Could not read %1: %2", $smbdconf_path, $!); return 0; } my $backupdata = join ("", <FILE>); close FILE; if (!open FILE, ">$smbdconf_path.kavbackup") { KL::Utils::error( "Could not write to %1: %2", "$smbdconf_path.kavbackup", $!); return 0; } print FILE $backupdata; close FILE; # Write the modified configuration file if (!open FILE, ">$smbdconf_path") { KL::Utils::error( "Could not write to %1: %2", $smbdconf_path, $!); return 0; } print FILE "$smbconf{header}" if $smbconf{"header"}; foreach my $name (@{$smbconf{"order"}}) { print FILE "[$name]\n$smbconf{sections}->{$name}"; } close FILE; # Save Samba configuration file in storage $self->settings('SAMBA_CONFPATH', $smbdconf_path); my @args = ('--set-app-settings', 'SambaConfigPath=' . $smbdconf_path); my ($ret, $msg) = $self->_control_nout(@args); KL::Utils::warning($MSG_COMMAND_FAILED, join(' ', @args), $msg) if $ret != 0; $self->_set_samba_protection(1); return 1; } ### Samba module setup routines called from KL::App ### sub do_setup_samba_module { my $self = shift; my $setup_cmd = $self->{'SETUP'} . ' --samba'; KL::Utils::debug("do_setup_samba_module"); KL::Utils::header($HEADER_SETUP_SAMBA); my $samba = $self->_ask_samba_paths(); if (!$samba) { KL::Utils::output ($MSG_SAMBA_SETUP_CANCELED, $setup_cmd); return 0; } if (!$self->_setup_samba_module($samba)) { return 0; } $self->ai_save('RTP_SAMBA_ENABLE', 'yes'); $self->ai_save('RTP_SAMBA_CONF', $samba->{'conf'}); $self->ai_save('RTP_SAMBA_VFS', $samba->{'vfsdir'}); $self->ai_save('RTP_SAMBA_VFS_MODULE', $samba->{'vfsmodule'}); KL::Utils::output ($MSG_SAMBA_VFS_CONFIGURED); KL::Utils::output ($MSG_SAMBA_SETUP_SUCCESS); return 1; } sub do_autoinstall_samba_module { my $self = shift; KL::Utils::debug("do_autoinstall_samba_module"); my $opt; my $mode = $self->ai_value('RTP_SAMBA_ENABLE'); if (not defined $mode or $mode eq 'no') { return 1; } KL::Utils::header($HEADER_SETUP_SAMBA); my $smbdinfo; if ($mode eq 'auto') { $smbdinfo = $self->_find_samba(); if (!$smbdinfo) { KL::Utils::error ($MSG_SAMBA_NOT_FOUND); return 0; } } else { my $confpath = $self->ai_value('RTP_SAMBA_CONF'); my $vfsdir = $self->ai_value('RTP_SAMBA_VFS'); $smbdinfo = { 'conf' => $confpath, 'vfsdir' => $vfsdir, 'vfsmodule' => $self->ai_value('RTP_SAMBA_VFS_MODULE'), }; # check conf if (!_parse_samba_config ($confpath)) { KL::Utils::error ($MSG_SAMBA_INVALID_CONFIG, $confpath); return 0; } # check vfsdir if ( !-d $vfsdir or !-f "$vfsdir/readonly.so" ) { KL::Utils::error ($MSG_SAMBA_BAD_VFS_PATH, $vfsdir); return 0; } } KL::Utils::output($MSG_SAMBA_AUTO, $smbdinfo->{'conf'}, $smbdinfo->{'vfsdir'}, $smbdinfo->{'vfsmodule'}, ); my $res = $self->_setup_samba_module($smbdinfo); if ($res) { KL::Utils::output ($MSG_SAMBA_VFS_CONFIGURED); } return $res; } sub do_remove_samba_module { my $self = shift; KL::Utils::debug("do_remove_samba_module"); my $vfsmodule = $self->settings('SAMBA_VFSMODULE'); if (defined $vfsmodule) { if (not unlink($vfsmodule)) { KL::Utils::warning($MSG_DELETE_FAILED, $vfsmodule, $!); } $self->remove_settings('SAMBA_VFSMODULE'); } my $smbconffile = $self->settings('SAMBA_CONFPATH'); if (!defined($smbconffile) or not -f $smbconffile) { return; } my %smbconf = _parse_samba_config ($smbconffile); my $modulename = sprintf('%s-smb-vfs%s', $self->appinfo('product', 'name')); foreach my $name (@{$smbconf{"order"}}) { # Do not add share on these sections next if $name eq "printers" || !defined $smbconf{"sections"}->{$name}; my $newcfgdata = undef; foreach my $line (split (/\n/, $smbconf{"sections"}->{$name}, -1)) { if ( $line =~ /^\s*vfs object\s*=\s*(.*)\s*$/ ) { my $curr_module = $1; if ( ($curr_module =~ /kavsamba5-/) || ($curr_module =~ /$modulename/) ) { # skip to remove vfs module next; } } next if $line =~ /# ADDED BY KASPERSKY ANTI-VIRUS/; $newcfgdata .= "$line\n"; } if ( defined $newcfgdata ) { $newcfgdata =~ s/\n$//; $smbconf{"sections"}->{$name} = $newcfgdata; } } # Make a backup if (not (open FILE, "<$smbconffile") ) { KL::Utils::warning($MSG_CANT_READ, $smbconffile, $!); return; } my $backupdata = join ("", <FILE>); close FILE; if (open FILE, ">$smbconffile.kavbackup") { print FILE $backupdata; close FILE; } # Write the modified configuration file if (not open FILE, ">$smbconffile") { KL::Utils::warning($MSG_CANT_WRITE, $smbconffile, $!); return; } print FILE "$smbconf{header}" if $smbconf{"header"}; foreach my $name (@{$smbconf{"order"}}) { print FILE "[$name]\n$smbconf{sections}->{$name}"; } close FILE; # Remove Samba configuration file & VFS module from storage $self->remove_settings('SAMBA_CONFPATH'); return 1; } 1;
💾 Save Changes
Cancel
📤 Upload File
×
Select File
Upload
Cancel
➕ Create New
×
Type
📄 File
📁 Folder
Name
Create
Cancel
✎ Rename Item
×
Current Name
New Name
Rename
Cancel
🔐 Change Permissions
×
Target File
Permission (e.g., 0755, 0644)
0755
0644
0777
Apply
Cancel