1 package FS::part_export::vpopmail;
3 use vars qw(@ISA @saltset $exportdir);
6 use FS::UID qw( datasrc );
9 @ISA = qw(FS::part_export);
11 @saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
13 sub rebless { shift; }
16 my($self, $svc_acct) = (shift, shift);
17 $self->vpopmail_queue( $svc_acct->svcnum, 'insert',
19 crypt($svc_acct->_password,$saltset[int(rand(64))].$saltset[int(rand(64))]),
26 my( $self, $new, $old ) = (shift, shift, shift);
28 my $cpassword = crypt(
29 $new->_password, $saltset[int(rand(64))].$saltset[int(rand(64))]
32 return "can't change username with vpopmail"
33 if $old->username ne $new->username;
35 #no.... if mail can't be preserved, better to disallow username changes
36 #if ($old->username ne $new->username || $old->domain ne $new->domain ) {
37 # vpopmail_queue( $svc_acct->svcnum, 'delete',
38 # $old->username, $old->domain
40 # vpopmail_queue( $svc_acct->svcnum, 'insert',
46 return '' unless $old->_password ne $new->_password;
48 $self->vpopmail_queue( $new->svcnum, 'replace',
49 $new->username, $cpassword, $new->domain, $new->quota );
53 my( $self, $svc_acct ) = (shift, shift);
54 $self->vpopmail_queue( $svc_acct->svcnum, 'delete',
55 $svc_acct->username, $svc_acct->domain );
58 #a good idea to queue anything that could fail or take any time
60 my( $self, $svcnum, $method ) = (shift, shift, shift);
62 my $exportdir = "/usr/local/etc/freeside/export." . datasrc;
63 mkdir $exportdir, 0700 or die $! unless -d $exportdir;
64 $exportdir .= "/vpopmail";
65 mkdir $exportdir, 0700 or die $! unless -d $exportdir;
66 $exportdir .= '/'. $self->machine;
67 mkdir $exportdir, 0700 or die $! unless -d $exportdir;
68 mkdir "$exportdir/domains", 0700 or die $! unless -d "$exportdir/domains";
70 my $queue = new FS::queue {
72 'job' => "FS::part_export::vpopmail::vpopmail_$method",
84 sub vpopmail_insert { #subroutine, not method
85 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
86 my( $username, $password, $domain, $quota ) = @_;
88 mkdir "$exportdir/domains/$domain", 0700 or die $!
89 unless -d "$exportdir/domains/$domain";
91 (open(VPASSWD, ">>$exportdir/domains/$domain/vpasswd")
92 and flock(VPASSWD,LOCK_EX)
93 ) or die "can't open vpasswd file for $username\@$domain: ".
94 "$exportdir/domains/$domain/vpasswd: $!";
95 print VPASSWD join(":",
101 "$dir/domains/$domain/$username",
102 $quota ? $quota.'S' : 'NOQUOTA',
105 flock(VPASSWD,LOCK_UN);
109 grep { ! -d $_ } map { "$exportdir/domains/$domain/$username$_" }
110 ( '', qw( /Maildir /Maildir/cur /Maildir/new /Maildir/tmp ) )
112 mkdir $mkdir, 0700 or die "can't mkdir $mkdir: $!";
115 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
119 sub vpopmail_replace { #subroutine, not method
120 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
121 my( $username, $password, $domain ) = @_;
123 (open(VPASSWD, "$exportdir/domains/$domain/vpasswd")
124 and flock(VPASSWD,LOCK_EX)
125 ) or die "can't open $exportdir/domains/$domain/vpasswd: $!";
127 open(VPASSWDTMP, ">$exportdir/domains/$domain/vpasswd.tmp")
128 or die "Can't open $exportdir/domains/$domain/vpasswd.tmp: $!";
131 my ($mailbox, $pw, $vuid, $vgid, $vfinger, $vdir, $vquota, @rest) =
133 if ( $username ne $mailbox ) {
137 print VPASSWDTMP join (':',
144 $quota ? $quota.'S' : 'NOQUOTA',
150 rename "$exportdir/domains/$domain/vpasswd.tmp", "$exportdir/domains/$domain/vpasswd"
151 or die "Can't rename $exportdir/domains/$domain/vpasswd.tmp: $!";
153 flock(VPASSWD,LOCK_UN);
156 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
160 sub vpopmail_delete { #subroutine, not method
161 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
162 my( $username, $domain ) = @_;
164 (open(VPASSWD, "$exportdir/domains/$domain/vpasswd")
165 and flock(VPASSWD,LOCK_EX)
166 ) or die "can't open $exportdir/domains/$domain/vpasswd: $!";
168 open(VPASSWDTMP, ">$exportdir/domains/$domain/vpasswd.tmp")
169 or die "Can't open $exportdir/domains/$domain/vpasswd.tmp: $!";
172 my ($mailbox, $rest) = split(':', $_);
173 print VPASSWDTMP $_ unless $username eq $mailbox;
178 rename "$exportdir/domains/$domain/vpasswd.tmp",
179 "$exportdir/domains/$domain/vpasswd"
180 or die "Can't rename $exportdir/domains/$domain/vpasswd.tmp: $!";
182 flock(VPASSWD,LOCK_UN);
185 rmtree "$exportdir/domains/$domain/$username"
186 or die "can't rmtree $exportdir/domains/$domain/$username: $!";
188 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid );
192 my( $exportdir, $machine, $dir, $uid, $gid ) = splice @_,0,5;
195 # my @args = ( $rsync, "-rlpt", "-e", $ssh, "domains/",
196 # "vpopmail\@$machine:$dir/domains/" );
197 # system {$args[0]} @args;
199 eval "use File::Rsync;";
202 my $rsync = File::Rsync->new({ rsh => 'ssh' });
208 src => "$exportdir/domains/",
209 dest => "vpopmail\@$machine:$dir/domains/",
210 } ); # true/false return value from exec is not working, alas
212 die "error uploading to vpopmail\@$machine:$dir/domains/ : ".
213 'exit status: '. $rsync->status. ', '.
214 'STDERR: '. join(" / ", $rsync->err). ', '.
215 'STDOUT: '. join(" / ", $rsync->out);