From 0b2da4195eae7cdcec04008fbac6d10d4ff93b50 Mon Sep 17 00:00:00 2001 From: Zdenek Sustr <git@sustr.net> Date: Tue, 18 Jul 2017 17:22:14 +0200 Subject: [PATCH 1/3] [process-voms*] Remove duplicate entries on input - Actively check the setting of property voms.skip_ca_check, - Remove duplicate user entries that only differ in CA - Avoid attempting to create/handle duplicate VOMS accounts. --- slave/process-voms-dirac/changelog | 8 +++ .../lib/process-voms_dirac.pl | 49 +++++++++++++++++++ slave/process-voms/changelog | 8 +++ slave/process-voms/lib/process-voms.pl | 49 +++++++++++++++++++ 4 files changed, 114 insertions(+) diff --git a/slave/process-voms-dirac/changelog b/slave/process-voms-dirac/changelog index 1acf5c2d..4ee3c859 100755 --- a/slave/process-voms-dirac/changelog +++ b/slave/process-voms-dirac/changelog @@ -1,3 +1,11 @@ +perun-slave-process-voms (1.0.1) stable; urgency=high + + * Actively check the setting of property voms.skip_ca_check and remove + duplicate user entries that only differ in CA before attempting to + create/handle duplicate VOMS accounts. + + -- Zdenek Sustr <sustr4@cesnet.cz> Tue Jul 18 17:19:34 CEST 2017 + perun-slave-process-voms-dirac (1.0.0) stable; urgency=medium * New slave forked from process-voms, enhanced with "nickname" attribute handling diff --git a/slave/process-voms-dirac/lib/process-voms_dirac.pl b/slave/process-voms-dirac/lib/process-voms_dirac.pl index 788d0aaf..1dbe69ec 100755 --- a/slave/process-voms-dirac/lib/process-voms_dirac.pl +++ b/slave/process-voms-dirac/lib/process-voms_dirac.pl @@ -17,6 +17,8 @@ my $csv = Text::CSV->new({ sep_char => ',' }); $attributeStatusFilePrefix = "/var/lib/perun/process-voms-dirac/process-voms-attributes-"; my $attributeStatusDir = dirname($attributeStatusFilePrefix); make_path($attributeStatusDir) unless (-e $attributeStatusDir); +my $etcDir = "/etc/voms-admin"; +my $etcPropertyFilename = "service.properties"; ### serialize is used to turn an array of hash references into a manageable structure sub serialize { @@ -110,6 +112,46 @@ sub knownCA { } +### readProperties reads VO properties file into an array +# $path Path to the file +sub readProperties { + $path = shift; + my %properties; + if (open(INI, "$path")) { + syslog LOG_DEBUG, "Reading config file \"$path\"."; + print STDERR "Reading config file \"$path\".\n"; + while (<INI>) { + chomp; + if (/^(\S*)\s*=\s*(\S*)(#.*)?$/) { + $properties{"$1"} = "$2"; + } + } + close (INI); + } + else { + syslog LOG_WARN, "Could not open config file \"$path\". No way to read VO properties"; + print STDERR "Could not open config file \"$path\". No way to read VO properties\n"; + } + return %properties; +} + +### uniqueDN checks if the user's DN already exists in a list of DNs seen +# $user_ref User structure reference +# $seen_ref List of DNs for comparison +sub uniqueDN { + $seen_ref = $_[1]; + $user_ref = $_[0]; + + if(grep {$_ eq "$user_ref->{'DN'}"} @$seen_ref) { + syslog LOG_ERR, "Duplicate user \"" . $user_ref->{'DN'} . + "\" dropped with CA \"" . $user_ref->{'CA'} . "\""; + print STDERR "Duplicate user \"" . $user_ref->{'DN'} . + "\" dropped with CA \"" . $user_ref->{'CA'} . "\"\n"; + return 0; + } + return 1; +} + # This is the actual start. openlog($program, 'cons,pid', 'user'); @@ -120,6 +162,10 @@ my $retval = 0; foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML $name = $vo->{'name'}; + my %properties = readProperties("$etcDir/$name/$etcPropertyFilename"); + my $checkCA = $properties{"voms.skip_ca_check"} eq "True" ? 0 : 1; + syslog LOG_DEBUG, "voms.skip_ca_check: " . $properties{"voms.skip_ca_check"} . ", $checkCA\n"; + print STDERR "voms.skip_ca_check: " . $properties{"voms.skip_ca_check"} . ", $checkCA\n"; #Collect lists from voms-admin my @groups_current=`voms-admin --vo \Q${name}\E list-groups`; @@ -195,9 +241,12 @@ foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML my @attributes_toBe; # List of al users with attributes my @groups_toBe = ( "/$name" ); # Desired list of groups my @roles_toBe = ( "VO-Admin" );# Desired list of roles, plus the default VO-Admin role + my @DNs_Seen; # DNs already included foreach $user (@{$vo->{'users'}->{'user'}}) { next unless knownCA(\@cas, $user->{'CA'}); my %theUser= ( 'CA' => "$user->{'CA'}",'DN' => "$user->{'DN'}", 'CN' => getCN($user->{'DN'}), 'email' => "$user->{'email'}" ); + next unless ($checkCA || uniqueDN(\%theUser, \@DNs_Seen)); + push(@DNs_Seen, $theUser{'DN'}); if($user->{'nickname'}) { my %userAttributes = ( 'CA' => "$user->{'CA'}",'DN' => "$user->{'DN'}", 'name' => 'nickname', 'value' => "$user->{'nickname'}" ); push(@attributes_toBe, \%userAttributes); diff --git a/slave/process-voms/changelog b/slave/process-voms/changelog index 71e02eb4..32520b72 100755 --- a/slave/process-voms/changelog +++ b/slave/process-voms/changelog @@ -1,3 +1,11 @@ +perun-slave-process-voms (3.1.7) stable; urgency=high + + * Actively check the setting of property voms.skip_ca_check and remove + duplicate user entries that only differ in CA before attempting to + create/handle duplicate VOMS accounts. + + -- Zdenek Sustr <sustr4@cesnet.cz> Tue Jul 18 17:19:34 CEST 2017 + perun-slave-process-voms (3.1.6) stable; urgency=high * fixing error output for list-roles and list-cas operations diff --git a/slave/process-voms/lib/process-voms.pl b/slave/process-voms/lib/process-voms.pl index c4b4b555..b056dc89 100755 --- a/slave/process-voms/lib/process-voms.pl +++ b/slave/process-voms/lib/process-voms.pl @@ -13,6 +13,9 @@ my $vos = XMLin( '-', KeyAttr => [] ); my $csv = Text::CSV->new({ sep_char => ',' }); +my $etcDir = "/etc/voms-admin"; +my $etcPropertyFilename = "service.properties"; + ### serialize is used to turn an array of hash references into a manageable structure sub serialize { JSON::XS->new->relaxed(0)->ascii(1)->canonical(1)->encode($_[0]); @@ -101,6 +104,45 @@ sub knownCA { } } +### readProperties reads VO properties file into an array +# $path Path to the file +sub readProperties { + $path = shift; + my %properties; + if (open(INI, "$path")) { + syslog LOG_DEBUG, "Reading config file \"$path\"."; + print STDERR "Reading config file \"$path\".\n"; + while (<INI>) { + chomp; + if (/^(\S*)\s*=\s*(\S*)(#.*)?$/) { + $properties{"$1"} = "$2"; + } + } + close (INI); + } + else { + syslog LOG_WARN, "Could not open config file \"$path\". No way to read VO properties"; + print STDERR "Could not open config file \"$path\". No way to read VO properties\n"; + } + return %properties; +} + +### uniqueDN checks if the user's DN already exists in a list of DNs seen +# $user_ref User structure reference +# $seen_ref List of DNs for comparison +sub uniqueDN { + $seen_ref = $_[1]; + $user_ref = $_[0]; + + if(grep {$_ eq "$user_ref->{'DN'}"} @$seen_ref) { + syslog LOG_ERR, "Duplicate user \"" . $user_ref->{'DN'} . + "\" dropped with CA \"" . $user_ref->{'CA'} . "\""; + print STDERR "Duplicate user \"" . $user_ref->{'DN'} . + "\" dropped with CA \"" . $user_ref->{'CA'} . "\"\n"; + return 0; + } + return 1; +} # This is the actual start. @@ -112,6 +154,10 @@ my $retval = 0; foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML $name = $vo->{'name'}; + my %properties = readProperties("$etcDir/$name/$etcPropertyFilename"); + my $checkCA = $properties{"voms.skip_ca_check"} eq "True" ? 0 : 1; + syslog LOG_DEBUG, "voms.skip_ca_check: " . $properties{"voms.skip_ca_check"} . ", $checkCA\n"; + print STDERR "voms.skip_ca_check: " . $properties{"voms.skip_ca_check"} . ", $checkCA\n"; #Collect lists from voms-admin my @groups_current=`voms-admin --vo \Q${name}\E list-groups`; @@ -162,9 +208,12 @@ foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML my %groupMembers_toBe; # Desired membership in groups (pure, disregarding roles) my @groups_toBe = ( "/$name" ); # Desired list of groups my @roles_toBe = ( "VO-Admin" );# Desired list of roles, plus the default VO-Admin role + my @DNs_Seen; # DNs already included foreach $user (@{$vo->{'users'}->{'user'}}) { next unless knownCA($user->{'CA'}); my %theUser= ( 'CA' => "$user->{'CA'}",'DN' => "$user->{'DN'}", 'CN' => getCN($user->{'DN'}), 'email' => "$user->{'email'}" ); + next unless ($checkCA || uniqueDN(\%theUser, \@DNs_Seen)); + push(@DNs_Seen, $theUser{'DN'}); push( @{$groupMembers_toBe{"/$name"}}, \%theUser ); #Add user to root group (make them a member) foreach $group (@{$user->{'groups'}->{'group'}}){ push(@groups_toBe, "/$name/$group->{'name'}") unless grep{$_ eq "/$name/$group->{'name'}"} @groups_toBe; -- GitLab From 7350c34d6f11a5eea9c43b4aa6a8bf7f9e0fdf7e Mon Sep 17 00:00:00 2001 From: Zdenek Sustr <git@sustr.net> Date: Wed, 19 Jul 2017 13:02:48 +0200 Subject: [PATCH 2/3] [process-voms*] Settling requirements form review - Indentation by \t - Simple comparison instead of ternary operator --- .../lib/process-voms_dirac.pl | 28 ++++++------ slave/process-voms/lib/process-voms.pl | 44 +++++++++---------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/slave/process-voms-dirac/lib/process-voms_dirac.pl b/slave/process-voms-dirac/lib/process-voms_dirac.pl index 2680587d..428bc4e3 100755 --- a/slave/process-voms-dirac/lib/process-voms_dirac.pl +++ b/slave/process-voms-dirac/lib/process-voms_dirac.pl @@ -47,9 +47,9 @@ sub getCN { # is not called in some cases # DN DN to process sub normalizeEmail { - my $normalized = shift; - $normalized =~ s/\/(E|e|((E|e|)(mail|mailAddress|mailaddress|MAIL|MAILADDRESS)))=/\/Email=/; - return $normalized + my $normalized = shift; + $normalized =~ s/\/(E|e|((E|e|)(mail|mailAddress|mailaddress|MAIL|MAILADDRESS)))=/\/Email=/; + return $normalized } ### normalizeUID applies the same normalization replacement on user DNs as voms-admin itself @@ -57,9 +57,9 @@ sub normalizeEmail { # is not called in some cases # DN DN to process sub normalizeUID { - my $normalized = shift; - $normalized =~ s/\/(UserId|USERID|userId|userid|uid|Uid)=/\/UID=/; - return $normalized + my $normalized = shift; + $normalized =~ s/\/(UserId|USERID|userId|userid|uid|Uid)=/\/UID=/; + return $normalized } ### listToHashes accepts a three-column CSV and produces an array of hashes with the following structure: @@ -138,19 +138,19 @@ sub readProperties { $path = shift; my %properties; if (open(INI, "$path")) { - syslog LOG_DEBUG, "Reading config file \"$path\"."; - print STDERR "Reading config file \"$path\".\n"; - while (<INI>) { + syslog LOG_DEBUG, "Reading config file \"$path\"."; + print STDERR "Reading config file \"$path\".\n"; + while (<INI>) { chomp; if (/^(\S*)\s*=\s*(\S*)(#.*)?$/) { $properties{"$1"} = "$2"; } } - close (INI); + close (INI); } else { - syslog LOG_WARN, "Could not open config file \"$path\". No way to read VO properties"; - print STDERR "Could not open config file \"$path\". No way to read VO properties\n"; + syslog LOG_WARN, "Could not open config file \"$path\". No way to read VO properties"; + print STDERR "Could not open config file \"$path\". No way to read VO properties\n"; } return %properties; } @@ -183,7 +183,7 @@ foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML $name = $vo->{'name'}; my %properties = readProperties("$etcDir/$name/$etcPropertyFilename"); - my $checkCA = $properties{"voms.skip_ca_check"} eq "True" ? 0 : 1; + my $checkCA = $properties{"voms.skip_ca_check"} ne "True"; syslog LOG_DEBUG, "voms.skip_ca_check: " . $properties{"voms.skip_ca_check"} . ", $checkCA\n"; print STDERR "voms.skip_ca_check: " . $properties{"voms.skip_ca_check"} . ", $checkCA\n"; @@ -237,7 +237,7 @@ foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML #Role Membership foreach $role (@roles_current) { $groupRoles_current{"$group"}{"$role"}=listToHashes(\@cas, `voms-admin --vo \Q${name}\E list-users-with-role \Q${group}\E \Q${role}\E`); - } + } } $attributeStatusFile = $attributeStatusFilePrefix.$name.".xml"; diff --git a/slave/process-voms/lib/process-voms.pl b/slave/process-voms/lib/process-voms.pl index 53d95a65..c8862b49 100755 --- a/slave/process-voms/lib/process-voms.pl +++ b/slave/process-voms/lib/process-voms.pl @@ -125,24 +125,24 @@ sub knownCA { } ### readProperties reads VO properties file into an array -# $path Path to the file +# $path Path to the file sub readProperties { $path = shift; my %properties; if (open(INI, "$path")) { - syslog LOG_DEBUG, "Reading config file \"$path\"."; - print STDERR "Reading config file \"$path\".\n"; - while (<INI>) { - chomp; - if (/^(\S*)\s*=\s*(\S*)(#.*)?$/) { - $properties{"$1"} = "$2"; - } - } - close (INI); + syslog LOG_DEBUG, "Reading config file \"$path\"."; + print STDERR "Reading config file \"$path\".\n"; + while (<INI>) { + chomp; + if (/^(\S*)\s*=\s*(\S*)(#.*)?$/) { + $properties{"$1"} = "$2"; + } + } + close (INI); } else { - syslog LOG_WARN, "Could not open config file \"$path\". No way to read VO properties"; - print STDERR "Could not open config file \"$path\". No way to read VO properties\n"; + syslog LOG_WARN, "Could not open config file \"$path\". No way to read VO properties"; + print STDERR "Could not open config file \"$path\". No way to read VO properties\n"; } return %properties; } @@ -155,11 +155,11 @@ sub uniqueDN { $user_ref = $_[0]; if(grep {$_ eq "$user_ref->{'DN'}"} @$seen_ref) { - syslog LOG_ERR, "Duplicate user \"" . $user_ref->{'DN'} . - "\" dropped with CA \"" . $user_ref->{'CA'} . "\""; - print STDERR "Duplicate user \"" . $user_ref->{'DN'} . - "\" dropped with CA \"" . $user_ref->{'CA'} . "\"\n"; - return 0; + syslog LOG_ERR, "Duplicate user \"" . $user_ref->{'DN'} . + "\" dropped with CA \"" . $user_ref->{'CA'} . "\""; + print STDERR "Duplicate user \"" . $user_ref->{'DN'} . + "\" dropped with CA \"" . $user_ref->{'CA'} . "\"\n"; + return 0; } return 1; } @@ -175,7 +175,7 @@ foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML $name = $vo->{'name'}; my %properties = readProperties("$etcDir/$name/$etcPropertyFilename"); - my $checkCA = $properties{"voms.skip_ca_check"} eq "True" ? 0 : 1; + my $checkCA = $properties{"voms.skip_ca_check"} ne "True"; syslog LOG_DEBUG, "voms.skip_ca_check: " . $properties{"voms.skip_ca_check"} . ", $checkCA\n"; print STDERR "voms.skip_ca_check: " . $properties{"voms.skip_ca_check"} . ", $checkCA\n"; @@ -219,7 +219,7 @@ foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML #Role Membership foreach $role (@roles_current) { $groupRoles_current{"$group"}{"$role"}=listToHashes(`voms-admin --vo \Q${name}\E list-users-with-role \Q${group}\E \Q${role}\E`); - } + } } @@ -228,7 +228,7 @@ foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML my %groupMembers_toBe; # Desired membership in groups (pure, disregarding roles) my @groups_toBe = ( "/$name" ); # Desired list of groups my @roles_toBe = ( "VO-Admin" );# Desired list of roles, plus the default VO-Admin role - my @DNs_Seen; # DNs already included + my @DNs_Seen; # DNs already included foreach $user (@{$vo->{'users'}->{'user'}}) { next unless knownCA($user->{'CA'}); my %theUser= ( 'CA' => "$user->{'CA'}",'DN' => normalizeUID(normalizeEmail($user->{'DN'})), 'CN' => getCN($user->{'DN'}), 'email' => "$user->{'email'}" ); @@ -261,7 +261,7 @@ foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML my %membersToAdd; my %rolesToAssign; my %rolesToDismiss; - foreach $group (@groups_toBe) { + foreach $group (@groups_toBe) { @{$membersToRemove{"$group"}} = array_minus_deep(@{$groupMembers_current{"$group"}}, @{$groupMembers_toBe{"$group"}}); @{$membersToRemove{"$group"}} = array_minus_deep(@{$membersToRemove{"$group"}}, @{$membersToRemove{"/$name"}}) unless( "$group" eq "/$name" ); # No need to remove user from groups if they are going to be fully removed @{$membersToAdd{"$group"}} = array_minus_deep(@{$groupMembers_toBe{"$group"}}, @{$groupMembers_current{"$group"}}); @@ -271,7 +271,7 @@ foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML @{$rolesToDismiss{"$group"}{"$role"}} = array_minus_deep(@{$rolesToDismiss{"$group"}{"$role"}}, @{$membersToRemove{"/$name"}}); # No need to revoke roles if the user is going to be fully removed @{$rolesToDismiss{"$group"}{"$role"}} = array_minus_deep(@{$rolesToDismiss{"$group"}{"$role"}}, @{$membersToRemove{"$group"}}); # No need to revoke roles if the user is going to be removed from the group } - } + } # Effect changes -- GitLab From 4118f53466801d1e3f3441bb80163ba617c16df3 Mon Sep 17 00:00:00 2001 From: Zdenek Sustr <git@sustr.net> Date: Wed, 23 Aug 2017 14:29:23 +0200 Subject: [PATCH 3/3] [process-voms] Resolving changelog conflicts --- slave/process-voms-dirac/changelog | 9 +++++++-- slave/process-voms/changelog | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/slave/process-voms-dirac/changelog b/slave/process-voms-dirac/changelog index 7e1cf4fb..d2205060 100755 --- a/slave/process-voms-dirac/changelog +++ b/slave/process-voms-dirac/changelog @@ -1,12 +1,17 @@ -perun-slave-process-voms-dirac (1.0.1) stable; urgency=high +perun-slave-process-voms-dirac (1.0.2) stable; urgency=high * Actively check the setting of property voms.skip_ca_check and remove duplicate user entries that only differ in CA before attempting to create/handle duplicate VOMS accounts. + + -- Zdenek Sustr <sustr4@cesnet.cz> Tue Jul 18 17:19:34 CEST 2017 + +perun-slave-process-voms-dirac (1.0.1) stable; urgency=high + * working around inconsistent normalization of DNs in voms-admin by pre-normalizing perun exports using the same pattern - -- Zdenek Sustr <sustr4@cesnet.cz> Tue Jul 18 17:19:34 CEST 2017 + -- Zdenek Sustr <sustr4@cesnet.cz> Mon Jul 17 17:36:21 CEST 2017 perun-slave-process-voms-dirac (1.0.0) stable; urgency=medium diff --git a/slave/process-voms/changelog b/slave/process-voms/changelog index c230acce..dc3d68be 100755 --- a/slave/process-voms/changelog +++ b/slave/process-voms/changelog @@ -1,12 +1,17 @@ -perun-slave-process-voms (3.1.7) stable; urgency=high +perun-slave-process-voms (3.1.8) stable; urgency=high * Actively check the setting of property voms.skip_ca_check and remove duplicate user entries that only differ in CA before attempting to create/handle duplicate VOMS accounts. + + -- Zdenek Sustr <sustr4@cesnet.cz> Tue Jul 18 17:19:34 CEST 2017 + +perun-slave-process-voms (3.1.7) stable; urgency=high + * working around inconsistent normalization of DNs in voms-admin by pre-normalizing perun exports using the same pattern - -- Zdenek Sustr <sustr4@cesnet.cz> Tue Jul 18 17:19:34 CEST 2017 + -- Zdenek Sustr <sustr4@cesnet.cz> Mon Jul 17 17:36:21 CEST 2017 perun-slave-process-voms (3.1.6) stable; urgency=high -- GitLab