Fetch specific user / group from LDAP where needed
authorJamie Cameron <jcameron@webmin.com>
Mon, 20 Sep 2010 05:13:15 +0000 (22:13 -0700)
committerJamie Cameron <jcameron@webmin.com>
Mon, 20 Sep 2010 05:13:15 +0000 (22:13 -0700)
acl/acl-lib.pl
acl/edit_group.cgi
acl/edit_user.cgi
acl/lang/en
acl/save_group.cgi
acl/save_user.cgi

index c000b68..a5781af 100755 (executable)
@@ -11,7 +11,6 @@ Library for editing webmin users, passwords and access rights.
 
 =cut
 
-# XXX use get_user / get_group
 # XXX make read_acl faster when we only care about one user
 
 BEGIN { push(@INC, ".."); };
@@ -105,7 +104,8 @@ if ($miniserv{'userdb'}) {
        if ($proto eq "mysql" || $proto eq "postgresql") {
                # Fetch users with SQL
                my %userid;
-               my $cmd = $dbh->prepare("select id,name,pass from webmin_user".
+               my $cmd = $dbh->prepare(
+                       "select id,name,pass from webmin_user".
                        ($only ? " where name in (".
                                 join(",", map { "'$_'" } @$only).")" : ""));
                $cmd && $cmd->execute() ||
@@ -188,7 +188,7 @@ my ($user) = grep { $_->{'name'} eq $username } @rv;
 return $user;
 }
 
-=head2 list_groups
+=head2 list_groups([&only-groups])
 
 Returns a list of hashes, one per Webmin group. Group membership is stored in
 /etc/webmin/webmin.groups, and other attributes in the config file. Useful
@@ -200,9 +200,13 @@ keys include :
 
 =item modules - Modules to grant to members
 
+If the only-groups parameter is given, limit the list to just groups with
+those group names.
+
 =cut
 sub list_groups
 {
+my ($only) = @_;
 my @rv;
 my %miniserv;
 &get_miniserv_config(\%miniserv);
@@ -212,12 +216,15 @@ open(GROUPS, "$config_directory/webmin.groups");
 while(<GROUPS>) {
        s/\r|\n//g;
        local @g = split(/:/, $_);
-       local $group = { 'name' => $g[0],
-                        'members' => [ split(/\s+/, $g[1]) ],
-                        'modules' => [ split(/\s+/, $g[2]) ],
-                        'desc' => $g[3],
-                        'ownmods' => [ split(/\s+/, $g[4]) ] };
-       push(@rv, $group);
+       if (@g) {
+               next if ($only && &indexof($g[0], @$only) < 0);
+               local $group = { 'name' => $g[0],
+                                'members' => [ split(/\s+/, $g[1]) ],
+                                'modules' => [ split(/\s+/, $g[2]) ],
+                                'desc' => $g[3],
+                                'ownmods' => [ split(/\s+/, $g[4]) ] };
+               push(@rv, $group);
+               }
        }
 close(GROUPS);
 
@@ -229,7 +236,9 @@ if ($miniserv{'userdb'}) {
                # Fetch groups with SQL
                my %groupid;
                my $cmd = $dbh->prepare(
-                       "select id,name,description from webmin_group");
+                       "select id,name,description from webmin_group ".
+                       ($only ? " where name in (".
+                                join(",", map { "'$_'" } @$only).")" : ""));
                $cmd && $cmd->execute() ||
                        &error("Failed to query groups : ".$dbh->errstr);
                while(my ($id, $name, $desc) = $cmd->fetchrow()) {
@@ -244,7 +253,9 @@ if ($miniserv{'userdb'}) {
 
                # Add group attributes
                my $cmd = $dbh->prepare(
-                       "select id,attr,value from webmin_group_attr");
+                       "select id,attr,value from webmin_group_attr ".
+                       ($only && %userid ?
+                         " where id in (".join(",", keys %userid).")" : ""));
                $cmd && $cmd->execute() ||
                        &error("Failed to query group attrs : ".$dbh->errstr);
                while(my ($id, $attr, $value) = $cmd->fetchrow()) {
@@ -258,9 +269,15 @@ if ($miniserv{'userdb'}) {
                }
        elsif ($proto eq "ldap") {
                # Find groups with LDAP query
+               my $filter = '(objectClass='.$args->{'groupclass'}.')';
+               if ($only) {
+                       my $gfilter =
+                               "(|".join("", map { "(cn=$_)" } @$only).")";
+                       $filter = "(&".$filter.$gfilter.")";
+                       }
                my $rv = $dbh->search(
                        base => $prefix,
-                       filter => '(objectClass='.$args->{'groupclass'}.')',
+                       filter => $filter,
                        scope => 'sub');
                if (!$rv || $rv->code) {
                        &error("Failed to search groups : ".
index 7ca1583..70196aa 100755 (executable)
@@ -8,17 +8,18 @@ $access{'groups'} || &error($text{'gedit_ecannot'});
 if ($in{'group'}) {
        # Editing an existing group
        &ui_print_header(undef, $text{'gedit_title'}, "");
-       foreach $g (&list_groups()) {
-               if ($g->{'name'} eq $in{'group'}) {
-                       %group = %$g;
-                       }
-               }
+       $g = &get_group($in{'group'});
+       $g || &error($text{'gedit_egone'});
+       %group = %$g;
        }
 else {
        # Creating a new group
        &ui_print_header(undef, $text{'gedit_title2'}, "");
-       foreach $g (&list_groups()) {
-               if ($g->{'name'} eq $in{'clone'}) {
+       %group = ( );
+       if ($in{'clone'}) {
+               # Copy modules from clone
+               $g = &get_group($in{'clone'});
+               if ($g) {
                        $group{'modules'} = $g->{'modules'};
                        }
                }
@@ -34,7 +35,7 @@ print &ui_hidden_table_start($text{'gedit_rights'}, "width=100%", 2, "rights",
 
 # Show the group name
 print &ui_table_row($text{'gedit_group'},
-       &ui_textbox("name", $group{'name'}, 30));
+       &ui_textbox("name", $group{'name'}, 30, 0, undef, "autocomplete=off"));
 
 # Show group description
 print &ui_table_row($text{'gedit_desc'},
index 4671a72..4bf4604 100755 (executable)
@@ -24,6 +24,9 @@ else {
                %user = %$u;
                delete($user{'name'});
                }
+       else {
+               %user = ( );
+               }
        $user{'skill'} = $user{'risk'} = 'high' if ($in{'risk'});
        }
 $me = &get_user($base_remote_user);
@@ -51,7 +54,8 @@ print &ui_hidden_table_start($text{'edit_rights'}, "width=100%", 2, "rights",
 # Username
 print &ui_table_row($text{'edit_user'},
        $access{'rename'} || !$in{'user'} ?
-               &ui_textbox("name", $user{'name'}, 30) : $user{'name'});
+               &ui_textbox("name", $user{'name'}, 30,
+                           0, undef, "autocomplete=off") : $user{'name'});
 
 # Source user for clone
 if ($in{'clone'}) {
@@ -130,7 +134,7 @@ if ($user{'lastchange'} && $miniserv{'pass_maxdays'}) {
        }
 print &ui_table_row($text{'edit_pass'},
        &ui_select("pass_def", $passmode, \@opts)." ".
-       &ui_password("pass", undef, 25).
+       &ui_password("pass", undef, 25, 0, undef, "autocomplete=off").
        ($lockbox || $tempbox ? "<br>" : "").$lockbox.$tempbox.$expmsg);
 
 # Real name
index 3906ccc..864e94e 100644 (file)
@@ -236,6 +236,7 @@ gedit_rights=Webmin group access rights
 gedit_modules=Members' modules
 gedit_members=Member users and groups
 gedit_desc=Group description
+gedit_egone=Selected group no longer exists!
 
 gdelete_err=Failed to delete group
 gdelete_ecannot=You are not allowed to delete groups
index 6bcde2a..1bf269d 100755 (executable)
@@ -15,13 +15,11 @@ elsif ($in{'but_delete'}) {
        exit;
        }
 
-@glist = &list_groups();
-@ulist = &list_users();
 if ($in{'old'}) {
+       # Get the original group
        %group = ( );
-       foreach $g (@glist) {
-               $old = $g if ($g->{'name'} eq $in{'old'});
-               }
+       $old = &get_group($in{'old'});
+       $old || &error($text{'gedit_egone'});
        $group{'members'} = $old->{'members'};
        $group{'proto'} = $old->{'proto'};
        $group{'id'} = $old->{'id'};
@@ -33,15 +31,12 @@ $in{'name'} =~ /^[A-z0-9\-\_\.\@]+$/ && $in{'name'} !~ /^\@/ ||
        &error(&text('gsave_ename', $in{'name'}));
 $in{'name'} eq 'webmin' && &error($text{'gsave_enamewebmin'});
 if (!$in{'old'} || $in{'old'} ne $in{'name'}) {
-       foreach $g (@glist) {
-               if ($g->{'name'} eq $in{'name'}) {
-                       &error(&text('gsave_edup', $in{'name'}));
-                       }
-               }
+       $clash = &get_group($in{'name'});
+       $clash && &error(&text('gsave_edup', $in{'name'}));
        }
 $in{'desc'} !~ /:/ || &error($text{'gsave_edesc'});
 
-# Find the current group
+# Find the current parent group
 if ($in{'old'}) {
        foreach $g (&list_groups()) {
                if (&indexof('@'.$in{'old'}, @{$g->{'members'}}) >= 0) {
@@ -61,8 +56,7 @@ if (defined($in{'group'})) {
                }
 
        # Store parent group membership
-       @glist = &list_groups();
-       ($group) = grep { $_->{'name'} eq $in{'group'} } @glist;
+       $newgroup = &get_group($in{'group'});
        if ($in{'group'} ne ($oldgroup ? $oldgroup->{'name'} : '')) {
                # Group has changed - update the member lists
                if ($oldgroup) {
@@ -71,9 +65,9 @@ if (defined($in{'group'})) {
                                  @{$oldgroup->{'members'}} ];
                        &modify_group($oldgroup->{'name'}, $oldgroup);
                        }
-               if ($group) {
-                       push(@{$group->{'members'}}, '@'.$in{'name'});
-                       &modify_group($in{'group'}, $group);
+               if ($newgroup) {
+                       push(@{$newgroup->{'members'}}, '@'.$in{'name'});
+                       &modify_group($in{'group'}, $newgroup);
                        }
                }
        }
@@ -86,20 +80,20 @@ if ($oldgroup) {
        @mods = grep { &indexof($_, @{$oldgroup->{'modules'}}) < 0 } @mods;
        }
 
-if ($group) {
+if ($newgroup) {
        # Add modules from parent group to list
        local @ownmods;
        foreach $m (@mods) {
                push(@ownmods, $m)
-                       if (&indexof($m, @{$group->{'modules'}}) < 0);
+                       if (&indexof($m, @{$newgroup->{'modules'}}) < 0);
                }
-       @mods = &unique(@mods, @{$group->{'modules'}});
+       @mods = &unique(@mods, @{$newgroup->{'modules'}});
        $group{'ownmods'} = \@ownmods;
 
        # Copy ACL files for parent group
        local $name = $in{'old'} ? $in{'old'} : $in{'name'};
        &copy_group_acl_files($in{'group'}, $name,
-                             [ @{$group->{'modules'}}, "" ]);
+                             [ @{$newgroup->{'modules'}}, "" ]);
        }
 
 # Store group options
@@ -112,6 +106,8 @@ if ($in{'old'}) {
        &modify_group($in{'old'}, \%group);
 
        # recursively update all member users and groups
+       @glist = &list_groups();
+       @ulist = &list_users();
        &update_members(\@ulist, \@glist, $group{'modules'},
                        $old->{'members'});
        }
index 60cf1d5..502f435 100755 (executable)
@@ -102,8 +102,7 @@ else {
                        }
 
                # Store group membership
-               @glist = &list_groups();
-               ($group) = grep { $_->{'name'} eq $in{'group'} } @glist;
+               $newgroup = &get_group($in{'group'});
                if ($in{'group'} ne ($oldgroup ? $oldgroup->{'name'} : '')) {
                        # Group has changed - update the member lists
                        if ($oldgroup) {
@@ -113,13 +112,13 @@ else {
                                          @{$oldgroup->{'members'}} ];
                                &modify_group($oldgroup->{'name'}, $oldgroup);
                                }
-                       if ($group) {
+                       if ($newgroup) {
                                # Put into new
-                               push(@{$group->{'members'}}, $in{'name'});
-                               &modify_group($in{'group'}, $group);
+                               push(@{$newgroup->{'members'}}, $in{'name'});
+                               &modify_group($in{'group'}, $newgroup);
                                }
                        }
-               elsif ($in{'old'} ne $in{'name'} && $oldgroup && $group) {
+               elsif ($in{'old'} ne $in{'name'} && $oldgroup && $newgroup) {
                        # Name has changed - rename in group
                        local $idx = &indexof(
                                $in{'old'}, @{$oldgroup->{'members'}});
@@ -147,7 +146,7 @@ else {
                }
        if ($base_remote_user eq $in{'old'} &&
            &indexof("acl", @mods) == -1 &&
-           (!$group || &indexof("acl", @{$group->{'modules'}}) == -1)) {
+           (!$newgroup || &indexof("acl", @{$newgroup->{'modules'}}) == -1)) {
                &error($text{'save_edeny'});
                }
 
@@ -162,20 +161,20 @@ else {
                &copy_acl_files($me->{'name'}, $in{'name'}, $me->{'modules'});
                }
 
-       if ($group) {
+       if ($newgroup) {
                # Add modules from group to list
                local @ownmods;
                foreach $m (@mods) {
                        push(@ownmods, $m)
-                               if (&indexof($m, @{$group->{'modules'}}) < 0);
+                               if (&indexof($m, @{$newgroup->{'modules'}}) < 0);
                        }
-               @mods = &unique(@mods, @{$group->{'modules'}});
+               @mods = &unique(@mods, @{$newgroup->{'modules'}});
                $user{'ownmods'} = \@ownmods;
 
                # Copy ACL files for group
                local $name = $in{'old'} ? $in{'old'} : $in{'name'};
                &copy_group_user_acl_files($in{'group'}, $name,
-                                     [ @{$group->{'modules'}}, "" ]);
+                                     [ @{$newgroup->{'modules'}}, "" ]);
                }
        $user{'modules'} = \@mods;
        delete($user{'skill'});
@@ -348,7 +347,7 @@ else {
                }
        }
 
-if ($in{'old'} && $in{'acl_security_form'} && !$group) {
+if ($in{'old'} && $in{'acl_security_form'} && !$newgroup) {
        # Update user's global ACL
        &foreign_require("", "acl_security.pl");
        &foreign_call("", "acl_security_save", \%uaccess, \%in);