diff --git a/Makefile b/Makefile index 7684d1d1..e6f6762d 100644 --- a/Makefile +++ b/Makefile @@ -69,9 +69,9 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \ swad_network.o swad_network_database.o swad_nickname.o \ swad_nickname_database.o swad_notice.o swad_notice_database.o \ swad_notification.o swad_notification_database.o \ - swad_pagination.o swad_parameter.o swad_password.o swad_photo.o \ - swad_place.o swad_plugin.o swad_privacy.o swad_profile.o swad_program.o \ - swad_project.o \ + swad_pagination.o swad_parameter.o swad_password.o \ + swad_password_database.o swad_photo.o swad_place.o swad_plugin.o \ + swad_privacy.o swad_profile.o swad_program.o swad_project.o \ swad_QR.o \ swad_record.o swad_report.o swad_role.o swad_room.o swad_RSS.o \ swad_scope.o swad_search.o swad_session.o swad_setting.o \ diff --git a/swad_ID_database.c b/swad_ID_database.c index 66d84536..d5e559c1 100644 --- a/swad_ID_database.c +++ b/swad_ID_database.c @@ -121,6 +121,19 @@ bool ID_DB_CheckIfConfirmed (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1]) ID) != 0); } +/*****************************************************************************/ +/********************** Check if a string is a user's ID *********************/ +/*****************************************************************************/ + +bool ID_DB_FindStrInUsrsIDs (const char *Str) + { + return (DB_QueryCOUNT ("can not check if a string matches any user's ID", + "SELECT COUNT(*)" + " FROM usr_ids" + " WHERE UsrID='%s'", + Str) != 0); + } + /*****************************************************************************/ /***************** Get list of user codes from user's IDs ********************/ /*****************************************************************************/ diff --git a/swad_ID_database.h b/swad_ID_database.h index 1a94b667..f71b6559 100644 --- a/swad_ID_database.h +++ b/swad_ID_database.h @@ -42,6 +42,7 @@ void ID_DB_ConfirmUsrID (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1]); unsigned ID_DB_GetIDsFromUsrCod (MYSQL_RES **mysql_res,long UsrCod); bool ID_DB_CheckIfConfirmed (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1]); +bool ID_DB_FindStrInUsrsIDs (const char *Str); unsigned ID_DB_GetUsrCodsFromUsrID (MYSQL_RES **mysql_res, const struct UsrData *UsrDat, const char *EncryptedPassword, diff --git a/swad_changelog.h b/swad_changelog.h index 3996436a..4f764839 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,14 +602,15 @@ TODO: FIX BUG, URGENT! En las fechas como par TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo. */ -#define Log_PLATFORM_VERSION "SWAD 21.22 (2021-10-04)" +#define Log_PLATFORM_VERSION "SWAD 21.23 (2021-10-04)" #define CSS_FILE "swad20.45.css" #define JS_FILE "swad20.69.1.js" /* TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams - Version 21.22: Oct 04, 2021 Queries related to notifications moved to other modules. (318058 lines) + Version 21.23: Oct 04, 2021 New module swad_password_database for database queries related to passwords. (318197 lines) + Version 21.22: Oct 04, 2021 Queries related to notifications moved to other modules. (318066 lines) Version 21.21.2: Oct 01, 2021 Queries moved to module swad_notification_database. (317963 lines) Version 21.21.1: Oct 01, 2021 Queries moved to module swad_notification_database. (317938 lines) Version 21.21: Sep 30, 2021 New module swad_notice_database for database queries related to notices. (317901 lines) diff --git a/swad_notification_database.h b/swad_notification_database.h index 9728d336..2100057a 100644 --- a/swad_notification_database.h +++ b/swad_notification_database.h @@ -34,7 +34,6 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ - /*****************************************************************************/ /******************************** Public types *******************************/ /*****************************************************************************/ diff --git a/swad_password.c b/swad_password.c index 0c75dac1..137eec1f 100644 --- a/swad_password.c +++ b/swad_password.c @@ -40,8 +40,10 @@ #include "swad_global.h" #include "swad_HTML.h" #include "swad_ID.h" +#include "swad_ID_database.h" #include "swad_mail_database.h" #include "swad_password.h" +#include "swad_password_database.h" #include "swad_parameter.h" #include "swad_user.h" @@ -81,7 +83,6 @@ static void Pwd_PutLinkToSendNewPasswdParams (void *UsrIdLogin); static void Pwd_CreateANewPassword (char PlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1]); static bool Pwd_CheckIfPasswdIsUsrIDorName (const char *PlainPassword); -static unsigned Pwd_GetNumOtherUsrsWhoUseThisPassword (const char *EncryptedPassword,long UsrCod); /*****************************************************************************/ /************* Get parameter with my plain password from a form **************/ @@ -118,13 +119,7 @@ bool Pwd_CheckCurrentPassword (void) bool Pwd_CheckPendingPassword (void) { /***** Get pending password from database *****/ - DB_QuerySELECTString (Gbl.Usrs.Me.PendingPassword, - sizeof (Gbl.Usrs.Me.PendingPassword) - 1, - "can not get pending password", - "SELECT PendingPassword" // row[0] - " FROM usr_pending_passwd" - " WHERE UsrCod=%ld", - Gbl.Usrs.Me.UsrDat.UsrCod); + Pwd_DB_GetPendingPassword (); return (Gbl.Usrs.Me.PendingPassword[0] ? !strcmp (Gbl.Usrs.Me.LoginEncryptedPassword,Gbl.Usrs.Me.PendingPassword) : @@ -138,12 +133,7 @@ bool Pwd_CheckPendingPassword (void) void Pwd_AssignMyPendingPasswordToMyCurrentPassword (void) { /***** Update my current password in database *****/ - DB_QueryUPDATE ("can not update your password", - "UPDATE usr_data" - " SET Password='%s'" - " WHERE UsrCod=%ld", - Gbl.Usrs.Me.PendingPassword, - Gbl.Usrs.Me.UsrDat.UsrCod); + Pwd_DB_AssignMyPendingPasswordToMyCurrentPassword (); /***** Update my current password *****/ Str_Copy (Gbl.Usrs.Me.UsrDat.Password,Gbl.Usrs.Me.PendingPassword, @@ -151,10 +141,7 @@ void Pwd_AssignMyPendingPasswordToMyCurrentPassword (void) /***** Remove my pending password from database since it is not longer necessary *****/ - DB_QueryDELETE ("can not remove pending password", - "DELETE FROM usr_pending_passwd" - " WHERE UsrCod=%ld", - Gbl.Usrs.Me.UsrDat.UsrCod); + Pwd_DB_RemoveMyPendingPassword (); } /*****************************************************************************/ @@ -488,19 +475,10 @@ void Pwd_SetMyPendingPassword (char PlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + Cry_EncryptSHA512Base64 (PlainPassword,Gbl.Usrs.Me.PendingPassword); /***** Remove expired pending passwords from database *****/ - DB_QueryDELETE ("can not remove expired pending passwords", - "DELETE LOW_PRIORITY FROM usr_pending_passwd" - " WHERE DateAndTime + if (Pwd_DB_GetNumOtherUsrsWhoUseThisPassword (EncryptedPassword,UsrCod) > Pwd_MAX_OTHER_USERS_USING_THE_SAME_PASSWORD) { Ale_CreateAlert (Ale_WARNING,Pwd_PASSWORD_SECTION_ID, @@ -543,64 +521,12 @@ bool Pwd_SlowCheckIfPasswordIsGood (const char PlainPassword[Pwd_MAX_BYTES_PLAIN static bool Pwd_CheckIfPasswdIsUsrIDorName (const char *PlainPassword) { - bool Found; + /***** Check if password is found in user's ID *****/ + if (ID_DB_FindStrInUsrsIDs (PlainPassword)) + return true; // Found - /***** Get if password is found in user's ID from database *****/ - Found = (DB_QueryCOUNT ("can not check if a password matches a user's ID", - "SELECT COUNT(*)" - " FROM usr_ids" - " WHERE UsrID='%s'", - PlainPassword) != 0); - - /***** Get if password is found in first name or surnames of anybody, from database *****/ - if (!Found) - Found = (DB_QueryCOUNT ("can not check if a password matches" - " a first name or a surname", - "SELECT COUNT(*)" - " FROM usr_data" - " WHERE FirstName='%s'" - " OR Surname1='%s'" - " OR Surname2='%s'", - PlainPassword, - PlainPassword, - PlainPassword) != 0); - - return Found; - } - -/*****************************************************************************/ -/************** Get the number of users who use yet a password ***************/ -/*****************************************************************************/ - -static unsigned Pwd_GetNumOtherUsrsWhoUseThisPassword (const char *EncryptedPassword,long UsrCod) - { - unsigned NumUsrs; - char *SubQuery; - - /***** Build subquery *****/ - if (UsrCod > 0) - { - if (asprintf (&SubQuery," AND UsrCod<>%ld",UsrCod) < 0) - Err_NotEnoughMemoryExit (); - } - else - SubQuery = ""; - - /***** Get number of other users who use a password from database *****/ - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not check if a password is trivial", - "SELECT COUNT(*)" - " FROM usr_data" - " WHERE Password='%s'" - "%s", - EncryptedPassword, - SubQuery); - - /***** Free subquery *****/ - if (UsrCod > 0) - free (SubQuery); - - return NumUsrs; + /***** Check if password is found in first name or surnames of anybody *****/ + return Usr_DB_FindStrInUsrsNames (PlainPassword); } /*****************************************************************************/ diff --git a/swad_password_database.c b/swad_password_database.c new file mode 100644 index 00000000..b205871b --- /dev/null +++ b/swad_password_database.c @@ -0,0 +1,160 @@ +// swad_password_database.c: Users' passwords, operations with database + +/* + SWAD (Shared Workspace At a Distance), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2021 Antonio Caņas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +#define _GNU_SOURCE // For asprintf +#include // For asprintf + +#include "swad_config.h" +#include "swad_database.h" +#include "swad_error.h" +#include "swad_global.h" +#include "swad_password_database.h" + +/*****************************************************************************/ +/************** External global variables from others modules ****************/ +/*****************************************************************************/ + +extern struct Globals Gbl; + +/*****************************************************************************/ +/***************************** Private constants *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************* Private types *******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private variables *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private prototypes ****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/************** Update my current pending password in database ***************/ +/*****************************************************************************/ + +void Pwd_DB_UpdateMyPendingPassword (void) + { + DB_QueryREPLACE ("can not create pending password", + "REPLACE INTO usr_pending_passwd" + " (UsrCod,PendingPassword,DateAndTime)" + " VALUES" + " (%ld,'%s',NOW())", + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Usrs.Me.PendingPassword); + } + +/*****************************************************************************/ +/******************* Update my current password in database ******************/ +/*****************************************************************************/ + +void Pwd_DB_AssignMyPendingPasswordToMyCurrentPassword (void) + { + DB_QueryUPDATE ("can not update your password", + "UPDATE usr_data" + " SET Password='%s'" + " WHERE UsrCod=%ld", + Gbl.Usrs.Me.PendingPassword, + Gbl.Usrs.Me.UsrDat.UsrCod); + } + +/*****************************************************************************/ +/******************* Get pending password from database **********************/ +/*****************************************************************************/ + +void Pwd_DB_GetPendingPassword (void) + { + DB_QuerySELECTString (Gbl.Usrs.Me.PendingPassword, + sizeof (Gbl.Usrs.Me.PendingPassword) - 1, + "can not get pending password", + "SELECT PendingPassword" // row[0] + " FROM usr_pending_passwd" + " WHERE UsrCod=%ld", + Gbl.Usrs.Me.UsrDat.UsrCod); + } + +/*****************************************************************************/ +/************** Get the number of users who use yet a password ***************/ +/*****************************************************************************/ + +unsigned Pwd_DB_GetNumOtherUsrsWhoUseThisPassword (const char *EncryptedPassword,long UsrCod) + { + unsigned NumUsrs; + char *SubQuery; + + /***** Build subquery *****/ + if (UsrCod > 0) + { + if (asprintf (&SubQuery," AND UsrCod<>%ld",UsrCod) < 0) + Err_NotEnoughMemoryExit (); + } + else + SubQuery = ""; + + /***** Get number of other users who use a password from database *****/ + NumUsrs = (unsigned) + DB_QueryCOUNT ("can not check if a password is trivial", + "SELECT COUNT(*)" + " FROM usr_data" + " WHERE Password='%s'" + "%s", + EncryptedPassword, + SubQuery); + + /***** Free subquery *****/ + if (UsrCod > 0) + free (SubQuery); + + return NumUsrs; + } + +/*****************************************************************************/ +/***************** Remove my pending password from database ******************/ +/*****************************************************************************/ + +void Pwd_DB_RemoveMyPendingPassword (void) + { + DB_QueryDELETE ("can not remove pending password", + "DELETE FROM usr_pending_passwd" + " WHERE UsrCod=%ld", + Gbl.Usrs.Me.UsrDat.UsrCod); + } + +/*****************************************************************************/ +/************* Remove expired pending passwords from database ****************/ +/*****************************************************************************/ + +void Pwd_DB_RemoveExpiredPendingPassword (void) + { + DB_QueryDELETE ("can not remove expired pending passwords", + "DELETE LOW_PRIORITY FROM usr_pending_passwd" + " WHERE DateAndTime. +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/************************* Public types and constants ************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Public prototypes *****************************/ +/*****************************************************************************/ + +void Pwd_DB_UpdateMyPendingPassword (void); +void Pwd_DB_AssignMyPendingPasswordToMyCurrentPassword (void); + +void Pwd_DB_GetPendingPassword (void); +unsigned Pwd_DB_GetNumOtherUsrsWhoUseThisPassword (const char *EncryptedPassword,long UsrCod); + +void Pwd_DB_RemoveMyPendingPassword (void); +void Pwd_DB_RemoveExpiredPendingPassword (void); + +#endif diff --git a/swad_user.c b/swad_user.c index 680601c1..b2d39cc9 100644 --- a/swad_user.c +++ b/swad_user.c @@ -10488,3 +10488,21 @@ unsigned Usr_DB_GetNumUsrsWhoChoseAnOption (const char *SubQuery) return 0; // Not reached } + +/*****************************************************************************/ +/****** Check if a string is found in first name or surnames of anybody ******/ +/*****************************************************************************/ + +bool Usr_DB_FindStrInUsrsNames (const char *Str) + { + return (DB_QueryCOUNT ("can not check if a string matches" + " a first name or a surname", + "SELECT COUNT(*)" + " FROM usr_data" + " WHERE FirstName='%s'" + " OR Surname1='%s'" + " OR Surname2='%s'", + Str, + Str, + Str) != 0); + } diff --git a/swad_user.h b/swad_user.h index 35a37960..f090661d 100644 --- a/swad_user.h +++ b/swad_user.h @@ -556,4 +556,6 @@ unsigned Usr_DB_GetOldUsrs (MYSQL_RES **mysql_res,time_t SecondsWithoutAccess); unsigned Usr_DB_GetNumUsrsWhoChoseAnOption (const char *SubQuery); +bool Usr_DB_FindStrInUsrsNames (const char *Str); + #endif