]> git.proxmox.com Git - pmg-api.git/blobdiff - PMG/LDAPCache.pm
api apt/versions: add some missing packages
[pmg-api.git] / PMG / LDAPCache.pm
index 9ac3fe3563cfb666ee7713fe590f96ca29e5129c..ca18ad66b2a3f7513e4831ab767d6a1e245d9c2f 100755 (executable)
@@ -65,6 +65,7 @@ sub new {
     # split list returns an array not a reference
     $self->{accountattr} = [split_list($self->{accountattr})];
     $self->{mailattr} = [split_list($self->{mailattr})];
+    $self->{groupclass} = [split_list($self->{groupclass})];
 
     $self->{server1} = $args{server1};
     $self->{server2} = $args{server2};
@@ -74,6 +75,8 @@ sub new {
     $self->{port} = $args{port};
     $self->{groupbasedn} = $args{groupbasedn};
     $self->{filter} = $args{filter};
+    $self->{verify} = $args{verify};
+    $self->{cafile} = $args{cafile};
 
     if ($args{syncmode} == 1) {
        # read local data only
@@ -238,14 +241,16 @@ sub queryusers {
 
        # Get cookie from paged control
        my ($resp) = $mesg->control(LDAP_CONTROL_PAGED) or last;
-       $cookie = $resp->cookie or last;
+       $cookie = $resp->cookie;
+
+       last if (!defined($cookie) || !length($cookie));
 
        # Set cookie in paged control
        $page->cookie($cookie);
     }
 
 
-    if ($cookie) {
+    if (defined($cookie) && length($cookie)) {
        # We had an abnormal exit, so let the server know we do not want any more
        $page->cookie($cookie);
        $page->size(0);
@@ -261,7 +266,13 @@ sub querygroups {
 
     return undef if !$self->{groupbasedn};
 
-    my $filter = "(|(objectclass=group)(objectclass=univentionGroup))";
+    my $filter = "(|";
+
+    for my $class (@{$self->{groupclass}}) {
+       $filter .= "(objectclass=$class)";
+    }
+
+    $filter .= ")";
 
     my $page = Net::LDAP::Control::Paged->new(size => 100);
 
@@ -340,7 +351,17 @@ sub ldap_connect {
     my $opts = { timeout => 10, onerror => 'die' };
 
     $opts->{port} = $self->{port} if $self->{port};
-    $opts->{schema} = $self->{mode};
+    if ($self->{mode} eq 'ldaps') {
+       $opts->{scheme} = 'ldaps';
+       $opts->{verify} = 'require' if $self->{verify};
+       if ($self->{cafile}) {
+           $opts->{cafile} = $self->{cafile};
+       } else {
+           $opts->{capath} = '/etc/ssl/certs/';
+       }
+    } else {
+       $opts->{scheme} = 'ldap';
+    }
 
     return Net::LDAP->new($hosts, %$opts);
 }
@@ -349,10 +370,24 @@ sub ldap_connect_and_bind {
      my ($self) = @_;
 
      my $ldap = $self->ldap_connect() ||
-        die "Can't bind to ldap server '$self->{id}': $!\n";
+        die "Can't bind to ldap server '$self->{id}': " . ($@ // "unknown error") . "\n";
 
      my $mesg;
 
+     if ($self->{mode} eq 'ldap+starttls') {
+        my $opts = {
+            verify => $self->{verify} ? 'require' : 'none',
+        };
+
+        if ($self->{cafile}) {
+            $opts->{cafile} = $self->{cafile};
+        } else {
+            $opts->{capath} = '/etc/ssl/certs/';
+        }
+
+        $ldap->start_tls(%$opts);
+     }
+
      if ($self->{binddn}) {
         $mesg = $ldap->bind($self->{binddn}, password => $self->{bindpw});
      } else {
@@ -553,10 +588,10 @@ sub loaddata {
     }
 }
 
-sub list_groups {
+sub get_groups {
     my ($self) = @_;
 
-    my $res = [];
+    my $res = {};
 
     my $dbh = $self->{dbstat}->{groups}->{dbh};
 
@@ -565,22 +600,19 @@ sub list_groups {
     my $key = 0 ;
     my $value = "" ;
     my $status = $dbh->seq($key, $value, R_FIRST());
-    my $keys;
 
     while ($status == 0) {
-       push @$res, {
-           dn => $key,
-       };
+       $res->{$value} = $key;
         $status = $dbh->seq($key, $value, R_NEXT());
     }
 
     return $res;
 }
 
-sub list_users {
+sub get_users {
     my ($self) = @_;
 
-    my $res = [];
+    my $res = {};
 
     my $dbh = $self->{dbstat}->{users}->{dbh};
 
@@ -593,7 +625,7 @@ sub list_users {
 
     while ($status == 0) {
        my ($pmail, $account, $dn) = unpack('n/a* n/a* n/a*', $value);
-       push @$res, {
+       $res->{$key} = {
            pmail => $pmail,
            account => $account,
            dn => $dn,
@@ -604,6 +636,68 @@ sub list_users {
     return $res;
 }
 
+sub get_gid_uid_map {
+    my ($self) = @_;
+
+    my $dbh = $self->{dbstat}->{memberof}->{dbh};
+
+    return [] if !$dbh;
+
+    my $key = 0 ;
+    my $value = "" ;
+
+    my $map = {};
+
+    if($dbh->seq($key, $value, R_FIRST()) == 0) {
+       do {
+           push @{$map->{$value}}, $key;
+       } while($dbh->seq($key, $value, R_NEXT()) == 0);
+    }
+
+    return $map;
+}
+
+sub list_groups {
+    my ($self) = @_;
+
+    my $res = [];
+
+    my $groups = $self->get_groups();
+
+    for my $gid (sort keys %$groups) {
+       push @$res, {
+           dn => $groups->{$gid},
+           gid => $gid,
+       };
+    }
+
+    return $res;
+}
+
+sub list_users {
+    my ($self, $gid) = @_;
+
+    my $res = [];
+
+    my $users = $self->get_users();
+
+    if (!defined($gid)) {
+       $res = [values %$users];
+    } else {
+       my $gid_uid_map = $self->get_gid_uid_map();
+       my $groups = $self->get_groups();
+       die "No such Group ID\n"
+           if !defined($groups->{$gid});
+       my $memberuids = $gid_uid_map->{$gid};
+       for my $uid (@$memberuids) {
+           next if !defined($users->{$uid});
+           push @$res, $users->{$uid};
+       }
+    }
+
+    return $res;
+}
+
 sub list_addresses {
     my ($self, $mail) = @_;