aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xfripost-adduser2
-rwxr-xr-xfripost-newalias2
-rwxr-xr-xfripost-newdomain4
-rwxr-xr-xfripost-searchalias144
-rwxr-xr-xfripost-searchdomain153
-rwxr-xr-xfripost-searchuser140
-rw-r--r--lib/Fripost/Schema/Search.pm10
-rw-r--r--lib/Fripost/Schema/Type/Domain.pm11
8 files changed, 461 insertions, 5 deletions
diff --git a/fripost-adduser b/fripost-adduser
index a785f07..633926e 100755
--- a/fripost-adduser
+++ b/fripost-adduser
@@ -202,7 +202,7 @@ my ($domain, $login);
if ($res->count) {
print STDERR "Error: Alias $user->{username} already exists. ";
print STDERR "(Targetting to ";
- print STDERR (join ', ', map { $_->{goto} } ($res->entries));
+ print STDERR (join ', ', map { $_->{goto} } $res->entries);
say STDERR ".)";
exit 1;
}
diff --git a/fripost-newalias b/fripost-newalias
index 075c43a..b5ad94f 100755
--- a/fripost-newalias
+++ b/fripost-newalias
@@ -195,7 +195,7 @@ for my $addr (@addr) {
else {
print STDERR "Error: Alias $addr already exists. ";
print STDERR "(Targetting to ";
- print STDERR (join ', ', map { $_->{goto} } ($rs->entries));
+ print STDERR (join ', ', map { $_->{goto} } $rs->entries);
say STDERR ".)";
exit 1;
}
diff --git a/fripost-newdomain b/fripost-newdomain
index 3c877e5..7cbac3b 100755
--- a/fripost-newdomain
+++ b/fripost-newdomain
@@ -185,7 +185,7 @@ else {
if ($res->count) {
print STDERR "WARN: Domain `" .$domain{domain}. "' already exists.";
my @owners;
- map { push @owners, $_->{owner} if defined $_->{owner} } ($res->entries);
+ map { push @owners, @{$_->{owner}} if defined $_->{owner} } $res->entries;
if (@owners) {
print STDERR " (Owned by ";
print STDERR (join ', ', map { '`' .$_. "'"} @owners);
@@ -224,7 +224,7 @@ sub create_alias {
if ($res->count) {
print STDERR "WARN: Alias $alias{address} already exists.";
print STDERR "(Targetting to ";
- print STDERR (join ', ', map { $_->{goto} } ($res->entries));
+ print STDERR (join ', ', map { $_->{goto} } $res->entries);
say STDERR ".)";
return unless grep { $_->{goto} eq $alias{goto} } $res->entries;
}
diff --git a/fripost-searchalias b/fripost-searchalias
new file mode 100755
index 0000000..0775942
--- /dev/null
+++ b/fripost-searchalias
@@ -0,0 +1,144 @@
+#!/usr/bin/perl
+
+use 5.010_000;
+use strict;
+use warnings;
+use utf8;
+
+=head1 NAME
+
+fripost-searchalias - List matching aliases
+
+=head1 SYNOPSIS
+
+B<fripost-searchalias> [B<--debug>] [I<goto> [I<from>]]
+
+=head1 DESCRIPTION
+
+B<fripost-seardomain> list virtual aliases matching exactly I<from>,
+targetting to I<goto>.
+Wildcards I<*> can appear in I<goto> or I<from>, to match zero or more
+characters.
+If no I<from> is given, list all aliases whose target matches I<goto>.
+If neither I<goto> nor I<from> are given, B<fripost-searchalias> list
+all existing virtual aliases.
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<--server_host=>I<host>
+
+The LDAP URI to connect to.
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--bind_dn=>I<binddn>
+
+The Distinguished Name (DN) to bind to the LDAP directory.
+(If not set, B<fripost-searchalias> binds anonymously.)
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--bind_pw=>I<password>
+
+The password to to bind with.
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--base_dn=>I<basedn>
+
+The root DN for everything done by B<fripost-searchalias>.
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--debug>
+
+Debug mode.
+
+=back
+
+=head1 CONFIGURATION
+
+The configuration is read from the file C<$HOME/.fripost.yml>.
+Valid keys include:
+
+=over 4
+
+=item I<server_host>
+
+The LDAP URI to connect to. Defaults to C<ldap://127.0.0.1:389>.
+
+=item I<bind_dn>
+
+The Distinguished Name (DN) to bind to the LDAP directory.
+(If not set, B<fripost-searchalias> binds anonymously.)
+
+=item I<bind_pw>
+
+The password to to bind with.
+
+=item I<base_dn>
+
+The root DN for everything done by B<fripost-searchalias>.
+
+=back
+
+=cut
+
+use FindBin qw($Bin);
+use lib "$Bin/lib";
+
+use Env qw /HOME/;
+use File::Spec::Functions;
+
+use Fripost::Schema;
+use Getopt::Long qw /:config noauto_abbrev no_ignore_case
+ gnu_compat bundling permute nogetopt_compat
+ auto_version auto_help/;
+use Pod::Usage;
+use YAML::Syck;
+
+
+## Get command line options
+our $conf = LoadFile( catfile ($HOME, '.fripost.yml') );
+
+GetOptions(
+ 'server_host=s' => \$conf->{server_host},
+ 'base_dn=s' => \$conf->{base_dn},
+ 'bind_dn=s' => \$conf->{bind_dn},
+ 'bind_pw=s' => \$conf->{bind_pw},
+ 'pretend' => \$conf->{pretend},
+ 'debug' => \$conf->{debug},
+ 'man' => sub { pod2usage(-exitstatus => 0,
+ -verbose => 2) }
+) or pod2usage(2);
+
+
+# Connect to the LDAP server
+my $ldap = Fripost::Schema->new( $conf );
+
+my %alias;
+$alias{goto} = $ARGV[0] if defined $ARGV[0];
+$alias{address} = $ARGV[1] if defined $ARGV[1];
+
+foreach my $alias ($ldap->alias->search( \%alias )->entries) {
+ say "From: " . (join ', ', @{$alias->{address}});
+ say "Goto: " . $alias->{goto};
+ say "IsActive: " . $alias->{isActive};
+ say "--------------------------------"
+}
+
+$ldap->unbind();
+
+
+=head1 AUTHOR
+
+Guilhem Moulin C<< <guilhem at fripost.org> >>
+
+=head1 COPYRIGHT
+
+Copyright 2012 Guilhem Moulin.
+
+=head1 LICENSE
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as perl itself.
+
+=cut
diff --git a/fripost-searchdomain b/fripost-searchdomain
new file mode 100755
index 0000000..bbd59a3
--- /dev/null
+++ b/fripost-searchdomain
@@ -0,0 +1,153 @@
+#!/usr/bin/perl
+
+use 5.010_000;
+use strict;
+use warnings;
+use utf8;
+
+=head1 NAME
+
+fripost-searchdomain - List matching domains
+
+=head1 SYNOPSIS
+
+B<fripost-searchdomain> [B<--debug>] [I<domain> [I<owner>]]
+
+=head1 DESCRIPTION
+
+B<fripost-seardomain> list virtual domains matching exactly I<domain>,
+and whose owner is I<owner>.
+Wildcards I<*> can appear in I<domain> or I<owner>, to match zero or more
+characters.
+If no I<owner> is given, list all domains I<domain>, regardless of the
+owner; If I<owner> is the empty string I<''>, list only the non
+self-managed domains.
+If neither I<domain> nor I<owner> are given, B<fripost-searchdomain> list
+all existing virtual domains.
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<--server_host=>I<host>
+
+The LDAP URI to connect to.
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--bind_dn=>I<binddn>
+
+The Distinguished Name (DN) to bind to the LDAP directory.
+(If not set, B<fripost-searchdomain> binds anonymously.)
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--bind_pw=>I<password>
+
+The password to to bind with.
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--base_dn=>I<basedn>
+
+The root DN for everything done by B<fripost-searchdomain>.
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--debug>
+
+Debug mode.
+
+=back
+
+=head1 CONFIGURATION
+
+The configuration is read from the file C<$HOME/.fripost.yml>.
+Valid keys include:
+
+=over 4
+
+=item I<server_host>
+
+The LDAP URI to connect to. Defaults to C<ldap://127.0.0.1:389>.
+
+=item I<bind_dn>
+
+The Distinguished Name (DN) to bind to the LDAP directory.
+(If not set, B<fripost-searchdomain> binds anonymously.)
+
+=item I<bind_pw>
+
+The password to to bind with.
+
+=item I<base_dn>
+
+The root DN for everything done by B<fripost-searchdomain>.
+
+=back
+
+=cut
+
+use FindBin qw($Bin);
+use lib "$Bin/lib";
+
+use Env qw /HOME/;
+use File::Spec::Functions;
+
+use Fripost::Schema;
+use Getopt::Long qw /:config noauto_abbrev no_ignore_case
+ gnu_compat bundling permute nogetopt_compat
+ auto_version auto_help/;
+use Pod::Usage;
+use YAML::Syck;
+
+
+## Get command line options
+our $conf = LoadFile( catfile ($HOME, '.fripost.yml') );
+
+GetOptions(
+ 'server_host=s' => \$conf->{server_host},
+ 'base_dn=s' => \$conf->{base_dn},
+ 'bind_dn=s' => \$conf->{bind_dn},
+ 'bind_pw=s' => \$conf->{bind_pw},
+ 'pretend' => \$conf->{pretend},
+ 'debug' => \$conf->{debug},
+ 'man' => sub { pod2usage(-exitstatus => 0,
+ -verbose => 2) }
+) or pod2usage(2);
+
+
+# Connect to the LDAP server
+my $ldap = Fripost::Schema->new( $conf );
+
+my %domain;
+$domain{domain} = $ARGV[0] if defined $ARGV[0];
+$domain{owner} = $ARGV[1] if defined $ARGV[1];
+
+foreach my $domain ($ldap->domain->search( \%domain )->entries) {
+ say "Domain: " . $domain->{domain};
+ print "Owner: ";
+ my $owners = $domain->{owner};
+ if (defined $owners) {
+ say (join ', ', @$owners);
+ }
+ else {
+ say "(none)";
+ }
+ say "IsActive: " . $domain->{isActive};
+ say "--------------------------------"
+}
+
+$ldap->unbind();
+
+
+=head1 AUTHOR
+
+Guilhem Moulin C<< <guilhem at fripost.org> >>
+
+=head1 COPYRIGHT
+
+Copyright 2012 Guilhem Moulin.
+
+=head1 LICENSE
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as perl itself.
+
+=cut
diff --git a/fripost-searchuser b/fripost-searchuser
new file mode 100755
index 0000000..30df331
--- /dev/null
+++ b/fripost-searchuser
@@ -0,0 +1,140 @@
+#!/usr/bin/perl
+
+use 5.010_000;
+use strict;
+use warnings;
+use utf8;
+
+=head1 NAME
+
+fripost-searchuser - List matching users
+
+=head1 SYNOPSIS
+
+B<fripost-searchuser> [B<--debug>] [I<username>]
+
+=head1 DESCRIPTION
+
+B<fripost-searchuser> list virtual mailboxes whose username exactly matches
+I<username>.
+Wildcards I<*> can appear in I<username>, to match zero or more characters.
+If no I<username> is given, B<fripost-searchuser> list all existing mailboxes.
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<--server_host=>I<host>
+
+The LDAP URI to connect to.
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--bind_dn=>I<binddn>
+
+The Distinguished Name (DN) to bind to the LDAP directory.
+(If not set, B<fripost-searchuser> binds anonymously.)
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--bind_pw=>I<password>
+
+The password to to bind with.
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--base_dn=>I<basedn>
+
+The root DN for everything done by B<fripost-searchuser>.
+The default value is read from the configuration file, see B<CONFIGURATION>.
+
+=item B<--debug>
+
+Debug mode.
+
+=back
+
+=head1 CONFIGURATION
+
+The configuration is read from the file C<$HOME/.fripost.yml>.
+Valid keys include:
+
+=over 4
+
+=item I<server_host>
+
+The LDAP URI to connect to. Defaults to C<ldap://127.0.0.1:389>.
+
+=item I<bind_dn>
+
+The Distinguished Name (DN) to bind to the LDAP directory.
+(If not set, B<fripost-searchuser> binds anonymously.)
+
+=item I<bind_pw>
+
+The password to to bind with.
+
+=item I<base_dn>
+
+The root DN for everything done by B<fripost-searchuser>.
+
+=back
+
+=cut
+
+use FindBin qw($Bin);
+use lib "$Bin/lib";
+
+use Env qw /HOME/;
+use File::Spec::Functions;
+
+use Fripost::Schema;
+use Getopt::Long qw /:config noauto_abbrev no_ignore_case
+ gnu_compat bundling permute nogetopt_compat
+ auto_version auto_help/;
+use Pod::Usage;
+use YAML::Syck;
+
+
+## Get command line options
+our $conf = LoadFile( catfile ($HOME, '.fripost.yml') );
+
+GetOptions(
+ 'server_host=s' => \$conf->{server_host},
+ 'base_dn=s' => \$conf->{base_dn},
+ 'bind_dn=s' => \$conf->{bind_dn},
+ 'bind_pw=s' => \$conf->{bind_pw},
+ 'pretend' => \$conf->{pretend},
+ 'debug' => \$conf->{debug},
+ 'man' => sub { pod2usage(-exitstatus => 0,
+ -verbose => 2) }
+) or pod2usage(2);
+
+
+# Connect to the LDAP server
+my $ldap = Fripost::Schema->new( $conf );
+
+my %user;
+$user{username} = $ARGV[0] if defined $ARGV[0];
+
+foreach my $user ($ldap->user->search( \%user )->entries) {
+ say "User: " . $user->{username};
+ say "Maildir: " . $user->{maildir};
+ say "IsActive: " . $user->{isActive};
+ say "--------------------------------"
+}
+
+$ldap->unbind();
+
+
+=head1 AUTHOR
+
+Guilhem Moulin C<< <guilhem at fripost.org> >>
+
+=head1 COPYRIGHT
+
+Copyright 2012 Guilhem Moulin.
+
+=head1 LICENSE
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as perl itself.
+
+=cut
diff --git a/lib/Fripost/Schema/Search.pm b/lib/Fripost/Schema/Search.pm
index 7c0ece6..3dc2efa 100644
--- a/lib/Fripost/Schema/Search.pm
+++ b/lib/Fripost/Schema/Search.pm
@@ -53,6 +53,12 @@ sub _domainEntry {
&_get_values( $entry, \%domain, 'domain', 'dc');
map { &_get_values($entry, \%domain, $_) }
qw /isActive owner/;
+ if (defined $domain{owner}) {
+ $domain{owner} = [ $domain{owner} ]
+ unless (ref $domain{owner}) eq 'ARRAY';
+ $domain{owner} = [ map { (split /=/, (split /,/, $_, 2)[0], 2)[1] }
+ @{$domain{owner}} ];
+ }
return \%domain;
}
@@ -60,6 +66,10 @@ sub _aliasEntry {
my $entry = shift;
my %alias;
&_get_values( $entry, \%alias, 'address', 'mailLocalAddress');
+ if (defined $alias{address}) {
+ $alias{address} = [ $alias{address} ]
+ unless (ref $alias{address}) eq 'ARRAY';
+ }
&_get_values( $entry, \%alias, 'goto', 'mailTarget');
&_get_values( $entry, \%alias, 'isActive');
return \%alias;
diff --git a/lib/Fripost/Schema/Type/Domain.pm b/lib/Fripost/Schema/Type/Domain.pm
index f85ea87..0d2be17 100644
--- a/lib/Fripost/Schema/Type/Domain.pm
+++ b/lib/Fripost/Schema/Type/Domain.pm
@@ -14,6 +14,8 @@ our $VERSION = '0.01';
# domain is given, returns all domains.
# Filters on values of both keys `domain' and `owner' (unless they are
# undefined).
+# If `owner' is the empty string, serch for non self-managed domains
+# only.
sub search {
my $self = shift;
@@ -26,7 +28,14 @@ sub search {
my @filters = ('(ObjectClass=virtualDomain)');
push @filters, "(dc=" .$_[0]->{domain}. ")" if defined $_[0]->{domain};
- push @filters, "(owner=" .$owner. ")" if defined $_[0]->{owner};
+ if (defined $_[0]->{owner}) {
+ if ($_[0]->{owner} eq '') {
+ push @filters, "(!(owner=*))";
+ }
+ else {
+ push @filters, "(owner=" .$owner. ")";
+ }
+ }
my $filter;
if ($#filters == 0) {
$filter = $filters[0];