1 package FS::part_export::vpopmail;
3 use vars qw(@ISA @saltset $exportdir $rsync $ssh);
5 use FS::UID qw( datasrc );
8 @ISA = qw(FS::part_export);
10 @saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
15 sub rebless { shift; }
18 my($self, $svc_acct) = (shift, shift);
19 $self->vpopmail_queue( $svc_acct->svcnum, 'insert',
21 crypt($svc_acct->_password,$saltset[int(rand(64))].$saltset[int(rand(64))]),
28 my( $self, $new, $old ) = (shift, shift, shift);
30 my $cpassword = crypt(
31 $new->_password, $saltset[int(rand(64))].$saltset[int(rand(64))]
34 return "can't change username with vpopmail"
35 if $old->username ne $new->username;
37 #no.... if mail can't be preserved, better to disallow username changes
38 #if ($old->username ne $new->username || $old->domain ne $new->domain ) {
39 # vpopmail_queue( $svc_acct->svcnum, 'delete',
40 # $old->username, $old->domain
42 # vpopmail_queue( $svc_acct->svcnum, 'insert',
48 return '' unless $old->_password ne $new->_password;
50 $self->vpopmail_queue( $new->svcnum, 'replace',
51 $new->username, $cpassword, $new->domain, $new->quota );
55 my( $self, $svc_acct ) = (shift, shift);
56 $self->vpopmail_queue( $svc_acct->svcnum, 'delete',
57 $svc_acct->username, $svc_acct->domain );
60 #a good idea to queue anything that could fail or take any time
62 my( $self, $svcnum, $method ) = (shift, shift, shift);
63 my $exportdir = "/usr/local/etc/freeside/export." . datasrc;
64 my $queue = new FS::queue {
66 'job' => "FS::part_export::vpopmail::vpopmail_$method",
78 sub vpopmail_insert { #subroutine, not method
79 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
80 my( $username, $password, $domain, $quota ) = @_;
82 (open(VPASSWD, ">>$exportdir/domains/$domain/vpasswd")
83 and flock(VPASSWD,LOCK_EX)
84 ) or die "can't open vpasswd file for $username\@$domain: ".
85 "$exportdir/domains/$domain/vpasswd: $!";
86 print VPASSWD join(":",
92 "$dir/domains/$domain/$username",
93 $quota ? $quota.'S' : 'NOQUOTA',
96 flock(VPASSWD,LOCK_UN);
100 map { "$exportdir/domains/$domain/$username$_" }
101 ( '', qw( /Maildir /Maildir/cur /Maildir/new /Maildir/tmp ) )
103 mkdir $mkdir, 0700 or die "can't mkdir $mkdir: $!";
106 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
110 sub vpopmail_replace { #subroutine, not method
111 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
112 my( $username, $password, $domain ) = @_;
114 (open(VPASSWD, "$exportdir/domains/$domain/vpasswd")
115 and flock(VPASSWD,LOCK_EX)
116 ) or die "can't open $exportdir/domains/$domain/vpasswd: $!";
118 open(VPASSWDTMP, ">$exportdir/domains/$domain/vpasswd.tmp")
119 or die "Can't open $exportdir/domains/$domain/vpasswd.tmp: $!";
122 my ($mailbox, $pw, $vuid, $vgid, $vfinger, $vdir, $vquota, @rest) =
124 if ( $username ne $mailbox ) {
128 print VPASSWDTMP join (':',
135 $quota ? $quota.'S' : 'NOQUOTA',
141 rename "$exportdir/domains/$domain/vpasswd.tmp", "$exportdir/domains/$domain/vpasswd"
142 or die "Can't rename $exportdir/domains/$domain/vpasswd.tmp: $!";
144 flock(VPASSWD,LOCK_UN);
147 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
151 sub vpopmail_delete { #subroutine, not method
152 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
153 my( $username, $domain ) = @_;
155 (open(VPASSWD, "$exportdir/domains/$domain/vpasswd")
156 and flock(VPASSWD,LOCK_EX)
157 ) or die "can't open $exportdir/domains/$domain/vpasswd: $!";
159 open(VPASSWDTMP, ">$exportdir/domains/$domain/vpasswd.tmp")
160 or die "Can't open $exportdir/domains/$domain/vpasswd.tmp: $!";
163 my ($mailbox, $rest) = split(':', $_);
164 print VPASSWDTMP $_ unless $username eq $mailbox;
169 rename "$exportdir/domains/$domain/vpasswd.tmp",
170 "$exportdir/domains/$domain/vpasswd"
171 or die "Can't rename $exportdir/domains/$domain/vpasswd.tmp: $!";
173 flock(VPASSWD,LOCK_UN);
176 rmtree "$exportdir/domains/$domain/$username"
177 or die "can't rmtree $exportdir/domains/$domain/$username: $!";
179 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
183 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
186 # my @args = ( $rsync, "-rlpt", "-e", $ssh, "domains/",
187 # "vpopmail\@$machine:$dir/domains/" );
188 # system {$args[0]} @args;
190 eval "use File::Rsync;";
193 my $rsync = File::Rsync->new({ rsh => 'ssh' });
199 src => "$exportdir/domains/",
200 dest => "vpopmail\@$machine:$dir/domains/",
201 } ); # true/false return value from exec is not working, alas
203 die "error uploading to vpopmail\@$machine:$dir/domains/ : ".
204 'exit status: '. $rsync->status. ', '.
205 'STDERR: '. join(" / ", $rsync->err). ', '.
206 'STDOUT: '. join(" / ", $rsync->out);