1 package FS::part_export::textradius;
3 use vars qw(@ISA $prefix);
5 use FS::UID qw(datasrc);
8 @ISA = qw(FS::part_export);
10 $prefix = "/usr/local/etc/freeside/export.";
12 sub rebless { shift; }
15 my($self, $svc_acct) = (shift, shift);
16 $err_or_queue = $self->textradius_queue( $svc_acct->svcnum, 'insert',
17 $svc_acct->username, $svc_acct->radius_check, '-', $svc_acct->radius_reply);
18 ref($err_or_queue) ? '' : $err_or_queue;
22 my( $self, $new, $old ) = (shift, shift, shift);
23 return "can't (yet?) change username with textradius"
24 if $old->username ne $new->username;
25 #return '' unless $old->_password ne $new->_password;
26 $err_or_queue = $self->textradius_queue( $new->svcnum, 'insert',
27 $new->username, $new->radius_check, '-', $new->radius_reply);
28 ref($err_or_queue) ? '' : $err_or_queue;
32 my( $self, $svc_acct ) = (shift, shift);
33 $err_or_queue = $self->textradius_queue( $svc_acct->svcnum, 'delete',
34 $svc_acct->username );
35 ref($err_or_queue) ? '' : $err_or_queue;
38 #a good idea to queue anything that could fail or take any time
39 sub textradius_queue {
40 my( $self, $svcnum, $method ) = (shift, shift, shift);
41 my $queue = new FS::queue {
43 'job' => "FS::part_export::textradius::textradius_$method",
46 $self->option('user')||'root',
48 $self->option('users'),
53 sub textradius_insert { #subroutine, not method
54 my( $user, $host, $users, $username, @attributes ) = @_;
58 push @check, $att while @attributes && ($att=shift @attributes) ne '-';
60 my %reply = @attributes;
62 my $file = textradius_download($user, $host, $users);
64 eval "use RADIUS::UserFile;";
67 my $userfile = new RADIUS::UserFile(
70 Check_Items => [ keys %check ],
71 ) or die "error parsing $file";
73 $userfile->remove($username);
76 Attributes => { %check, %reply },
77 Comment => 'user added by Freeside',
78 ) or die "error adding to $file";
80 $userfile->update( Who => [ $username ] )
81 or die "error updating $file";
83 textradius_upload($user, $host, $users);
87 sub textradius_delete { #subroutine, not method
88 my( $user, $host, $users, $username ) = @_;
90 my $file = textradius_download($user, $host, $users);
92 eval "use RADIUS::UserFile;";
95 my $userfile = new RADIUS::UserFile(
98 ) or die "error parsing $file";
100 $userfile->remove($username);
102 $userfile->update( Who => [ $username ] )
103 or die "error updating $file";
105 textradius_upload($user, $host, $users);
108 sub textradius_download {
109 my( $user, $host, $users ) = @_;
111 my $dir = $prefix. datasrc;
112 mkdir $dir, 0700 or die $! unless -d $dir;
114 mkdir $dir, 0700 or die $! unless -d $dir;
116 my $dest = "$dir/users";
118 eval "use File::Rsync;";
120 my $rsync = File::Rsync->new({ rsh => 'ssh' });
122 open(LOCK, "+>>$dest.lock")
123 and flock(LOCK,LOCK_EX)
124 or die "can't open $dest.lock: $!";
127 src => "$user\@$host:$users",
129 } ); # true/false return value from exec is not working, alas
131 die "error downloading $user\@$host:$users : ".
132 'exit status: '. $rsync->status. ', '.
133 'STDERR: '. join(" / ", $rsync->err). ', '.
134 'STDOUT: '. join(" / ", $rsync->out);
140 sub textradius_upload {
141 my( $user, $host, $users ) = @_;
143 my $dir = $prefix. datasrc. "/$host";
145 eval "use File::Rsync;";
147 my $rsync = File::Rsync->new({
153 dest => "$user\@$host:$users",
154 } ); # true/false return value from exec is not working, alas
156 die "error uploading to $user\@$host:$users : ".
157 'exit status: '. $rsync->status. ', '.
158 'STDERR: '. join(" / ", $rsync->err). ', '.
159 'STDOUT: '. join(" / ", $rsync->out);