use FS::svc_acct_pop;
use FS::cust_main_invoice;
use FS::svc_domain;
+use FS::svc_pbx;
use FS::raddb;
use FS::queue;
use FS::radius_usergroup;
=over 4
-=item svcnum - primary key (assigned automatcially for new accounts)
+=item svcnum
+
+Primary key (assigned automatcially for new accounts)
=item username
-=item _password - generated if blank
+=item _password
+
+generated if blank
+
+=item _password_encoding
+
+plain, crypt, ldap (or empty for autodetection)
-=item _password_encoding - plain, crypt, ldap (or empty for autodetection)
+=item sec_phrase
-=item sec_phrase - security phrase
+security phrase
-=item popnum - Point of presence (see L<FS::svc_acct_pop>)
+=item popnum
+
+Point of presence (see L<FS::svc_acct_pop>)
=item uid
=item gid
-=item finger - GECOS
+=item finger
+
+GECOS
+
+=item dir
-=item dir - set automatically if blank (and uid is not)
+set automatically if blank (and uid is not)
=item shell
-=item quota - (unimplementd)
+=item quota
+
+=item slipip
+
+IP address
+
+=item seconds
+
+=item upbytes
+
+=item downbyte
+
+=item totalbytes
-=item slipip - IP address
+=item domsvc
-=item seconds -
+svcnum from svc_domain
-=item upbytes -
+=item pbxsvc
-=item downbytes -
+Optional svcnum from svc_pbx
-=item totalbytes -
+=item radius_I<Radius_Attribute>
-=item domsvc - svcnum from svc_domain
+I<Radius-Attribute> (reply)
-=item radius_I<Radius_Attribute> - I<Radius-Attribute> (reply)
+=item rc_I<Radius_Attribute>
-=item rc_I<Radius_Attribute> - I<Radius-Attribute> (check)
+I<Radius-Attribute> (check)
=back
disable_inventory => 1,
},
+ 'domsvc' => {
+ label => 'Domain',
+ type => 'select',
+ select_table => 'svc_domain',
+ select_key => 'svcnum',
+ select_label => 'domain',
+ disable_inventory => 1,
+
+ },
+ 'pbxsvc' => { label => 'PBX',
+ type => 'select-svc_pbx.html',
+ disable_inventory => 1,
+ disable_select => 1, #UI wonky, pry works otherwise
+ },
'usergroup' => {
label => 'RADIUS groups',
type => 'radius_usergroup_selector',
$class->search_sql_field('username', $string ).
' ) ';
} else {
- ' ( '.
- $class->search_sql_field('username', $string).
- ( $string =~ /^\d+$/
- ? 'OR '. $class->search_sql_field('svcnum', $string)
- : ''
- ).
- ' ) ';
+ $class->search_sql_field('username', $string);
}
}
my $error = $self->ut_numbern('svcnum')
#|| $self->ut_number('domsvc')
- || $self->ut_foreign_key('domsvc', 'svc_domain', 'svcnum' )
+ || $self->ut_foreign_key( 'domsvc', 'svc_domain', 'svcnum' )
+ || $self->ut_foreign_keyn('pbxsvc', 'svc_pbx', 'svcnum' )
|| $self->ut_textn('sec_phrase')
|| $self->ut_snumbern('seconds')
|| $self->ut_snumbern('upbytes')
# First, if _password is blank, generate one and set default encoding.
if ( ! $recref->{_password} ) {
- $self->set_password('');
+ $error = $self->set_password('');
}
# But if there's a _password but no encoding, assume it's plaintext and
# set it to default encoding.
elsif ( ! $recref->{_password_encoding} ) {
- $self->set_password($recref->{_password});
+ $error = $self->set_password($recref->{_password});
}
+ return $error if $error;
# Next, check _password to ensure compliance with the encoding.
if ( $recref->{_password_encoding} eq 'ldap' ) {
$recref->{_password} =~ /\!/ and return gettext('illegal_password');
}
}
- elsif ( $recref->{_password_encoding} eq 'legacy' ) {
- # this happens when set_password fails
- return gettext('illegal_password'). " $passwordmin-$passwordmax ".
- FS::Msgcat::_gettext('illegal_password_characters').
- ": ". $recref->{_password};
+ else {
+ return "invalid password encoding ('".$recref->{_password_encoding}."'";
}
$self->SUPER::check;
=cut
sub set_password {
- my $self = shift;
- my $pass = shift;
- my ($encoding, $encryption);
+ my( $self, $pass ) = ( shift, shift );
+ my $failure = gettext('illegal_password'). " $passwordmin-$passwordmax ".
+ FS::Msgcat::_gettext('illegal_password_characters').
+ ": ". $pass;
- if($self->_password_encoding) {
+ my ($encoding, $encryption);
+
+ if ( $self->_password_encoding ) {
$encoding = $self->_password_encoding;
# identify existing encryption method, try to use it.
$encryption = $self->_password_encryption;
- if(!$encryption) {
+ if (!$encryption) {
# use the system default
undef $encoding;
}
}
- if(!$encoding) {
+ if ( !$encoding ) {
# set encoding to system default
- ($encoding, $encryption) = split(/-/, lc($conf->config('default-password-encoding')));
+ ($encoding, $encryption) =
+ split(/-/, lc($conf->config('default-password-encoding')));
$encoding ||= 'legacy';
$self->_password_encoding($encoding);
}
- if($encoding eq 'legacy') {
+ if( $encoding eq 'legacy' ) {
+
# The legacy behavior from check():
# If the password is blank, randomize it and set encoding to 'plain'.
if(!defined($pass) or (length($pass) == 0 and $passwordmin)) {
$pass = join('',map($pw_set[ int(rand $#pw_set) ], (0..7) ) );
$self->_password_encoding('plain');
- }
- else {
+ } else {
# Prefix + valid-length password
if ( $pass =~ /^((\*SUSPENDED\* |!!?)?)([^\t\n]{$passwordmin,$passwordmax})$/ ) {
$pass = $1.$3;
$self->_password_encoding('plain');
- }
# Prefix + crypt string
- elsif ( $pass =~ /^((\*SUSPENDED\* |!!?)?)([\w\.\/\$\;\+]{13,64})$/ ) {
+ } elsif ( $pass =~ /^((\*SUSPENDED\* |!!?)?)([\w\.\/\$\;\+]{13,64})$/ ) {
$pass = $1.$3;
$self->_password_encoding('crypt');
- }
# Various disabled crypt passwords
- elsif ( $pass eq '*' or
+ } elsif ( $pass eq '*' or
$pass eq '!' or
$pass eq '!!' ) {
$self->_password_encoding('crypt');
- }
- else {
- # do nothing; check() will recognize this as an error
+ } else {
+ return $failure;
}
}
+
+ $self->_password($pass);
+ return;
+
}
- elsif($encoding eq 'crypt') {
- if($encryption eq 'md5') {
+
+ return $failure
+ if $passwordmin && length($pass) < $passwordmin
+ or $passwordmax && length($pass) > $passwordmax;
+
+ if ( $encoding eq 'crypt' ) {
+ if ($encryption eq 'md5') {
$pass = unix_md5_crypt($pass);
- }
- elsif($encryption eq 'des') {
+ } elsif ($encryption eq 'des') {
$pass = crypt($pass, $saltset[int(rand(64))].$saltset[int(rand(64))]);
}
- }
- elsif($encoding eq 'ldap') {
- if($encryption eq 'md5') {
+
+ } elsif ( $encoding eq 'ldap' ) {
+ if ($encryption eq 'md5') {
$pass = md5_base64($pass);
- }
- elsif($encryption eq 'sha1') {
+ } elsif ($encryption eq 'sha1') {
$pass = sha1_base64($pass);
- }
- elsif($encryption eq 'crypt') {
+ } elsif ($encryption eq 'crypt') {
$pass = crypt($pass, $saltset[int(rand(64))].$saltset[int(rand(64))]);
}
# else $encryption eq 'plain', do nothing
#$self->snapshot; #not necessary, we retain the old values
#create an object with the updated usage values
my $new = qsearchs('svc_acct', { 'svcnum' => $self->svcnum });
- #call exports
- my $error = $new->replace($self);
+ local($FS::Record::nowarn_identical) = 1;
+ my $error = $new->replace($self); #call exports
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return "Error replacing: $error";