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))]),
27 my( $self, $new, $old ) = (shift, shift, shift);
29 my $cpassword = crypt(
30 $new->_password, $saltset[int(rand(64))].$saltset[int(rand(64))]
33 return "can't change username with vpopmail"
34 if $old->username ne $new->username;
36 #no.... if mail can't be preserved, better to disallow username changes
37 #if ($old->username ne $new->username || $old->domain ne $new->domain ) {
38 # vpopmail_queue( $svc_acct->svcnum, 'delete',
39 # $old->username, $old->domain
41 # vpopmail_queue( $svc_acct->svcnum, 'insert',
47 return '' unless $old->_password ne $new->_password;
49 $self->vpopmail_queue( $new->svcnum, 'replace',
50 $new->username, $cpassword, $new->domain, $new->quota, $new->finger );
54 my( $self, $svc_acct ) = (shift, shift);
55 $self->vpopmail_queue( $svc_acct->svcnum, 'delete',
56 $svc_acct->username, $svc_acct->domain );
59 #a good idea to queue anything that could fail or take any time
61 my( $self, $svcnum, $method ) = (shift, shift, shift);
63 my $exportdir = "/usr/local/etc/freeside/export." . datasrc;
64 mkdir $exportdir, 0700 or die $! unless -d $exportdir;
65 $exportdir .= "/vpopmail";
66 mkdir $exportdir, 0700 or die $! unless -d $exportdir;
67 $exportdir .= '/'. $self->machine;
68 mkdir $exportdir, 0700 or die $! unless -d $exportdir;
69 mkdir "$exportdir/domains", 0700 or die $! unless -d "$exportdir/domains";
71 my $queue = new FS::queue {
73 'job' => "FS::part_export::vpopmail::vpopmail_$method",
81 $self->option('restart'),
86 sub vpopmail_insert { #subroutine, not method
87 my( $exportdir, $machine, $dir, $uid, $gid, $restart ) = splice @_,0,6;
88 my( $username, $password, $domain, $quota, $finger ) = @_;
90 mkdir "$exportdir/domains/$domain", 0700 or die $!
91 unless -d "$exportdir/domains/$domain";
93 (open(VPASSWD, ">>$exportdir/domains/$domain/vpasswd")
94 and flock(VPASSWD,LOCK_EX)
95 ) or die "can't open vpasswd file for $username\@$domain: ".
96 "$exportdir/domains/$domain/vpasswd: $!";
97 print VPASSWD join(":",
103 "$dir/domains/$domain/$username",
104 $quota ? $quota.'S' : 'NOQUOTA',
107 flock(VPASSWD,LOCK_UN);
111 grep { ! -d $_ } map { "$exportdir/domains/$domain/$username$_" }
112 ( '', qw( /Maildir /Maildir/cur /Maildir/new /Maildir/tmp ) )
114 mkdir $mkdir, 0700 or die "can't mkdir $mkdir: $!";
117 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid, $restart );
121 sub vpopmail_replace { #subroutine, not method
122 my( $exportdir, $machine, $dir, $uid, $gid, $restart ) = splice @_,0,6;
123 my( $username, $password, $domain, $quota, $finger ) = @_;
125 (open(VPASSWD, "$exportdir/domains/$domain/vpasswd")
126 and flock(VPASSWD,LOCK_EX)
127 ) or die "can't open $exportdir/domains/$domain/vpasswd: $!";
129 open(VPASSWDTMP, ">$exportdir/domains/$domain/vpasswd.tmp")
130 or die "Can't open $exportdir/domains/$domain/vpasswd.tmp: $!";
133 my ($mailbox, $pw, $vuid, $vgid, $vfinger, $vdir, $vquota, @rest) =
135 if ( $username ne $mailbox ) {
139 print VPASSWDTMP join (':',
145 "$dir/domains/$domain/$username", #$vdir
146 $quota ? $quota.'S' : 'NOQUOTA',
152 rename "$exportdir/domains/$domain/vpasswd.tmp", "$exportdir/domains/$domain/vpasswd"
153 or die "Can't rename $exportdir/domains/$domain/vpasswd.tmp: $!";
155 flock(VPASSWD,LOCK_UN);
158 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid, $restart );
162 sub vpopmail_delete { #subroutine, not method
163 my( $exportdir, $machine, $dir, $uid, $gid, $restart ) = splice @_,0,6;
164 my( $username, $domain ) = @_;
166 (open(VPASSWD, "$exportdir/domains/$domain/vpasswd")
167 and flock(VPASSWD,LOCK_EX)
168 ) or die "can't open $exportdir/domains/$domain/vpasswd: $!";
170 open(VPASSWDTMP, ">$exportdir/domains/$domain/vpasswd.tmp")
171 or die "Can't open $exportdir/domains/$domain/vpasswd.tmp: $!";
174 my ($mailbox, $rest) = split(':', $_);
175 print VPASSWDTMP $_ unless $username eq $mailbox;
180 rename "$exportdir/domains/$domain/vpasswd.tmp",
181 "$exportdir/domains/$domain/vpasswd"
182 or die "Can't rename $exportdir/domains/$domain/vpasswd.tmp: $!";
184 flock(VPASSWD,LOCK_UN);
187 rmtree "$exportdir/domains/$domain/$username"
188 or die "can't rmtree $exportdir/domains/$domain/$username: $!";
190 vpopmail_sync( $exportdir, $machine, $dir, $uid, $gid, $restart );
194 my( $exportdir, $machine, $dir, $uid, $gid, $restart ) = splice @_,0,6;
197 # my @args = ( $rsync, "-rlpt", "-e", $ssh, "domains/",
198 # "vpopmail\@$machine:$dir/domains/" );
199 # system {$args[0]} @args;
201 eval "use File::Rsync;";
204 my $rsync = File::Rsync->new({ rsh => 'ssh' });
210 src => "$exportdir/domains/",
211 dest => "vpopmail\@$machine:$dir/domains/",
212 } ); # true/false return value from exec is not working, alas
214 die "error uploading to vpopmail\@$machine:$dir/domains/ : ".
215 'exit status: '. $rsync->status. ', '.
216 'STDERR: '. join(" / ", $rsync->err). ', '.
217 'STDOUT: '. join(" / ", $rsync->out);
220 eval "use Net::SSH;";
223 ssh("vpopmail\@$machine", $restart) if $restart;