diff options
Diffstat (limited to 'lib/GitACL/LDAP.pm')
-rw-r--r-- | lib/GitACL/LDAP.pm | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/lib/GitACL/LDAP.pm b/lib/GitACL/LDAP.pm new file mode 100644 index 0000000..daa5b72 --- /dev/null +++ b/lib/GitACL/LDAP.pm @@ -0,0 +1,100 @@ +package GitACL::LDAP; +use parent 'GitACL'; +use strict; +use Net::LDAP; + +sub parse_ldap_conf { + my $self = shift; + my $filename = GitACL::git_value('config', 'hooks.aclldapconf') || + "/etc/ldap.conf"; + + my $fd; + open($fd, "<", $filename) or + $self->deny("cannot open file $filename: $!"); + while (<$fd>) { + chomp; + s/^\s+//; + s/\s+$//; + s/#.*//; + next if ($_ eq ""); + my @x = split(/\s+/, $_, 2); + $self->{"ldap_".$x[0]} = $x[1]; + } + close(fd); +} + +sub check_acl($) { + my $self = shift; + my $filter = "(&(objectClass=gitACL)(|(gitAclProject=$self->{project_name})(gitAclProject=all)))"; + my %searchargs; + + $self->parse_ldap_conf(); + + $searchargs{filter} = $filter; + + $self->debug(2, "connecting to the database"); + my $ldap = Net::LDAP->new($self->{ldap_uri}) + or $self->deny("unable to connect to LDAP server $self->{ldap_uri}: $@"); + $self->debug(2, "searching for $filter"); + my $sres = $ldap->search(base => $self->{ldap_base}, + filter => $filter); + $self->deny("an error occurred while searching: ". + ldap_error_text($sres->code)) + if ($sres->code); + $self->debug(2, "got ".$sres->entries." entries"); + my @entries = sort { + my $pa = $a->get_value('gitAclProject'); + my $pb = $b->get_value('gitAclProject'); + + if ($pa ne $pb) { + if ($pa eq "all") { + return 1; + } else { + return -1; + } + } elsif ($a->exists('gitAclOrder')) { + if ($b->exists('gitAclOrder')) { + return $a->get_value('gitAclOrder') <=> $b->get_value('gitAclOrder'); + } else { + return 1; + } + } elsif ($b->exists('gitAclOrder')) { + return -1; + } else { + my @aa = $a->attributes(nooptions => 1); + my @ab = $b->attributes(nooptions => 1); + return $#ab <=> $#aa; + } + } $sres->entries; + + foreach my $ent (@entries) { + my @x; + push(@x, $ent->get_value('gitAclVerb')); + push(@x, $ent->get_value('gitAclProject')); + push(@x, $ent->exists('gitAclUser') ? + $ent->get_value('gitAclUser') : "all"); + push(@x, $ent->get_value('gitAclOp')) + if $ent->exists('gitAclOp'); + push(@x, $ent->get_value('gitAclRef')) + if $ent->exists('gitAclRef'); + + my @res = $self->match_tuple(\@x); + if ($res[0] == 0) { + $self->debug(2, $ent->dn.": $res[1]"); + next; + } + $ldap->unbind; + if ($res[1]) { + $res[0]->($self, $res[1], $ent->dn); + } else { + $res[0]->($self, $ent->dn); + } + exit(127); + } + $ldap->unbind; + $self->allow("default rule"); +} + +1; + + |