2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-02 15:36:03 +00:00

feat(policy): allow Unix group rules

Co-authored-by: Samveen <samveen@samveen.in>
This commit is contained in:
Vinícius Ferrão
2026-08-30 17:22:51 -03:00
parent a5ad2f7b26
commit 2f798c20ea
3 changed files with 57 additions and 4 deletions
+44
View File
@@ -1606,6 +1606,50 @@ sub getHomeDir
}
#--------------------------------------------------------------------------------
=head3 user_matches_policy_name
Match an authenticated username against a policy name. Bare names
match usernames exactly; names prefixed with '%' match Unix groups.
Arguments:
username, policy name
Returns:
1 - match
0 - no match
=cut
#--------------------------------------------------------------------------------
sub user_matches_policy_name
{
my ($class, $username, $policy_name) = @_;
return 0 unless defined($username) && length($username);
return 0 unless defined($policy_name) && length($policy_name);
return $username eq $policy_name unless $policy_name =~ /\A%(.*)\z/x;
my $group_name = $1;
return 0 unless length($group_name);
my @user = getpwnam($username);
return 0 unless @user;
my @group = getgrnam($group_name);
return 0 unless @group;
return 1 if defined($user[3]) && defined($group[2]) && $user[3] == $group[2];
return 0 unless defined($group[3]) && length($group[3]);
foreach my $member (split(/\s+/x, $group[3])) {
return 1 if $member eq $username;
}
return 0;
}
#-------------------------------------------------------------------------------
+7 -2
View File
@@ -90,7 +90,7 @@ sub validate {
# check to see if peerhost is trusted
foreach $rule (@sortedpolicies) {
if (($rule->{name} and $rule->{name} eq $peername) && ($rule->{rule} =~ /trusted/i)) {
if (($rule->{name} and $rule->{name} !~ /\A%/x and $rule->{name} eq $peername) && ($rule->{rule} =~ /trusted/i)) {
$peerstatus = "Trusted";
last;
}
@@ -108,11 +108,16 @@ sub validate {
}
}
my %principal_matches;
RULE: foreach $rule (@sortedpolicies) {
if ($rule->{name} and $rule->{name} ne '*') {
#TODO: more complex matching (lists, wildcards)
next unless ($peername and $peername eq $rule->{name});
$principal_matches{ $rule->{name} } =
xCAT::Utils->user_matches_policy_name($peername, $rule->{name})
unless exists($principal_matches{ $rule->{name} });
next unless $principal_matches{ $rule->{name} };
}
if ($rule->{name} and $rule->{name} eq '*') { #a name is required, but can be any name whatsoever....
next unless ($peername);
+6 -2
View File
@@ -1277,9 +1277,13 @@ sub check_policy {
my $policies = $policytable->getAllEntries;
$policytable->close;
my %principal_matches;
foreach my $rule (@$policies) {
if ($rule->{name} &&
(($rule->{name} eq "*") || ($rule->{name} eq $userid))) {
if ($rule->{name}) {
$principal_matches{ $rule->{name} } =
xCAT::Utils->user_matches_policy_name($userid, $rule->{name})
unless exists($principal_matches{ $rule->{name} });
next unless ($rule->{name} eq "*" || $principal_matches{ $rule->{name} });
if ($rule->{commands}) {
if (($rule->{commands} eq "") || ($rule->{commands} eq "*") || ($rule->{commands} =~ /$xcatcmd/)) {
return 0; # match found