[Rt-devel] MAJOR BUG in group membership.
Ruslan U. Zakirov
cubic at acronis.ru
Fri Apr 23 14:20:33 EDT 2004
Khe-khe, folks, good time of day.
Bug located in $UserObj->Create().
This function buggy in many ways like an 'Maasdam' cheese.
1) Doesn't check return values when add users to system groups.
AddMember check ACLs. Report below. Step to reproduce: Grant user with
'AdminUsers', revoke 'AdminGroup' and use his account to create new
user. :) Not all work under SU.
2)
my $principal_id = $principal->Create(PrincipalType => 'User',
Disabled => $args{'Disabled'},
ObjectId => '0');
$principal->__Set(Field => 'ObjectId', Value => $principal_id);
??? IMHO it'll die if we couldn't create a principal Id.
Or update all principals because $principal object don't have fetched
fields :)))))
# If we couldn't create a principal Id, get the fuck out.
unless ($principal_id) {
??? We check it too old.
$RT::Handle->Rollback();
$RT::Logger->crit("Couldn't create a Principal on new user
create. Strange things are afoot at the circle K");
return ( 0, $self->loc('Could not create user') );
}
3)
$RT::Handle->Commit;
#$RT::Logger->debug("Adding the
user as a member of everyone");
Do we realy create user? Why commit? User that doesn't live in
'Everyone' is not an user. :)
Same with Priveleged/Unpriveleged.
Attached script fix tables, it _must_ be included/merged in RT update
script in next release.
Good luck. Ruslan.
An angry PS:
1) I don't need/want/wish/like fucking users who sweem around in RT DB
like an piece of shit.
2) This bug once again proof that using return values for error handling
is bad practice.
3) I don't know what exactly moving you guys, marketing team or somebody
else, you're maintaining two branches at the same time. When your code
base, core of your project, has lucks in many ways which should be
refactored.
4) Why does RT operates so slow? It wouldn't be fast if there will be
next code:
$RT::Logger->crit("Deleting groups violates referential integrity
until we go through and fix this");
# TODO XXX
# Remove the principal object
# Remove this group from anything it's a member of.
# Remove all cached members of this group
# Remove any rights granted to this group
# remove any rights delegated by way of this group
return ( $self->SUPER::Delete(@_) );
5) Even MySQL allow FKs now, but RT still doesn't have FKs.
6) Our mail relay was stopped for less then 3 days. 5000 mails were in
spool. What do you think happened when we did run it? Don't know? Yeh,
RT didn't live for 5 minutes, This problem not only with RT, all
together Apache/mod_perl eat all memory and begin lost mysql connection
due OOMKiller, mysql which can't limit number threads on i386 Linux, RT
which does some things slowly. It's fine machine with >2GHz, >1GB...
Huh, I end up. Exhausts are ended too. Nearest monthes I'll not retry
such things :)
Ruslan U. Zakirov wrote:
> We have 449 user who has no member ship in group Everyone!
>
> select count(1) from Principals pr left join GroupMembers gm on
> (gm.MemberId = pr.id and gm.GroupId = 3) where pr.PrincipalType = 'User'
> and gm.id is null;
>
> Most of this users were created via CLI.
>
> We have
> select count(1) from Principals where PrincipalType = 'User';
> +----------+
> | count(1) |
> +----------+
> | 43696 |
> +----------+
> users.
>
> Users by system groups
> select g.id, g.Domain, g.Type, count(gm.id) members from GroupMembers
> gm, Groups g where gm.GroupId in(3,4,5) and g.id = gm.GroupId group by
> gm.GroupId;
> +----+----------------+--------------+---------+
> | id | Domain | Type | members |
> +----+----------------+--------------+---------+
> | 3 | SystemInternal | Everyone | 43247 |
> | 4 | SystemInternal | Privileged | 51 |
> | 5 | SystemInternal | Unprivileged | 43196 |
> +----+----------------+--------------+---------+
>
> This 449 users don't have membership in system groups.
>
> Please, I need solution tomorrow.
>
> Best regards. Ruslan.
-------------- next part --------------
#!/usr/bin/perl -w
use strict;
use Carp;
use Getopt::Long;
use lib '/opt/rt3/lib';
use lib '/opt/rt3/etc';
#use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
#CleanEnv();
use RT;
use RT::Ticket;
use RT::Tickets;
#Load RT's config file
RT::LoadConfig();
# Connect to the database. set up loggign
RT::Init();
my $where = shift;
unless( $where =~ /^(un)?priveleged$/i ) {
print <<END;
Script fixes users membership in RT system groups: Everyone, Priveleged, Unpriveleged.
In RT-3.0.x was bug and under some conditions users can leave this groups and lost
thier rights.
User must be always member of Everyone.
User must be always member of Priveleged or Unpriveleged and must be only in one,
so you have to choose group where broken users would be placed.
usage: $0 priveleged | unprivelged
END
die "Please choose group where scipt would place broken users";
}
my $everyone = RT::Group->new( $RT::SystemUser );
$everyone->LoadSystemInternalGroup('Everyone');
unless( $everyone->id ) {
die "Something wrong, you don't have system group Everyone";
};
my $unpriv = RT::Group->new( $RT::SystemUser );
$unpriv->LoadSystemInternalGroup('Unprivileged');
unless( $unpriv->id ) {
die "Something wrong, you don't have group Unpriveleged";
};
my $priv = RT::Group->new( $RT::SystemUser );
$priv->LoadSystemInternalGroup('Privileged');
unless( $priv->id ) {
die "Something wrong, you don't have group Priveleged";
};
my $dbh = $RT::Handle->dbh;
# select all users who don't belong to everyone.
my $sth = $dbh->prepare( "select
pr.id
from Principals pr
left join GroupMembers gm
on (gm.MemberId = pr.id and gm.GroupId = ". $everyone->id ." )
where pr.PrincipalType = 'User' and gm.id is null " );
$sth->execute() or die $sth->errstr;
my $Users = $sth->fetchall_arrayref( [0] );
if( scalar @$Users ) {
print "You have ". scalar @$Users ." users who aren't members of Everyone group\n";
FixSystemMembership( $Users, $everyone );
}
$sth->finish;
# select all users who don't belong to priveleged and not to unpriveleged.
$sth = $dbh->prepare( "select
pr.id
from Principals pr
left join GroupMembers gm
on (gm.MemberId = pr.id and
gm.GroupId in( ". $priv->id .", ". $unpriv->id ." ) )
where pr.PrincipalType = 'User' and gm.id is null " );
$sth->execute() or die $sth->errstr;
$Users = $sth->fetchall_arrayref( [0] );
if( scalar @$Users ) {
print "You have ". scalar @$Users ." users who aren't members of Priveleged or Unpriveleged groups\n";
print "Will add this users to ". ucfirst lc $where ." group\n";
if( $where =~ /^un/i ) {
FixSystemMembership( $Users, $unpriv );
} else {
FixSystemMembership( $Users, $priv );
}
}
$sth->finish;
print "Your tables now fine\n";
exit(0);
sub FixSystemMembership {
my ( $Users, $Group ) = @_;
foreach my $u ( @$Users ) {
next if( $u->[0] == $RT::SystemUser->id );
print "Fixing user #". $u->[0] .":";
my ( $status, $msg ) = $Group->AddMember( $u->[0] );
unless( $status ) {
die "$msg";
}
print "\tOK\n";
}
};
More information about the Rt-devel
mailing list