48 return array(
"mem" =>
"AlternC's account password");
57 'title' => _(
"Settings"),
58 'link' =>
'mem_param.php',
71 return ($this->user[
"su"] ==
"1");
83 function login($username, $password, $restrictip = 0, $authip_token =
false) {
84 global $db, $msg, $cuid, $authip;
85 $msg->log(
"mem",
"login", $username);
86 if ($msg->has_msgs(
"ERROR"))
return false;
88 $db->query(
"select * from membres where login= ? ;", array($username));
89 if ($db->num_rows() == 0) {
90 $msg->raise(
"ERROR",
"mem", _(
"User or password incorrect"));
94 if (!password_verify($password, $db->f(
'pass'))) {
95 $db->query(
"UPDATE membres SET lastfail=lastfail+1 WHERE uid= ? ;", array($db->f(
"uid")));
96 $msg->raise(
"ERROR",
"mem", _(
"User or password incorrect"));
99 if (!$db->f(
"enabled")) {
100 $msg->raise(
"ERROR",
"mem", _(
"This account is locked, contact the administrator."));
103 $this->user = $db->Record;
104 $cuid = $db->f(
"uid");
107 if (strncmp($db->f(
'pass'),
'$1$', 3) == 0) {
108 $db->query(
"update membres set pass = ? where uid = ?",
109 array(password_hash($password, PASSWORD_BCRYPT), $cuid));
112 if (panel_islocked() && $cuid != 2000) {
113 $msg->raise(
"ALERT",
"mem", _(
"This website is currently under maintenance, login is currently disabled."));
123 $aga = $authip->get_allowed(
'panel');
124 foreach ($aga as $k => $v) {
125 if ($authip->is_in_subnet(get_remote_ip(), $v[
'ip'], $v[
'subnet'])) {
131 if (
sizeof($aga) > 1 && !$allowed_ip && !$authip->is_wl(get_remote_ip())) {
132 $msg->raise(
"ERROR",
"mem", _(
"Your IP isn't allowed to connect"));
138 $ip = get_remote_ip();
143 $db->query(
"DELETE FROM sessions WHERE DATE_ADD(ts,INTERVAL 2 DAY)<NOW();");
145 if (isset($_COOKIE[
"oldid"])) {
146 setcookie(
'oldid',
'', 0,
'/');
149 $sess = md5(mt_rand().mt_rand().mt_rand());
150 $_REQUEST[
"session"] = $sess;
151 $db->query(
"insert into sessions (sid,ip,uid) values (?, ?, ?);", array($sess, $ip, $cuid));
152 setcookie(
"session", $sess, 0,
"/");
155 $db->query(
"SELECT * FROM local WHERE uid= ? ;", array($cuid));
156 if ($db->num_rows()) {
158 $this->local = $db->Record;
175 global $db, $msg, $cuid, $mysql, $quota;
176 $msg->log(
"mem",
"setid", $id);
177 $db->query(
"select * from membres where uid= ? ;", array($id));
178 if ($db->num_rows() == 0) {
179 $msg->raise(
"ERROR",
"mem", _(
"User or password incorrect"));
183 $this->user = $db->Record;
184 $cuid = $db->f(
"uid");
186 $mysql->reload_dbus();
188 $ip = get_remote_ip();
189 $sess = md5(mt_rand().mt_rand().mt_rand());
190 $_REQUEST[
"session"] = $sess;
191 $db->query(
"insert into sessions (sid,ip,uid) values (?, ?, ?);", array($sess, $ip, $cuid));
192 setcookie(
"session", $sess, 0,
"/");
195 $db->query(
"SELECT * FROM local WHERE uid= ? ;", array($cuid));
196 if ($db->num_rows()) {
198 $this->local = $db->Record;
200 $quota->getquota(
'',
true);
210 $ip = getenv(
"REMOTE_HOST");
212 $ip = get_remote_ip();
214 $db->query(
"UPDATE membres SET lastlogin=NOW(), lastfail=0, lastip= ? WHERE uid= ?;", array($ip, $cuid));
220 $db->query(
"select pass from membres where uid= ?;", array($cuid));
222 $i = intval(time() / 3600);
226 return md5(
"$i--" . $db->f(
'pass'));
261 global $db, $msg, $cuid;
264 static $already=
false;
265 if ($already)
return false;
268 if (isset($_REQUEST[
"username"])) {
269 if (empty($_REQUEST[
'password'])) {
270 $msg->raise(
"ERROR",
"mem", _(
"Missing password"));
273 if ($_REQUEST[
"username"] && $_REQUEST[
"password"]) {
274 return $this->
login($_REQUEST[
"username"], $_REQUEST[
"password"], (isset($_REQUEST[
"restrictip"]) ? $_REQUEST[
"restrictip"] : 0));
278 $_COOKIE[
"session"] = isset($_COOKIE[
"session"]) ? $_COOKIE[
"session"] :
"";
280 if (strlen($_COOKIE[
"session"]) != 32) {
282 $msg->raise(
"ERROR",
"mem", _(
"Identity lost or unknown, please login"));
286 $ip = get_remote_ip();
287 $db->query(
"select uid, ? as me,ip from sessions where sid= ?;", array($ip, $_COOKIE[
"session"]));
288 if ($db->num_rows() == 0) {
290 $msg->raise(
"ERROR",
"mem", _(
"Identity lost or unknown, please login"));
294 $cuid = $db->f(
"uid");
296 if (panel_islocked() && $cuid != 2000) {
297 $msg->raise(
"ALERT",
"mem", _(
"This website is currently under maintenance, login is currently disabled."));
301 $db->query(
"select * from membres where uid= ? ;", array($cuid));
303 $this->user = $db->Record;
306 $db->query(
"SELECT * FROM local WHERE uid= ? ;", array($cuid));
307 if ($db->num_rows()) {
309 $this->local = $db->Record;
321 global $cuid, $db, $msg, $mysql;
322 if (!$this->olduid) {
323 $this->olduid = $cuid;
325 $db->query(
"select * from membres where uid= ? ;", array($uid));
326 if ($db->num_rows() == 0) {
327 $msg->raise(
"ERROR",
"mem", _(
"User or password incorrect"));
331 $this->user = $db->Record;
332 $cuid = $db->f(
"uid");
335 $mysql->reload_dbus();
346 if (!$this->olduid) {
349 $this->
su($this->olduid);
352 $mysql->reload_dbus();
362 global $db,
$user, $msg, $cuid, $hooks;
363 $_COOKIE[
"session"] = isset($_COOKIE[
"session"]) ? $_COOKIE[
"session"] :
'';
364 setcookie(
"session",
"", 0,
"/");
365 setcookie(
"oldid",
"", 0,
"/");
366 if ($_COOKIE[
"session"] ==
"") {
369 if (strlen($_COOKIE[
"session"]) != 32) {
372 $ip = get_remote_ip();
373 $db->query(
"select uid, ? as me,ip from sessions where sid= ? ;", array($ip, $_COOKIE[
"session"]));
374 if ($db->num_rows() == 0) {
378 $cuid = $db->f(
"uid");
379 $db->query(
"delete from sessions where sid= ? ;", array($_COOKIE[
"session"]));
381 $hooks->invoke(
"alternc_del_session");
396 function passwd($oldpass, $newpass, $newpass2) {
397 global $db, $msg, $cuid, $admin;
398 $msg->log(
"mem",
"passwd");
399 if (!$this->user[
"canpass"]) {
400 $msg->raise(
"ERROR",
"mem", _(
"You are not allowed to change your password."));
405 if (!password_verify($oldpass, $this->user[
'pass'])) {
406 $msg->raise(
"ERROR",
"mem", _(
"The old password is incorrect"));
411 if ($newpass != $newpass2) {
412 $msg->raise(
"ERROR",
"mem", _(
"The new passwords are differents, please retry"));
415 $db->query(
"SELECT login FROM membres WHERE uid= ? ;", array($cuid));
417 $login = $db->Record[
"login"];
418 if (!$admin->checkPolicy(
"mem", $login, $newpass)) {
421 $newpass = password_hash($newpass, PASSWORD_BCRYPT);
422 $db->query(
"UPDATE membres SET pass= ? WHERE uid= ?;", array($newpass, $cuid));
424 setcookie(
'require_old_password',
'', 1);
435 global $db, $msg, $cuid;
436 $msg->log(
"mem",
"admlist");
437 if (!$this->user[
"su"]) {
438 $msg->raise(
"ERROR",
"mem", _(
"You must be a system administrator to do this."));
441 $db->query(
"UPDATE membres SET admlist= ? WHERE uid= ?;", array($admlist, $cuid));
455 global $msg, $db, $L_HOSTING, $L_FQDN;
456 $msg->log(
"mem",
"send_pass");
457 $db->query(
"SELECT * FROM membres WHERE login= ? ;", array($login));
458 if (!$db->num_rows()) {
459 $msg->raise(
"ERROR",
"mem", _(
"This account is locked, contact the administrator."));
463 if (time() - $db->f(
"lastaskpass") < 86400) {
464 $msg->raise(
"ERROR",
"mem", _(
"The new passwords are differents, please retry"));
467 $txt = sprintf(_(
"Hello,
469 You requested the modification of your password for your
471 Here are your username and password to access the panel :
473 --------------------------------------
478 --------------------------------------
480 Note : if you didn't requested that modification, it means that
481 someone did it instead of you. You can choose to ignore this message.
482 If it happens again, please contact your server's Administrator.
485 "), $login, $L_HOSTING, $db->f(
"login"), $db->f(
"pass"));
486 mail($db->f(
"mail"),
"Your password on $L_HOSTING", $txt,
"From: postmaster@$L_FQDN\nReply-to: postmaster@$L_FQDN");
487 $db->query(
"UPDATE membres SET lastaskpass= ? WHERE login= ? ;", array(time(), $login));
499 global $msg, $db, $L_HOSTING, $L_FQDN, $cuid;
500 $msg->log(
"mem",
"changemail1", $newmail);
501 $db->query(
"SELECT * FROM membres WHERE uid= ? ;", array($cuid));
502 if (!$db->num_rows()) {
503 $msg->raise(
"ERROR",
"mem", _(
"This account is locked, contact the administrator."));
509 $COOKIE = substr(md5(mt_rand().mt_rand()), 0, 20);
511 $KEY = substr(md5(mt_rand().mt_rand()), 0, 6);
512 $link =
"https://$L_FQDN/mem_cm.php?usr=$cuid&cookie=$COOKIE&cle=$KEY";
513 $txt = sprintf(_(
"Hello,
515 Someone (maybe you) requested an email's address modification of the account
517 To confirm your request, go to this url :
521 (Warning : if this address is displayed on 2 lines, don't forgot to
522 take it on one line).
523 The panel will ask you the key given when the email address
524 modification was requested.
526 If you didn't asked for this modification, it means that someone
527 did it instead of you. You can choose to ignore this message. If it happens
528 again, please contact your server's administrator.
531 "), $db->f(
"login"), $L_HOSTING, $link);
532 mail($newmail,
"Email modification request on $L_HOSTING", $txt,
"From: postmaster@$L_FQDN\nReply-to: postmaster@$L_FQDN");
534 $db->query(
"DELETE FROM chgmail WHERE uid= ? ;", array($cuid));
535 $db->query(
"INSERT INTO chgmail (cookie,ckey,uid,mail,ts) VALUES ( ?, ?, ?, ?, ?);", array($COOKIE, $KEY, $cuid, $newmail, time()));
537 $lts = time() - 86400;
538 $db->query(
"DELETE FROM chgmail WHERE ts< ? ;", array($lts));
552 $msg->log(
"mem",
"changemail2", $uid);
553 $db->query(
"SELECT * FROM chgmail WHERE cookie= ? and ckey= ? and uid= ?;", array($COOKIE, $KEY, $uid));
554 if (!$db->num_rows()) {
555 $msg->raise(
"ERROR",
"mem", _(
"The information you entered is incorrect."));
561 $db->query(
"UPDATE membres SET mail= ? WHERE uid = ? ;", array($db->f(
"mail"), $uid));
563 $db->query(
"DELETE FROM chgmail WHERE uid= ? ;", array($uid));
565 $lts = time() - 86400;
566 $db->query(
"DELETE FROM chgmail WHERE ts< ? ;", array($lts));
576 global $db, $msg, $cuid;
577 $msg->log(
"mem",
"set_help_param", $show);
578 $db->query(
"UPDATE membres SET show_help= ? WHERE uid= ? ;", array($show, $cuid));
587 return $this->user[
"show_help"];
597 if ($this->user[
"show_help"] || $force) {
598 $hlp = _(
"hlp_$file");
599 if ($hlp !=
"hlp_$file") {
601 "#HELPID_([0-9]*)#",
"<a href=\"javascript:help(\\1);\"><img src=\"/aide/help.png\" width=\"17\" height=\"17\" style=\"vertical-align: middle;\" alt=\"" . _(
"Help") .
"\" /></a>", $hlp);
602 echo
"<p class=\"hlp\">" . $hlp .
"</p>";
617 $msg->debug(
"dom",
"get_creator_by_uid");
618 $db->query(
"select creator from membres where uid = ? ;", array($uid));
619 if (!$db->next_record()) {
622 return intval($db->f(
'creator'));
632 $msg->log(
"mem",
"export");
633 $str =
" <member>\n";
635 $str.=
" <uid>" . $users[
"uid"] .
"</uid>\n";
636 $str.=
" <login>" . $users[
"login"] .
"</login>\n";
637 $str.=
" <enabled>" . $users[
"enabled"] .
"</enabled>\n";
638 $str.=
" <su>" . $users[
"su"] .
"</su>\n";
639 $str.=
" <password>" . $users[
"pass"] .
"</password>\n";
640 $str.=
" <mail>" . $users[
"mail"] .
"</mail>\n";
641 $str.=
" <created>" . $users[
"created"] .
"</created>\n";
642 $str.=
" <lastip>" . $users[
"lastip"] .
"</lastip>\n";
643 $str.=
" <lastlogin>" . $users[
"lastlogin"] .
"</lastlogin>\n";
644 $str.=
" <lastfail>" . $users[
"lastfail"] .
"</lastfail>\n";
645 $str.=
" </member>\n";
651 if (empty($_COOKIE[
'session'])) {
654 $sid = $_COOKIE[
'session'];
655 if (empty($_SESSION[$sid .
'-' . $uid])) {
658 $j = $_SESSION[$sid .
'-' . $uid];
659 $j = json_decode($j,
true);
660 if (!empty($j[$v])) {
668 if (empty($_COOKIE[
'session'])) {
671 $sid = $_COOKIE[
'session'];
673 if (!empty($_SESSION[$sid .
'-' . $uid])) {
674 $p = json_decode($_SESSION[$sid .
'-' . $uid],
true);
676 if (!$ecrase && (isset($p[$k]) && is_array($p[$k])) && is_array($v)) {
677 $v = array_merge($p[$k], $v);
681 $_SESSION[$sid .
'-' . $uid] = json_encode($p);
689 global $msg, $L_FQDN, $L_HOSTING, $db;
691 $db->query(
"SELECT * FROM membres WHERE login = ? OR mail = ? ;", array($email_or_login, $email_or_login));
693 $msg->log(
'mem',
'send_reset_url',
'Password reset requested for: ' . $email_or_login);
695 $msg->raise(
'INFO',
'mem', _(
'An e-mail with information on how to connect has been sent to the owner of the account if one exists'));
700 if (!$db->num_rows()) {
701 $msg->log(
'mem',
'send_reset_url',
'No member found with login or mail ' . $email_or_login);
704 if ($db->num_rows()) {
708 $mail = $db->f(
'mail');
710 if (!$url || !$mail) {
713 $duration = variable_get(
'password_reset_expiration', 86400,
'The number of seconds for which a password reset link is valid');
714 $duration_hours = ($duration / 3600.0) .
' ' . _(
'hours');
715 $message = sprintf(_(
'
718 someone requested a password reset for your account at %s (%s).
720 You may connect to your account and change your account by clicking on the following URL or copying it into your browser :
724 This link may only be used once. You should change your password in your account settings once connected. This link will only be valid for %s, and no changes will be made if it is not used.
725 '), $L_HOSTING, $L_FQDN, $url, $duration_hours);
726 mail($mail,
"Password reset request on {$L_HOSTING}", $message,
"From: postmaster@{$L_FQDN}\nReply-to: postmaster@{$L_FQDN}");
727 $msg->log(
'mem',
'send_reset_url',
"Password reset e-mail sent for account {$uid} at {$mail}");
741 $db->query(
"SELECT * FROM membres WHERE uid = ? ;", array($uid));
742 if (!$db->num_rows()) {
745 if ($db->num_rows()) {
748 return $this->
_get_reset_url(time(), $db->f(
'uid'), $db->f(
'login'), $db->f(
'pass'));
761 $salt = variable_get(
'salt_password_reset', base64_encode(random_bytes(128)),
'The salt used when hasing password resets - change to invalidate all existing reset tokens') . $password;
762 $data = $timestamp . $uid . $login;
763 $token = hash_hmac(
'sha512', $data, $salt);
766 return 'https://' . $L_FQDN .
'/reset.php?' . http_build_query(array(
768 'timestamp' => $timestamp,
776 function temporary_login($uid, $timestamp, $token, $restrictip = 0, $authip_token =
false) {
777 global $db, $msg, $cuid, $authip;
781 $msg->log(
"mem",
"temporary_login", $username);
782 if ($msg->has_msgs(
"ERROR")) {
786 $db->query(
"select * from membres where uid= ? ;", array($uid));
787 if ($db->num_rows() == 0) {
794 if (!$db->f(
"enabled")) {
795 $msg->raise(
"ERROR",
"mem", _(
"This account is locked, contact the administrator."));
799 $this->user = $db->Record;
800 $cuid = $db->f(
"uid");
801 if (panel_islocked() && $cuid != 2000) {
802 $msg->raise(
"ALERT",
"mem", _(
"This website is currently under maintenance, login is currently disabled."));
812 $aga = $authip->get_allowed(
'panel');
813 foreach ($aga as $k => $v) {
814 if ($authip->is_in_subnet(get_remote_ip(), $v[
'ip'], $v[
'subnet'])) {
820 if (
sizeof($aga) > 1 && !$allowed_ip && !$authip->is_wl(get_remote_ip())) {
821 $msg->raise(
"ERROR",
"mem", _(
"Your IP isn't allowed to connect"));
827 $ip = get_remote_ip();
833 $db->query(
"DELETE FROM sessions WHERE DATE_ADD(ts,INTERVAL 2 DAY)<NOW();");
836 if (isset($_COOKIE[
"oldid"])) {
837 setcookie(
'oldid',
'', 0,
'/');
841 $sess = md5(mt_rand().mt_rand().mt_rand());
842 $_REQUEST[
"session"] = $sess;
843 $db->query(
"insert into sessions (sid,ip,uid) values (?, ?, ?);", array($sess, $ip, $cuid));
844 setcookie(
"session", $sess, 0,
"/");
848 $db->query(
"SELECT * FROM local WHERE uid= ? ;", array($cuid));
849 if ($db->num_rows()) {
851 $this->local = $db->Record;
857 $db->query(
'select lastlogin, pass from membres where uid = ?;', array($uid));
858 if ($db->num_rows()) {
860 $cookie_data = $cuid . $db->f(
'lastlogin');
861 $salt = variable_get(
'salt_password_reset', base64_encode(random_bytes(128))) . $db->f(
'pass');
862 $c = setcookie(
'require_old_password', hash_hmac(
'sha512', $cookie_data, $salt), 0,
'/');
864 $msg->log(
'mem',
'temporary_login',
'Failed to set cookie require_old_password');
872 $cookie = $_COOKIE[
'require_old_password'];
876 $db->query(
'select lastlogin, pass from membres where uid = ?;', array($cuid));
877 if ($db->num_rows()) {
879 $cookie_data = $cuid . $db->f(
'lastlogin');
880 $salt = variable_get(
'salt_password_reset', base64_encode(random_bytes(128))) . $db->f(
'pass');
881 if ($cookie == hash_hmac(
'sha512', $cookie_data, $salt)) {
892 global $cuid, $db, $msg;
895 $msg->raise(
'ERROR',
'mem', _(
'You are already logged in, you may not use a one-time login link'));
896 $msg->log(
'mem',
'validate_reset_url',
'Refused one-time log-in since the user is already connected');
901 $fail_message = _(
'The login-link has already been used or is expired');
902 $duration = variable_get(
'password_reset_expiration', 86400,
'The number of seconds for which a password reset link is valid');
903 if (time() - $timestamp >= $duration) {
904 $msg->raise(
'ERROR',
'mem', $fail_message);
905 $msg->log(
'mem',
'validate_reset_url',
'Refused one-time log-in since the time elapsed is greater than limit of ' . $duration);
909 $db->query(
"SELECT * FROM membres WHERE uid = ? ;", array($uid));
910 if (!$db->num_rows()) {
911 $msg->raise(
'ERROR',
'mem', $fail_message);
912 $msg->log(
'mem',
'validate_reset_url',
'Refused one-time log-in since a user with ID ' . $uid.
' does not exist');
916 $last_login = strtotime($db->f(
'lastlogin'));
918 if ($last_login >= time() || $last_login >= $timestamp) {
919 $msg->raise(
'ERROR',
'mem', $fail_message);
920 $msg->log(
'mem',
'validate_reset_url',
"Refused one-time log-in since the most recent login was more recent than the timestamp in the log-in link. Last: {$last_login}, Timestamp: {$timestamp}");
925 if (!$db->f(
'enabled') || !$db->f(
'canpass')) {
926 $msg->raise(
'ERROR',
'mem', $fail_message);
927 $msg->log(
'mem',
'validate_reset_url',
'Refused one-time log-in since the user account is disabled or cannot change it\'s password.');
933 $salt = variable_get(
'salt_password_reset', base64_encode(random_bytes(128))) . $db->f(
'pass');
934 $data = $timestamp . $uid . $db->f(
'login');
935 $ref_token = hash_hmac(
'sha512', $data, $salt);
936 if ($token != $ref_token) {
937 $msg->raise(
'ERROR',
'mem', $fail_message);
941 $msg->raise(
'INFO',
'mem', _(
'You have used a one-time login link. Please set a new password now.'));
This class manage user sessions in the web desktop.
$user
This array contains the Tableau contenant les champs de la table "membres" du membre courant.
hook_menu()
hook called by the m_menu class to add menu to the left of the panel
temporary_login($uid, $timestamp, $token, $restrictip=0, $authip_token=false)
Logs a user in from a one-time login link.
get_help_param()
tell if the help parameter is set
ChangeMail2($COOKIE, $KEY, $uid)
Change the email of a member (second step, Cookie + key change)
alternc_password_policy()
Password kind used in this class (hook for admin class)
setid($id)
Start a session as another user from an administrator account.
checkright()
Check that the current user is an admnistrator.
alternc_export_conf()
Exports all the personal user related information for an account.
generate_reset_url($uid)
Generate a reset URL for an account given it's e-mail or login.
session_tempo_params_get($v)
unsu()
Goes back to the original identity (of an admin, usually)
$olduid
Original uid for the temporary uid swapping (for administrators)
validate_reset_url($uid, $timestamp, $token)
Validates a reset URL that has been received.
del_session()
Ends a session on the panel (logout)
login($username, $password, $restrictip=0, $authip_token=false)
Start a session in the web desktop.
ChangeMail1($newmail)
Change the email of an account (first step: sending of a Cookie) TODO : insert this mail string into ...
requires_old_password_for_change()
set_help_param($show)
Change the help parameter.
$local
contains all the fields of the "local" table for an account in AlternC.
su($uid)
Change the identity of the user temporarily (SUDO)
checkid($show_msg=true)
Check that the current session is correct (valid cookie) If necessary, and if we received username & ...
passwd($oldpass, $newpass, $newpass2)
Change the password of the current user.
resetlast()
After a successful connection, reset the user's last connection date.
adminpref($admlist)
Change the administrator preferences of an admin account.
send_reset_url($email_or_login)
Sends a password-reset URL.
send_pass($login)
Send a mail with a password to an account Note : We can ask for a password only once a day TODO : Tra...
_get_reset_url($timestamp, $uid, $login, $password)
Builds a full reset URL from the uid, login, password and timestamp.
show_help($file, $force=false)
show (echo) a contextual help
session_tempo_params_set($k, $v, $ecrase=false)