From 4621129636ce089f15e517e2f1016c085696e571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radoslav=20=C4=8Cerh=C3=A1k?= Date: Thu, 16 Sep 2021 13:44:18 +0200 Subject: [PATCH 1/6] feat: add new service openstack_projects - Added gen and send scripts for new service openstack_projects to manage access to OpenStack. --- gen/openstack_projects | 129 ++++++++++++++++++++++++++++++++++++++++ send/openstack_projects | 4 ++ 2 files changed, 133 insertions(+) create mode 100755 gen/openstack_projects create mode 100755 send/openstack_projects diff --git a/gen/openstack_projects b/gen/openstack_projects new file mode 100755 index 00000000..71eb238a --- /dev/null +++ b/gen/openstack_projects @@ -0,0 +1,129 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use perunServicesInit; +use perunServicesUtils; +use JSON::XS; + +our $SERVICE_NAME = "openstack_projects"; +our $PROTOCOL_VERSION = "3.0.0"; +my $SCRIPT_VERSION = "3.0.0"; + +perunServicesInit::init; +my $DIRECTORY = perunServicesInit::getDirectory; +my $data = perunServicesInit::getHashedHierarchicalData; + +our $A_FACILITY_PROJECT_NAMESPACE; *A_FACILITY_PROJECT_NAMESPACE = \'urn:perun:facility:attribute-def:def:projectNamespace'; +our $A_USER_MAIL; *A_USER_MAIL = \'urn:perun:user:attribute-def:def:preferredMail'; +our $A_USER_FACILITY_LOGIN; *A_USER_FACILITY_LOGIN = \'urn:perun:user_facility:attribute-def:virt:login'; +our $A_USER_OPTIONAL_LOGIN; *A_USER_OPTIONAL_LOGIN = \'urn:perun:user:attribute-def:virt:optionalLogin-namespace:mu'; +our $A_RESOURCE_NAME; *A_RESOURCE_NAME = \'urn:perun:resource:attribute-def:core:name'; +our $A_MEMBER_EXPIRATION; *A_MEMBER_EXPIRATION = \'urn:perun:member:attribute-def:def:membershipExpiration'; +our $A_MEMBER_STATUS; *A_MEMBER_STATUS = \'urn:perun:member:attribute-def:core:status'; + +our $STATUS_VALID; *STATUS_VALID = \'VALID'; + +our $members = {}; + +my $instance = $data->getFacilityAttributeValue(attrName => $A_FACILITY_PROJECT_NAMESPACE); +my $projectPrefix = lc $instance . "_"; + +foreach my $resourceId ($data->getResourceIds()) { + + my $resourceName = $data->getResourceAttributeValue(resource => $resourceId, attrName => $A_RESOURCE_NAME); + my $projectName = $resourceName; + + my $hasAccess = 0; + if ($resourceName =~ /-access$/) { + $hasAccess = 1; + $projectName = $projectPrefix . substr $resourceName, 0, length($resourceName) - 7; + } + + my $isManager = 0; + if ($resourceName =~ /-managers$/) { + $isManager = 1; + $projectName = $projectPrefix . substr $resourceName, 0, length($resourceName) - 9; + } + + my $isPersonalProject = 0; + if ($resourceName =~ /-personalProjects$/) { + $isPersonalProject = 1; + } + + foreach my $memberId ($data->getMemberIdsForResource(resource => $resourceId)) { + my $identifier = $data->getUserFacilityAttributeValue(member => $memberId, attrName => $A_USER_FACILITY_LOGIN); + $identifier = $identifier . "\@muni.cz" if $projectPrefix eq "mu_"; + + if($members->{$identifier}) { + if ($hasAccess) { + push @{$members->{$identifier}->{'projects_access'}}, $projectName; + } + if ($isManager) { + push @{$members->{$identifier}->{'projects_managers'}}, $projectName; + } + if ($isPersonalProject) { + my $status = $data->getMemberAttributeValue(member => $memberId, attrName => $A_MEMBER_STATUS); + if($status eq $STATUS_VALID) { + $members->{$identifier}->{'personal_project'} = JSON::XS::true; + my $memberExpiration = $data->getMemberAttributeValue(member => $memberId, attrName => $A_MEMBER_EXPIRATION); + if (!$memberExpiration) { + $memberExpiration = ""; + } + $members->{$identifier}->{'expiration'} = $memberExpiration; + } + } + } else { + my @additionalIdentifier = (); + my $muLogin = $data->getUserAttributeValue(member => $memberId, attrName => $A_USER_OPTIONAL_LOGIN); + if ($muLogin) { + push @additionalIdentifier, $muLogin . "\@muni.cz"; + } + + my $mail = $data->getUserAttributeValue(member => $memberId, attrName => $A_USER_MAIL); + + my @projects_access = (); + if ($hasAccess) { + push @projects_access, $projectName; + } + my @projects_managers = (); + if ($isManager) { + push @projects_managers, $projectName; + } + + my $member = { + identifier => $identifier, + additional_identifier => \@additionalIdentifier, + mail => $mail, + projects_access => \@projects_access, + projects_managers => \@projects_managers + }; + + my $status = $data->getMemberAttributeValue(member => $memberId, attrName => $A_MEMBER_STATUS); + if ($isPersonalProject && $status eq $STATUS_VALID) { + $member->{'personal_project'} = JSON::XS::true; + my $memberExpiration = $data->getMemberAttributeValue(member => $memberId, attrName => $A_MEMBER_EXPIRATION); + if(!$memberExpiration) { + $memberExpiration = ""; + } + $member->{'expiration'} = $memberExpiration; + } else { + $member->{'personal_project'} = JSON::XS::false; + } + + $members->{$identifier} = $member; + } + } +} + +my @values = values(%$members); +my $fileData = { + instance => $instance, + access => \@values +}; +my $file = $DIRECTORY . "access.json"; +open FILE_USERS, ">$file" or die "Cannot open $file: $! \n"; +print FILE_USERS JSON::XS->new->utf8->pretty->canonical->encode($fileData), "\n"; +close(FILE_USERS) or die "Cannot close $file: $! \n"; + +perunServicesInit::finalize; diff --git a/send/openstack_projects b/send/openstack_projects new file mode 100755 index 00000000..dc13ac19 --- /dev/null +++ b/send/openstack_projects @@ -0,0 +1,4 @@ +#!/bin/bash +SERVICE_NAME="openstack_projects" + +. generic_send From bce9003e988a6d2c652773f530fb8ba952e35049 Mon Sep 17 00:00:00 2001 From: Michal Stava Date: Wed, 29 Sep 2021 15:30:50 +0200 Subject: [PATCH 2/6] feat(o365_mu_account_status): add new service - Added gen, send and slave scripts for new service o365_mu_account_status --- gen/o365_mu_account_status | 12 ++++++++ send/o365_mu_account_status | 4 +++ .../bin/process-o365_mu_account_status.sh | 28 +++++++++++++++++++ .../process-o365-mu-account-status/changelog | 5 ++++ .../conf/example-pre_01_set_target_dir | 3 ++ .../dependencies | 1 + .../rpm.dependencies | 1 + .../process-o365-mu-account-status/short_desc | 1 + 8 files changed, 55 insertions(+) create mode 100755 gen/o365_mu_account_status create mode 100755 send/o365_mu_account_status create mode 100644 slave/process-o365-mu-account-status/bin/process-o365_mu_account_status.sh create mode 100644 slave/process-o365-mu-account-status/changelog create mode 100644 slave/process-o365-mu-account-status/conf/example-pre_01_set_target_dir create mode 100644 slave/process-o365-mu-account-status/dependencies create mode 100644 slave/process-o365-mu-account-status/rpm.dependencies create mode 100644 slave/process-o365-mu-account-status/short_desc diff --git a/gen/o365_mu_account_status b/gen/o365_mu_account_status new file mode 100755 index 00000000..3c1e190d --- /dev/null +++ b/gen/o365_mu_account_status @@ -0,0 +1,12 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use File::Basename; +use perunDataGenerator; + +local $::SERVICE_NAME = basename($0); +local $::PROTOCOL_VERSION = "3.0.0"; + +perunDataGenerator::generateUsersDataInJSON; + diff --git a/send/o365_mu_account_status b/send/o365_mu_account_status new file mode 100755 index 00000000..8c7faa1f --- /dev/null +++ b/send/o365_mu_account_status @@ -0,0 +1,4 @@ +#!/bin/bash +SERVICE_NAME="o365_mu_account_status" + +. generic_send diff --git a/slave/process-o365-mu-account-status/bin/process-o365_mu_account_status.sh b/slave/process-o365-mu-account-status/bin/process-o365_mu_account_status.sh new file mode 100644 index 00000000..623a4a68 --- /dev/null +++ b/slave/process-o365-mu-account-status/bin/process-o365_mu_account_status.sh @@ -0,0 +1,28 @@ +#!/bin/bash +PROTOCOL_VERSION='3.0.0' + +function process { + + ### Status codes + I_CHANGED=(0 "${DST_FILE} updated") + I_NOT_CHANGED=(0 "${DST_FILE} has not changed") + + E_MISSING_DST=(50 'Missing destination of file (DST_FILE), need to be set in pre_script.') + + FROM_PERUN="${WORK_DIR}/o365_mu_account_status" + + if [ -z ${DST_FILE} ]; then + log_msg E_MISSING_DST + fi + + create_lock + + # Create diff between old.perun and .new + diff_mv_sync "${FROM_PERUN}" "${DST_FILE}" + + if [ $? -eq 0 ]; then + log_msg I_CHANGED + else + log_msg I_NOT_CHANGED + fi +} diff --git a/slave/process-o365-mu-account-status/changelog b/slave/process-o365-mu-account-status/changelog new file mode 100644 index 00000000..f3665469 --- /dev/null +++ b/slave/process-o365-mu-account-status/changelog @@ -0,0 +1,5 @@ +perun-slave-process-o365-mu-account-status (3.1.1) stable; urgency=low + + * New package version for perun-slave-process-o365-mu-account-status + + -- Michal Stava Wed, 29 Sep 2021 15:21:00 +0200 diff --git a/slave/process-o365-mu-account-status/conf/example-pre_01_set_target_dir b/slave/process-o365-mu-account-status/conf/example-pre_01_set_target_dir new file mode 100644 index 00000000..e65eabc1 --- /dev/null +++ b/slave/process-o365-mu-account-status/conf/example-pre_01_set_target_dir @@ -0,0 +1,3 @@ +#!/bin/sh +#SET destination file +#DST_FILE=/var/opt/perun/o365_mu_account_status diff --git a/slave/process-o365-mu-account-status/dependencies b/slave/process-o365-mu-account-status/dependencies new file mode 100644 index 00000000..a6717984 --- /dev/null +++ b/slave/process-o365-mu-account-status/dependencies @@ -0,0 +1 @@ +perun-slave-base diff --git a/slave/process-o365-mu-account-status/rpm.dependencies b/slave/process-o365-mu-account-status/rpm.dependencies new file mode 100644 index 00000000..a6717984 --- /dev/null +++ b/slave/process-o365-mu-account-status/rpm.dependencies @@ -0,0 +1 @@ +perun-slave-base diff --git a/slave/process-o365-mu-account-status/short_desc b/slave/process-o365-mu-account-status/short_desc new file mode 100644 index 00000000..f11ff80b --- /dev/null +++ b/slave/process-o365-mu-account-status/short_desc @@ -0,0 +1 @@ +Package for perun service - o365_mu_account_status From 1568a1d741667447fe08983349ec6ed7ce6a944c Mon Sep 17 00:00:00 2001 From: Metodej Klang Date: Fri, 24 Sep 2021 17:38:58 +0200 Subject: [PATCH 3/6] fix(send): log to STDERR when updating group membership in AD - Group membership update in AD now logs which members were added/removed to STDERR as well as to local file. --- send/ADConnector.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/send/ADConnector.pm b/send/ADConnector.pm index 09c2407f..691180be 100644 --- a/send/ADConnector.pm +++ b/send/ADConnector.pm @@ -577,6 +577,7 @@ sub add_members_to_entry($$$$) { ldap_log($service_name, "Group members added: " . $ad_entry->dn() . " | \n" . join(",\n", @$_)); } else { ldap_log($service_name, "Group members NOT added: " . $ad_entry->dn() . " | " . $response->error() . " | \n" . join(",\n", @$_)); + print STDERR "Group members NOT added: " . $ad_entry->dn() . " | " . $response->error() . " | \n" . join(",\n", @$_); $return_code = $FAIL; } } @@ -611,6 +612,7 @@ sub remove_members_from_entry($$$$) { ldap_log($service_name, "Group members removed: " . $ad_entry->dn() . " | \n" . join(",\n", @$_)); } else { ldap_log($service_name, "Group members NOT removed: " . $ad_entry->dn() . " | " . $response->error() . " | \n" . join(",\n", @$_)); + print STDERR "Group members NOT removed: " . $ad_entry->dn() . " | " . $response->error() . " | \n" . join(",\n", @$_); $return_code = $FAIL; } } From 5d6f2528d1b58841069bc09998396d09414b8c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Zl=C3=A1mal?= Date: Thu, 30 Sep 2021 17:46:07 +0200 Subject: [PATCH 4/6] fix(ad_user_vsup): primary mail must be between proxyAddresses - It is marked as primary mail using "SMTP:" prefix. --- gen/ad_user_vsup | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gen/ad_user_vsup b/gen/ad_user_vsup index cf67ffef..81b4ba90 100755 --- a/gen/ad_user_vsup +++ b/gen/ad_user_vsup @@ -217,6 +217,10 @@ for my $login (@logins) { print FILE "altSecurityIdentities: " . $val . "\n"; } + # primary mail must be in proxyAddresses for normal users + if (defined $exchangeMail and length $exchangeMail) { + print FILE "proxyAddresses: SMTP:" . $exchangeMail . "\n"; + } foreach my $val (@$exchangeMailAliases) { print FILE "proxyAddresses: smtp:" . $val . "\n"; } From 03fe992eb90b8b77ce479dbd1810e701fb274414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Zl=C3=A1mal?= Date: Thu, 30 Sep 2021 17:47:25 +0200 Subject: [PATCH 5/6] fix(ad_user_vsup_service): preferred mail must be between proxyAddresses - It is marked as primary mail using "SMTP:" prefix. --- gen/ad_user_vsup_service | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gen/ad_user_vsup_service b/gen/ad_user_vsup_service index e3e60b76..c6a182a1 100755 --- a/gen/ad_user_vsup_service +++ b/gen/ad_user_vsup_service @@ -200,6 +200,10 @@ for my $login (@logins) { print FILE "altSecurityIdentities: " . $val . "\n"; } + # preferred mail must be in proxyAddresses as primary mail for service users + if (defined $vsupPrefMail and length $vsupPrefMail) { + print FILE "proxyAddresses: SMTP:" . $vsupPrefMail . "\n"; + } foreach my $val (@$exchangeMailAliases) { print FILE "proxyAddresses: smtp:" . $val . "\n"; } From 0aa71301f6ef08a09387ddb033a7b011328db932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Zl=C3=A1mal?= Date: Thu, 30 Sep 2021 18:03:27 +0200 Subject: [PATCH 6/6] fix(ad_user_vsup_service): override displayName with adDisplayName value - If service user have user:def:adDisplayName attribute set, prefer its value before calculated value from actual name. --- gen/ad_user_vsup_service | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gen/ad_user_vsup_service b/gen/ad_user_vsup_service index c6a182a1..b3280ceb 100755 --- a/gen/ad_user_vsup_service +++ b/gen/ad_user_vsup_service @@ -37,6 +37,7 @@ our $A_CARD_CHIP_NUMBERS; *A_CARD_CHIP_NUMBERS = \'urn:perun:user:attribute-def our $A_VSUP_PREF_MAIL; *A_VSUP_PREF_MAIL = \'urn:perun:user:attribute-def:def:vsupPreferredMail'; our $A_VSUP_SSH_KEYS; *A_VSUP_SSH_KEYS = \'urn:perun:user:attribute-def:def:sshPublicKey'; our $A_VSUP_EXCHANGE_MAIL_ALIASES; *A_VSUP_EXCHANGE_MAIL_ALIASES = \'urn:perun:user:attribute-def:def:vsupExchangeMailAliases'; +our $A_AD_DISPLAY_NAME; *A_AD_DISPLAY_NAME = \'urn:perun:user:attribute-def:def:adDisplayName'; # CHECK ON FACILITY ATTRIBUTES if (!defined($data->getFacilityAttributeValue( attrName => $A_F_BASE_DN ))) { @@ -99,6 +100,7 @@ foreach my $memberId ($data->getMemberIdsForFacility()) { # store standard attrs $users->{$login}->{$A_FIRST_NAME} = $artisticFirstName || $firstName; $users->{$login}->{$A_LAST_NAME} = $artisticLastName || $lastName; + $users->{$login}->{$A_AD_DISPLAY_NAME} = $data->getUserAttributeValue( member => $memberId, attrName => $A_AD_DISPLAY_NAME ); $users->{$login}->{$A_UCO} = $data->getUserAttributeValue( member => $memberId, attrName => $A_UCO ); $users->{$login}->{$A_TITLE_BEFORE} = $data->getUserAttributeValue( member => $memberId, attrName => $A_TITLE_BEFORE ); $users->{$login}->{$A_TITLE_AFTER} = $data->getUserAttributeValue( member => $memberId, attrName => $A_TITLE_AFTER ); @@ -135,6 +137,7 @@ for my $login (@logins) { # skip attributes which are empty and LDAP can't handle it (FIRST_NAME, EMAIL) my $sn = $users->{$login}->{$A_LAST_NAME}; my $givenName = $users->{$login}->{$A_FIRST_NAME}; + my $adDisplayName = $users->{$login}->{$A_AD_DISPLAY_NAME}; my $uco = $users->{$login}->{$A_UCO}; my $titleBefore = $users->{$login}->{$A_TITLE_BEFORE}; my $titleAfter = $users->{$login}->{$A_TITLE_AFTER}; @@ -154,6 +157,10 @@ for my $login (@logins) { } elsif (!(defined $givenName and length $givenName) and defined $sn and length $sn) { $printedDisplayName = $sn; } + # prefer manually set display name for service accounts if present + if (defined $adDisplayName and length $adDisplayName) { + $printedDisplayName = $adDisplayName; + } if (defined $printedDisplayName and length $printedDisplayName) { print FILE "displayName: " . $printedDisplayName . "\n"; print FILE "gecos: " . $printedDisplayName . "\n";