Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit 91952f0a authored by vernada's avatar vernada
Browse files

added script to sync ldap2sid

parent a202a816
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/perl
#
use strict;
use warnings;
#
use Data::Dumper;
use Config::IniFiles;
use File::Basename;
use CGI qw/:standard/;
use Spreadsheet::WriteExcel;
use Getopt::Long;
use JSON;
use utf8;
# Remove non-breaking space char
binmode( STDOUT, ":utf8" );
use Net::LDAP;
use Cache::FileCache;
# unbuffered output:
$| = 1;
BEGIN {
my $global_iniFile = new Config::IniFiles( -file => "/opt/etc/ini/global.ini" );
push( @INC, $global_iniFile->val( 'APPLICATION', 'LIBRARY' ) );
}
use SNET::access;
use SNET::common;
use SNET::dumper;
use SNET::html;
use SNET::libdb;
use SNET::ActiveDirectory;
use vars qw($verbose $debug $help $env $script $force $cli_mode $stderr);
$debug = 0;
$verbose = 0;
( $script ) = split( /\./, basename( $0 ) );
$stderr = 1;
my $title = "LDAP Group User Check";
my $function = $title;
$function =~ s/\s/_/g;
my $href = "";
my $header = h1( a( { href => "/cgi-bin/nCheck/$script.pl" }, $title ) );
my $html_msg = "";
my $global_iniFile = new Config::IniFiles( -file => "/opt/etc/ini/global.ini" );
$env = "test";
( $html_msg ) = Access_snet_script_head( $script, $global_iniFile, $ENV, $env );
#
# Global Declarations
#
my $AiniFile = new Config::IniFiles( -file => $global_iniFile->val( 'INI', 'LDAP' ) );
$html_msg .= "error value of AiniFile is undefined" . "\n" if ( !defined( $AiniFile ) );
my $ldapserver = $AiniFile->val( 'LDAP_EC', 'SERVER' );
$html_msg .= "error value of ldapserver is undefined" . "\n" if ( !defined( $ldapserver ) );
my $basedn = $AiniFile->val( 'LDAP_EC', 'BASE' );
$html_msg .= "error value of basedn is undefined" . "\n" if ( !defined( $basedn ) );
my $ldapuser = $AiniFile->val( 'LDAP_EC', 'USER' );
$html_msg .= "error value of ldapuser is undefined" . "\n" if ( !defined( $ldapuser ) );
my $ldappasswd = $AiniFile->val( 'LDAP_EC', 'PASSWORD' );
$html_msg .= "error value of ldappasswd is undefined" . "\n" if ( !defined( $ldappasswd ) );
my $cfg_ldap_server = $AiniFile->val( 'LDAP_SNET_NG', 'SERVER' );
$html_msg .= "error value of cfg_ldap_server is undefined" . "\n" if ( !defined( $cfg_ldap_server ) );
my $cfg_ldap_user = $AiniFile->val( 'LDAP_SNET_NG', 'USER' );
$html_msg .= "error value of cfg_ldap_user is undefined" . "\n" if ( !defined( $cfg_ldap_user ) );
my $cfg_ldap_passwd = $AiniFile->val( 'LDAP_SNET_NG', 'PASSWORD' );
$html_msg .= "error value of cfg_ldap_passwd is undefined" . "\n" if ( !defined( $cfg_ldap_passwd ) );
my $cfg_ldap_group_search = $AiniFile->val( 'LDAP_SNET_NG', 'GRP_SEARCH' );
$html_msg .= "error value of cfg_ldap_group_search is undefined" . "\n" if ( !defined( $cfg_ldap_group_search ) );
my $cfg_ldap_group_search_filter = $AiniFile->val( 'LDAP_SNET_NG', 'FILTER_posix' );
$html_msg .= "error value of cfg_ldap_group_search_filter is undefined" . "\n" if ( !defined( $cfg_ldap_group_search_filter ) );
my $cfg_ldap_group_attribute = $AiniFile->val( 'LDAP_SNET_NG', 'GRP_ATTRIBUTE' );
$html_msg .= "error value of cfg_ldap_group_attribute is undefined" . "\n" if ( !defined( $cfg_ldap_group_attribute ) );
my $cfg_ldap_search_scope = $AiniFile->val( 'LDAP_SNET_NG', 'SEARCH_SCOPE' );
$html_msg .= "error value of cfg_ldap_search_scope is undefined" . "\n" if ( !defined( $cfg_ldap_search_scope ) );
my $cfg_ldap_cafile = $AiniFile->val( 'LDAP_SNET_NG', 'CA' );
$html_msg .= "error value of cfg_ldap_cafile is undefined" . "\n" if ( !defined( $cfg_ldap_cafile ) );
my $all_ldap_group = $AiniFile->val( 'LDAP_EC', 'SID_GROUP' );
$html_msg .= "error value of all_ldap_group is undefined" . "\n" if ( !defined( $all_ldap_group ) );
######
my $groups = ();
@$groups = split( ',', $all_ldap_group );
my $colnames = [ 'uid', 'cn', 'departmentNumber', 'physicalDeliveryOfficeName', 'building', 'dg', 'telephoneNumber' ];
# Get all the SNet member of NS.
my $snet_member = {};
my $off_member = {};
my $group = '';
my $cache_report = new Cache::FileCache(
{
'namespace' => 'nCheck_ldap_group_check',
'cache_root' => '/opt/resources_SNet/DGtools',
'default_expires_in' => '1h',
'auto_purge_interval' => '1h'
}
);
metaprint( 'info', "init_cache cache_report" ) if $verbose;
$force = 0;
$force = 1 if ( ( defined( param( 'force' ) ) ) && ( param( 'force' ) !~ /^$/ ) && ( param( 'force' ) =~ /^Reload$/ ) );
$verbose = 1 if ( ( defined( param( 'verbose' ) ) ) && ( param( 'verbose' ) !~ /^$/ ) && ( param( 'verbose' ) =~ /^[\d\w]+$/ ) && ( param( 'verbose' ) eq 'godmode1' ) );
my $res = $cache_report->get( 'snet_member' );
if ( ( !defined $res ) || $force ) {
undef( $res );
# do action
my $ldap = Net::LDAP->new(
$cfg_ldap_server,
async => 0,
onerror => (
( $debug == 0 ) ? sub { return $_[0] } : sub {
my $message = shift;
my $error = defined( $message->error_desc ) ? $message->error_desc : $message->error();
print STDERR 'Ldap: Unable to process request: ' . $error . "\n";
return $message;
}
),
);
if ( !$ldap ) {
metaprint 'error', "Could not connect to LDAP: $cfg_ldap_server!";
exit 1;
}
metaprint( 'info', "LDAP connection completed successfully." ) if $verbose;
my $message;
eval {
print STDERR 'Starting tls' . "\n" if ( $debug );
$message = $ldap->start_tls( verify => 'require',
cafile => $cfg_ldap_cafile, );
if ( $message->is_error() ) {
metaprint( 'error', "Could not encrypt LDAP connection." );
exit 1;
}
};
if ( $@ ) {
metaprint( 'error', "Crash - Could not encrypt LDAP connection." );
exit 1;
}
eval {
print STDERR 'binding' . "\n" if ( $debug );
$message = $ldap->bind(
$cfg_ldap_user,
password => $cfg_ldap_passwd,
version => 3,
);
if ( $message->is_error() ) {
metaprint( 'error', "LDAP bind error occurred." );
exit 1;
}
};
if ( $@ ) {
metaprint( 'error', "Crash - LDAP bind error occurred" );
exit 1;
}
metaprint( 'info', "LDAP bind operation completed successfully." ) if $verbose;
my $snetcol = [ 'memberUid', 'cn' ];
$cfg_ldap_group_attribute = [ 'memberUid', 'cn' ];
$group = '|(cn=com)(cn=ss)(cn=sd)(cn=pm)(cn=net)(cn=sec)(cn=tda)(cn=mgt)(cn=pi)(cn=bcp)';
my %searchargs;
my $cfg_ldap_group_search_f = $cfg_ldap_group_search_filter;
$cfg_ldap_group_search_f =~ s/cn=REPLACE/$group/;
$searchargs{base} = $cfg_ldap_group_search;
$searchargs{scope} = $cfg_ldap_search_scope;
$searchargs{filter} = $cfg_ldap_group_search_f;
$searchargs{attrs} = $cfg_ldap_group_attribute;
metaprint( 'info', Dumper( \%searchargs ) ) if $verbose;
my $results;
eval {
print STDERR 'searching' . "\n" if ( $debug );
$results = $ldap->search( %searchargs );
if ( $results->is_error() ) {
metaprint( 'error', "LDAP search error occurred:" . $results->code . " : " . $results->error );
exit 1;
}
};
if ( $@ ) {
metaprint( 'error', "Crash - LDAP Users Search." );
exit 1;
}
my $count = $results->count;
if ( $count >= 1 ) {
foreach my $entry ( $results->entries ) {
foreach my $key ( $entry->get_value( $snetcol->[0] ) ) {
push( @{ $snet_member->{"$key"} }, $entry->get_value( $snetcol->[1] ) );
}
}
} else {
$html_msg .= "$group is an empty group.\n" . br;
}
AD_disconnect( $ldap );
print Dumper ( $snet_member ) if ( $debug );
$cache_report->set( 'snet_member', $snet_member );
} else {
$snet_member = $res;
}
# print html_rendering (Dumper ( $snet_member ) );
######
my $fromcache = 1;
my $data = [];
foreach my $group ( @{$groups} ) {
my $gdata = $cache_report->get( $group );
if ( ( !defined $gdata ) || $force ) {
undef( $gdata );
# do action
my $ldap = AD_connect( $ldapserver, $ldapuser, $ldappasswd );
my $searchquery = "(&(objectclass=*)(cudgroup=$group))";
my $filter = "cudgroup=$group";
my $results = $ldap->search( base => $basedn, filter => $filter, attrs => $colnames );
my $count = $results->count;
$html_msg .= "Total entries returned for $group: $count." . "\n" if $main::debug;
if ( $count >= 1 ) {
foreach my $entry ( $results->entries ) {
my $tmp = ();
push( @{$tmp}, $group );
foreach my $cln ( @{$colnames} ) {
push( @{$tmp}, ( $entry->get_value( $cln ) ? $entry->get_value( $cln ) : '' ) );
}
push( @{$gdata}, $tmp );
}
} else {
$html_msg .= "$group is an empty group." . br;
}
AD_disconnect( $ldap );
$cache_report->set( $group, $gdata );
}
foreach my $dd ( @{$gdata} ) {
push( @{$data}, $dd );
}
}
# taking LDAP group 'DIGIT_NS_TEAM' as reference, for the official list members.
$group = 'DIGIT_NS_TEAM';
foreach my $member (
grep { !/^$/ } map {
if ( $_->[0] eq $group ) { $_->[1] }
} map {
$_
} @$data
) {
$off_member->{$member} = 1;
}
######
# print Dumper ( $data );
my $data_users = ();
my $data_groups = ();
my $cln = ();
for ( my $i = 0 ; $i <= $#{$colnames} ; $i++ ) {
$cln->{ $colnames->[$i] } = ( $i + 1 );
}
print Dumper ( $cln );
for my $group ( @{$groups} ) {
print( "Group is $group\n" );
$data_groups->{$group} = ();
foreach my $d ( @$data ) {
next if ( $d->[0] ne $group );
if ( $d->[1] eq 'vernada' ) {
print Dumper( $d );
}
#$VAR1 = [
# 'DIGIT_UNIX', group
# 'gabrigr', uid
# 'GABRIEL Gregory', cn
# 'DIGIT.C.3.004', departement
# 'DRB- D1/007E' physical delivry Office
# ];
# colnames: 'uid', 'cn', 'departmentNumber', 'physicalDeliveryOfficeName', 'building', 'dg', 'telephoneNumber'
my $member = $d->[ $cln->{'uid'} ];
if ( $group eq 'DIGIT_SNET' ) {
# Could not be part of official and SNet at the same time
next if ( defined( $off_member->{$member} ) && ( $off_member->{$member} ) );
# Should be declared in Snet LDAP system.
next if ( !defined( $snet_member->{$member} ) );
foreach my $g ( @{ $snet_member->{$member} } ) {
next if ( $g eq 'bcp' );
push( @{ $data_groups->{ $group . '_' . uc( $g ) }{'contains'} }, $member );
push( @{ $data_users->{$member}{'is_members_of'} }, $group . '_' . uc( $g ) );
}
} elsif ( $group eq 'DIGIT_SNET_PROX' ) {
if ( ( $member !~ /^j/ ) && ( $member !~ /^x/ ) ) {
# TODO open a ticket to request removal....
next;
}
}
push( @{ $data_groups->{$group}{'contains'} }, $member );
push( @{ $data_users->{$member}{'is_members_of'} }, $group );
$data_users->{$member}{'departement'} = $d->[ $cln->{'departmentNumber'} ];
$data_users->{$member}{'office'} = $d->[ $cln->{'physicalDeliveryOfficeName'} ];
$data_users->{$member}{'cn'} = $d->[ $cln->{'cn'} ];
$data_users->{$member}{'building'} = $d->[ $cln->{'building'} ];
$data_users->{$member}{'dg'} = $d->[ $cln->{'dg'} ];
$data_users->{$member}{'telephoneNumber'} = $d->[ $cln->{'telephoneNumber'} ];
# cleaning stuff
$data_users->{$member}{'building'} =~ s/\-$//;
$data_users->{$member}{'office'} =~ s/^.+\s//;
# 'office' => 'D2/058',$
if ( $data_users->{$member}{'office'} =~ /\// ) {
$data_users->{$member}{'nop'} = $data_users->{$member}{'office'};
if ( $data_users->{$member}{'office'} =~ /^([A-Za-z])/ ) {
$data_users->{$member}{'aisle'} = $1;
}
if ( $data_users->{$member}{'office'} =~ /^[A-Za-z]?(\d+)\// ) {
$data_users->{$member}{'floor'} = $1;
$data_users->{$member}{'floor'} =~ s/^0//;
}
$data_users->{$member}{'office'} =~ s/^.*\///;
}
}
}
print Dumper( $data_users );
my $json;
my $cert_data;
print Dumper ( $data_groups );
$json = JSON->new->allow_nonref;
$cert_data = $json->pretty->canonical->encode( $data_groups );
open( OUTFILE, ">/tmp/groups.json" );
print OUTFILE $cert_data;
close( OUTFILE );
print Dumper ( $data_users );
$json = JSON->new->allow_nonref;
$cert_data = $json->pretty->canonical->encode( $data_users );
open( OUTFILE, ">/tmp/users.json" );
print OUTFILE $cert_data;
close( OUTFILE );
exit 0;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment