2011-06-27 23:38:19 +02:00
|
|
|
/*
|
|
|
|
* This file is a part of Winix
|
2014-10-04 20:04:03 +02:00
|
|
|
* and is distributed under the 2-Clause BSD licence.
|
|
|
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2018-01-06 19:12:53 +01:00
|
|
|
* Copyright (c) 2011-2018, Tomasz Sowa
|
2011-06-27 23:38:19 +02:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
2014-10-04 20:04:03 +02:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
2011-06-27 23:38:19 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "passwd.h"
|
|
|
|
#include "core/slog.h"
|
|
|
|
#include "functions/functions.h"
|
|
|
|
|
|
|
|
|
2014-02-12 17:30:49 +01:00
|
|
|
|
|
|
|
namespace Winix
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-06-27 23:38:19 +02:00
|
|
|
namespace Fun
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
Passwd::Passwd()
|
|
|
|
{
|
|
|
|
fun.url = L"passwd";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Passwd::HasAccess()
|
|
|
|
{
|
2013-05-16 22:08:07 +02:00
|
|
|
// a not logged user can use this function to reset his password
|
|
|
|
return true;
|
2011-06-27 23:38:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-03-09 23:56:54 +01:00
|
|
|
bool Passwd::IsPasswordCorrect(const std::wstring & pass, const std::wstring & conf_pass, bool use_ses_log)
|
2011-06-27 23:38:19 +02:00
|
|
|
{
|
2012-03-09 23:56:54 +01:00
|
|
|
if( pass != conf_pass )
|
|
|
|
{
|
|
|
|
log << log2 << "Passwd: passwords are different" << logend;
|
|
|
|
|
|
|
|
if( use_ses_log )
|
|
|
|
slog << logerror << T("adduser_err_passwords_different") << logend;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pass.size() < config->pass_min_size )
|
|
|
|
{
|
|
|
|
log << log2 << "Passwd: password is too small" << logend;
|
|
|
|
|
|
|
|
if( use_ses_log )
|
|
|
|
slog << logerror << T("adduser_err_password_too_small") << " "
|
|
|
|
<< config->pass_min_size << " " << T("adduser_err_password_too_small2") << logend;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pass.size() > WINIX_ACCOUNT_MAX_PASSWORD_SIZE )
|
|
|
|
{
|
|
|
|
log << log2 << "Passwd: password can't be longer than: " << WINIX_ACCOUNT_MAX_PASSWORD_SIZE << " characters" << logend;
|
|
|
|
|
|
|
|
if( use_ses_log )
|
|
|
|
slog << logerror << T("adduser_err_password_too_big") << " " << WINIX_ACCOUNT_MAX_PASSWORD_SIZE
|
|
|
|
<< " " << T("adduser_err_password_too_big2") << logend;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2011-06-27 23:38:19 +02:00
|
|
|
|
2012-03-09 23:56:54 +01:00
|
|
|
|
|
|
|
return true;
|
2011-06-27 23:38:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-03-09 23:56:54 +01:00
|
|
|
bool Passwd::ChangePassword(long user_id, const std::wstring & new_password)
|
2011-06-27 23:38:19 +02:00
|
|
|
{
|
2012-03-09 23:56:54 +01:00
|
|
|
bool result = false;
|
2011-06-27 23:38:19 +02:00
|
|
|
|
2012-03-09 23:56:54 +01:00
|
|
|
User * puser = system->users.GetUser(user_id);
|
2011-06-27 23:38:19 +02:00
|
|
|
|
2012-03-09 23:56:54 +01:00
|
|
|
if( puser )
|
|
|
|
{
|
2014-06-07 13:20:44 +02:00
|
|
|
up.has_pass = true;
|
2012-03-09 23:56:54 +01:00
|
|
|
up.pass = new_password;
|
|
|
|
system->crypt.PassHashCrypt(up);
|
|
|
|
result = (db->ChangeUserPass(user_id, up) == WINIX_ERR_OK);
|
|
|
|
|
|
|
|
if( result )
|
|
|
|
log << log2 << "Passwd: password for user " << puser->name << " has been changed" << logend;
|
|
|
|
else
|
|
|
|
log << log1 << "Passwd: I cannot change password -- database problem" << logend;
|
|
|
|
}
|
2011-06-27 23:38:19 +02:00
|
|
|
else
|
2012-03-09 23:56:54 +01:00
|
|
|
{
|
|
|
|
log << log1 << "Passwd: there is no a user with id: " << user_id << logend;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Passwd::ChangePassword(User * puser)
|
|
|
|
{
|
|
|
|
long user_id;
|
2011-06-27 23:38:19 +02:00
|
|
|
|
|
|
|
const std::wstring & pass_cur = cur->request->PostVar(L"passwordcur");
|
|
|
|
const std::wstring & pass_new = cur->request->PostVar(L"passwordnew");
|
|
|
|
const std::wstring & pass_conf = cur->request->PostVar(L"passwordconfirm");
|
|
|
|
|
2012-03-09 23:56:54 +01:00
|
|
|
if( !cur->session->puser->super_user && !functions->fun_login.CheckUserPass(puser->name, pass_cur, user_id) )
|
2011-06-27 23:38:19 +02:00
|
|
|
{
|
|
|
|
log << log3 << "Passwd: incorrect current password" << logend;
|
|
|
|
slog << logerror << T("passwd_err_bad_current_password") << logend;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-30 08:44:38 +02:00
|
|
|
if( !IsPasswordCorrect(pass_new, pass_conf, true) )
|
2011-06-27 23:38:19 +02:00
|
|
|
return;
|
|
|
|
|
2012-03-30 08:44:38 +02:00
|
|
|
if( ChangePassword(puser->id, pass_new) )
|
2011-06-27 23:38:19 +02:00
|
|
|
{
|
|
|
|
slog << loginfo << T("passwd_password_changed") << logend;
|
|
|
|
system->RedirectToLastItem();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-16 21:26:44 +02:00
|
|
|
|
|
|
|
|
|
|
|
bool Passwd::SetNewPassword(User * puser, bool use_ses_log)
|
|
|
|
{
|
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
const std::wstring & pass = cur->request->PostVar(L"passwordnew");
|
|
|
|
const std::wstring & pass_conf = cur->request->PostVar(L"passwordconfirm");
|
|
|
|
|
|
|
|
if( IsPasswordCorrect(pass, pass_conf, use_ses_log) )
|
|
|
|
{
|
|
|
|
if( ChangePassword(puser->id, pass) )
|
|
|
|
{
|
|
|
|
result = true;
|
|
|
|
|
|
|
|
if( use_ses_log )
|
|
|
|
slog << loginfo << T("pw_password_changed") << logend;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( use_ses_log )
|
|
|
|
slog << logerror << T("service_unavailable") << logend;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Passwd::ResetPassword(User * puser, long code, bool use_ses_log, bool only_check_access)
|
|
|
|
{
|
2018-01-06 19:12:53 +01:00
|
|
|
std::wstring * user_code_str = puser->aenv.GetFirstValue(L"password_change_code");
|
2013-05-16 21:26:44 +02:00
|
|
|
|
|
|
|
if( user_code_str )
|
|
|
|
{
|
|
|
|
if( Tol(*user_code_str) == code )
|
|
|
|
{
|
|
|
|
if( only_check_access )
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return SetNewPassword(puser, use_ses_log);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log << log2 << "Passwd: incorrect change password code" << logend;
|
|
|
|
|
|
|
|
if( use_ses_log )
|
|
|
|
slog << logerror << T(L"incorrect_change_password_code") << logend;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log << log1 << "Passwd: there is no change password code in admin environment" << logend;
|
|
|
|
|
|
|
|
if( use_ses_log )
|
|
|
|
slog << loginfo << T(L"password_cannot_be_changed") << logend;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Passwd::ResetPassword(const std::wstring & login, long code, bool use_ses_log, bool only_check_access)
|
|
|
|
{
|
|
|
|
bool result = false;
|
|
|
|
User * puser = system->users.GetUser(login);
|
|
|
|
|
|
|
|
if( puser )
|
|
|
|
{
|
|
|
|
long t = static_cast<long>(cur->request->start_time);
|
|
|
|
|
|
|
|
if( puser->aenv.Long(L"password_change_time") + config->reset_password_code_expiration_time > t )
|
|
|
|
{
|
|
|
|
result = ResetPassword(puser, code, use_ses_log, only_check_access);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log << log2 << "Passwd: the code has expired" << logend;
|
|
|
|
|
|
|
|
if( use_ses_log )
|
|
|
|
slog << logerror << T(L"code_expired") << logend;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log << log1 << "Passwd: there is no a user: " << login << logend;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Passwd::ResetPassword()
|
|
|
|
{
|
|
|
|
const std::wstring & login = cur->request->PostVar(L"login");
|
|
|
|
long code = Tol(cur->request->PostVar(L"code"));
|
|
|
|
|
2013-05-16 22:11:27 +02:00
|
|
|
if( ResetPassword(login, code, true, false) )
|
|
|
|
system->RedirectToLastItem();
|
2013-05-16 21:26:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Passwd::ShowResetPasswordForm()
|
|
|
|
{
|
|
|
|
const std::wstring & login = cur->request->ParamValue(L"login");
|
|
|
|
long code = Tol(cur->request->ParamValue(L"code"));
|
|
|
|
|
|
|
|
if( !login.empty() )
|
|
|
|
{
|
|
|
|
if( !ResetPassword(login, code, true, true) )
|
|
|
|
system->RedirectToLastItem();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
system->RedirectToLastItem();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-03-09 23:56:54 +01:00
|
|
|
/*
|
|
|
|
if you are a root (super_user) you can change a password for everyone
|
|
|
|
(the html form has a select option)
|
|
|
|
|
|
|
|
but if you are not a root you can change only your password
|
|
|
|
and you should provide your current password as well
|
|
|
|
*/
|
|
|
|
void Passwd::MakePost()
|
|
|
|
{
|
|
|
|
const std::wstring * plogin;
|
|
|
|
|
2014-06-19 01:18:28 +02:00
|
|
|
// CHECK ME
|
|
|
|
// may it is better to check first for 'resetpassword'
|
|
|
|
// now if a user is logged then 'resetpassword' has no effect
|
|
|
|
// actually 'resetpassword' would be used for other user
|
|
|
|
|
2012-03-09 23:56:54 +01:00
|
|
|
if( cur->session->puser )
|
|
|
|
{
|
|
|
|
if( cur->session->puser->super_user )
|
|
|
|
plogin = &cur->request->PostVar(L"login");
|
|
|
|
else
|
|
|
|
plogin = &cur->session->puser->name;
|
|
|
|
|
|
|
|
User * puser = system->users.GetUser(*plogin);
|
|
|
|
|
|
|
|
if( puser )
|
|
|
|
ChangePassword(puser);
|
|
|
|
else
|
|
|
|
log << log1 << "Passwd: there is no such a user: " << *plogin << logend;
|
|
|
|
}
|
2013-05-16 21:26:44 +02:00
|
|
|
else
|
|
|
|
if( cur->request->IsParam(L"resetpassword") )
|
|
|
|
{
|
|
|
|
ResetPassword();
|
|
|
|
}
|
2012-03-09 23:56:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-16 21:26:44 +02:00
|
|
|
void Passwd::MakeGet()
|
|
|
|
{
|
|
|
|
if( cur->request->IsParam(L"resetpassword") )
|
|
|
|
ShowResetPasswordForm();
|
2013-05-16 22:08:07 +02:00
|
|
|
else
|
|
|
|
if( !cur->session->puser )
|
|
|
|
cur->request->status = WINIX_ERR_PERMISSION_DENIED;
|
2013-05-16 21:26:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-06-27 23:38:19 +02:00
|
|
|
|
|
|
|
} // namespace
|
2014-02-12 17:30:49 +01:00
|
|
|
|
|
|
|
} // namespace Winix
|
|
|
|
|