Пример #1
0
 /**
  * This function generates the unique index for a specific lock key.
  * Once an index is assigned to a key, it never changes - so this is
  * statically cached.
  *
  * @param string $key
  * @return int
  * @throws \moodle_exception
  */
 protected function get_index_from_key($key)
 {
     if (isset(self::$lockidcache[$key])) {
         return self::$lockidcache[$key];
     }
     $index = 0;
     $record = $this->db->get_record('lock_db', array('resourcekey' => $key));
     if ($record) {
         $index = $record->id;
     }
     if (!$index) {
         $record = new \stdClass();
         $record->resourcekey = $key;
         try {
             $index = $this->db->insert_record('lock_db', $record);
         } catch (\dml_exception $de) {
             // Race condition - never mind - now the value is guaranteed to exist.
             $record = $this->db->get_record('lock_db', array('resourcekey' => $key));
             if ($record) {
                 $index = $record->id;
             }
         }
     }
     if (!$index) {
         throw new \moodle_exception('Could not generate unique index for key');
     }
     self::$lockidcache[$key] = $index;
     return $index;
 }
Пример #2
0
 /**
  * Write session handler.
  *
  * {@see http://php.net/manual/en/function.session-set-save-handler.php}
  *
  * NOTE: Do not write to output or throw any exceptions!
  *       Hopefully the next page is going to display nice error or it recovers...
  *
  * @param string $sid
  * @param string $session_data
  * @return bool success
  */
 public function handler_write($sid, $session_data)
 {
     global $USER;
     // TODO: MDL-20625 we need to rollback all active transactions and log error if any open needed
     if ($this->failed) {
         // do not write anything back - we failed to start the session properly
         return false;
     }
     $userid = 0;
     if (!empty($USER->realuser)) {
         $userid = $USER->realuser;
     } else {
         if (!empty($USER->id)) {
             $userid = $USER->id;
         }
     }
     if (isset($this->record->id)) {
         $data = base64_encode($session_data);
         // There might be some binary mess :-(
         // Skip db update if nothing changed,
         // do not update the timemodified each second.
         $hash = sha1($data);
         if ($this->lasthash === $hash and $this->record->userid == $userid and time() - $this->record->timemodified < 20 and $this->record->lastip == getremoteaddr()) {
             // No need to update anything!
             return true;
         }
         $this->record->sessdata = $data;
         $this->record->userid = $userid;
         $this->record->timemodified = time();
         $this->record->lastip = getremoteaddr();
         try {
             $this->database->update_record_raw('sessions', $this->record);
             $this->lasthash = $hash;
         } catch (dml_exception $ex) {
             if ($this->database->get_dbfamily() === 'mysql') {
                 try {
                     $this->database->set_field('sessions', 'state', 9, array('id' => $this->record->id));
                 } catch (Exception $ignored) {
                 }
                 error_log('Can not write database session - please verify max_allowed_packet is at least 4M!');
             } else {
                 error_log('Can not write database session');
             }
             return false;
         } catch (Exception $ex) {
             error_log('Can not write database session');
             return false;
         }
     } else {
         // fresh new session
         try {
             $record = new stdClass();
             $record->state = 0;
             $record->sid = $sid;
             $record->sessdata = base64_encode($session_data);
             // there might be some binary mess :-(
             $record->userid = $userid;
             $record->timecreated = $record->timemodified = time();
             $record->firstip = $record->lastip = getremoteaddr();
             $record->id = $this->database->insert_record_raw('sessions', $record);
             $this->record = $this->database->get_record('sessions', array('id' => $record->id));
             $this->lasthash = sha1($record->sessdata);
             $this->database->get_session_lock($this->record->id, SESSION_ACQUIRE_LOCK_TIMEOUT);
         } catch (Exception $ex) {
             // this should not happen
             error_log('Can not write new database session or acquire session lock');
             $this->failed = true;
             return false;
         }
     }
     return true;
 }
Пример #3
0
 /**
  * Read session handler
  *
  * {@see http://php.net/manual/en/function.session-set-save-handler.php}
  *
  * @param string $sid
  * @return string
  */
 public function handler_read($sid)
 {
     global $CFG;
     if ($this->record and $this->record->sid != $sid) {
         error_log('Weird error reading database session - mismatched sid');
         $this->failed = true;
         return '';
     }
     try {
         if (!($record = $this->database->get_record('sessions', array('sid' => $sid)))) {
             $record = new stdClass();
             $record->state = 0;
             $record->sid = $sid;
             $record->sessdata = null;
             $record->userid = 0;
             $record->timecreated = $record->timemodified = time();
             $record->firstip = $record->lastip = getremoteaddr();
             $record->id = $this->database->insert_record_raw('sessions', $record);
         }
     } catch (Exception $ex) {
         // do not rethrow exceptions here, we need this to work somehow before 1.9.x upgrade and during install
         error_log('Can not read or insert database sessions');
         $this->failed = true;
         return '';
     }
     try {
         $this->database->get_session_lock($record->id, SESSION_ACQUIRE_LOCK_TIMEOUT);
     } catch (Exception $ex) {
         // This is a fatal error, better inform users.
         // It should not happen very often - all pages that need long time to execute
         // should close session soon after access control checks
         error_log('Can not obtain session lock');
         $this->failed = true;
         throw $ex;
     }
     // verify timeout
     if ($record->timemodified + $CFG->sessiontimeout < time()) {
         $ignoretimeout = false;
         if (!empty($record->userid)) {
             // skips not logged in
             if ($user = $this->database->get_record('user', array('id' => $record->userid))) {
                 if (!isguestuser($user)) {
                     $authsequence = get_enabled_auth_plugins();
                     // auths, in sequence
                     foreach ($authsequence as $authname) {
                         $authplugin = get_auth_plugin($authname);
                         if ($authplugin->ignore_timeout_hook($user, $record->sid, $record->timecreated, $record->timemodified)) {
                             $ignoretimeout = true;
                             break;
                         }
                     }
                 }
             }
         }
         if ($ignoretimeout) {
             //refresh session
             $record->timemodified = time();
             try {
                 $this->database->update_record('sessions', $record);
             } catch (Exception $ex) {
                 // very unlikely error
                 error_log('Can not refresh database session');
                 $this->failed = true;
                 throw $ex;
             }
         } else {
             //time out session
             $record->state = 0;
             $record->sessdata = null;
             $record->userid = 0;
             $record->timecreated = $record->timemodified = time();
             $record->firstip = $record->lastip = getremoteaddr();
             try {
                 $this->database->update_record('sessions', $record);
             } catch (Exception $ex) {
                 // very unlikely error
                 error_log('Can not time out database session');
                 $this->failed = true;
                 throw $ex;
             }
         }
     }
     $data = is_null($record->sessdata) ? '' : base64_decode($record->sessdata);
     unset($record->sessdata);
     // conserve memory
     $this->record = $record;
     return $data;
 }
Пример #4
0
 /**
  * @param stdClass $instance
  * @param $name
  * @param moodle_database $DB
  * @return int|mixed id of the group
  * @throws coding_exception
  * @throws moodle_exception
  */
 private function get_group(stdClass $instance, $name, moodle_database $DB)
 {
     $idnumber = "autoenrol|{$instance->id}|{$name}";
     $group = $DB->get_record('groups', array('idnumber' => $idnumber, 'courseid' => $instance->courseid));
     if ($group == null) {
         $newgroupdata = new stdclass();
         $newgroupdata->courseid = $instance->courseid;
         $newgroupdata->name = $name;
         $newgroupdata->idnumber = $idnumber;
         $newgroupdata->description = get_string('auto_desc', 'enrol_autoenrol');
         $group = groups_create_group($newgroupdata);
     } else {
         $group = $group->id;
     }
     return $group;
 }
Пример #5
-1
 /**
  * Destroy session handler.
  *
  * {@see http://php.net/manual/en/function.session-set-save-handler.php}
  *
  * @param string $sid
  * @return bool success
  */
 public function handler_destroy($sid)
 {
     if (!($session = $this->database->get_record('sessions', array('sid' => $sid), 'id, sid'))) {
         if ($sid == session_id()) {
             $this->recordid = null;
             $this->lasthash = null;
         }
         return true;
     }
     if ($this->recordid and $session->id == $this->recordid) {
         try {
             $this->database->release_session_lock($this->recordid);
         } catch (\Exception $ex) {
             // Ignore problems.
         }
         $this->recordid = null;
         $this->lasthash = null;
     }
     $this->database->delete_records('sessions', array('id' => $session->id));
     return true;
 }