mirror of
https://github.com/ovh/the-bastion.git
synced 2024-09-20 23:15:58 +08:00
fix: accountCreate --uid-auto: rare case where a free UID couldn't be found
This happened when a free UID was found, along with a corresponding GID, but the corresponding GID for the ttyrec group of the account was not available. Now this is checked directly in get_next_available_uid()
This commit is contained in:
parent
6b4418e864
commit
c0bebf23d4
|
@ -120,7 +120,7 @@ if (defined $uid) {
|
||||||
getgrgid($uid) and HEXIT('ERR_GID_COLLISION', msg => "This GID ($uid) is already taken");
|
getgrgid($uid) and HEXIT('ERR_GID_COLLISION', msg => "This GID ($uid) is already taken");
|
||||||
}
|
}
|
||||||
elsif ($uidAuto) {
|
elsif ($uidAuto) {
|
||||||
$fnret = OVH::Bastion::get_next_available_uid();
|
$fnret = OVH::Bastion::get_next_available_uid(available_gid => 1, available_gid_ttyrec => 1);
|
||||||
$fnret or HEXIT($fnret);
|
$fnret or HEXIT($fnret);
|
||||||
$uid = $fnret->value();
|
$uid = $fnret->value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,14 +114,40 @@ sub is_valid_uid {
|
||||||
sub get_next_available_uid {
|
sub get_next_available_uid {
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
|
|
||||||
|
# if true, also check for the availablility of the corresponding GID:
|
||||||
|
my $available_gid = $params{'available_gid'};
|
||||||
|
|
||||||
|
# if true, also check for the availability of the corresponding GID + the ttyrec offset:
|
||||||
|
my $available_gid_ttyrec = $params{'available_gid_ttyrec'};
|
||||||
|
|
||||||
my $higher = OVH::Bastion::config('accountUidMax')->value();
|
my $higher = OVH::Bastion::config('accountUidMax')->value();
|
||||||
my $lower = OVH::Bastion::config('accountUidMin')->value();
|
my $lower = OVH::Bastion::config('accountUidMin')->value();
|
||||||
my $next = $higher;
|
my $next = $higher;
|
||||||
|
my $found = 0;
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
# find the first available UID, starting from the upper ID allowed and decrementing
|
||||||
while ($next >= $lower) {
|
while ($next >= $lower) {
|
||||||
last if not scalar(getpwuid($next));
|
last if not scalar(getpwuid($next));
|
||||||
$next--;
|
$next--;
|
||||||
}
|
}
|
||||||
return R('OK', value => $next) if not scalar(getpwuid($next));
|
|
||||||
|
# did we get out of the loop because we found a candidate, or because we're out of bounds?
|
||||||
|
last if $next < $lower;
|
||||||
|
|
||||||
|
# if $available_gid, also check if the corresponding GID is available
|
||||||
|
# if $available_gid_ttyrec, also check if the corresponding GID + the ttyrec offset is available
|
||||||
|
if ( (!$available_gid || !scalar(getgrgid($next)))
|
||||||
|
&& (!$available_gid_ttyrec || !scalar(getgrgid($next + OVH::Bastion::config('ttyrecGroupIdOffset')->value))))
|
||||||
|
{
|
||||||
|
$found = 1;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
|
# if we're here, at least one of the $available_gid* check failed, so continue looking
|
||||||
|
$next--;
|
||||||
|
}
|
||||||
|
return R('OK', value => $next) if $found;
|
||||||
return R('ERR_UID_COLLISION', msg => "No available UID in the allowed range");
|
return R('ERR_UID_COLLISION', msg => "No available UID in the allowed range");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue