You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

180 lines
6.0 KiB

#!@l_prefix@/bin/perl
##
## dbmail-folders -- DBMail Folders Creation Utility
## Copyright (c) 2007-2008 Ralf S. Engelschall <rse@engelschall.com>
##
## See also:
## http://www.dbmail.org/dokuwiki/doku.php?id=shared-mbox
## http://library.mobrien.com/dbmailadministrator/DBMA_ACLs.htm
##
# language requirements
require 5.008;
use strict;
use warnings;
# load extensions
use Getopt::Long;
use DBI;
use DBD::Pg;
use DBIx::Simple;
# command line argument parsing
my $opt = {
-help => 0,
-hostname => ($ENV{"PGHOST"} || "localhost"),
-database => ($ENV{"PGDATABASE"} || "dbmail" ),
-username => ($ENV{"PGUSER"} || "dbmail" ),
-password => ($ENV{"PGPASSWORD"} || "dbmail" ),
};
my $p = new Getopt::Long::Parser;
$p->configure("bundling");
$p->getoptions(
'h|help' => \$opt->{-help},
'H|hostname=s' => \$opt->{-hostname},
'D|database=s' => \$opt->{-database},
'U|username=s' => \$opt->{-username},
'P|password=s' => \$opt->{-password},
) || die "option parsing failed";
undef $p;
if ($opt->{-help} or @ARGV < 2) {
printf(STDERR "USAGE: dbmail-folders [-h|--help]\n");
printf(STDERR " [-H|--hostname <db-hostname>] [-D|--database <db-name>]\n");
printf(STDERR " [-U|--username <db-username>] [-P|--password <db-password>]\n");
printf(STDERR " <owner> <folder> [[{ro,rw}:]<user> ...]\n");
printf(STDERR "EXAMPLES:\n");
printf(STDERR "1. # create public folder #Public/<folder> (fully shared)\n");
printf(STDERR " \$ dbmail-folders __public__ <folder> anyone\n");
printf(STDERR "2. # create personal shared folder #Users/<owner>/<folder> (fully shared)\n");
printf(STDERR " \$ dbmail-folders <owner> <folder> anyone\n");
printf(STDERR "3. # create personal shared folder #Users/<owner>/<folder> (fully shared, different access)\n");
printf(STDERR " \$ dbmail-folders <owner> <folder> ro:anyone rw:<proxy>\n");
printf(STDERR "4. # create personal shared folder #Users/<owner>/<folder> (partly shared)\n");
printf(STDERR " \$ dbmail-folders <owner> <folder> <user1> <user2> ...\n");
printf(STDERR "5. # create personal private folder #Users/<owner>/<folder> (not shared)\n");
printf(STDERR " \$ dbmail-folders <owner> <folder>\n");
exit($opt->{-help} ? 0 : 1);
}
my $owner = shift(@ARGV);
my $folder = shift(@ARGV);
my @users = @ARGV;
# connect to DBMail's PostgreSQL-based backend RDBMS
my $db = DBIx::Simple->connect(
sprintf("dbi:Pg:host=%s;dbname=%s", $opt->{-hostname}, $opt->{-database}),
$opt->{-username}, $opt->{-password},
{ RaiseError => 1, AutoCommit => 1 }
);
die "failed to connect to database"
if (not defined($db));
# ensure that the folder owner exists
my ($owner_id) = $db->query(q{
SELECT user_idnr
FROM dbmail_users
WHERE userid = ?;
}, $owner)->flat();
if (not defined $owner_id) {
printf(STDERR "dbmail-folders:ERROR: folder owner \"%s\" not existing\n", $owner);
exit(1);
}
# check whether folder already exists
my ($mailbox_id) = $db->query(q{
SELECT mailbox_idnr
FROM dbmail_mailboxes
WHERE owner_idnr = ? AND name = ?;
}, $owner_id, $folder)->flat();
if (not defined $mailbox_id) {
# create it if still not existing
$db->query(q{
INSERT
INTO dbmail_mailboxes
( owner_idnr, name,
seen_flag, answered_flag, deleted_flag, flagged_flag, recent_flag, draft_flag,
no_inferiors, no_select, permission )
VALUES ( ?, ?,
1, 1, 1, 1, 1, 1,
0, 0, 2 );
}, $owner_id, $folder)
or printf(STDERR "dbmail-folders:ERROR: unable to create folder \"%s/%s\": %s\n", $owner, $folder, $db->error()), exit(1);
($mailbox_id) = $db->query(q{
SELECT mailbox_idnr
FROM dbmail_mailboxes
WHERE owner_idnr = ? AND name = ?;
}, $owner_id, $folder)->flat();
if (not defined $mailbox_id) {
printf(STDERR "dbmail-folders:ERROR: unable to determine id of newly created folder\n");
exit(1);
}
}
# optionally grant access to folder for additional users (beside folder owner)
$db->query(q{
DELETE
FROM dbmail_acl
WHERE mailbox_id = ?;
}, $mailbox_id);
foreach my $user (@ARGV) {
my $mode = "rw";
if ($user =~ m/^(r[ow]):(.+)$/) {
$mode = $1;
$user = $2;
}
my ($user_id) = $db->query(q{
SELECT user_idnr
FROM dbmail_users
WHERE userid = ?;
}, $user)->flat();
if (not defined $user_id) {
printf(STDERR "dbmail-folders:WARNING: user \"%s\" not existing\n", $user);
next;
}
if ($mode eq "rw") {
$db->query(q{
INSERT
INTO dbmail_acl
( user_id, mailbox_id,
lookup_flag, read_flag, seen_flag, write_flag, insert_flag,
post_flag, create_flag, delete_flag, administer_flag )
VALUES ( ?, ?,
1, 1, 1, 1, 1,
1, 1, 1, 1 );
}, $user_id, $mailbox_id);
}
else {
$db->query(q{
INSERT
INTO dbmail_acl
( user_id, mailbox_id,
lookup_flag, read_flag, seen_flag, write_flag, insert_flag,
post_flag, create_flag, delete_flag, administer_flag )
VALUES ( ?, ?,
1, 1, 0, 0, 0,
0, 0, 0, 0 );
}, $user_id, $mailbox_id);
}
}
# make sure at least owner is subscribed to folder
my ($exists) = $db->query(q{
SELECT 1
FROM dbmail_subscription
WHERE user_id = ? AND mailbox_id = ?;
}, $owner_id, $mailbox_id)->flat();
if (not (defined $exists and $exists)) {
$db->query(q{
INSERT
INTO dbmail_subscription
( user_id, mailbox_id )
VALUES ( ?, ? );
}, $owner_id, $mailbox_id);
}
# disconnect from DBMail's PostgreSQL-based backend RDBMS
$db->disconnect();
undef $db;
# die gracefully
exit(0);