############################################################################### # LogInOut.pm # # $Date: 01.09.2026 $ # ############################################################################### # YaBB: Yet another Bulletin Board # # Open-Source Community Software for Webmasters # # Version: YaBBForum 3.1 # # Packaged: 01 Sep, 2026 # # Distributed by: https://yabbforum.nz # # =========================================================================== # # Copyright (c) 2000-2026 YaBB (yabbforum.nz) - All Rights Reserved. # # Software by: The YaBB Development Team # # with assistance from the YaBB community. # ############################################################################### use CGI::Carp qw(fatalsToBrowser); our $VERSION = '3.1'; $loginoutpmver = 'YaBBForum 3.1'; if ( $action eq 'detailedversion' ) { return 1; } if ($regcheck) { require Sources::Decoder; } LoadLanguage('LogInOut'); $regstyle = q{}; sub Login { if ( !$iamguest && $sessionvalid == 1 ) { fatal_error( 'logged_in_already', $username ); } $sharedLogin_title = $loginout_txt{'34'}; $yymain .= sharedLogin() . q~~; $yytitle = $loginout_txt{'34'}; template(); return; } sub Login2 { if ( !$iamguest && $sessionvalid == 1 ) { fatal_error( 'logged_in_already', $username ); } if ( $FORM{'username'} eq q{} ) { fatal_error('no_username'); } if ( $FORM{'passwrd'} eq q{} ) { fatal_error('no_password'); } $username = $FORM{'username'}; $username =~ s/\s/_/gxsm; if ( $username =~ /[^ \w\x80-\xFF\[\]\(\)#\%\+,\-\|\.:=\?\@\^]/sm ) { $error_txt = isempty($loginout_txt{'35a'}, "$loginout_txt{'35'} $loginout_txt{'241'}"); fatal_error( 'invalid_character', "$error_txt" ); } ## Check if login ID is not an email address ## if ( !-e "$memberdir/$username.vars" ) { $test_id = MemberIndex( 'who_is', "$FORM{'username'}" ); if ( $test_id ) { $username = $test_id; } } if ( -e "$memberdir/$username.pre" && ( $regtype == 1 || $regtype == 2 ) ) { fatal_error('not_activated'); } elsif ( -e "$memberdir/$username.wait" && $regtype == 1 ) { fatal_error('prereg_wait'); } elsif ( !-e "$memberdir/$username.vars" ) { fatal_error('bad_credentials'); } if ( -e "$memberdir/$username.pre" && -e "$memberdir/$username.vars" ) { unlink "$memberdir/$username.pre"; } # Need to do this to get correct case of user ID, # for case insensitive systems. Can cause weird issues otherwise $caseright = 0; ManageMemberlist('load'); while ( ( $curmemb, $value ) = each %memberlist ) { if ( $username eq $curmemb ) { $caseright = 1; last; } } undef %memberlist; if ( !$caseright ) { $username = 'Guest'; fatal_error('bad_credentials'); } if ( -e "$memberdir/$username.vars" ) { LoadUser($username); my $spass = ${ $uid . $username }{'password'}; my $cryptpass = encode_password("$FORM{'passwrd'}"); # convert non encrypted password to MD5 encrypted one if ( $spass eq $FORM{'passwrd'} && $spass ne $cryptpass ) { # only encrypt the password if it's not already MD5 encrypted # MD5 hashes in YaBB are always 22 chars long (base64) if ( length( ${ $uid . $username }{'password'} ) != 22 ) { ${ $uid . $username }{'password'} = $cryptpass; UserAccount($username); $spass = $cryptpass; } } if ( $spass ne $cryptpass ) { $username = 'Guest'; fatal_error('bad_credentials'); } } else { $username = 'Guest'; fatal_error('bad_credentials'); } $iamadmin = ${ $uid . $username }{'position'} eq 'Administrator' ? 1 : 0; $iamgmod = ${ $uid . $username }{'position'} eq 'Global Moderator' ? 1 : 0; $sessionvalid = 1; $iamguest = 0; if ( $maintenance && !$iamadmin ) { $username = 'Guest'; fatal_error('admin_login_only'); } banning(); if ( $FORM{'cookielength'} == 1 ) { $ck{'len'} = 'Sunday, 17-Jan-2038 00:00:00 GMT'; } else { $ck{'len'} = q{}; } ${ $uid . $username }{'session'} = encode_password($user_ip); UpdateCookie( 'write', $username, encode_password( $FORM{'passwrd'} ), ${ $uid . $username }{'session'}, q{/}, $ck{'len'} ); UserAccount( $username, 'update', q{-} ); # "-" to not update 'lastonline' here buildIMS( $username, 'load' ); # isn't loaded because was Guest before buildIMS( $username, q{} ); # rebuild the Members/$username.ims file on login WriteLog(); if ( $FORM{'sredir'} ) { $FORM{'sredir'} =~ s/\~/\=/gxsm; $FORM{'sredir'} =~ s/x3B/;/gsm; $FORM{'sredir'} =~ s/search2/search/gsm; $FORM{'sredir'} = qq~?$FORM{'sredir'}~; if ( $FORM{'sredir'} =~ /action=(register|login2|reminder|reminder2)/xsm ) { $FORM{'sredir'} = q{}; } } $yySetLocation = qq~$scripturl$FORM{'sredir'}~; redirectexit(); return; } sub Logout { if ( $username ne 'Guest' ) { RemoveUserOnline($username); # Remove user from online log UserAccount( $username, 'update', 'lastonline' ); } UpdateCookie('delete'); $yySetLocation = $guestaccess ? $scripturl : qq~$scripturl?action=login~; $username = 'Guest'; redirectexit(); return; } sub sharedLogin { get_template('Loginout'); if ( $action eq 'login' || $maintenance ) { $yynavigation = qq~› $loginout_txt{'34'}~; } #cookie length is now all or nothing. if ( $sharedLogin_title ne q{} ) { $sharedlog = $mysharedloga; $sharedlog =~ s/{yabb sharedLogin_title}/$sharedLogin_title/sm; if ( $sharedLogin_text ne q{} ) { $sharedlog .= $mysharedlogb; $sharedlog =~ s/{yabb sharedLogin_text}/$sharedLogin_text/sm; } $sharedlog .= $mysharedlogc; $sharedbot = $myborder_bottom; } else { $sharedlog = $mysharedlog_top; $sharedbot = $mysharedbot; } if ($maintenance) { $hide_passlink = ' style="visibility: hidden;"' } if ( $maintenance || !$regtype ) { $hide_reglink = ' style="visibility: hidden;"';; } $sharedlog .= qq~