#!/usr/bin/perl -w use strict; use Template; use Net::LDAP; use File::Slurp; use YAML qw/LoadFile/; use LWP::UserAgent; my $config_file = '/etc/mgapeople.conf'; my $config = LoadFile($ENV{MGAPEOPLE_CONF} ? $ENV{MGAPEOPLE_CONF} : $config_file); my %maintdb; my %groups; my %users; sub process_template { my ($template, $src, $vars, $dest) = @_; for my $extension (@{$config->{output_format}}) { next unless -f "$config->{tmpl_dir}/$src.$extension"; $template->process("$src.$extension", $vars, "$dest.$extension"); } } sub loadmaintdb { return unless $config->{maintdburl}; my $ua = LWP::UserAgent->new; my $r = $ua->get($config->{maintdburl}); return unless $r->is_success; for my $line (split /^/, $r->decoded_content) { my ($pkg, $user) = split ' ', $line; push @{$maintdb{$user}}, $pkg; } } sub loaduser { my ($ldap, $user) = @_; my $m = $ldap->search( base => $user, scope => 'base', filter => '(objectClass=inetOrgPerson)', ); die $m->error if $m->is_error; my $res = $m->as_struct; if (exists $res->{$user}) { $res->{$user}->{groups} = []; $users{$user} = $res->{$user}; } } sub loadgroups { my ($ldap) = @_; my $m = $ldap->search( base => $config->{groupbase}, filter => '(objectClass=groupOfNames)', ); die $m->error if $m->is_error; my $res = $m->as_struct; for my $groupname (keys %$res) { $groups{$groupname} = $res->{$groupname}; for my $user (@{$groups{$groupname}->{member}}) { loaduser($ldap, $user) unless exists $users{$user}; if (exists $users{$user}) { push @{$users{$user}->{groups}}, $groupname; } } $res->{$groupname}->{member} = [ grep { exists $users{$_} } @{$groups{$groupname}->{member}} ]; } } sub output_users { my $template = Template->new({ INCLUDE_PATH => $config->{tmpl_dir}, OUTPUT_PATH => "$config->{output_dir}/u", }); for my $user (keys %users) { my $vars = { config => $config, user => $user, users => \%users, groups => \%groups, maintdb => \%maintdb, }; my $uid = $users{$user}->{uid}->[0]; process_template($template, 'user', $vars, $uid); } my $vars = { config => $config, users => \%users, groups => \%groups, maintdb => \%maintdb, }; process_template($template, 'userindex', $vars, 'index'); } sub output_groups { my $template = Template->new({ INCLUDE_PATH => $config->{tmpl_dir}, OUTPUT_PATH => "$config->{output_dir}/g", }); for my $group (keys %groups) { my $vars = { config => $config, group => $group, users => \%users, groups => \%groups, maintdb => \%maintdb, }; my $cn = $groups{$group}->{cn}->[0]; process_template($template, 'group', $vars, $cn); } my $vars = { config => $config, users => \%users, groups => \%groups, maintdb => \%maintdb, }; process_template($template, 'groupindex', $vars, 'index'); } sub output_index { my $template = Template->new({ INCLUDE_PATH => $config->{tmpl_dir}, OUTPUT_PATH => "$config->{output_dir}", }); my $vars = { config => $config, users => \%users, groups => \%groups, maintdb => \%maintdb, }; process_template($template, 'index', $vars, 'index'); } my $bindpw = read_file($config->{bindpwfile}); chomp $bindpw; my $ldap = Net::LDAP->new($config->{ldapserver}) or die "$@"; my $m; $m = $ldap->start_tls(verify => 'none'); die $m->error if $m->is_error; $m = $ldap->bind($config->{binddn}, password => $bindpw); die $m->error if $m->is_error; loadmaintdb; loadgroups($ldap); output_users(); output_groups(); output_index();