1 package FS::part_export::vpopmail;
3 use vars qw(@ISA @saltset $exportdir);
5 use FS::UID qw( datasrc );
8 @ISA = qw(FS::part_export);
10 @saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
12 sub rebless { shift; }
15 my($self, $svc_acct) = (shift, shift);
16 $self->vpopmail_queue( $svc_acct->svcnum, 'insert',
18 crypt($svc_acct->_password,$saltset[int(rand(64))].$saltset[int(rand(64))]),
25 my( $self, $new, $old ) = (shift, shift, shift);
27 my $cpassword = crypt(
28 $new->_password, $saltset[int(rand(64))].$saltset[int(rand(64))]
31 return "can't change username with vpopmail"
32 if $old->username ne $new->username;
34 #no.... if mail can't be preserved, better to disallow username changes
35 #if ($old->username ne $new->username || $old->domain ne $new->domain ) {
36 # vpopmail_queue( $svc_acct->svcnum, 'delete',
37 # $old->username, $old->domain
39 # vpopmail_queue( $svc_acct->svcnum, 'insert',
45 return '' unless $old->_password ne $new->_password;
47 $self->vpopmail_queue( $new->svcnum, 'replace',
48 $new->username, $cpassword, $new->domain, $new->quota );
52 my( $self, $svc_acct ) = (shift, shift);
53 $self->vpopmail_queue( $svc_acct->svcnum, 'delete',
54 $svc_acct->username, $svc_acct->domain );
57 #a good idea to queue anything that could fail or take any time
59 my( $self, $svcnum, $method ) = (shift, shift, shift);
61 my $exportdir = "/usr/local/etc/freeside/export." . datasrc;
62 mkdir $exportdir, 0700 or die $! unless -d $exportdir;
63 $exportdir .= "/vpopmail";
64 mkdir $exportdir, 0700 or die $! unless -d $exportdir;
65 $exportdir .= '/'. $self->machine;
66 mkdir $exportdir, 0700 or die $! unless -d $exportdir;
67 mkdir "$exportdir/domains", 0700 or die $! unless -d "$exportdir/domains";
69 my $queue = new FS::queue {
71 'job' => "FS::part_export::vpopmail::vpopmail_$method",
83 sub vpopmail_insert { #subroutine, not method
84 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
85 my( $username, $password, $domain, $quota ) = @_;
87 mkdir "$exportdir/domains/$domain", 0700 or die $!
88 unless -d "$exportdir/domains/$domain";
90 (open(VPASSWD, ">>$exportdir/domains/$domain/vpasswd")
91 and flock(VPASSWD,LOCK_EX)
92 ) or die "can't open vpasswd file for $username\@$domain: ".
93 "$exportdir/domains/$domain/vpasswd: $!";
94 print VPASSWD join(":",
100 "$dir/domains/$domain/$username",
101 $quota ? $quota.'S' : 'NOQUOTA',
104 flock(VPASSWD,LOCK_UN);
108 map { "$exportdir/domains/$domain/$username$_" }
109 ( '', qw( /Maildir /Maildir/cur /Maildir/new /Maildir/tmp ) )
111 mkdir $mkdir, 0700 or die "can't mkdir $mkdir: $!";
114 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
118 sub vpopmail_replace { #subroutine, not method
119 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
120 my( $username, $password, $domain ) = @_;
122 (open(VPASSWD, "$exportdir/domains/$domain/vpasswd")
123 and flock(VPASSWD,LOCK_EX)
124 ) or die "can't open $exportdir/domains/$domain/vpasswd: $!";
126 open(VPASSWDTMP, ">$exportdir/domains/$domain/vpasswd.tmp")
127 or die "Can't open $exportdir/domains/$domain/vpasswd.tmp: $!";
130 my ($mailbox, $pw, $vuid, $vgid, $vfinger, $vdir, $vquota, @rest) =
132 if ( $username ne $mailbox ) {
136 print VPASSWDTMP join (':',
143 $quota ? $quota.'S' : 'NOQUOTA',
149 rename "$exportdir/domains/$domain/vpasswd.tmp", "$exportdir/domains/$domain/vpasswd"
150 or die "Can't rename $exportdir/domains/$domain/vpasswd.tmp: $!";
152 flock(VPASSWD,LOCK_UN);
155 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
159 sub vpopmail_delete { #subroutine, not method
160 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
161 my( $username, $domain ) = @_;
163 (open(VPASSWD, "$exportdir/domains/$domain/vpasswd")
164 and flock(VPASSWD,LOCK_EX)
165 ) or die "can't open $exportdir/domains/$domain/vpasswd: $!";
167 open(VPASSWDTMP, ">$exportdir/domains/$domain/vpasswd.tmp")
168 or die "Can't open $exportdir/domains/$domain/vpasswd.tmp: $!";
171 my ($mailbox, $rest) = split(':', $_);
172 print VPASSWDTMP $_ unless $username eq $mailbox;
177 rename "$exportdir/domains/$domain/vpasswd.tmp",
178 "$exportdir/domains/$domain/vpasswd"
179 or die "Can't rename $exportdir/domains/$domain/vpasswd.tmp: $!";
181 flock(VPASSWD,LOCK_UN);
184 rmtree "$exportdir/domains/$domain/$username"
185 or die "can't rmtree $exportdir/domains/$domain/$username: $!";
187 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
191 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
194 # my @args = ( $rsync, "-rlpt", "-e", $ssh, "domains/",
195 # "vpopmail\@$machine:$dir/domains/" );
196 # system {$args[0]} @args;
198 eval "use File::Rsync;";
201 my $rsync = File::Rsync->new({ rsh => 'ssh' });
207 src => "$exportdir/domains/",
208 dest => "vpopmail\@$machine:$dir/domains/",
209 } ); # true/false return value from exec is not working, alas
211 die "error uploading to vpopmail\@$machine:$dir/domains/ : ".
212 'exit status: '. $rsync->status. ', '.
213 'STDERR: '. join(" / ", $rsync->err). ', '.
214 'STDOUT: '. join(" / ", $rsync->out);