#!/usr/bin/perl -w

#------------------------------------------------------------
#This action provisions a Samba 4 active directory domain
#
#Copyright 2016 Koozali Foundation, Inc.
#07/14/2016: G.Zartman <gzartman@koozali.org>
#
#The code contained herein can be distributed under the same
#license as Perl
#------------------------------------------------------------

use strict;
use warnings;
use esmith::ConfigDB;
use esmith::util;
use esmith::AD;

##Pull arguments
my $event = $ARGV [0];
my $adminPass = $ARGV [1];

die 'Samba provisioning error: Missing admin password' unless ($adminPass);

##Make sure samba deamons are down
esmith::util::serviceControl(
                              NAME  =>  'smb',
                              ACTION => 'stop'
                            );

##Pull domain name from config dbase.  This is the samba realm
my $cdb = esmith::ConfigDB->open;
my $domainName = $cdb->get('DomainName')->value || 
    die 'Samba provisioning error: Primary Domain Name not defined';
my $workGroup = $cdb->get_prop ('smb', 'Workgroup') ||
    die 'Samba provisioning error: Workgroup not defined';
my $realm = $workGroup . "." . $domainName;

##Remove existing smb.conf file or the provision will error out
unlink ('/etc/samba/smb.conf') if (-e '/etc/samba/smb.conf');

##Generate complex password for SME Server runtime transactions with AD
##Encrypt and stash the password locally
my @set = ('0'..'9','A'..'Z','a'..'z');
my $set = '';
my $provisionPass = join '' => map $set[rand @set], 1..20;

warn "Creating and stashing complex password for AD transactions.\n";

my $encrypted_pass = MIME::Base64::encode($provisionPass);
unlink '/etc/samba/AD.pw';
unless ( open( WR, ">/etc/samba/AD.pw" ) ) {
    die "Samba provisioning error: Unable to create Active Directory LDAP password\n";
    return undef;
}
print WR "$encrypted_pass\n";
close WR;
chmod 0600, '/etc/samba/AD.pw';


##Initialize Samba Domain
warn "Samba domain: Provisioning Active Directory\n";
my $provision = "/usr/bin/samba-tool domain provision --server-role=dc " .
                "--domain=$workGroup " .
                "--realm=$realm " .
                "--adminpass=$provisionPass " .
                "--dns-backend=SAMBA_INTERNAL " . 
                "--use-rfc2307 " .
                "--use-xattrs=yes";

system ($provision);
die "Unable to provision Samba in $event" if ($? == -1);

##Disable default Samba password policy so we can control it in the SME UI
warn "Samba domain:  Disabling default Samba password policy.\n";

my $policy_reset = "/usr/bin/samba-tool domain passwordsettings set " .
                   "--complexity=off "  .
                   "--min-pwd-length=0 " .
                   "--min-pwd-age=0 " .
                   "--max-pwd-age=365 " .
                   "-U Administrator\%$provisionPass";
system ($policy_reset);
die "Samba domain error: Unable to disable default password policy.\n" if ($? == -1);

##Change administrator password from the stashed password to the admin password 
warn "Samba domain: Setting Admin Password\n";
my $set_admin_pass = "/usr/bin/samba-tool user setpassword Administrator " .
                     "--newpassword=" . $adminPass . " " .
                     "-U Administrator\%" . $provisionPass;

system ($set_admin_pass);
die "Samba domain error: Unable to SME Server admin password.\n" if ($? == -1);

##Set samba dbase key indicating Samba has been provisioned per the current configuration
$cdb->set_prop('smb','provisioned','yes') ||
  warn "Unable to set provisioned property for smb dbase key";  

exit(0);
