login_err; case "scrambler": Base::session_init (); if (empty ($_SESSION['cms']['scrambler'])) { Base::session_open (); $_SESSION['cms']['scrambler'] = md5 (time ()); Base::session_close (); } return $_SESSION['cms']['scrambler']; default: return self::get ($name); } } /** * Daten zum angemeldeten User abfragen. Wird kein 'key' angegeben, wird ein assoziatives Array mit allen verfügbaren Daten zurückgegeben * * \param key name des gesuchten Wertes (optional) * \param defaultvalue Wert der zurückgegeben wird, wenn der gesuchte Wert nicht verfügbar ist (optional) * \return Wenn ein key angegeben ist der gesuchte Wert wenn verfügbar sonst der angegebene defaultwert oder ein leerstring, andernfalls ein assoziatives Array mit allen verfügbaren Daten */ public static function get ($key="", $defaultvalue="") { if ($key == "id") { Base::session_init (); return isset ($_SESSION['cms']['user']['id']) ? $_SESSION['cms']['user']['id'] : 0; } else if (!self::$user) { self::loadData (); } return (!$key) ? self::$user : (isset (self::$user[$key]) ? self::$user[$key] : $defaultvalue); } /** * Läd alle userspezifischen Daten des angemeldeten Users in den Objekt Cache */ public static function loadData () { $user_id = self::get ("id"); if ($user_id && Setting::checkDb ()) { // Userdaten aus DB holen $db = new Database (); if ($db->query ("SELECT * FROM `{prefix}user` WHERE id='$user_id'")) { self::$user = $db[0]; self::$user['is_ldap_user'] = self::$user['status'] & self::STATUS_LDAP_USER; // Rechte auswerten $groups = array (); foreach (explode (",", self::$user['groups']) as $group) { $group = trim ($group); $name = preg_replace ("/[+-]$/", "", $group); if ($name) { $groups[$name] = self::RIGHT_VIEW; $groups[$name] |= !preg_match ("/\-$/", $group) ? self::RIGHT_EDIT : self::RIGHT_NONE; $groups[$name] |= preg_match ("/\+$/", $group) ? self::RIGHT_ONLINE : self::RIGHT_NONE; } } $groups[$user_id] = isset ($groups['self']) ? $groups['self'] : self::RIGHT_ONLINE; unset ($groups['self']); self::$user['groups'] = $groups; // User spezifische einstellungen laden foreach (Setting::get ("user/".self::$user['id'], array ()) as $key => $value) { if (!isset(self::$user[$key])) { self::$user[$key] = $value; } } } } else { self::$user = array (); } } /** * Editierrechte des angemeldeten Users für die angegebene Gruppen Kombination abfragen * * \param groups Gruppen für die ermettelt werden soll welche Rechte der User hat \n * Komma getrennte Gruppen sind alternativ, die Gruppe mit den höchsten Rechten bestimmt den Modus \n * Space getrennte Gruppen sind aditional, die Gruppe mit den niedrigsten Rechten bestimmt den Modus \n * Bsp.: "site de, navi" => 'site' und 'de' Rechte oder 'navi' Rechte müssen bestehen * \return User::RIGHT_NONE | User::RIGHT_VIEW | User::RIGHT_EDIT | User::RIGHT_ONLINE */ public static function getEditRight ($groups) { $mode = self::RIGHT_NONE; if (self::get('id')) { if (Setting::get ("system", "disable_cms")) { // Editieren ist deaktiviert (über Systemeinstellungen) } else if (self::get('is_admin')) { $mode = self::RIGHT_VIEW | self::RIGHT_EDIT | self::RIGHT_ONLINE; } else { foreach (explode (",", $groups.",all") as $group) { if ($group) { $mod = self::RIGHT_VIEW | self::RIGHT_EDIT | self::RIGHT_ONLINE; foreach (explode (" ", $group) as $name) { if ($name) { $mod &= isset (self::$user['groups'][$name]) ? self::$user['groups'][$name] : self::RIGHT_NONE; } } $mode |= $mod; } } } } return $mode; } /** * Daten zu einem User setzen. Wird keine id angegeben und existiert der gegebene username noch nicht, so wird ein neuer User angelegt. * * \param id ID des Users dessen Daten geändert werden sollen oder 0 für einen neuen User * \param values Ein assoziativ Array mit den Daten die gesetzt werden sollen (realname, username, password, groups, may_edit_users, is_admin, beliebige weitere Werte) * \param set_history wenn true dann wird die Änderung in der History vermerkt, andernfalls wird kein History Eintrag erstellt * \return ID des Users bei erfolgreicher Ausführung, false wenn die Rechte für die Änderung fehlen, -1 wenn der Username bereits von einem anderem User verwendet wird */ public static function set ($id, $values, $set_history=true) { $db = new Database (); $id = (Base::is_int ($id)) ? $id : 0; $values = Database::escape ($values); if (self::get('may_edit_users') || $id == self::get('id')) { $history = new History ("user set"); $history->groupStart(); // Prüfen ob Username bereits vergeben ist $username = isset ($values['username']) ? $values['username'] : ""; if ((!$id && !$username) || $db->query ("SELECT id FROM `{prefix}user` WHERE id!=$id AND username='$username' AND !(status&".self::STATUS_ERASED.")")) { return -1; } if (!$id || !$db->query ("SELECT id FROM `{prefix}user` WHERE id=$id")) { // Neuen User anlegen $db->query ("INSERT INTO `{prefix}user` (status) VALUES (".self::STATUS_ERASED.")"); $id = $db->rowid; $history->storeOld ($id, "user", false); $db->query ("UPDATE `{prefix}user` SET status=".self::STATUS_DB_USER." WHERE id=$id"); } // Daten speichern if ($set_history) { $history->storeOld ($id, "user", false); } foreach ($values as $name => $value) { if ($name == "id" || (($name == "may_edit_users" || $name == "may_make_backups") && !self::$user['is_admin'] && (!self::$user[$name] || $id == self::$user['id'])) || ($name == "is_admin" && (!self::$user['is_admin'] || $id == self::$user['id'])) || ($name == "groups" && !self::$user['is_admin'] && $id == self::$user['id'])) { continue; } if ($name == "password") { $value = md5 ($value); } if ($name == "groups") { $values = array (); foreach (explode (",", $value) as $group) { $group = trim ($group); $groupName = preg_replace ("/[+-]$/", "", $group); $userRight = max (isset (self::$user['groups'][$groupName]) ? self::$user['groups'][$groupName] : self::RIGHT_NONE, isset (self::$user['groups']['all']) ? self::$user['groups']['all'] : self::RIGHT_NONE, self::$user['is_admin'] ? self::RIGHT_ONLINE : self::RIGHT_NONE); if ($userRight) { $right = self::RIGHT_VIEW; $right |= !preg_match ("/\-$/", $group) ? self::RIGHT_EDIT : self::RIGHT_NONE; $right |= preg_match ("/\+$/", $group) ? self::RIGHT_ONLINE : self::RIGHT_NONE; $right = min ($right, $userRight); $values[$groupName] = $groupName . (($right&self::RIGHT_ONLINE) ? "+" : (($right&self::RIGHT_EDIT) ? "" : "-")); } } $value = implode (",", $values); } if ($name == "realname" || $name == "username" || $name == "password" || $name == "groups" || $name == "may_edit_users" || $name == "is_admin") { $db->query ("UPDATE `{prefix}user` SET $name='$value' WHERE id=$id"); } else { Setting::set ("user/$id", $name, $value, $set_history); } if ($id == self::$user['id']) { self::$user[$name] = $value; } } if ($set_history) { $history->store ($id, "user", false); } $history->groupEnd(); // LDAP User in LDAP Datenbank speichern if ($db->query ("SELECT id FROM `{prefix}user` WHERE id=$id AND status&".self::STATUS_LDAP_USER)) { self::setLdap ($id, $values); } return $id; } return false; } /** * Userdaten in LDAP speichern sofern der angegebene User über LDAP verwaltet wird * * \param id ID des Users dessen Daten geändert werden sollen * \param values Ein assoziativ Array mit den Daten die geändert werden sollen (groups, may_edit_users, is_admin) * \return true wenn der angegebene User über LDAP verwaltet wird, sonst false */ public static function setLdap ($id, $values) { $id = (Base::is_int ($id)) ? $id : 0; $conf = Setting::get ("config", "ldap"); if (($conf && !empty ($conf['manager'])) && ($ldap_c = ldap_connect ($conf['hostname'])) && @ldap_bind ($ldap_c, "{$conf['manager']}, {$conf['base']}", $conf['password'])) { $val = array (); isset ($values ['groups']) && $val['cmsGroups'] = $values ['groups'] ? $values ['groups'] : array (); isset ($values ['may_edit_users']) && $val['cmsMayEditUsers'] = $values ['may_edit_users'] ? "TRUE" : "FALSE"; isset ($values ['is_admin']) && $val['cmsIsAdmin'] = $values ['is_admin'] ? "TRUE" : "FALSE"; $conf['server'] = isset ($conf['server']) ? $conf['server'] : "cmsServer=".preg_replace ("/\..*/", "", $_SERVER['SERVER_NAME']); $db = new Database (); if ($val && $db->query ("SELECT username FROM `{prefix}user` WHERE id=$id")) { $username = $db['username']; ldap_modify ($ldap_c, "{$conf['server']}, uid=$username, {$conf['users']}, {$conf['base']}", $val); return true; } } return false; } /** * Liste mit Daten aller registrierten User oder zu dem User der angegebenen id * * \param id ID des Users zu dem die Daten gesucht werden (optional). Ist ID 0 werden die Daten zu allen Usern geliefert * \return Ein oder mehrere assoziative Arrays mit den gesuchten Userdaten */ public static function getList ($id=0) { $id = (Base::is_int ($id)) ? $id : 0; $db = new Database (); $users = array (); if ($db->query ("SELECT * FROM `{prefix}user` WHERE ($id=0 OR id=$id) AND ('".self::get("is_admin")."' OR !is_admin) AND !(status&".self::STATUS_ERASED.") ORDER BY realname")) { foreach ($db->result as $user) { $mayEdit = true; if (!self::get('is_admin')) { foreach (explode (",", $user['groups']) as $group) { $group = trim ($group); $groupName = preg_replace ("/[+-]$/", "", $group); $userRight = max (isset (self::$user['groups'][$groupName]) ? self::$user['groups'][$groupName] : self::RIGHT_NONE, isset (self::$user['groups']['all']) ? self::$user['groups']['all'] : self::RIGHT_NONE, !empty (self::$user['is_admin']) ? self::RIGHT_ONLINE : self::RIGHT_NONE); $right = self::RIGHT_VIEW; $right |= !preg_match ("/\-$/", $group) ? self::RIGHT_EDIT : self::RIGHT_NONE; $right |= preg_match ("/\+$/", $group) ? self::RIGHT_ONLINE : self::RIGHT_NONE; if ($userRight < $right) { $mayEdit = false; break; } } } if ($mayEdit) { $users[] = Setting::get ("user/{$user['id']}", "", $user); } } if ($id) { $users = $users[0]; } } return $users; } /** * Liste der bisher verwendeten editier Gruppen (Namen von Gruppen denen die User angehören) * * \param withSpecialGroups Wenn true werden auch sondergruppen (self, all, ticket) zurückgegeben (optional) * \return Ein assoziatives Array aus gruppennamen und die Gruppe beschreibener text */ public static function getEditGroups ($withSpecialGroups=false) { $db = new Database (); $groups = array (); $groupList = ""; if ($db->query ("SELECT DISTINCT groups FROM `{prefix}user` WHERE !(status&".self::STATUS_ERASED.")")) { foreach ($db as $row) { $groupList .= ",".$row['groups']; } } if ($db->query ("SELECT DISTINCT edit_groups FROM `{prefix}group` WHERE !(status&".Base::STATUS_ERASED.")")) { foreach ($db as $row) { $groupList .= ",".$row['edit_groups']; } } foreach (explode (",", $groupList) as $group) { $group = trim (preg_replace ("/[-+]$|(^| +)\d+($| +)/", "", $group)); if ($group) { $groups[$group] = $group; } } unset ($groups['self']); unset ($groups['all']); asort ($groups); if ($withSpecialGroups) { $groups['self'] = "- self -"; $groups['all'] = "- all groups -"; $groups['ticket'] = "- tickets -"; } return $groups; } /** * Den angegebenen User löschen * * \param id ID des Users der gelöscht werden soll */ public static function del ($id) { $db = new Database (); $id = (Base::is_int ($id)) ? $id : 0; if (self::get('may_edit_users')) { $history = new History ("user del"); $history->storeOld ($id, "user", false); $db->query ("UPDATE `{prefix}user` SET status=status|".self::STATUS_ERASED." WHERE id=$id"); $history->store ($id, "user", false); } } /** * Den angemeldeten User ausloggen */ public static function logout () { self::$user = array (); Base::session_open (); foreach ($_SESSION['cms'] as $key => $row) { if (is_array ($row)) { unset ($_SESSION['cms'][$key]); } } Base::session_close (); } /** * Den angegebenen User anmelden * * \param username Username des Users * \param password Passwort des Users * \return ID des Users wenn der Login erfolgreich war, sonst 0 */ public function login ($username, $password=null, $scrambler="") { self::logout (); Base::session_open (); $_SESSION['cms']['user']['id'] = $this->dbLogin ($username, $password, $scrambler); if (!$_SESSION['cms']['user']['id'] && Setting::get ("config", "ldap")) { $_SESSION['cms']['user']['id'] = $this->ldapLogin ($username, $password); } Base::session_close (); return $_SESSION['cms']['user']['id']; } /** * Den angegebenen User über die cms-Datenbank anmelden * * \param username Username des Users * \param password Passwort des Users * \return ID des Users wenn der Login erfolgreich war, sonst 0 */ public function smfLogin ($user) { global $sc; $db = new Database (); $user = Database::escape ($user); if (empty($user['is_guest'])) { if ($db->query ("SELECT id FROM `{prefix}user` WHERE username='{$user['username']}' AND !(status&".self::STATUS_ERASED.")")) { $id = $db['id']; $history = new History ("user set"); $history->storeOld ($id, "user", false); $db->query ("UPDATE `{prefix}user` SET may_edit_users='{$user['can_mod']}', is_admin='{$user['is_admin']}', realname='{$user['name']}' WHERE id={$id}"); $history->store ($id, "user", false); Setting::set ("user/$id", "email", $user['email']); Setting::set ("user/$id", "language", strstr($user['language'], "german") ? "de" : "en"); Base::session_open (); $_SESSION['cms']['user']['id'] = $id; Base::session_close (); return $id; } } return 0; } /** * Den angegebenen User über LDAP anmelden * * \param username Username des Users * \return ID des Users wenn der Login erfolgreich war, sonst 0 */ private function ldapLogin ($username, $password=null) { $db = new Database (); $username = Database::escape ($username); $conf = Setting::get ("config", "ldap"); $conf['server'] = isset ($conf['server']) ? $conf['server'] : "cmsServer=".preg_replace ("/\..*/", "", $_SERVER['SERVER_NAME']); $user = array (); if ($username) { if ($ldap_c = ldap_connect ($conf['hostname'])) { if ($password!==null) { // es wurde nicht die http Authentifizierung benutzt $base = !empty ($conf['users']) ? ($conf['users'].",".$conf['base']) : $conf['base']; if (@ldap_bind ($ldap_c, "uid=$username, $base", $password)) { if (empty ($conf['manager']) && ($ldap_s = ldap_search ($ldap_c, $base, "uid=$username", array ("cn"))) && ($ldap_e = ldap_get_entries ($ldap_c, $ldap_s)) && !empty ($ldap_e[0]['cn'])) { $user['realname'] = Database::escape ($ldap_e[0]['cn'][0]); if ($db->query ("SELECT id FROM `{prefix}user` WHERE username='$username'")) { $user['id'] = $db['id']; } else if (!empty ($conf['gust_groups'])) { $db->query ("INSERT INTO `{prefix}user` (username, status) VALUES ('$username', ".self::STATUS_ERASED.")"); $user['id'] = $db->rowid; // Gastaccount für alle LDAP User $user['groups'] = Database::escape ($conf['gust_groups']); $db->query ("UPDATE `{prefix}user` SET groups='{$user['groups']}' WHERE id={$user['id']}"); } if (!empty ($user['id'])) { $history = new History ("user set"); $history->storeOld ($user['id'], "user", false); $db->query ("UPDATE `{prefix}user` SET realname='{$user['realname']}', status=".self::STATUS_LDAP_USER." WHERE id={$user['id']}"); $history->store ($user['id'], "user", false); } else { $username = ""; } } } else { $username = ""; } } if ($username && !empty ($conf['manager']) && @ldap_bind ($ldap_c, "{$conf['manager']}, {$conf['base']}", $conf['password'])) { // LDAP Verbindung mit LdapManager aufbauen // CMS Daten aus ldap lesen if (($ldap_s = @ldap_search ($ldap_c, "uid=$username, {$conf['users']}, {$conf['base']}", $conf['server'], array ("cmsIsAdmin", "cmsMayEditUsers", "cmsGroups"))) && ($ldap_e = ldap_get_entries ($ldap_c, $ldap_s)) && isset ($ldap_e[0])) { $user['groups'] = isset ($ldap_e[0]['cmsgroups'][0]) ? $ldap_e[0]['cmsgroups'][0] : ""; $user['may_edit_users'] = isset ($ldap_e[0]['cmsmayeditusers'][0]) && $ldap_e[0]['cmsmayeditusers'][0]=="TRUE"; $user['may_edit_i18n'] = isset ($ldap_e[0]['cmsmayediti18n'][0]) && $ldap_e[0]['cmsmayediti18n'][0]=="TRUE"; $user['may_make_backups'] = isset ($ldap_e[0]['cmsmaymakebackups'][0]) && $ldap_e[0]['cmsmaymakebackups'][0]=="TRUE"; $user['is_admin'] = isset ($ldap_e[0]['cmsisadmin'][0]) && $ldap_e[0]['cmsisadmin'][0]=="TRUE"; } // User ist Superadmin if (($ldap_s = ldap_search ($ldap_c, "{$conf['users']}, {$conf['base']}", "uid=$username", array ("cmsIsSuperAdmin"))) && ($ldap_e = ldap_get_entries ($ldap_c, $ldap_s)) && isset ($ldap_e[0]['cmsissuperadmin'][0]) && $ldap_e[0]['cmsissuperadmin'][0]=="TRUE") { $user['groups'] = "admin"; $user['is_admin'] = true; } // Realname des Users if (($user || !empty ($conf['gust_groups'])) && ($ldap_s = ldap_search ($ldap_c, "{$conf['users']}, {$conf['base']}", "uid=$username", array ("cn"))) && ($ldap_e = ldap_get_entries ($ldap_c, $ldap_s)) && !empty ($ldap_e[0]['cn'])) { if (!$user && !empty ($conf['gust_groups'])) { // Gastaccount für alle LDAP User $user['groups'] = $conf['gust_groups']; } $user['realname'] = $ldap_e[0]['cn'][0]; } // Userdaten in cms-DB übertragen if ($user) { if ($db->query ("SELECT id FROM `{prefix}user` WHERE username='$username' AND status=".self::STATUS_LDAP_USER)) { $user['id'] = $db['id']; } else { $db->query ("INSERT INTO `{prefix}user` (username, status) VALUES ('$username', ".self::STATUS_ERASED.")"); $user['id'] = $db->rowid; } $user = Database::escape ($user); $history = new History ("user set"); $history->storeOld ($user['id'], "user", false); $db->query ("UPDATE `{prefix}user` SET groups='{$user['groups']}', may_edit_users='{$user['may_edit_users']}', is_admin='{$user['is_admin']}', realname='{$user['realname']}', status=".self::STATUS_LDAP_USER." WHERE id={$user['id']}"); $history->store ($user['id'], "user", false); } } } if (empty ($user['id'])) { $this->login_err = ldap_error ($ldap_c); if ($this->login_err == "Success") { $this->login_err = "no cms account on this server"; } } ldap_unbind ($ldap_c); } return isset ($user['id']) ? $user['id'] : 0; } /** * Den angegebenen User über die cms-Datenbank anmelden * * \param username Username des Users * \param password Passwort des Users * \return ID des Users wenn der Login erfolgreich war, sonst 0 */ private function dbLogin ($username, $password, $scrambler="") { $db = new Database (); $username = Database::escape ($username); $password = Database::escape ($password); $scrambler = $scrambler ? Database::escape ($scrambler) : $this->scrambler; if ($username && $password) { // Verzoegertes einloggen bei mehreren Zugriffen gleichzeitig $logintime = Setting::get ("user", "logintime", 0) + 3; Setting::set ("user", "logintime", $logintime, false); $wait = $logintime - time (); if ($wait > 6) { // zu viele Versuche Setting::set ("user", "logintime", time () + 6, false); $this->login_err = "to many trials"; } else if ($wait > 0) { // verzoegertes Einloggen sleep ($wait); } else { // letzter Versuch ist lange her Setting::set ("user", "logintime", time (), false); } if ($db->query ("SELECT id FROM `{prefix}user` WHERE username='$username' AND MD5(CONCAT(password,'$scrambler'))='$password' AND !(status&".self::STATUS_ERASED.")")) { Setting::set ("user", "logintime", time ()-3, false); Base::session_open (); unset ($_SESSION['cms']['scrambler']); Base::session_close (); return $db['id']; } } return 0; } } ?>