mirror of
https://github.com/ovh/the-bastion.git
synced 2024-09-20 06:55:58 +08:00
feat: add groupSetServers
This commit is contained in:
parent
97c0252605
commit
f4de5957a3
105
bin/helper/osh-groupSetServers
Executable file
105
bin/helper/osh-groupSetServers
Executable file
|
@ -0,0 +1,105 @@
|
|||
#! /usr/bin/perl -T
|
||||
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
||||
# KEYSUDOERS # as an aclkeeper, we can add/del a server from the group server list in /home/%GROUP%/allowed.ip
|
||||
# KEYSUDOERS SUPEROWNERS, %%GROUP%-aclkeeper ALL=(%GROUP%) NOPASSWD: /usr/bin/env perl -T %BASEPATH%/bin/helper/osh-groupSetServers --group %GROUP%
|
||||
# FILEMODE 0755
|
||||
# FILEOWN 0 0
|
||||
|
||||
#>HEADER
|
||||
use common::sense;
|
||||
use Getopt::Long qw(:config no_auto_abbrev no_ignore_case);
|
||||
use JSON;
|
||||
|
||||
use File::Basename;
|
||||
use lib dirname(__FILE__) . '/../../lib/perl';
|
||||
use OVH::Result;
|
||||
use OVH::Bastion;
|
||||
use OVH::Bastion::Helper;
|
||||
|
||||
# Fetch command options
|
||||
my $fnret;
|
||||
my ($result, @optwarns);
|
||||
my $group;
|
||||
eval {
|
||||
local $SIG{__WARN__} = sub { push @optwarns, shift };
|
||||
$result = GetOptions(
|
||||
"group=s" => sub { $group //= $_[1] }, # ignore subsequent --group on cmdline (anti-sudoers-override)
|
||||
);
|
||||
};
|
||||
if ($@) { die $@ }
|
||||
|
||||
if (!$result) {
|
||||
local $" = ", ";
|
||||
HEXIT('ERR_BAD_OPTIONS', msg => "Error parsing options: @optwarns");
|
||||
}
|
||||
|
||||
OVH::Bastion::Helper::check_spurious_args();
|
||||
|
||||
if (not $group) {
|
||||
HEXIT('ERR_MISSING_PARAMETER', msg => "Missing argument 'group'");
|
||||
}
|
||||
|
||||
#<HEADER
|
||||
|
||||
#>PARAMS:GROUP
|
||||
osh_debug("Checking group $group");
|
||||
$fnret = OVH::Bastion::is_valid_group_and_existing(group => $group, groupType => 'key');
|
||||
$fnret or HEXIT($fnret);
|
||||
|
||||
# get returned untainted value
|
||||
$group = $fnret->value->{'group'};
|
||||
my $shortGroup = $fnret->value->{'shortGroup'};
|
||||
osh_debug("got group $group/$shortGroup");
|
||||
|
||||
#<PARAMS:GROUP
|
||||
|
||||
#>RIGHTSCHECK
|
||||
if ($self eq 'root') {
|
||||
osh_debug "Real root, skipping checks of permissions";
|
||||
}
|
||||
else {
|
||||
$fnret = OVH::Bastion::is_group_aclkeeper(account => $self, group => $shortGroup, sudo => 1, superowner => 1);
|
||||
$fnret or HEXIT('ERR_NOT_ALLOWED', msg => "Sorry, you must be an aclkeeper of group $shortGroup");
|
||||
}
|
||||
|
||||
#<RIGHTSCHECK
|
||||
|
||||
#>CODE
|
||||
|
||||
# the new ACL is built by the plugin and sent to our STDIN in pre-parsed JSON format
|
||||
my $jsonData = <STDIN>;
|
||||
my $data = eval { decode_json($jsonData); };
|
||||
if ($@) {
|
||||
HEXIT('ERR_INVALID_ARGUMENT', msg => "Invalid JSON data sent by the plugin, couldn't decode");
|
||||
}
|
||||
|
||||
if (!$data || ref $data ne 'ARRAY') {
|
||||
HEXIT('ERR_INVALID_ARGUMENT', msg => "Invalid JSON import format sent by the plugin");
|
||||
}
|
||||
|
||||
$fnret = OVH::Bastion::access_modify(
|
||||
way => 'group',
|
||||
action => 'clear',
|
||||
group => $group,
|
||||
);
|
||||
$fnret or HEXIT($fnret);
|
||||
|
||||
osh_info("Setting ACL entries, this may take a while...");
|
||||
|
||||
my @errors;
|
||||
foreach my $entry (@$data) {
|
||||
$fnret = OVH::Bastion::access_modify(
|
||||
way => 'group',
|
||||
action => 'add',
|
||||
group => $group,
|
||||
ip => $entry->{ip},
|
||||
user => $entry->{user},
|
||||
port => $entry->{port},
|
||||
);
|
||||
push @errors, $fnret if !$fnret;
|
||||
}
|
||||
|
||||
if (!@errors) {
|
||||
HEXIT('OK', value => {ACL => $data, errors => []});
|
||||
}
|
||||
HEXIT('OK_WITH_ERRORS', value => {ACL => $data, errors => \@errors});
|
188
bin/plugin/group-aclkeeper/groupSetServers
Executable file
188
bin/plugin/group-aclkeeper/groupSetServers
Executable file
|
@ -0,0 +1,188 @@
|
|||
#! /usr/bin/env perl
|
||||
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
||||
use common::sense;
|
||||
use JSON;
|
||||
|
||||
use File::Basename;
|
||||
use lib dirname(__FILE__) . '/../../../lib/perl';
|
||||
use OVH::Result;
|
||||
use OVH::Bastion;
|
||||
use OVH::Bastion::Plugin qw( :DEFAULT help );
|
||||
use OVH::Bastion::Plugin::ACL;
|
||||
|
||||
my $remainingOptions = OVH::Bastion::Plugin::begin(
|
||||
argv => \@ARGV,
|
||||
header => "replace a group's current ACL by a new one",
|
||||
userAllowWildcards => 1,
|
||||
options => {
|
||||
"group=s" => \my $group,
|
||||
"dry-run" => \my $dryRun,
|
||||
"skip-errors" => \my $skipErrors,
|
||||
},
|
||||
helptext => <<'EOF',
|
||||
Replace a group's current ACL by a new list
|
||||
|
||||
Usage: --osh SCRIPT_NAME --group GROUP [OPTIONS]
|
||||
|
||||
--group GROUP Specify which group to modify the ACL of
|
||||
--dry-run Don't actually modify the ACL, just report whether the input contains errors
|
||||
--skip-errors Don't abort on STDIN parsing errors, just skip the non-parseable lines
|
||||
|
||||
The list of the assets to constitute the new ACL should then be given on ``STDIN``,
|
||||
respecting the following format: ``[USER@]HOST[:PORT][ COMMENT]``, with ``USER`` and ``PORT`` being optional,
|
||||
and ``HOST`` being either a hostname, an IP, or an IP block in CIDR notation. The ``COMMENT`` is also optional,
|
||||
and may contain spaces.
|
||||
|
||||
Example of valid lines to be fed through ``STDIN``::
|
||||
|
||||
server12.example.org
|
||||
logs@server
|
||||
192.0.2.21
|
||||
host1.example.net:2222 host1 on secondary sshd with alternate port
|
||||
root@192.0.2.0/24 production database cluster
|
||||
EOF
|
||||
);
|
||||
|
||||
my $fnret;
|
||||
|
||||
if (not $group) {
|
||||
help();
|
||||
osh_exit 'ERR_MISSING_PARAMETER', "Missing mandatory parameter 'group'";
|
||||
}
|
||||
|
||||
$fnret = OVH::Bastion::is_valid_group_and_existing(group => $group, groupType => "key");
|
||||
$fnret or osh_exit($fnret);
|
||||
|
||||
# get returned untainted value
|
||||
$group = $fnret->value->{'group'};
|
||||
my $shortGroup = $fnret->value->{'shortGroup'};
|
||||
|
||||
$fnret = OVH::Bastion::is_group_aclkeeper(account => $self, group => $shortGroup, superowner => 1);
|
||||
$fnret
|
||||
or osh_exit 'ERR_NOT_GROUP_ACLKEEPER',
|
||||
"Sorry, you must be an aclkeeper of group $shortGroup to be able to add servers to it";
|
||||
|
||||
osh_info
|
||||
"Specify the entries of the new ACL below, one per line, with the following format: [USER\@]HOST[:PORT][ COMMENT]";
|
||||
osh_info "The list ends at EOF (usually CTRL+D).";
|
||||
osh_info "You may abort with CTRL+C if needed.";
|
||||
|
||||
my @ACL;
|
||||
my @errors;
|
||||
my $nbLines = 0;
|
||||
my $comment;
|
||||
while (my $line = <STDIN>) {
|
||||
# trim white spaces
|
||||
$line =~ s/^\s+|\s+$//g;
|
||||
|
||||
# empty line ?
|
||||
$line or next;
|
||||
|
||||
$nbLines++;
|
||||
|
||||
my ($acl_user, $acl_host, $acl_ip, $acl_port);
|
||||
if ($line =~ m{^(?:(\S+)\@)?([a-zA-Z0-9_./-]+)(?::(\d+))?(?:\s+(.+))?$}) {
|
||||
$acl_user = $1;
|
||||
$acl_host = $2;
|
||||
$acl_port = $3;
|
||||
$comment = $4;
|
||||
}
|
||||
else {
|
||||
push @errors, "Couldn't parse the line '$line'";
|
||||
osh_warn($errors[-1]);
|
||||
next;
|
||||
}
|
||||
|
||||
# check port
|
||||
if (defined $acl_port) {
|
||||
$fnret = OVH::Bastion::is_valid_port(port => $acl_port);
|
||||
if (!$fnret) {
|
||||
push @errors, "In line $nbLines ($line), port '$acl_port' is invalid";
|
||||
osh_warn($errors[-1]);
|
||||
next;
|
||||
}
|
||||
$acl_port = $fnret->value;
|
||||
}
|
||||
|
||||
# check user
|
||||
if (defined $acl_user) {
|
||||
$fnret = OVH::Bastion::is_valid_remote_user(user => $acl_user, allowWildcards => 1);
|
||||
if (!$fnret) {
|
||||
push @errors, "In line $nbLines ($line), user '$acl_user' is invalid";
|
||||
osh_warn($errors[-1]);
|
||||
next;
|
||||
}
|
||||
$acl_user = $fnret->value;
|
||||
}
|
||||
|
||||
# resolve host, unless it looks like a prefix
|
||||
if ($acl_host =~ m{/}) {
|
||||
$fnret = OVH::Bastion::is_valid_ip(ip => $acl_host, allowPrefixes => 1);
|
||||
}
|
||||
else {
|
||||
$fnret = OVH::Bastion::get_ip(host => $acl_host);
|
||||
}
|
||||
if (!$fnret) {
|
||||
push @errors, "In line $nbLines ($line), $fnret";
|
||||
osh_warn($errors[-1]);
|
||||
next;
|
||||
}
|
||||
else {
|
||||
$acl_ip = $fnret->value->{'ip'};
|
||||
}
|
||||
|
||||
push @ACL, {ip => $acl_ip, port => $acl_port, user => $acl_user, comment => $comment};
|
||||
}
|
||||
|
||||
osh_info("Parsed " . @ACL . "/$nbLines lines successfully");
|
||||
|
||||
if (@errors && !$skipErrors) {
|
||||
osh_exit(
|
||||
R(
|
||||
'ERR_INVALID_PARAMETER',
|
||||
msg => "Aborting due to the "
|
||||
. @errors
|
||||
. " parsing or host resolving errors above, use --skip-errors to proceed anyway",
|
||||
value => {parsedLines => $nbLines, dryrun => $dryRun ? \1 : \0, errors => \@errors, ACL => \@ACL},
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($dryRun) {
|
||||
osh_ok({parsedLines => $nbLines, errors => \@errors, dryrun => \1, ACL => \@ACL});
|
||||
}
|
||||
|
||||
#
|
||||
# Now do it
|
||||
#
|
||||
|
||||
if (!@ACL) {
|
||||
osh_exit(R('OK_NO_CHANGE', msg => "No ACL was given, no change was made"));
|
||||
}
|
||||
|
||||
my @command = qw{ sudo -n -u };
|
||||
push @command,
|
||||
($group, '--', '/usr/bin/env', 'perl', '-T', $OVH::Bastion::BASEPATH . '/bin/helper/osh-groupSetServers');
|
||||
push @command, '--group', $group;
|
||||
|
||||
$fnret = OVH::Bastion::helper(cmd => \@command, stdin_str => encode_json(\@ACL));
|
||||
$fnret or osh_exit($fnret);
|
||||
|
||||
# merge both error lists
|
||||
if ($fnret->value && $fnret->value->{'errors'}) {
|
||||
push @errors, @{$fnret->value->{'errors'} || []};
|
||||
}
|
||||
|
||||
osh_exit(
|
||||
R(
|
||||
'OK',
|
||||
msg => "The new ACL has been set with " . @{$fnret->value->{'ACL'}} . " entries and " . @errors . " errors",
|
||||
value => {
|
||||
parsedLines => $nbLines,
|
||||
dryrun => $dryRun ? \1 : \0,
|
||||
group => $shortGroup,
|
||||
ACL => $fnret->value->{'ACL'},
|
||||
errors => \@errors
|
||||
}
|
||||
)
|
||||
);
|
40
doc/sphinx/plugins/group-aclkeeper/groupSetServers.rst
Normal file
40
doc/sphinx/plugins/group-aclkeeper/groupSetServers.rst
Normal file
|
@ -0,0 +1,40 @@
|
|||
================
|
||||
groupSetServers
|
||||
================
|
||||
|
||||
Replace a group's current ACL by a new list
|
||||
===========================================
|
||||
|
||||
|
||||
.. admonition:: usage
|
||||
:class: cmdusage
|
||||
|
||||
--osh groupSetServers --group GROUP [OPTIONS]
|
||||
|
||||
.. program:: groupSetServers
|
||||
|
||||
|
||||
.. option:: --group GROUP
|
||||
|
||||
Specify which group to modify the ACL of
|
||||
|
||||
.. option:: --dry-run
|
||||
|
||||
Don't actually modify the ACL, just report whether the input contains errors
|
||||
|
||||
.. option:: --skip-errors
|
||||
|
||||
Don't abort on STDIN parsing errors, just skip the non-parseable lines
|
||||
|
||||
|
||||
The list of the assets to constitute the new ACL should then be given on ``STDIN``,
|
||||
respecting the following format: ``[USER@]HOST[:PORT][ COMMENT]``, with ``USER`` and ``PORT`` being optional,
|
||||
and ``HOST`` being either a hostname, an IP, or an IP block in CIDR notation. The ``COMMENT`` is also optional,
|
||||
and may contain spaces.
|
||||
|
||||
Example of valid lines to be fed through ``STDIN``::
|
||||
|
||||
server12.example.org
|
||||
logs@server
|
||||
host1.example.net:2222 host1 on secondary sshd with alternate port
|
||||
root@192.0.2.0/24 production database cluster
|
|
@ -6,3 +6,4 @@ group-aclkeeper plugins
|
|||
|
||||
groupAddServer
|
||||
groupDelServer
|
||||
groupSetServers
|
||||
|
|
|
@ -34,5 +34,8 @@ SUPEROWNERS, %%GROUP%-gatekeeper ALL=(allowkeeper) NOPASSWD: /usr/bin/env perl -
|
|||
# as an aclkeeper, we can add/del a server from the group server list in /home/%GROUP%/allowed.ip
|
||||
SUPEROWNERS, %%GROUP%-aclkeeper ALL=(%GROUP%) NOPASSWD: /usr/bin/env perl -T %BASEPATH%/bin/helper/osh-groupAddServer --group %GROUP% *
|
||||
|
||||
# as an aclkeeper, we can replace the group servers list in /home/%GROUP%/allowed.ip in batch with one command
|
||||
SUPEROWNERS, %%GROUP%-aclkeeper ALL=(%GROUP%) NOPASSWD: /usr/bin/env perl -T %BASEPATH%/bin/helper/osh-groupSetServers --group %GROUP%
|
||||
|
||||
# as an owner, we can delete our own group
|
||||
SUPEROWNERS, %%GROUP%-owner ALL=(root) NOPASSWD: /usr/bin/env perl -T %BASEPATH%/bin/helper/osh-groupDelete --group %GROUP%
|
||||
|
|
|
@ -326,9 +326,15 @@ sub access_modify {
|
|||
|
||||
my $fnret;
|
||||
|
||||
foreach my $mandatoryParam (qw/action ip way/) {
|
||||
if (!$params{$mandatoryParam}) {
|
||||
return R('ERR_MISSING_PARAMETER', msg => "Missing parameter '$mandatoryParam'");
|
||||
if (!grep { $action eq $_ } qw{ add del clear }) {
|
||||
return R('ERR_INVALID_PARAMETER', msg => "Action should be add, del or clear");
|
||||
}
|
||||
|
||||
if ($action ne 'clear') {
|
||||
foreach my $mandatoryParam (qw/action ip way/) {
|
||||
if (!$params{$mandatoryParam}) {
|
||||
return R('ERR_MISSING_PARAMETER', msg => "Missing parameter '$mandatoryParam'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,26 +369,24 @@ sub access_modify {
|
|||
return R('ERR_INVALID_PARAMETER', msg => "Parameter 'way' must be either personal, group or groupguest");
|
||||
}
|
||||
|
||||
if ($action ne 'add' and $action ne 'del') {
|
||||
return R('ERR_INVALID_PARAMETER', msg => "Action should be either 'del' or 'add'");
|
||||
}
|
||||
|
||||
# check ip
|
||||
$fnret = OVH::Bastion::is_valid_ip(ip => $ip, allowPrefixes => 1);
|
||||
return $fnret unless $fnret;
|
||||
$ip = $fnret->value->{'ip'};
|
||||
if ($action ne 'clear') {
|
||||
$fnret = OVH::Bastion::is_valid_ip(ip => $ip, allowPrefixes => 1);
|
||||
return $fnret unless $fnret;
|
||||
$ip = $fnret->value->{'ip'};
|
||||
|
||||
if ($fnret->value->{'type'} eq 'prefix') {
|
||||
my $ipVersion = $fnret->value->{'version'};
|
||||
if (defined $widestVxPrefix{$ipVersion} && $fnret->value->{'prefixlen'} < $widestVxPrefix{$ipVersion}) {
|
||||
return R(
|
||||
'ERR_INVALID_PARAMETER',
|
||||
msg => sprintf(
|
||||
"Specified prefix (/%d) is too wide, maximum allowed for IPv%d is /%d by this bastion policy",
|
||||
$fnret->value->{'prefixlen'},
|
||||
$ipVersion, $widestVxPrefix{$ipVersion}
|
||||
),
|
||||
);
|
||||
if ($fnret->value->{'type'} eq 'prefix') {
|
||||
my $ipVersion = $fnret->value->{'version'};
|
||||
if (defined $widestVxPrefix{$ipVersion} && $fnret->value->{'prefixlen'} < $widestVxPrefix{$ipVersion}) {
|
||||
return R(
|
||||
'ERR_INVALID_PARAMETER',
|
||||
msg => sprintf(
|
||||
"Specified prefix (/%d) is too wide, maximum allowed for IPv%d is /%d by this bastion policy",
|
||||
$fnret->value->{'prefixlen'},
|
||||
$ipVersion, $widestVxPrefix{$ipVersion}
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,7 +408,8 @@ sub access_modify {
|
|||
my ($remoteaccount, $sysaccount);
|
||||
if (defined $account) {
|
||||
# accountType==normal : account must NOT be a realm_* account (but can be a realm/jdoe account)
|
||||
$fnret = OVH::Bastion::is_bastion_account_valid_and_existing(account => $account, accountType => 'normal');
|
||||
$fnret =
|
||||
OVH::Bastion::is_bastion_account_valid_and_existing(account => $account, accountType => 'normal', cache => 1);
|
||||
$fnret or return $fnret;
|
||||
$sysaccount = $fnret->value->{'sysaccount'};
|
||||
$account = $fnret->value->{'account'};
|
||||
|
@ -414,7 +419,7 @@ sub access_modify {
|
|||
# check group
|
||||
my $shortGroup;
|
||||
if (defined $group) {
|
||||
$fnret = OVH::Bastion::is_valid_group_and_existing(group => $group, groupType => 'key');
|
||||
$fnret = OVH::Bastion::is_valid_group_and_existing(group => $group, groupType => 'key', cache => 1);
|
||||
$fnret or return $fnret;
|
||||
$group = $fnret->value->{'group'}; # untainted
|
||||
$shortGroup = $fnret->value->{'shortGroup'}; # untainted
|
||||
|
@ -509,28 +514,30 @@ sub access_modify {
|
|||
}
|
||||
|
||||
# end of dryrun
|
||||
return R('OK', msg => "Would have added the access but we've been called with dryrun") if $dryrun;
|
||||
return R('OK', msg => "Would have modified the access ($action) but we've been called with dryrun") if $dryrun;
|
||||
|
||||
# now, check if the access we're being asked to change is already in place or not
|
||||
osh_debug(
|
||||
"for action $action of $user\@$ip:$port of way $way with account=$account and group=$group, checking if already granted"
|
||||
);
|
||||
$fnret = OVH::Bastion::is_access_way_granted(
|
||||
user => $user,
|
||||
ip => $ip,
|
||||
port => $port,
|
||||
way => $way,
|
||||
group => $shortGroup,
|
||||
account => $account,
|
||||
exactMatch => 1, # we're checking if the exact right we're asked to modify exists or not
|
||||
);
|
||||
osh_debug("... result is $fnret");
|
||||
if ($action ne 'clear') {
|
||||
# now, check if the access we're being asked to change is already in place or not
|
||||
osh_debug(
|
||||
"for action $action of $user\@$ip:$port of way $way with account=$account and group=$group, checking if already granted"
|
||||
);
|
||||
$fnret = OVH::Bastion::is_access_way_granted(
|
||||
user => $user,
|
||||
ip => $ip,
|
||||
port => $port,
|
||||
way => $way,
|
||||
group => $shortGroup,
|
||||
account => $account,
|
||||
exactMatch => 1, # we're checking if the exact right we're asked to modify exists or not
|
||||
);
|
||||
osh_debug("... result is $fnret");
|
||||
|
||||
if ($action eq 'add' and $fnret) {
|
||||
return R('OK_NO_CHANGE', msg => "The requested access to add was already granted");
|
||||
}
|
||||
elsif ($action eq 'del' and not $fnret) {
|
||||
return R('OK_NO_CHANGE', msg => "The requested access to delete was not found, no change made");
|
||||
if ($action eq 'add' and $fnret) {
|
||||
return R('OK_NO_CHANGE', msg => "The requested access to add was already granted");
|
||||
}
|
||||
elsif ($action eq 'del' and not $fnret) {
|
||||
return R('OK_NO_CHANGE', msg => "The requested access to delete was not found, no change made");
|
||||
}
|
||||
}
|
||||
|
||||
# ok, now do the change, first define this sub
|
||||
|
@ -543,19 +550,41 @@ sub access_modify {
|
|||
|
||||
# check if we can access the file
|
||||
if (!(-e $file)) {
|
||||
|
||||
# it doesn't exist yet, create it
|
||||
OVH::Bastion::touch_file($file, oct(644));
|
||||
if (!(-e $file)) {
|
||||
warn_syslog("Couldn't create $file ($!)");
|
||||
return R('ERR_CANNOT_CREATE_FILE', msg => "File '$file' is missing and couldn't be created");
|
||||
}
|
||||
}
|
||||
|
||||
# can we write to it ?
|
||||
if (!(-w $file)) {
|
||||
warn_syslog("Couldn't write to $file ($!)");
|
||||
return R('ERR_CANNOT_OPEN_FILE', msg => "File '$file' cannot be written to");
|
||||
}
|
||||
|
||||
# if we're being asked to clear, it's pretty straightforward
|
||||
if ($action eq 'clear') {
|
||||
if (truncate($file, 0)) {
|
||||
OVH::Bastion::syslogFormatted(
|
||||
severity => 'info',
|
||||
type => 'acl',
|
||||
fields => [
|
||||
['action', 'clear'],
|
||||
['type', $params{'way'}],
|
||||
['group', $shortGroup],
|
||||
['account', $params{'account'}],
|
||||
]
|
||||
);
|
||||
return R('OK', msg => "Accesses successfully cleared");
|
||||
}
|
||||
else {
|
||||
warn_syslog("Couldn't truncate $file ($!)");
|
||||
return R('ERR_CANNOT_OPEN_FILE', msg => "Unable to truncate $file");
|
||||
}
|
||||
}
|
||||
|
||||
# build the line we're either adding or looking for (to delete it)
|
||||
my $entry = $ip;
|
||||
$entry = $user . "@" . $entry if defined $user;
|
||||
|
|
|
@ -1039,6 +1039,56 @@ EOS
|
|||
contain REGEX '127\.0\.0\.1[[:space:]]+22[[:space:]]+g1[[:space:]]+'$group1'\(group\)[[:space:]]+'$account2'[[:space:]]'
|
||||
contain '1 accesses listed'
|
||||
|
||||
# test groupSetServers here, then restore the previous ACL so the tests can continue
|
||||
# shellcheck disable=SC1004
|
||||
script groupSetServers_valid_dryrun $a1 --osh groupSetServers --group $group1 --dry-run '< <(printf \
|
||||
"%s\n%s\n%s\n" \
|
||||
"user@127.0.0.1:1234 comment with spaces" \
|
||||
"localhost" \
|
||||
"0.0.0.0/4:42" \
|
||||
)'
|
||||
json .command groupSetServers .error_code OK .value.parsedLines 3 .value.errors '[]' .value.dryrun true
|
||||
json '.value.ACL[0].user' user '.value.ACL[0].ip' 127.0.0.1 '.value.ACL[0].port' 1234 '.value.ACL[0].comment' 'comment with spaces'
|
||||
json '.value.ACL[1].user' null '.value.ACL[1].ip' 127.0.0.1 '.value.ACL[1].port' null '.value.ACL[1].comment' null
|
||||
json '.value.ACL[2].user' null '.value.ACL[2].ip' 0.0.0.0/4 '.value.ACL[2].port' 42 '.value.ACL[2].comment' null
|
||||
|
||||
# shellcheck disable=SC1004
|
||||
script groupSetServers_invalid $a1 --osh groupSetServers --group $group1 --dry-run '< <(printf \
|
||||
"%s\n%s\n%s\n%s\n" \
|
||||
"inva{}lid@127.0.0.1" \
|
||||
"doesntexist.invalid" \
|
||||
"0.0.0.0:77777" \
|
||||
"203.0.113.4/4:42" \
|
||||
)'
|
||||
json .command groupSetServers .error_code ERR_INVALID_PARAMETER .value.parsedLines 4 '.value.errors|length' 4 .value.dryrun true
|
||||
|
||||
# restore the previous ACL
|
||||
# shellcheck disable=SC1004
|
||||
script groupSetServers_valid_skiperrors $a1 --osh groupSetServers --group $group1 --skip-errors '< <(printf \
|
||||
"%s\n%s\n%s\n%s\n%s\n" \
|
||||
"g1@127.0.0.1:22" \
|
||||
"badport:99999" \
|
||||
"g2@127.0.0.2:22" \
|
||||
"127.0.0.10" \
|
||||
"127.0.0.11" \
|
||||
)'
|
||||
json .command groupSetServers .error_code OK .value.parsedLines 5 '.value.errors|length' 1 .value.dryrun false
|
||||
json '.value.ACL[0].user' 'g1' '.value.ACL[0].ip' 127.0.0.1 '.value.ACL[0].port' 22 '.value.ACL[0].comment' null
|
||||
json '.value.ACL[1].user' 'g2' '.value.ACL[1].ip' 127.0.0.2 '.value.ACL[1].port' 22 '.value.ACL[1].comment' null
|
||||
json '.value.ACL[2].user' null '.value.ACL[2].ip' 127.0.0.10 '.value.ACL[2].port' null '.value.ACL[2].comment' null
|
||||
json '.value.ACL[3].user' null '.value.ACL[3].ip' 127.0.0.11 '.value.ACL[3].port' null '.value.ACL[3].comment' null
|
||||
|
||||
success groupListServers_verify_after_groupSetServers $a1 --osh groupListServers --group $group1
|
||||
json .command groupListServers .error_code OK
|
||||
contain REGEX '127\.0\.0\.1[[:space:]]+22[[:space:]]+g1[[:space:]]+'$group1'\(group\)[[:space:]]+'$account1'[[:space:]]'
|
||||
contain REGEX '127\.0\.0\.2[[:space:]]+22[[:space:]]+g2[[:space:]]+'$group1'\(group\)[[:space:]]+'$account1'[[:space:]]'
|
||||
contain REGEX '127\.0\.0\.10[[:space:]]+\*[[:space:]]+\*[[:space:]]+'$group1'\(group\)[[:space:]]+'$account1'[[:space:]]'
|
||||
contain REGEX '127\.0\.0\.11[[:space:]]+\*[[:space:]]+\*[[:space:]]+'$group1'\(group\)[[:space:]]+'$account1'[[:space:]]'
|
||||
nocontain REGEX '127\.0\.0\.12[[:space:]]+\*[[:space:]]+\*[[:space:]]+'$group1'\(group\)[[:space:]]+'$account1'[[:space:]]'
|
||||
contain '4 accesses listed'
|
||||
|
||||
# /groupSetServers tests
|
||||
|
||||
# group1: a1(owner,aclkeeper,gatekeeper,member) a2() servers(127.0.0.10,127.0.0.11)
|
||||
plgfail list $a2 --osh groupListServers --group $group1
|
||||
json .command groupListServers .error_code KO_ACCESS_DENIED .value null
|
||||
|
|
Loading…
Reference in a new issue