From 6a5a286c1eddb781b2b99b27523f22f978f2bc8d Mon Sep 17 00:00:00 2001 From: "mahlon@laika.com" Date: Mon, 11 Aug 2014 18:07:00 +0000 Subject: [PATCH] Add 'rm' for a fully qualified DN, instead of only working with RDN. Reported by Lars Tauber . FossilOrigin-Name: 018facf53aa8b6da5181afc3dafd8f02bb4274fd162cb430f91b96acb7041c78 --- CONTRIBUTORS | 2 ++ shelldap | 74 +++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 44dfe2c..ba0b235 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -6,6 +6,7 @@ Giacomo Tenaglia Jonathan Rozes Josef Wells Landry Breuil +Lars Täuber Michael Granger Michael Raitza Mike Hix @@ -14,3 +15,4 @@ Rick H. Rong-En Fan Salvatore Bonaccorso Yann Cezard + diff --git a/shelldap b/shelldap index 0853241..aa179fd 100755 --- a/shelldap +++ b/shelldap @@ -291,10 +291,12 @@ aliased to: touch =item B Remove an entry from the directory. Globbing is supported. -All deletes are sanity-prompted. +All deletes are sanity-prompted. The -v flag prints the entries out +for review before delete. delete uid=mahlon delete uid=ma* + rm -v uid=mahlon,ou=People,dc=example,o=company l=office aliased to: rm @@ -400,6 +402,8 @@ Modify various runtime variables normally set from the command line. Show current auth credentials. Unless you specified a binddn, this will just show an anonymous bind. +aliased to: id + =back =head1 TODO @@ -1450,31 +1454,76 @@ sub run_create sub run_delete { my $self = shift; - my @DNs = @_; + my @args = @_; + my @matches; + my $s; + my $verbose; - unless ( scalar @DNs ) { + unless ( scalar @args ) { print "No dn specified.\n"; return; } - my $filter; - unless ( $DNs[0] eq '*' ) { - $filter = $self->make_filter( \@DNs ) or return; + # Flags. + # + if ( $args[0] =~ /^\-v/ ) { + $verbose = 1; + shift @args; + } + + # Separate real args from filter arguments. + # + foreach my $dn ( @args ) { + if ( $dn eq '*' ) { + $s = $self->search({ scope => 'one' }); + map { push @matches, $_ } @{ $s->{'entries'} } if $s->{'code'} == LDAP_SUCCESS; + } + + # Search by filter + # + else { + + my $filter = $self->make_filter( [$dn] ) or next; + $s = $self->search({ scope => 'one', filter => $filter }); + if ( scalar @{$s->{'entries'}} != 0 ) { + map { push @matches, $_ } @{ $s->{'entries'} } if $s->{'code'} == LDAP_SUCCESS; + } + + # Search by exact DN. + # + else { + $dn = $self->path_to_dn( $dn ); + $s = $self->search({ base => $dn, vals => 0 }); + my $e = ${ $s->{'entries'} }[0]; + push @matches, $e if $s->{'code'} == LDAP_SUCCESS; + } + } } - my $s = $self->search({ scope => 'one', filter => $filter }); - unless ( $s->{'code'} == LDAP_SUCCESS ) { - print "$s->{'message'}\n"; + # Unique the matchset for a consistent count, keyed by DN. + # + my @uniq_matches = keys %{{ map { $_->dn => 1 } @matches }}; + + my $mcount = scalar @uniq_matches; + if ( $mcount == 0 ) { + print "Nothing matched.\n"; return; } - print "Are you sure? [Ny]: "; + if ( $verbose ) { + print "* $_\n" foreach @uniq_matches; + } + + print "About to remove $mcount item(s). Are you sure? [Ny]: "; chomp( my $resp = ); return unless $resp =~ /^y/i; - - foreach my $e ( @{ $s->{'entries'} } ) { + + my %seen; + foreach my $e ( @matches ) { my $dn = $e->dn(); + next if $seen{ $dn }; my $rv = $self->ldap->delete( $dn ); + $seen{ $dn }++; print "$dn: ", $rv->error(), "\n"; } @@ -1538,7 +1587,6 @@ sub run_edit } close LDIF; } - # checksum it, then open it in an editor # my $hash_orig = $self->chksum( $self->{'ldif_fname'} );