From b01ea27eb10c4177e75fcd05bee89a6008498259 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Thu, 16 Sep 2010 23:14:27 -0700 Subject: [PATCH] More work on LDAP --- acl/acl-lib.pl | 48 ++++++++++++++++++++++++++++++++++++++++++------ miniserv.pl | 33 +++++++++++++++++++++++++++++---- web-lib-funcs.pl | 30 ++++++++++++++++++++++-------- 3 files changed, 93 insertions(+), 18 deletions(-) diff --git a/acl/acl-lib.pl b/acl/acl-lib.pl index 9334f8223..6f90899ab 100755 --- a/acl/acl-lib.pl +++ b/acl/acl-lib.pl @@ -134,7 +134,7 @@ if ($miniserv{'userdb'}) { my $rv = $dbh->search( base => $prefix, filter => '(objectClass='.$args->{'userclass'}.')', - scope => 'one'); + scope => 'sub'); if (!$rv || $rv->code) { &error("Failed to search users : ". ($rv ? $rv->error : "Unknown error")); @@ -234,7 +234,7 @@ if ($miniserv{'userdb'}) { my $rv = $dbh->search( base => $prefix, filter => '(objectClass='.$args->{'groupclass'}.')', - scope => 'one'); + scope => 'sub'); if (!$rv || $rv->code) { &error("Failed to search groups : ". ($rv ? $rv->error : "Unknown error")); @@ -795,7 +795,7 @@ if ($miniserv{'userdb'}) { base => $prefix, filter => '(&(cn='.$username.')(objectClass='. $args->{'userclass'}.'))', - scope => 'one'); + scope => 'sub'); if (!$rv || $rv->code) { &error("Failed to find user : ". ($rv ? $rv->error : "Unknown error")); @@ -803,10 +803,28 @@ if ($miniserv{'userdb'}) { my ($user) = $rv->all_entries; if ($user) { + # Delete sub-objects + my $rv = $dbh->search( + base => $user->dn(), + filter => '(objectClass=*)', + scope => 'sub'); + if (!$rv || $rv->code) { + &error("Failed to delete LDAP user : ". + ($rv ? $rv->error : "Unknown error")); + } + foreach my $so ($rv->all_entries) { + next if ($so->dn() eq $user->dn()); + my $drv = $dbh->delete($so->dn()); + if ($drv->code) { + &error("Failed to delete LDAP ". + "sub-object : ".$drv->error); + } + } + # Delete the user from LDAP my $rv = $dbh->delete($user->dn()); if (!$rv || $rv->code) { - &error("Failed to delete user : ". + &error("Failed to delete LDAP user : ". ($rv ? $rv->error : "Unknown error")); } } @@ -1082,7 +1100,7 @@ if ($miniserv{'userdb'}) { base => $prefix, filter => '(&(cn='.$groupname.')(objectClass='. $args->{'groupclass'}.'))', - scope => 'one'); + scope => 'sub'); if (!$rv || $rv->code) { &error("Failed to find group : ". ($rv ? $rv->error : "Unknown error")); @@ -1090,10 +1108,28 @@ if ($miniserv{'userdb'}) { my ($group) = $rv->all_entries; if ($group) { + # Delete sub-objects + my $rv = $dbh->search( + base => $group->dn(), + filter => '(objectClass=*)', + scope => 'sub'); + if (!$rv || $rv->code) { + &error("Failed to delete LDAP group : ". + ($rv ? $rv->error : "Unknown error")); + } + foreach my $so ($rv->all_entries) { + next if ($so->dn() eq $group->dn()); + my $drv = $dbh->delete($so->dn()); + if ($drv->code) { + &error("Failed to delete LDAP ". + "sub-object : ".$drv->error); + } + } + # Delete the group from LDAP my $rv = $dbh->delete($group->dn()); if (!$rv || $rv->code) { - &error("Failed to delete group : ". + &error("Failed to delete LDAP group : ". ($rv ? $rv->error : "Unknown error")); } } diff --git a/miniserv.pl b/miniserv.pl index c42c2ed14..6fa5ec784 100755 --- a/miniserv.pl +++ b/miniserv.pl @@ -4151,7 +4151,7 @@ if ($config{'userdb'}) { base => $prefix, filter => '(&(cn='.$username.')(objectClass='. $args->{'userclass'}.'))', - scope => 'one'); + scope => 'sub'); if (!$rv || $rv->code) { print STDERR "Failed to lookup user : ", ($rv ? $rv->error : "Unknown error"),"\n"; @@ -4249,7 +4249,25 @@ if ($config{'userdb'}) { } elsif ($proto eq "ldap") { # Lookup in LDAP - # XXX + my $rv = $dbh->search( + base => $prefix, + filter => '(objectClass='. + $args->{'userclass'}.')', + scope => 'sub', + attrs => [ 'cn', 'webminAttr' ]); + if ($rv && !$rv->code) { + foreach my $u ($rv->all_entries) { + my @attrs = $u->get_value('webminAttr'); + foreach my $la (@attrs) { + my ($attr, $value) = split(/=/, $la, 2); + if ($attr eq "cert" && + ($value eq $peername || + $value eq $peername2)) { + return $u->get_value('cn'); + } + } + } + } } } return undef; @@ -4995,7 +5013,7 @@ if (!$uinfo->{'proto'}) { if ($config{'userdb'}) { # Update user DB - my ($dbh, $proto) = &connect_userdb($config{'userdb'}); + my ($dbh, $proto, $prefix, $args) = &connect_userdb($config{'userdb'}); if (!$dbh) { return -1; } @@ -5013,7 +5031,14 @@ if ($config{'userdb'}) { $cmd->finish() if ($cmd); } elsif ($proto eq "ldap") { - # XXX update in LDAP + # Update LDAP object + my $rv = $dbh->modify($uinfo->{'id'}, + replace => { 'webminPass' => '!'.$uinfo->{'pass'} }); + if (!$rv || $rv->code) { + print STDERR "Failed to lock password : ", + ($rv ? $rv->error : "Unknown error"),"\n"; + return -1; + } } &disconnect_userdb($config{'userdb'}, $dbh); return 0; diff --git a/web-lib-funcs.pl b/web-lib-funcs.pl index 93eb52271..7c9618806 100755 --- a/web-lib-funcs.pl +++ b/web-lib-funcs.pl @@ -1740,12 +1740,12 @@ if (!%main::acl_hash_cache) { } elsif ($proto eq "ldap") { # Find users in LDAP - # XXX limit attrs? my $rv = $dbh->search( base => $prefix, filter => '(objectClass='. $args->{'userclass'}.')', - scope => 'one'); + scope => 'sub', + attrs => [ 'cn', 'webminModule' ]); if ($rv && !$rv->code) { foreach my $u ($rv->all_entries) { my $user = $u->get_value('cn'); @@ -3370,7 +3370,7 @@ elsif ($u ne '') { base => $prefix, filter => '(&(cn='.$u.')(objectClass='. $args->{'userclass'}.'))', - scope => 'one'); + scope => 'sub'); if (!$rv || $rv->code) { &error(&text('euserdbacl', $rv ? $rv->error : "Unknown error")); @@ -3470,7 +3470,7 @@ if ($userdb) { base => $prefix, filter => '(&(cn='.$g.')(objectClass='. $args->{'groupclass'}.'))', - scope => 'one'); + scope => 'sub'); if (!$rv || $rv->code) { &error(&text('egroupdbacl', $rv ? $rv->error : "Unknown error")); @@ -3587,7 +3587,7 @@ if ($userdb && ($u ne $base_remote_user || $remote_user_proto)) { base => $prefix, filter => '(&(cn='.$u.')(objectClass='. $args->{'userclass'}.'))', - scope => 'one'); + scope => 'sub'); if (!$rv || $rv->code) { &error(&text('euserdbacl', $rv ? $rv->error : "Unknown error")); @@ -3725,7 +3725,7 @@ if ($userdb) { base => $prefix, filter => '(&(cn='.$g.')(objectClass='. $args->{'groupclass'}.'))', - scope => 'one'); + scope => 'sub'); if (!$rv || $rv->code) { &error(&text('egroupdbacl', $rv ? $rv->error : "Unknown error")); @@ -4024,7 +4024,8 @@ $remote_user_proto = $ENV{"REMOTE_USER_PROTO"}; %remote_user_attrs = ( ); if ($remote_user_proto) { my $userdb = &get_userdb_string(); - my ($dbh, $proto) = $userdb ? &connect_userdb($userdb) : ( ); + my ($dbh, $proto, $prefix, $args) = + $userdb ? &connect_userdb($userdb) : ( ); if (ref($dbh)) { if ($proto eq "mysql" || $proto eq "postgresql") { # Read attrs from SQL @@ -4037,7 +4038,20 @@ if ($remote_user_proto) { } } elsif ($proto eq "ldap") { - # XXX read attrs from LDAP + # Read attrs from LDAP + my $rv = $dbh->search( + base => $prefix, + filter => '(&(cn='.$base_remote_user.')'. + '(objectClass='. + $args->{'userclass'}.'))', + scope => 'sub'); + my ($u) = $rv && !$rv->code ? $rv->all_entries : ( ); + if ($u) { + foreach $la ($u->get_value('webminAttr')) { + my ($attr, $value) = split(/=/, $la, 2); + $remote_user_attrs{$attr} = $value; + } + } } &disconnect_userdb($userdb, $dbh); }