#!/usr/bin/perl -w
# This script (sophomorix-cacls) is maintained by Rüdiger Beck
# It is Free Software (License GPLv3)
# If you find errors, contact the author
# jeffbeck@web.de  or  jeffbeck@linuxmuster.net

# modules
use strict;
#use Quota;
use Getopt::Long;
Getopt::Long::Configure ("bundling");
use Sophomorix::SophomorixConfig;
use Net::LDAP;
use Data::Dumper;
$Data::Dumper::Indent = 1;
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Useqq = 1;
$Data::Dumper::Terse = 1; 

use Sophomorix::SophomorixBase qw(
                                 print_line
                                 print_title
                                 unlock_sophomorix
                                 lock_sophomorix
                                 backup_auk_file
                                 get_passwd_charlist
                                 get_plain_password
                                 check_options
                                 config_sophomorix_read
                                 result_sophomorix_init
                                 result_sophomorix_add
                                 result_sophomorix_add_summary
                                 result_sophomorix_check_exit
                                 result_sophomorix_print
                                 filelist_fetch
                                 remove_whitespace
                                 json_dump
                                 recode_utf8_to_ascii
                                 );
use Sophomorix::SophomorixSambaAD qw(
                                 AD_get_passwd
                                 AD_school_create
                                 AD_bind_admin
                                 AD_unbind_admin
                                 AD_user_create
                                 AD_group_create
                                 AD_group_addmember
                                 AD_group_update
                                 AD_get_schoolname
                                 AD_get_name_tokened
                                 AD_dn_fetch_multivalue
                                 AD_dns_get
                                 AD_object_search
                                     );

# Variablen für Optionen
$Conf::log_level=1;
my $help=0;

my $ls=0;
my $stat=0;
my $allinfo=0;

my $append_to_file="";

my %sophomorix_result=&result_sophomorix_init("sophomorix-cacls");
my $user=$DevelConf::sophomorix_AD_admin;
my ($pass)=&AD_get_passwd($DevelConf::sophomorix_AD_admin,$DevelConf::secret_file_sophomorix_AD_admin);

my ($ldap,$root_dse) = &AD_bind_admin();
my $root_dns=&AD_dns_get($root_dse);
my %sophomorix_config=&config_sophomorix_read($ldap,$root_dse,\%sophomorix_result);

# Parsen der Optionen
my $testopt=GetOptions(
           "verbose|v+" => \$Conf::log_level,
           "help|h" => \$help,
           "ls" => \$ls,
           "allinfo" => \$allinfo,
           "stat" => \$stat,
           "append-to-file=s" => \$append_to_file,
          );

# Prüfen, ob Optionen erkannt wurden, sonst Abbruch
&check_options($testopt);

# --help
if ($help==1) {
   # Scriptname ermitteln
   my @list = split(/\//,$0);
   my $scriptname = pop @list;
   # Befehlsbeschreibung
   print('
sophomorix-cacls accepts one or more unix paths as the option and connects via smb to this path to show ntacls with smbcacls

Options:
  -h  / --help

  --append-to-file /abs/file.txt   
    appends >> the diffable result to /abs/file.txt
    (this is used for sophomorix-repair to make an ACL snapshot)

Alternative options:
   Do a dir listing with smbclient instead of smbcacls:
      --ls

   Show allinfo with smbclient instead of smbcacls:
      --allinfo

   Show stat with smbclient instead of smbcacls:
      --stat

');
   print "\n";
   exit;
}

# use multiple options
my @linux_paths=@ARGV;

# create lookup-table: path -> sharename 
my %share_by_path=();
foreach my $share (keys %{$sophomorix_config{'samba'}{'net_conf_list'}}) {
    if (exists $sophomorix_config{'samba'}{'net_conf_list'}{$share}{'path'}){
        my $path=$sophomorix_config{'samba'}{'net_conf_list'}{$share}{'path'};
        #print " $path --> $share\n";
        $share_by_path{$path}=$share;
    }
}
# add some shares
$share_by_path{'/var/lib/samba/sysvol'}='sysvol';



# --append-to-file works only if file exists already
if ($append_to_file ne ""){
    if (not -f $append_to_file){
        print "\nERROR: Not an existing file: $append_to_file\n\n";
        exit;
    }
}



foreach my $linux_path (@linux_paths){
    my $smb_unc="";
    my $smb_rel="";
    my $command="";
    my $command_append="";
    my $is_smb=0;

    # rewrite path if it is under /srv/samba/mount
    if ($linux_path=~m/^$sophomorix_config{'INI'}{'PATHS'}{'MOUNTPOINT'}/){
        my $old_linux_path=$linux_path;
        $linux_path=~s/^$sophomorix_config{'INI'}{'PATHS'}{'MOUNTPOINT'}/$sophomorix_config{'INI'}{'PATHS'}{'REPAIR_SNAPSHOT_SOURCE'}/;
        print "=============================================================\n";
        print "Rewriting mount path to smb path:\n";
        print "   $old_linux_path\n";
        print "    --->\n";
        print "   $linux_path\n";
    }

    foreach my $path (keys %share_by_path) {
        # if unix path starts with a known share path
        my $share=$share_by_path{$path};
        if ($linux_path=~m/^$path/){
            # calculate smbcacls command
            $is_smb=1;
            $smb_unc="//".$root_dns."/".$share;
            $smb_rel=$linux_path;
            $smb_rel=~s/^$path//;
            $smb_rel=~s/^\///g;
            $smb_rel=~s/\/$//g;
            if ($smb_rel eq ""){
                $smb_rel="/"; # not allowed to be empty
            }
            if ($allinfo==1){
                $command=$sophomorix_config{'INI'}{'EXECUTABLES'}{'SMBCLIENT'}.
                     " -U ".$user."%`cat /etc/linuxmuster/.secret/administrator` ".$smb_unc." -c 'allinfo \"".$smb_rel."\"'";
            } elsif ($stat==1){
                $command=$sophomorix_config{'INI'}{'EXECUTABLES'}{'SMBCLIENT'}.
                     " -U ".$user."%`cat /etc/linuxmuster/.secret/administrator` ".$smb_unc." -c 'stat \"".$smb_rel."\"'";
            } elsif ($ls==1){
                $command=$sophomorix_config{'INI'}{'EXECUTABLES'}{'SMBCLIENT'}.
                     " -U ".$user."%`cat /etc/linuxmuster/.secret/administrator` ".$smb_unc." -c 'cd \"".$smb_rel."\"; ls'";
            } else {
                $command=$sophomorix_config{'INI'}{'EXECUTABLES'}{'SMBCACLS'}.
                     " -U ".$user."%`cat /etc/linuxmuster/.secret/administrator` ".$smb_unc." '".$smb_rel."'";
            }

            $command_append=$command." >> ".$append_to_file;
        }
    }

    # printout
    if ($append_to_file eq ""){
        # print to console
        if ($is_smb==0){
            print "=============================================================\n";
            print "LINUX: $linux_path is not on a SMB share\n";
        } else {
            print "=============================================================\n";
            print "LINUX: $linux_path\n";
            print "   SMB-UNC: $smb_unc\n";
            print "   SMB-RELPATH: $smb_rel\n";
            print "   $command\n";
            print "---------------------------------------------------------------\n";
            if ($smb_rel eq ""){
                print "directory/file name is not allowed to be empty\n";
            } else {
                system($command);
            }
            print "\n\n";
        }
    } else {
        # append to file
        system("echo '\n$linux_path' >> $append_to_file");
        print "   $command_append\n";
        system($command_append);
    }
}
