#!/usr/local/bin/perl
#
# $Id: groupmodify,v 1.1 2002/05/03 21:44:51 visick Exp $
#
# groupmodify - edit a group in LDAP
#
# Copyright (C) 2002 Steven Barrus
# Copyright (C) 2002 Dana Dahlstrom
# Copyright (C) 2002 Robert Ricci
# Copyright (C) 2002 Spencer Visick
#
# See the AUTHORS file for contact info
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA



use Getopt::Std;
use Term::ReadLine;

require 'usertools.ph';

use strict;
no strict "vars";

$term = new Term::ReadLine;

@fields = ( 'cn', 'gidNumber', 'memberUid' );
if ($config{group_attribute}){
  for (split(/,/,$config{group_attribute})){
    push(@fields,$_)
  }
}

%special_sub = ( 'memberUid' => \&get_memberuids);
if($config{group_attribute}){
  for (@fields){
    if ($_ eq "owner"){
      $special_sub{owner} = \&get_dn;
    }
  }
}

# Check for -h
if ($ARGV[0] =~ /^-h/) {
  exit &usage;
}

# Connect to the LDAP server
$ldap = ldap_connect() || exit(1);

if (@ARGV) {
  foreach (@ARGV) {
    &chentry($_);
  }
} else {
  while (1) {
    print "Lookup entry for group (blank to end): ";
    $group = <STDIN>;
    chomp $group;
    if ($group) {
      &chentry($group);
    } else {
      last;
    }
  }
}

sub chentry {
  $group = shift;

  $search = "(cn=" . $group . ")";
  $mesg = $ldap->search(base => $config{groupbase}, filter => $search);
  $entry = $mesg->entry();

  if ($entry) {
    print "Found LDAP entry for $group\n";
  } else {
    print "Unable to find LDAP entry for $group\n";
    return 0;
  }

  while (1) {
    print "\n";
    $index = 1;
    foreach ( @fields ) {
      $aref = $entry->get_value($_, asref => 1);
      printf("%2d)%20s: ",$index++,$_);
      if ($aref) {
        print join ", ", @$aref;
      }
      print "\n";
    }
    print " C)ancel all changes\n";
    print " S)ave changes\n";
    print " D)elete this group\n";
    
    print "\nSelection? ";
    $choice = lc(<STDIN>);
    chomp $choice;

    # C)ancel all changes
    if ($choice =~ /^c/) {
      return;
    }

    # D)elete this group
    if ($choice =~ /^d/) {
      print "Really delete $group? [y/N] ";
      $choice = lc(<STDIN>);
      if ($choice =~ /^y/) {
        $mesg = $ldap->delete($entry);
        print $mesg->error if $mesg->code;
        return;
      } else {
        next;
      }
    }

    # S)ave changes and exit
    if ($choice =~ /^s/) {
      $mesg = $entry->update( $ldap) ;
      print $mesg->error if $mesg->code;
      return;
    }

    next if ($choice eq "" or $choice < 1);

    $field = $fields[$choice-1];

    if ($special_sub{$field}) {
      &{$special_sub{$field}};
    } else {
       $value = $term->readline("$field: ", $entry->get_value($field));
       $mesg = $entry->replace($field => $value);
    }
  }
}

sub usage {

  print << "EOSTR";

Usage: $0 [groupnames]

If no group name is given, $0 will enter a loop, prompting for groups.

EOSTR

  1;
}

sub edit_list {
  if ($entry->get_value($field)) {
    $aref = $entry->get_value($field, asref => 1);
    $list_string = join ', ', @$aref;
  }
  $list_string = $term->readline("$field: ", $list_string);
  @new_array = split ',', $list_string;
  foreach (@new_array) { s/^\s*// }
  $entry->replace($field => \@new_array);
}

sub get_memberuids {

  if ($entry->get_value($field)) {
    $aref = $entry->get_value($field, asref => 1);
    $list_string = join ', ', @$aref;
  }

  while (1) { 
    $list_string = $term->readline("Members: ", $list_string);
    $list_string =~ s/,/ /g;
    $list_string =~ s/\s+/, /g;
    @uids = split ', ', $list_string;
    @bad_uids = ();
    @good_uids = ();

    foreach $uid (@uids) {
      if (($ldap->search(base => $config{userbase},filter => "(uid=$uid)"))->entry()) {
        push @good_uids, $uid;
      } else {
        push @bad_uids, $uid;
      }
    }

    if (@bad_uids) {
      print "Sorry, the following usernames were not found in LDAP:\n";
      print join ", ", @bad_uids;
      print "\n";
    } else {
      $entry->replace($field => \@good_uids);
      return;
    }
  }

}

sub get_dn {

  while (1) {
    $input = $term->readline("$field: ", $entry->get_value($field)); 

    if ($input eq "") {
      $entry->replace($field =>  $input );
      return;
    } elsif ($input =~ /uid=/) {
      $uid = (split ',', $')[0];
    } else {
      $uid = $input;
    }

    $mesg = $ldap->search(base => $config{userbase},filter => "(uid=$uid)");
    $search = $mesg->entry();

    if ($search) {
      $entry->replace($field => $search->dn()) ;
      return;
    } else {
      print "Sorry, $uid was not found in LDAP. Try another username.\n";
    }
  }

}

__END__
=head1 NAME

groupmodify - edit a group in LDAP

=head1 SYNOPSIS

B<groupmodify> [groupnames]

B<groupmodify> [-h]
     

=head1 DESCRIPTION

B<groupmodify> allows changes to a group in the LDAP directory 
specified in /etc/usertools.conf or $HOME/.usertoolsrc. 
You will be prompted for a password with which to bind. If no 
group name is given, B<groupmodify> will enter a loop, prompting 
for groups.

You may edit cn, gid number, members, and any custom attribute
in the list group_attribute in your configuration file.

=head1 OPTIONS

B<-h>

Print out usage information.

=head1 BUGS

lots probably, sorry. Contact AUTHORS if you find any.

=head1 AUTHORS

The usertools were written at the CADE by various opers. See the AUTHORS file 
for details.

=head1 SEE ALSO

groupcreate(1), groupsearch(1),
usercreate(1), usermodify(1), userrevert(1), usersearch(1), userdelete(1).


=cut 

