#!/usr/bin/perl

use strict;
use warnings;
use Net::LDAP;
use Text::Iconv;

my $converter = Text::Iconv->new("UTF-8","ascii//TRANSLIT");

my $ldap_server = "ldap.example.com";
my $ldap_port = "389";
my $ldap_version = "3";
my $ldap_username = "cn=read,dc=example,dc=com";
my $ldap_password = "somepass";
my $ldap_base = "ou=People, dc=example, dc=com";
my $ldap_filter = "uid=*";
my $pve_ldap_realm = "example";

my $ldap = Net::LDAP->new($ldap_server, port => $ldap_port, version => $ldap_version) or die "$@";

my $mesg = $ldap->bind( $ldap_username,
  password => $ldap_password
);

$mesg->code && die $mesg->error;

$mesg = $ldap->search( base => $ldap_base,
  scope => "sub",
  filter => $ldap_filter
);

$mesg->code && die $mesg->error;

my @ldap_uids;
my @pve_uids;
foreach my $entry ($mesg->entries)
{
  my ($uid, $fn, $ln, $mail);
  foreach my $attr ($entry->attributes)
  {
    foreach my $value ($entry->get_value($attr))
    {
      if ($attr eq 'uid')
      {
        $uid = $value;
      }
      elsif ($attr eq 'givenName')
      {
        $fn = $converter->convert($value);
        $fn =~ s/'//;
      }
      elsif ($attr eq 'sn')
      {
        $ln = $converter->convert($value);
        $ln =~ s/'//;
      }
      elsif ($attr eq 'mail')
      {
        $mail = $value;
      }
    }
  }
  push(@ldap_uids, $uid);
  my $groups = "Users";
  my $cmd = '';
  if (`grep "user:$uid" /etc/pve/user.cfg`) {
    $cmd = "pveum usermod $uid\@$pve_ldap_realm -email $mail -firstname '$fn' -lastname '$ln' -groups '$groups'";
  } else {
    $cmd = "pveum useradd $uid\@$pve_ldap_realm -email $mail -firstname '$fn' -lastname '$ln' -groups '$groups'";
  }
  print("$cmd\n");
  `$cmd`;
}
$mesg = $ldap->unbind;

@pve_uids = `cat /etc/pve/user.cfg | grep "user:...\@$pve_ldap_realm" | cut -d ":" -f 2 | cut -d "@" -f 1`;

foreach my $uid (@pve_uids) {
  chomp($uid);
  if (!grep(/^$uid$/, @ldap_uids)) {
    my $cmd = "pveum userdel '$uid\@$pve_ldap_realm'";
    print("$cmd\n");
    `$cmd`;
  }
}
