diff --git a/utils/lpt b/utils/lpt index 0f08a1b..5fc2f31 100755 --- a/utils/lpt +++ b/utils/lpt @@ -76,7 +76,6 @@ my %cmds_account = "services" => \&cmd_account_services, "shell" => \&cmd_account_shell, "view" => \&cmd_account_view, - "view" => \&cmd_account_view, "grant-intra" => \&cmd_account_grantintra, "grant-lab" => \&cmd_account_grantlab, @@ -85,9 +84,9 @@ my %cmds_account = my %cmds_group = ( - "list" => \&cmd_group_list, - "add" => \&cmd_group_add, - "remove" => \&cmd_group_remove, + "view" => \&cmd_group_view, + "members" => \&cmd_group_members, + "rights" => \&cmd_group_rights, "create" => \&cmd_group_create, "delete" => \&cmd_group_delete ); @@ -767,9 +766,16 @@ sub cmd_account_view($@) sub cmd_group(@) { my $gname = shift; + my $year; + + if ($gname && $gname =~ /^(20[0-9]{2})$/) + { + $year = $1; + $gname = shift; + } if (! $gname) { - log(USAGE, "lpt group [arguments ...]"); + log(USAGE, "lpt group [year] [arguments ...]"); return 1; } @@ -784,209 +790,268 @@ sub cmd_group(@) return 1; } - return $cmds_group{$subcmd}($gname, @_); + return $cmds_group{$subcmd}($gname, $year, @_); } -sub cmd_group_list(@) +sub cmd_group_multiple_vieworchange { - if ($#ARGV > 0) - { - log(USAGE, " group list [group]"); - exit(1); - } - - my $group = $ARGV[0]; - my $ldap = LDAP::ldap_connect_anon(); - if ($#ARGV == 0) - { - my $mesg = $ldap->search( # search a group - base => "cn=$group,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "objectClass=posixGroup", - attrs => ['memberUid'] - ); - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; - - foreach my $entry ($mesg->sorted('memberUid')) - { - foreach my $user ($entry->get_value("memberUid")) - { - print "$user\n"; - } - } - } - else - { - my $mesg = $ldap->search( # list groups - base => "ou=groups,dc=acu,dc=epita,dc=fr", - filter => "objectClass=posixGroup", - attrs => ['cn', 'gidNumber'] - ); - - - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; - - foreach my $entry ($mesg->sorted('gidNumber')) - { - print $entry->get_value("cn")." --->"; - print $entry->get_value("gidNumber")."\n"; - } - } - - $ldap->unbind; # take down session -} - -sub cmd_group_add(@) -{ - my $group = shift; - - if ($#_ < 0) - { - log(USAGE, " group add "); - exit(1); - } - - my $login = shift; - - my $ldap = LDAP::ldap_connect(); - - my $mesg = $ldap->search( # search a group - base => "cn=$group,ou=system,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "objectClass=posixGroup", - attrs => ['memberUid'] - ) or die $!; - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; - - foreach my $entry ($mesg->entries) - { - my @mem = $entry->get_value("memberUid"); - - foreach my $member (@mem) - { - if ($member eq $login) - { - log WARN, "$login est déjà dans le groupe $group"; - $ldap->unbind; - exit 1; - } - } - - push @mem, $login; - $entry->replace("memberUid" => \@mem); - $entry->update($ldap); - - log INFO, "$login ajouté au groupe $group avec succès."; - } - $ldap->unbind; # take down session -} - -sub cmd_group_remove(@) -{ - if ($#ARGV < 1) - { - log(USAGE, " group remove "); - exit(1); - } - - my $group = $ARGV[0]; - my $login = $ARGV[1]; - - my $ldap = LDAP::ldap_connect(); - - my $mesg = $ldap->search( # search a group - base => "cn=$group,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "objectClass=posixGroup", - attrs => ['memberUid'] - ); - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; - - foreach my $entry ($mesg->sorted('memberUid')) - { - my @mem = $entry->get_value("memberUid"); - my $found = 0; - foreach my $user (@mem) - { - if ($user eq $login) - { - $found = 1; - } - } - - if ($found) - { - @mem = grep(!/$login$/, @mem); - $entry->replace("memberUid" => [@mem]); - $entry->update($ldap); - } - else - { - print "$login n'est pas dans le groupe $group\n"; - } - - print "Nouvelle liste des membres de $group :\n"; - foreach my $user (@mem) - { - print "$user\n"; - } - - } - $ldap->unbind; # take down session - - system('service nscd restart'); -} - -sub cmd_group_create($$) -{ - if ($#_ != 1) - { - log(USAGE, " group create "); - exit(1); - } - my $type = shift; - my $year = shift; - my $cn = $type . $year; - my $gid; - if ($type eq "acu") { - $gid = $year; + my $typeName = shift; + my $gname = shift; + my $year = shift // LDAP::get_year(); + my $action = shift // "list"; + my $change = shift; + + if (($action ne "list" and $action ne "add" and $action ne "del" and $action ne "flush") or (!$change and $action ne "list" and $action ne "flush")) { + log(USAGE, " group $typeName [list|add|del|flush] [string]"); + return 1; } - elsif ($type eq "yaka") { - $gid = $year - 1000; + + my $ldap; + $ldap = LDAP::ldap_connect() if ($action ne "list"); + $ldap = LDAP::ldap_connect_anon() if ($action eq "list"); + my $mesg = $ldap->search( # search + base => "ou=groups,dc=acu,dc=epita,dc=fr", + filter => "cn=$gname", + attrs => [ $type ], + scope => "sub" + ); + if ($mesg->code != 0) { + log(ERROR, $mesg->error); + } + if ($mesg->count != 1) { + log(ERROR, "Group $gname not found or multiple presence"); + } + + if ($action eq "add") { + log(INFO, "Adding $change as ".$typeName."s for $gname ..."); + + my @data = $mesg->entry(0)->get_value($type); + + if (! grep(/^$change$/, @data)) { + push @data, $change; + $mesg->entry(0)->replace($type => \@data) or die $!; + $mesg->entry(0)->update($ldap) or die $!; + + log(INFO, "Done!"); + } + else { + log(WARN, "$gname has already $change $typeName."); + } + } + elsif ($action eq "del") { + log(INFO, "Checking if $change is a ".$typeName."s of $gname ..."); + my @data = $mesg->entry(0)->get_value($type); + if (grep(/^$change$/, @data)) { + log(INFO, "Deleting $change as $typeName for $gname ..."); + + @data = grep(!/$change$/, @data); + + $mesg->entry(0)->replace($type => \@data) or die $!; + $mesg->entry(0)->update($ldap) or die $!; + + log(INFO, "Done!"); + } + else { + log(WARN, "$change is not a $typeName for $gname."); + } + } + elsif ($action eq "flush") { + $ldap->modify($mesg->entry(0)->dn, delete => [$type]); + log(INFO, "$gname have no more $typeName."); } else { - log(ERROR, "Error: type must be acu or yaka!"); + if ($mesg->entry(0)->get_value($type)) { + log(INFO, $gname."'s ".$typeName."s are:"); + for my $val ($mesg->entry(0)->get_value($type)) { + say " - $val"; + } + } + else { + log(INFO, "$gname have no $typeName."); + } } - my $ldap = LDAP::ldap_connect(); + $ldap->unbind or die ("couldn't disconnect correctly"); + return 0; +} - my $mesg = $ldap->add( "cn=$cn,ou=groups,dc=acu,dc=epita,dc=fr", - attrs => [ - objectclass => "posixGroup", - gidNumber => $gid, - cn => $cn, - ] +sub cmd_group_vieworchange +{ + my $type = shift; + my $typeName = shift; + my $gname = shift; + my $year = shift // LDAP::get_year(); + + if ($#_ > 0) { + log(USAGE, " group $typeName [new_string]"); + return 1; + } + + my $change = shift; + + my $ldap; + $ldap = LDAP::ldap_connect() if ($change); + $ldap = LDAP::ldap_connect_anon() if (!$change); + + my $mesg = $ldap->search( # search + base => "ou=groups,dc=acu,dc=epita,dc=fr", + filter => "uid=$gname", + attrs => [ $type ], + scope => "sub" ); - if ($mesg->code != 0) { die $mesg->error; } + if ($mesg->code != 0) { + log(ERROR, $mesg->error); + } + if ($mesg->count != 1) { + log(ERROR, "User $gname not found or multiple presence"); + } + + if ($change) { + log(INFO, "Setting $typeName to $change for $gname ..."); + + $mesg->entry(0)->replace($type => $change) or die $!; + $mesg->entry(0)->update($ldap) or die $!; + + log(INFO, "Done!"); + } + elsif ($mesg->entry(0)->get_value($type)) { + log(INFO, $gname."'s $typeName is ".$mesg->entry(0)->get_value($type)."."); + } + else { + log(INFO, $gname."'s has no $typeName."); + } $ldap->unbind or die ("couldn't disconnect correctly"); + return 0; +} - log(INFO, "group added: $cn"); +sub cmd_group_view +{ + my $gname = shift; + my $year = shift; + if ($year) { + $year = "ou=$year,"; + } else { + $year = ""; + } + + my $ldap = LDAP::ldap_connect_anon(); + + my $mesg = $ldap->search(base => $year."ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", + filter => "cn=$gname", + attrs => ['objectClass']); + + $mesg->code && log(ERROR, $mesg->error); + log(ERROR, "No such group!") if ($mesg->count <= 0); + + log(DEBUG, "objectClasses:\t" . join(', ', $mesg->entry(0)->get_value("objectClass"))); + + my @attrs = ['dn']; + if ($#_ >= 0) { + push @attrs, @_; + } + else { + if (grep { "intraGroup" } $mesg->entry(0)->get_value("objectClass")) { + push @attrs, 'intraRight'; + } + if (grep { "posixGroup" } $mesg->entry(0)->get_value("objectClass")) { + push @attrs, 'cn', 'memberUid'; + } + } + + log(DEBUG, "attrs to get: " . join(', ', @attrs)); + + $mesg = $ldap->search(base => $year."ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", + filter => "cn=$gname", + attrs => \@attrs); + $mesg->code && die $mesg->error; + + shift @attrs; # Remove dn + my $nb = 0; + for my $entry ($mesg->entries) + { + if ($nb > 0) { + say "=="; + } + say BOLD, YELLOW, "dn: ", RESET, YELLOW, $entry->dn, RESET; + + for my $attr (@attrs) { + if ($#attrs < 3) { + for my $entry ($entry->get_value($attr)) { + say CYAN, "$attr: ", RESET , $entry; + } + } + else { + say CYAN, "$attr: ", RESET , join(', ', $entry->get_value($attr)); + } + } + + $nb++; + } + + if ($nb > 1) { + say "\n$nb groups displayed"; + } + + $ldap->unbind or die ("couldn't disconnect correctly"); + return 0; +} + +sub cmd_group_members($@) +{ + return cmd_group_multiple_vieworchange('memberUid', 'member', @_); +} + +sub cmd_group_rights($@) +{ + return cmd_group_multiple_vieworchange('intraRight', 'right', @_); +} + +sub cmd_group_create +{ + my $gname = shift; + my $year = shift // LDAP::get_year(); + + log(DEBUG, "Adding dn: cn=$gname,ou=$year,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr ..."); + + my $ldap = LDAP::ldap_connect(); + my $mesg = $ldap->add( "cn=$gname,ou=$year,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", + attrs => [ + objectclass => [ "top", "intraGroup" ], + cn => $gname, + ] + ); + + #$ldap->unbind or die ("couldn't disconnect correctly"); + + if ($mesg->code == 0) { + log(INFO, "Group added: $gname"); + return 0; + } + else { + log(ERROR, "Unable to add: $gname: ", RESET, $mesg->error); + } } sub cmd_group_delete(@) { - if ($#ARGV != 1) - { - log(USAGE, " group delete "); - exit(1); + my $gname = shift; + my $year = shift // LDAP::get_year(); + + my $dn = "cn=$gname,ou=$year,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr"; + + log(DEBUG, "Deletinging dn: $dn ..."); + + my $ldap = LDAP::ldap_connect(); + if (LDAP::delete_entry($ldap, $dn)) { + log DONE, "Group $gname successfully deleted."; + } else { + log ERROR, "Unable to delete group $gname."; + return 1; } - print "TODO!"; - print "hint: ldapdelete -v -h ldap.acu.epita.fr -x -w \$LDAP_PASSWD -D 'cn=admin,dc=acu,dc=epita,dc=fr' 'cn=yaka2042,ou=groups,dc=acu,dc=epita,dc=fr'"; - exit(1); + return 0; }