#!/usr/bin/perl
#
# File: ldap-delete-branch
# Description: Delete a branch from an LDAP directory
# Author: Bill MacAllister <bill@ca-zephyr.org>
# Copyright 2019, Dropbox, Inc.
# Copyright 2023 CZ Software

use Getopt::Long;
use Pod::Usage;
use strict;

my $opt_debug;
my $opt_help;
my $opt_manual;
my $opt_verbose;

my $host_default = 'ldap-master.com';
my $base_default = 'cn=hosts,dc=ldap,dc=com';

##############################################################################
# Main Routine
##############################################################################

# -- get options
GetOptions(
    'debug'   => \$opt_debug,
    'help'    => \$opt_help,
    'manual'  => \$opt_manual,
    'verbose' => \$opt_verbose
);

# -- Flush output immediately
local $| = 1;

my $action = shift(@ARGV);

# Display help if requested
if ($action eq 'help') {
    $opt_help = 1;
}
if ($opt_help) {
    pod2usage(-verbose => 0);
}
if ($action eq 'manual') {
    $opt_manual = 1;
}
if ($opt_manual) {
    pod2usage(-verbose => 2);
}

my $host = shift(@ARGV);
if (!$host) {
    $host = $host_default;
}

my $base = shift(@ARGV);
if (!$base) {
    $base = $base_default;
}

if ($action !~ /^(show|update)$/xms) {
    print("ERROR: unknown action ($action)\n");
    pod2usage(-verbose => 0);
}

my $cmd = "ldapsearch -o ldif-wrap=no -LLL -Q -h $host -b $base dn";

if ($opt_debug) {
    print("cmd:$cmd\n");
}
my @lines = `$cmd`;

my %dn_list = ();

for my $t (@lines) {
    chomp($t);
    if ($t =~ /^dn:\s+ (.*)/xms) {
        my $dn  = $1;
        my $len = sprintf('%08d', length($dn));
        $dn_list{"${len}${dn}"} = $dn;
    }
}

for my $dnkey (sort { $b cmp $a } keys %dn_list) {
    my $dn    = $dn_list{$dnkey};
    my $upcmd = "echo '$dn' | ldapdelete -Q -h $host";
    if ($action eq 'update') {
        if ($opt_verbose || $opt_debug) {
            print("Executing: $upcmd\n");
        }
        `$upcmd`;
    } else {
        print("Proposing: $upcmd\n");
    }
}

if ($action eq 'update') {
    print(scalar(keys %dn_list) . " entries deleted\n");
} else {
    print(scalar(keys %dn_list) . " entries to be deleted\n");
}

exit;

__END__

=head1 NAME

ldap-delete-branch - delete a branch of an LDAP directory

=head1 SYNOPSIS

ldap-delete-branch show|update|help|manual [<ldap master hostname>]
[<branch dn>] [--help] [--manual] [--debug] [--verbose]

=head1 DESCRIPTION

A simpleton script to delete all the entries in the branch of a
directory.

=head1 OPTIONS

=over 4

=item --help

Display short help text.

=item --manual

Display the complete documentation.

=item --debug

Display debugging messages.

=item --verbose

Display actions as they are performed.

=back

=head1 AUTHOR

Bill MacAllister <bill@ca-zephyr.org>

=head1 COPYRIGHT

Copyright (C) 2019, Dropbox Inc.

This code is free software; you can redistribute it and/or modify it
under the same terms as Perl. For more details, see the full
text of the at https://opensource.org/licenses/Artistic-2.0.

This program is distributed in the hope that it will be
useful, but without any warranty; without even the implied
warranty of merchantability or fitness for a particular purpose.

Copyright 2023 CZ Software

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=cut
