mirror of
https://github.com/webmin/webmin.git
synced 2026-02-12 18:12:05 +00:00
More work on user DB
This commit is contained in:
261
acl/acl-lib.pl
261
acl/acl-lib.pl
@@ -33,7 +33,8 @@ Returns a list of hashes containing Webmin user details. Useful keys include :
|
||||
=cut
|
||||
sub list_users
|
||||
{
|
||||
local(%miniserv, $_, @rv, %acl, %logout);
|
||||
my (%miniserv, $_, @rv, %acl, %logout);
|
||||
local %_;
|
||||
&read_acl(undef, \%acl);
|
||||
&get_miniserv_config(\%miniserv);
|
||||
foreach my $a (split(/\s+/, $miniserv{'logouttimes'})) {
|
||||
@@ -148,7 +149,9 @@ keys include :
|
||||
=cut
|
||||
sub list_groups
|
||||
{
|
||||
local @rv;
|
||||
my @rv;
|
||||
|
||||
# Add groups from local files
|
||||
open(GROUPS, "$config_directory/webmin.groups");
|
||||
while(<GROUPS>) {
|
||||
s/\r|\n//g;
|
||||
@@ -161,6 +164,49 @@ while(<GROUPS>) {
|
||||
push(@rv, $group);
|
||||
}
|
||||
close(GROUPS);
|
||||
|
||||
# If a user DB is enabled, get groups from it too
|
||||
if ($miniserv{'userdb'}) {
|
||||
my ($proto, $user, $pass, $host, $prefix, $args) =
|
||||
&split_userdb_string($miniserv{'userdb'});
|
||||
my $dbh = &connect_userdb($miniserv{'userdb'});
|
||||
&error("Failed to connect to group database : $dbh") if (!ref($dbh));
|
||||
if ($proto eq "mysql" || $proto eq "postgresql") {
|
||||
# Fetch groups with SQL
|
||||
my %groupid;
|
||||
my $cmd = $dbh->prepare(
|
||||
"select id,name,description from webmin_group");
|
||||
$cmd && $cmd->execute() ||
|
||||
&error("Failed to query groups : ".$dbh->errstr);
|
||||
while(my ($id, $name, $desc) = $cmd->fetchrow()) {
|
||||
my $g = { 'name' => $pass, 'desc' => $desc,
|
||||
'proto' => $proto };
|
||||
push(@rv, $g);
|
||||
$groupid{$id} = $g;
|
||||
}
|
||||
$cmd->finish();
|
||||
|
||||
# Add group attributes
|
||||
my $cmd = $dbh->prepare(
|
||||
"select id,attr,value from webmin_group_attr");
|
||||
$cmd && $cmd->execute() ||
|
||||
&error("Failed to query group attrs : ".$dbh->errstr);
|
||||
while(my ($id, $attr, $value) = $cmd->fetchrow()) {
|
||||
if ($attr eq "members" || $attr eq "modules" ||
|
||||
$attr eq "ownmods") {
|
||||
$value = [ split(/\s+/, $value) ];
|
||||
}
|
||||
$groupid{$id}->{$attr} = $value;
|
||||
}
|
||||
$cmd->finish();
|
||||
}
|
||||
elsif ($proto eq "ldap") {
|
||||
# Find groups with LDAP query
|
||||
# XXX
|
||||
}
|
||||
&disconnect_userdb($miniserv{'userdb'}, $dbh);
|
||||
}
|
||||
|
||||
return @rv;
|
||||
}
|
||||
|
||||
@@ -196,11 +242,11 @@ settings from for this new user.
|
||||
=cut
|
||||
sub create_user
|
||||
{
|
||||
my (%miniserv, @mods);
|
||||
my %user = %{$_[0]};
|
||||
my $clone = $_[1];
|
||||
my %miniserv;
|
||||
my @mods = &list_modules();
|
||||
|
||||
&lock_file($ENV{'MINISERV_CONFIG'});
|
||||
&get_miniserv_config(\%miniserv);
|
||||
|
||||
if ($miniserv{'userdb'} && !$miniserv{'userdb_addto'}) {
|
||||
@@ -244,6 +290,7 @@ if ($miniserv{'userdb'} && !$miniserv{'userdb_addto'}) {
|
||||
}
|
||||
else {
|
||||
# Adding to local files
|
||||
&lock_file($ENV{'MINISERV_CONFIG'});
|
||||
if ($user{'theme'}) {
|
||||
$miniserv{"preroot_".$user{'name'}} =
|
||||
$user{'theme'}.($user{'overlay'} ? " ".$user{'overlay'} : "");
|
||||
@@ -280,7 +327,6 @@ else {
|
||||
&unlock_file($miniserv{'userfile'});
|
||||
|
||||
&lock_file(&acl_filename());
|
||||
@mods = &list_modules();
|
||||
&open_tempfile(ACL, ">>".&acl_filename());
|
||||
&print_tempfile(ACL, &acl_line(\%user, \@mods));
|
||||
&close_tempfile(ACL);
|
||||
@@ -314,17 +360,9 @@ else {
|
||||
&write_file("$config_directory/config", \%gconfig);
|
||||
}
|
||||
|
||||
# Copy ACLs from user being cloned
|
||||
if ($clone) {
|
||||
# XXX clone
|
||||
foreach $m ("", @mods) {
|
||||
my $file = "$config_directory/$m/$clone.acl";
|
||||
my $dest = "$config_directory/$m/$user{'name'}.acl";
|
||||
if (-r $file) {
|
||||
my %macl;
|
||||
&read_file($file, \%macl);
|
||||
&write_file($dest, \%macl);
|
||||
}
|
||||
}
|
||||
©_acl_files($clone, $user{'name'}, [ "", @mods ]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,7 +593,7 @@ if ($miniserv{'userdb'}) {
|
||||
my ($id) = $cmd->fetchrow();
|
||||
$cmd->finish();
|
||||
|
||||
if ($id) {
|
||||
if (defined($id)) {
|
||||
# Delete the user
|
||||
my $cmd = $dbh->prepare(
|
||||
"delete from webmin_user where id = ?");
|
||||
@@ -602,16 +640,65 @@ keys are :
|
||||
=cut
|
||||
sub create_group
|
||||
{
|
||||
&lock_file("$config_directory/webmin.groups");
|
||||
open(GROUP, ">>$config_directory/webmin.groups");
|
||||
print GROUP &group_line($_[0]),"\n";
|
||||
close(GROUP);
|
||||
&unlock_file("$config_directory/webmin.groups");
|
||||
my %group = %{$_[0]};
|
||||
my $clone = $_[1];
|
||||
my %miniserv;
|
||||
&get_miniserv_config(\%miniserv);
|
||||
|
||||
if ($_[1]) {
|
||||
if ($miniserv{'userdb'} && !$miniserv{'userdb_addto'}) {
|
||||
# Adding to group database
|
||||
my ($proto, $user, $pass, $host, $prefix, $args) =
|
||||
&split_userdb_string($miniserv{'userdb'});
|
||||
my $dbh = &connect_userdb($miniserv{'userdb'});
|
||||
&error("Failed to connect to group database : $dbh") if (!ref($dbh));
|
||||
if ($proto eq "mysql" || $proto eq "postgresql") {
|
||||
# Add group with SQL
|
||||
my $cmd = $dbh->prepare("insert into webmin_group (name,description) values (?, ?)");
|
||||
$cmd && $cmd->execute($group{'name'}, $group{'desc'}) ||
|
||||
&error("Failed to add group : ".$dbh->errstr);
|
||||
$cmd->finish();
|
||||
my $cmd = $dbh->prepare("select last_insert_id()");
|
||||
$cmd->execute();
|
||||
my ($id) = $cmd->fetchrow();
|
||||
$cmd->finish();
|
||||
|
||||
# Add other attributes
|
||||
my $cmd = $dbh->prepare("insert into webmin_group_attr (id,attr,value) values (?, ?, ?)");
|
||||
foreach my $attr (keys %group) {
|
||||
next if ($attr eq "name" || $attr eq "desc");
|
||||
my $value = $group{$attr};
|
||||
if ($attr eq "members" || $attr eq "modules" ||
|
||||
$attr eq "ownmods") {
|
||||
$value = join(" ", @$value);
|
||||
}
|
||||
$cmd->execute($id, $attr, $value) ||
|
||||
&error("Failed to add group attribute : ".
|
||||
$dbh->errstr);
|
||||
$cmd->finish();
|
||||
}
|
||||
}
|
||||
elsif ($proto eq "ldap") {
|
||||
# Add user to LDAP
|
||||
# XXX
|
||||
}
|
||||
&disconnect_userdb($miniserv{'userdb'}, $dbh);
|
||||
$group{'proto'} = $proto;
|
||||
}
|
||||
else {
|
||||
# Adding to local files
|
||||
&lock_file("$config_directory/webmin.groups");
|
||||
open(GROUP, ">>$config_directory/webmin.groups");
|
||||
print GROUP &group_line(\%group),"\n";
|
||||
close(GROUP);
|
||||
&unlock_file("$config_directory/webmin.groups");
|
||||
}
|
||||
|
||||
if ($clone) {
|
||||
# Clone ACLs
|
||||
# XXX
|
||||
foreach $m ("", &list_modules()) {
|
||||
local $file = "$config_directory/$m/$_[1].gacl";
|
||||
local $dest = "$config_directory/$m/$_[0]->{'name'}.gacl";
|
||||
local $file = "$config_directory/$m/$clone.gacl";
|
||||
local $dest = "$config_directory/$m/$group{'name'}.gacl";
|
||||
if (-r $file) {
|
||||
local %macl;
|
||||
&read_file($file, \%macl);
|
||||
@@ -659,12 +746,63 @@ Delete a webmin group, identified by the name parameter.
|
||||
=cut
|
||||
sub delete_group
|
||||
{
|
||||
my ($groupname) = @_;
|
||||
|
||||
# Delete from local files
|
||||
&lock_file("$config_directory/webmin.groups");
|
||||
local $lref = &read_file_lines("$config_directory/webmin.groups");
|
||||
@$lref = grep { !/^([^:]+):/ || $1 ne $_[0] } @$lref;
|
||||
@$lref = grep { !/^([^:]+):/ || $1 ne $groupname } @$lref;
|
||||
&flush_file_lines();
|
||||
&unlock_file("$config_directory/webmin.groups");
|
||||
&unlink_file(map { "$config_directory/$_/$_[0].gacl" } &list_modules());
|
||||
&unlink_file(map { "$config_directory/$_/$groupname.gacl" } &list_modules());
|
||||
|
||||
if ($miniserv{'userdb'}) {
|
||||
# Also delete from group database
|
||||
my ($proto, $user, $pass, $host, $prefix, $args) =
|
||||
&split_userdb_string($miniserv{'userdb'});
|
||||
my $dbh = &connect_userdb($miniserv{'userdb'});
|
||||
&error("Failed to connect to group database : $dbh") if (!ref($dbh));
|
||||
if ($proto eq "mysql" || $proto eq "postgresql") {
|
||||
# Find the group with SQL query
|
||||
my $cmd = $dbh->prepare(
|
||||
"select id from webmin_group where name = ?");
|
||||
$cmd && $cmd->execute($groupname) ||
|
||||
&error("Failed to find group : ".$dbh->errstr);
|
||||
my ($id) = $cmd->fetchrow();
|
||||
$cmd->finish();
|
||||
|
||||
if (defined($id)) {
|
||||
# Delete the group
|
||||
my $cmd = $dbh->prepare(
|
||||
"delete from webmin_group where id = ?");
|
||||
$cmd && $cmd->execute($id) ||
|
||||
&error("Failed to delete group : ".$dbh->errstr);
|
||||
$cmd->finish();
|
||||
|
||||
# Delete attributes
|
||||
my $cmd = $dbh->prepare(
|
||||
"delete from webmin_group_attr where id = ?");
|
||||
$cmd && $cmd->execute($id) ||
|
||||
&error("Failed to delete group attrs : ".
|
||||
$dbh->errstr);
|
||||
$cmd->finish();
|
||||
|
||||
# Delete ACLs
|
||||
my $cmd = $dbh->prepare(
|
||||
"delete from webmin_group_acl where id = ?");
|
||||
$cmd && $cmd->execute($id) ||
|
||||
&error("Failed to delete group acls : ".
|
||||
$dbh->errstr);
|
||||
$cmd->finish();
|
||||
}
|
||||
}
|
||||
elsif ($proto eq "ldap") {
|
||||
# Find group with LDAP query
|
||||
# XXX
|
||||
}
|
||||
&disconnect_userdb($miniserv{'userdb'}, $dbh);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
=head2 group_line(&group)
|
||||
@@ -864,13 +1002,62 @@ The parameters are :
|
||||
=cut
|
||||
sub copy_acl_files
|
||||
{
|
||||
local $m;
|
||||
foreach $m (@{$_[2]}) {
|
||||
&unlink_file("$config_directory/$m/$_[1].acl");
|
||||
local %acl;
|
||||
if (&read_file("$config_directory/$m/$_[0].acl", \%acl)) {
|
||||
&write_file("$config_directory/$m/$_[1].acl", \%acl);
|
||||
my ($from, $to, $mods) = @_;
|
||||
my ($dbh, $fromid, $toid);
|
||||
my ($proto, $user, $pass, $host, $prefix, $args);
|
||||
|
||||
# Check if the user is in a DB
|
||||
&get_miniserv_config(\%miniserv);
|
||||
if ($miniserv{'userdb'}) {
|
||||
$dbh = &connect_userdb($miniserv{'userdb'});
|
||||
&error($dbh) if (!ref($dbh));
|
||||
($proto, $user, $pass, $host, $prefix, $args) =
|
||||
&split_userdb_string($miniserv{'userdb'});
|
||||
if ($proto eq "mysql" || $proto eq "postgresql") {
|
||||
# Search in SQL DB
|
||||
my $cmd = $dbh->prepare(
|
||||
"select id from webmin_user where name = ?");
|
||||
$cmd->execute($from);
|
||||
($fromid) = $cmd->fetchrow();
|
||||
$cmd->finish();
|
||||
$cmd->execute($to);
|
||||
($toid) = $cmd->fetchrow();
|
||||
$cmd->finish();
|
||||
}
|
||||
elsif ($proto eq "ldap") {
|
||||
# Search in LDAP
|
||||
# XXX
|
||||
}
|
||||
}
|
||||
|
||||
if (defined($fromid) && defined($toid)) {
|
||||
# Copy from database to database
|
||||
if ($proto eq "mysql" || $proto eq "postgresql") {
|
||||
my $cmd = $dbh->prepare("insert into webmin_user_acl select ?,attr,value from webmin_user_acl where id = ?");
|
||||
$cmd && $cmd->execute($toid, $fromid) ||
|
||||
&error("Failed to copy ACLs : ".$dbh->errstr);
|
||||
$cmd->finish();
|
||||
}
|
||||
elsif ($proto eq "ldap") {
|
||||
# XXX
|
||||
}
|
||||
}
|
||||
elsif (!defined($fromid) && !defined($toid)) {
|
||||
# Copy files
|
||||
foreach my $m (@$mods) {
|
||||
&unlink_file("$config_directory/$m/$to.acl");
|
||||
my %acl;
|
||||
if (&read_file("$config_directory/$m/$from.acl", \%acl)) {
|
||||
&write_file("$config_directory/$m/$to.acl", \%acl);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Source and dest use different storage types
|
||||
# XXX
|
||||
}
|
||||
if ($dbh) {
|
||||
&disconnect_userdb($miniserv{'userdb'}, $dbh);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,12 +1075,12 @@ are :
|
||||
=cut
|
||||
sub copy_group_acl_files
|
||||
{
|
||||
local $m;
|
||||
foreach $m (@{$_[2]}) {
|
||||
&unlink_file("$config_directory/$m/$_[1].gacl");
|
||||
my ($from, $to, $mods) = @_;
|
||||
foreach my $m (@$mods) {
|
||||
&unlink_file("$config_directory/$m/$to.gacl");
|
||||
local %acl;
|
||||
if (&read_file("$config_directory/$m/$_[0].gacl", \%acl)) {
|
||||
&write_file("$config_directory/$m/$_[1].gacl", \%acl);
|
||||
if (&read_file("$config_directory/$m/$from.gacl", \%acl)) {
|
||||
&write_file("$config_directory/$m/$to.gacl", \%acl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user