$username_noperiod $username_uppercase
$shellmachine $useradd $usermod $userdel $mydomain
$cyrus_server $cyrus_admin_user $cyrus_admin_pass
+ $cp_server $cp_user $cp_pass $cp_workgroup
$dirhash
$icradius_dbh
@saltset @pw_set);
$cyrus_admin_user = '';
$cyrus_admin_pass = '';
}
- if ( $conf->exists('icradius_secrets') ) {
- $icradius_dbh = DBI->connect($conf->config('icradius_secrets'))
- or die $DBI::errstr;
+ if ( $conf->exists('cp_app') ) {
+ ($cp_server, $cp_user, $cp_pass, $cp_workgroup) =
+ $conf->config('cp_app');
+ eval "use Net::APP;"
+ } else {
+ $cp_server = '';
+ $cp_user = '';
+ $cp_pass = '';
+ $cp_workgroup = '';
+ }
+ if ( $conf->exists('icradiusmachines') ) {
+ if ( $conf->exists('icradius_secrets') ) {
+ #need some sort of late binding so it's only connected to when
+ # actually used, hmm
+ $icradius_dbh = DBI->connect($conf->config('icradius_secrets'))
+ or die $DBI::errstr;
+ } else {
+ $icradius_dbh = dbh;
+ }
} else {
$icradius_dbh = '';
}
%hash = $record->radius_check;
+ $domain = $record->domain;
+
+ $svc_domain = $record->svc_domain;
+
+ $email = $record->email;
+
+ $seconds_since = $record->seconds_since($timestamp);
+
=head1 DESCRIPTION
An FS::svc_acct object represents an account. FS::svc_acct inherits from
$self->shell,
);
if ( $username && $uid && $dir && $shellmachine && ! $nossh_hack ) {
- my $queue = new FS::queue { 'job' => 'FS::svc_acct::ssh' };
+ my $queue = new FS::queue {
+ 'svcnum' => $self->svcnum,
+ 'job' => 'Net::SSH::ssh_cmd',
+ };
$error = $queue->insert("root\@$shellmachine", eval qq("$useradd") );
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
}
if ( $cyrus_server ) {
- my $queue = new FS::queue { 'job' => 'FS::svc_acct::cyrus_insert' };
+ my $queue = new FS::queue {
+ 'svcnum' => $self->svcnum,
+ 'job' => 'FS::svc_acct::cyrus_insert',
+ };
$error = $queue->insert($self->username, $self->quota);
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return "queueing job (transaction rolled back): $error";
}
}
+
+ if ( $cp_server ) {
+ my $queue = new FS::queue {
+ 'svcnum' => $self->svcnum,
+ 'job' => 'FS::svc_acct::cp_insert'
+ };
+ $error = $queue->insert($self->username, $self->_password);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
+ }
+
if ( $icradius_dbh ) {
- my $queue = new FS::queue { 'job' => 'FS::svc_acct::icradius_rc_insert' };
- $error = $queue->insert( $self->username,
- $self->_password,
- $self->radius_check
- );
+
+ my $radcheck_queue =
+ new FS::queue {
+ 'svcnum' => $self->svcnum,
+ 'job' => 'FS::svc_acct::icradius_rc_insert'
+ };
+ $error = $radcheck_queue->insert( $self->username,
+ $self->_password,
+ $self->radius_check
+ );
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return "queueing job (transaction rolled back): $error";
}
+
+ my $radreply_queue =
+ new FS::queue {
+ 'svcnum' => $self->svcnum,
+ 'job' => 'FS::svc_acct::icradius_rr_insert'
+ };
+ $error = $radreply_queue->insert( $self->username,
+ $self->_password,
+ $self->radius_reply
+ );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
+
}
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
1;
}
+sub cp_insert {
+ my( $username, $password ) = @_;
+
+ my $app = new Net::APP ( $cp_server,
+ User => $cp_user,
+ Password => $cp_pass,
+ Domain => $mydomain,
+ Timeout => 60,
+ #Debug => 1,
+ ) or die $@;
+
+ $app->create_mailbox(
+ Mailbox => $username,
+ Password => $password,
+ Workgroup => $cp_workgroup,
+ Domain => $mydomain,
+ );
+
+ die $app->message unless $app->ok;
+}
+
sub icradius_rc_insert {
my( $username, $password, %radcheck ) = @_;
1;
}
+sub icradius_rr_insert {
+ my( $username, $password, %radreply ) = @_;
+
+ foreach my $attribute ( keys %radreply ) {
+ my $sth = $icradius_dbh->prepare(
+ "INSERT INTO radreply ( id, UserName, Attribute, Value ) VALUES ( ".
+ join(", ", map { $icradius_dbh->quote($_) } (
+ '',
+ $username,
+ $attribute,
+ $radreply{$attribute},
+ ) ). " )"
+ );
+ $sth->execute or die "can't insert into radreply table: ". $sth->errstr;
+ }
+
+ 1;
+}
+
=item delete
Deletes this account from the database. If there is an error, returns the
$self->dir,
);
if ( $username && $shellmachine && ! $nossh_hack ) {
- my $queue = new FS::queue { 'job' => 'FS::svc_acct::ssh' };
+ my $queue = new FS::queue { 'job' => 'Net::SSH::ssh_cmd' };
$error = $queue->insert("root\@$shellmachine", eval qq("$userdel") );
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return "queueing job (transaction rolled back): $error";
}
}
+
+ if ( $cp_server ) {
+ my $queue = new FS::queue { 'job' => 'FS::svc_acct::cp_delete' };
+ $error = $queue->insert($self->username);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
+ }
+
if ( $icradius_dbh ) {
- my $queue = new FS::queue { 'job' => 'FS::svc_acct::icradius_rc_delete' };
- $error = $queue->insert( $self->username );
+
+ my $radcheck_queue =
+ new FS::queue { 'job' => 'FS::svc_acct::icradius_rc_delete' };
+ $error = $radcheck_queue->insert( $self->username );
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return "queueing job (transaction rolled back): $error";
}
+
+ my $radreply_queue =
+ new FS::queue { 'job' => 'FS::svc_acct::icradius_rr_delete' };
+ $error = $radreply_queue->insert( $self->username );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
+
}
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
1;
}
+sub cp_delete {
+ my( $username ) = @_;
+ my $app = new Net::APP ( $cp_server,
+ User => $cp_user,
+ Password => $cp_pass,
+ Domain => $mydomain,
+ Timeout => 60,
+ #Debug => 1,
+ ) or die $@;
+
+ $app->delete_mailbox(
+ Mailbox => $username,
+ Domain => $mydomain,
+ );
+
+ die $app->message unless $app->ok;
+}
+
sub icradius_rc_delete {
my $username = shift;
1;
}
+sub icradius_rr_delete {
+ my $username = shift;
+
+ my $sth = $icradius_dbh->prepare(
+ 'DELETE FROM radreply WHERE UserName = ?'
+ );
+ $sth->execute($username)
+ or die "can't delete from radreply table: ". $sth->errstr;
+
+ 1;
+}
+
=item replace OLD_RECORD
Replaces OLD_RECORD with this one in the database. If there is an error,
$new->getfield('gid'),
);
if ( $old_dir && $new_dir && $old_dir ne $new_dir && ! $nossh_hack ) {
- my $queue = new FS::queue { 'job' => 'FS::svc_acct::ssh' };
+ my $queue = new FS::queue {
+ 'svcnum' => $new->svcnum,
+ 'job' => 'Net::SSH::ssh_cmd'
+ };
$error = $queue->insert("root\@$shellmachine", eval qq("$usermod") );
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
}
}
+ if ( $cp_server && $old->username ne $new->username ) {
+ my $queue = new FS::queue {
+ 'svcnum' => $new->svcnum,
+ 'job' => 'FS::svc_acct::cp_rename'
+ };
+ $error = $queue->insert( $old->username, $new->username );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
+ }
+
+ if ( $cp_server && $old->_password ne $new->_password ) {
+ my $queue = new FS::queue {
+ 'svcnum' => $new->svcnum,
+ 'job' => 'FS::svc_acct::cp_change'
+ };
+ $error = $queue->insert( $new->username, $new->_password );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
+ }
+
if ( $icradius_dbh ) {
- my $queue = new FS::queue { 'job' => 'FS::svc_acct::icradius_rc_replace' };
+ my $queue = new FS::queue {
+ 'svcnum' => $new->svcnum,
+ 'job' => 'FS::svc_acct::icradius_rc_replace'
+ };
$error = $queue->insert( $new->username,
$new->_password,
);
1;
}
+sub cp_rename {
+ my ( $old_username, $new_username ) = @_;
+
+ my $app = new Net::APP ( $cp_server,
+ User => $cp_user,
+ Password => $cp_pass,
+ Domain => $mydomain,
+ Timeout => 60,
+ #Debug => 1,
+ ) or die $@;
+
+ $app->rename_mailbox(
+ Domain => $mydomain,
+ Old_Mailbox => $old_username,
+ New_Mailbox => $new_username,
+ );
+
+ die $app->message unless $app->ok;
+
+}
+
+sub cp_change {
+ my ( $username, $password ) = @_;
+
+ my $app = new Net::APP ( $cp_server,
+ User => $cp_user,
+ Password => $cp_pass,
+ Domain => $mydomain,
+ Timeout => 60,
+ #Debug => 1,
+ ) or die $@;
+
+ $app->change_mailbox(
+ Domain => $mydomain,
+ Mailbox => $username,
+ Password => $password,
+ );
+
+ die $app->message unless $app->ok;
+
+}
+
=item suspend
Suspends this account by prefixing *SUSPENDED* to the password. If there is an
sub radius_reply {
my $self = shift;
- map {
- /^(radius_(.*))$/;
- my($column, $attrib) = ($1, $2);
- #$attrib =~ s/_/\-/g;
- ( $FS::raddb::attrib{lc($attrib)}, $self->getfield($column) );
- } grep { /^radius_/ && $self->getfield($_) } fields( $self->table );
+ my %reply =
+ map {
+ /^(radius_(.*))$/;
+ my($column, $attrib) = ($1, $2);
+ #$attrib =~ s/_/\-/g;
+ ( $FS::raddb::attrib{lc($attrib)}, $self->getfield($column) );
+ } grep { /^radius_/ && $self->getfield($_) } fields( $self->table );
+ if ( $self->ip && $self->ip ne '0e0' ) {
+ $reply{'Framed-IP-Address'} = $self->ip;
+ }
+ %reply;
}
=item radius_check
: qsearchs( 'svc_domain', { 'svcnum' => $self->domsvc } );
}
+=item cust_svc
+
+Returns the FS::cust_svc record for this account (see L<FS::cust_svc>).
+
+sub cust_svc {
+ my $self = shift;
+ qsearchs( 'cust_svc', { 'svcnum' => $self->svcnum } );
+}
+
=item email
Returns an email address associated with the account.
$self->username. '@'. $self->domain;
}
-=item ssh
+=item seconds_since TIMESTAMP
-=cut
+Returns the number of seconds this account has been online since TIMESTAMP.
+See L<FS::session>
-sub ssh {
- my ( $host, @cmd_and_args ) = @_;
+TIMESTAMP is specified as a UNIX timestamp; see L<perlfunc/"time">. Also see
+L<Time::Local> and L<Date::Parse> for conversion functions.
- use IO::File;
- my $reader = IO::File->new();
- my $writer = IO::File->new();
- my $error = IO::File->new();
-
- &Net::SSH::sshopen3( $host, $reader, $writer, $error, @cmd_and_args) or die $!;
-
- local $/ = undef;
- my $output_stream = <$writer>;
- my $error_stream = <$error>;
- if ( length $error_stream ) {
- #warn "[FS::svc_acct::ssh] STDERR $error_stream";
- die "[FS::svc_acct::ssh] STDERR $error_stream";
- }
- if ( length $output_stream ) {
- warn "[FS::svc_acct::ssh] STDOUT $output_stream";
- }
+=cut
-# &Net::SSH::ssh(@args,">>/usr/local/etc/freeside/sshoutput 2>&1");
+#note: POD here, implementation in FS::cust_svc
+sub seconds_since {
+ my $self = shift;
+ $self->cust_svc->seconds_since(@_);
}
=back
-=head1 VERSION
-
-$Id: svc_acct.pm,v 1.60 2001-12-20 02:09:52 ivan Exp $
-
=head1 BUGS
-The bits which ssh should fork before doing so (or maybe queue jobs for a
-daemon).
-
The $recref stuff in sub check should be cleaned up.
The suspend, unsuspend and cancel methods update the database, but not the
=head1 SEE ALSO
-L<FS::svc_Common>, L<FS::Record>, L<FS::Conf>, L<FS::cust_svc>,
-L<FS::part_svc>, L<FS::cust_pkg>, L<FS::queue>, L<freeside-queued>),
-L<Net::SSH>, L<ssh>, L<FS::svc_acct_pop>,
+L<FS::svc_Common>, edit/part_svc.cgi from an installed web interface,
+export.html from the base documentation, L<FS::Record>, L<FS::Conf>,
+L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>, L<FS::queue>,
+L<freeside-queued>), L<Net::SSH>, L<ssh>, L<FS::svc_acct_pop>,
schema.html from the base documentation.
=cut