User tests: Successful: Unsuccessful:
This small PR has a large number of benefits - it reduces the amount of user data stored in the database in the session table, it ensures the the user object is fully updated every page load removing some hackish code required for forcing password resets. Finally it solves the age old problem we have in Joomla of user groups not properly updating when they are changed by an admin or extension like Admin Tools. This comes at a slight overhead of reloading the user object on every page load.
Create a super admin and a second regular user. Log into that account into the frontend and browse around. Then log into the backend as the super admin and flag the normal users account as requiring a password reset. As soon as the frontend user goes to the next page they should be taken and only be able to access the profile edit page. Then reset password for the normal user and browse the site as usual again.
This ensures that the serialization replaces the "hack" implemented for the Password Reset code successfully.
As a bonus you can also test things like akeeba subs. I have not tested this myself but I think this should solve the age old problem we've had in Joomla that when a user's groups are changed it's not applied until the user logs out and logs back in again (e.g. the reverted #3972)
The user object is now reloaded at the start of every page. This is going to introduce a performance hit as the system is now going to reload the user from the database and the user groups assigned on every page load (around 10-20ms). For what it's worth though this is consistent with various other PHP Frameworks out there like Lavarel
There are no major b/c breaks. The serialization is ONLY done when the session gets closed and when it is kicked up again. There will be a b/c break if you are directly editing the database to change the database information. But imho if you are doing this then you pretty much get what you deserve - because you shouldn't even be relying on the data being stored there because of the different session handlers available.
Status | New | ⇒ | Pending |
Labels |
Added:
?
|
It shouldn't make a difference - but you can do!
This really sounds to be a great improvement. We always had to logout and login to reset user instance in the session, or manually code to reset it at time of need.
One issue I found is that with one of my extension where I take a snapshot of the user object for internal logging purpose. The snapshot is taken as serialize($user)
and it gives the whole serialized object, which I can unserialize
any time to get the old instance.
I can make that work by using serialize($user->getProperties())
, fine with me. I can also look for a solution for already stored values.
But I am afraid what if some more people are using serialize
over JUser
for whatever purpose. If so that would break, as now serialize only gives the array($id)
instead of JUser
object previously.
Please enlighten.
Houston, we have a major problem. Using this code on an existing site with already logged in users (i.e. upgrade from Joomla! 3.4.8 to 3.5.x that will include this code change) results in existing users getting blank / Internal Server Error 500 pages.
Right now you have a JUser object serialized in the session. Since it lacks serialization handlers, PHP simply spawns the object from the serialized data.
In the new code you have serialization and unserialization handlers. The unserialization handler expects an array of values. However, since the already serialized object is not an array of values you get an invalid offset warning and the whole thing dies (apparently because PHP doesn't know what to do?).
The problem is that you cannot store the serialized user in the same user session variable as before. What we should do instead is trash this code and change JSession so that it saves a user ID.
The logic on load would be like this:
Before saving the session we should do this:
* Set the user ID in the session to the user ID in the user object found in the session (even if it's 0, yes)
These changes would need to happen only in JSession.
Doing this object-value dance we maintain backwards compatibility: the session always has a JUser object and if someone (idiotically, like yours truly) manipulates that object directly nothing breaks; our new code will handle that transparently on the save handler (storing the ID and unsetting the JUser object).
As i can see in your code changes, you're not serializing the JUser object, but the 'id' (so why use the serialize function for this integer data?) then you 'load' the user by id at each page load
The overhead you're introducing with this is not simply due to unserialize at each page load, but to the subsequent $this->load($id) which implies a dababase query (not good when #__user table and related permission tables are big, may be not scalable)
@creativeprogramming
I'm using serialize because it pretty much keeps b/c with us having the full user object being stored in the session (which I know many components rely upon)
I already stated the overhead comes from the loading of the user on each page. Unfortunately there are several aspects where we need this behaviour (refreshing user permissions when people purchase things or when the user has to do a password reset to update the flag in their user object), all of which have required hacks in the system for basically this issue. Yes on large sites this is going to introduce a performance issue and I have been open about that. But there are many many other areas where we can save performance - but the massive restrictions that statically storing the user object into the session gives should not be one of them
@nikosdion Thanks for the test - I'll look into it and come up with a solution :)
e. Yes on large sites this is going to introduce a performance issue and I have been open about that. But there are many many other areas where we can save performance - but the massive restrictions that statically storing the user object into the session gives should not be one of them
@wilsonge sure that this is the only - and best - solution? Introducing 2+ queries at EACH page load for ANY user just to refresh the JUser object when something changes? From an event-driven framework like Joomla I expect much more.....
Something like md5 hash of user object, lastmoddate, or some version numbering to 'flag' it as 'reload-needed' in a lazy way only onAfterUserSave event isn't better?
Isn't better to keep caching it like before when nothing changes?
If you've got a suggestion, we'd all be open to hear it. But frankly, there isn't a reliable manner to tell an application that admin X made a change to user Y's account and that the cached user data in the session must be refreshed. For Joomla to do this, you'd still need to introduce at least one new database query somewhere around the point of the first time the user's loaded from the session.
The current cached JUser object is a major issue. Right now it only refreshes when the current user makes a change to their own account, and that only happens because it was a required hack to make the required password reset feature work. Before 3.3, once the user was loaded into the session, the only way to change it was to log out and log in again.
We don't have versioning on users and with the current versioning system I don't see it as feasible (largely because there is no way of excluding fields and I have no intentions on storing a history of users passwords and usernames - it would be a complete catastrophe).
So to give an example of a "modern" CMS. October CMS have their user object (https://github.com/octobercms/october/blob/master/modules/backend/models/User.php) which extends the base user object (https://github.com/octobercms/library/blob/master/src/Auth/Models/User.php#L41-L44) which ultimately extends Laravels Eloquent. Eloquent when stored in the session will serialize the data https://laravel.com/docs/master/eloquent-serialization . As you can see they actually include all the user data with the exception of the specified information in my link above (in the $hidden
attribute) which at least means passwords are not stored in the saved session data in between pages. So I personally don't believe that caching is the "right" solution (although "right" in this sense is all personal opinion :P)
If you've got a suggestion, we'd all be open to hear it.
Here's my suggestion:
Remember we have #__session
database table that's always used in read/write even if another handler is in use for the session storage?
Let's take advantage of that! Let's give a sense to it.
For instance you can add a column to this table:
ALTER TABLE #_session
ADD COLUMN juser_needs_refresh TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'boolean flag to check if the chached JUser object needs to be reloaded from db'
then you can set this flag to 1 - for any active session of that user - even when an admin or a script changes it:
/*this should be executed at onAfterUserSave event and at each related permission change*/
"UPDATE #__session SET juser_needs_refresh=1 WHERE userid=".(int).$theJUserId."";
Then you may say:
For Joomla to do this, you'd still need to introduce at least one new database query somewhere around the point of the first time the user's loaded from the session
Yes, but that query is already there, the #__session table is already queried at each page load, so you're just fetching a boolean data it's a 'piggyback', not a new query...
At this point, only one time per logged user session, and only if something changed, the cached, in-session, JUser object will be refreshed by the worker of that client at its next page request, with a JUser->load($id)...
Then of course you should set the boolean flag to zero for this #__session tuple: 'the message is consumed'
Yes, that's not good, we're introducing some writes, so, you can optimize it a bit more making it a version numbering, not a whole versioning system:
ALTER TABLE #_session
ADD COLUMN juser_last_version_number BIGINT 'version of the cached JUser object'
sql ALTER TABLE `#_user`
ADD COLUMN version_number BIGINT DEFAULT 0 'progressive version id of the JUser object and related properties'
then do this when an admin, a script o who else changes an user property (including permissions):
/*this should be executed at onBeforeUserSave event and before each related permission change*/
$this->version_number++; (on the JUser instance we're saving)
/*this should be executed at onAfterUserSave event and at each related permission change*/
"UPDATE #__session SET juser_last_version_number=juser_last_version_number+1 WHERE userid=".(int).$theJUserId."";
In this way at each pageload you can check the JSession's piggyback message $xxx->juser_last_version_number > JFactory::getUser()->get('version_number')
and if this is true refresh the JUser object with a ->load($id), no need to write, the message is already consumed as now (next time) the cached JUser in JFactory::getUser() will return the current version_number so the refresh will be exectued only once
Doing this should solve this:
The current cached JUser object is a major issue. Right now it only refreshes when the current user makes a change to their own account, and that only happens because it was a required hack to make the required password reset feature work. Before 3.3, once the user was loaded into the session, the only way to change it was to log out and log in again.
without introducing that new 20ms overhead (but I fear more) at each http request for any active user session - maybe also guests - (so please think also that if you do this in large sites, that 20ms will become more, due to many concurrent workers doing a job for more time, so CPU usage may increase on the server and so all may become a bit more slow - maybe i'm paraoid about performance, but being paranoid is part of our work, you know...):
As you can see they actually include all the user data with the exception of the specified information in my link above (in the $hidden attribute) which at least means passwords are not stored in the saved session data in between pages. So I personally don't believe that caching is the "right" solution (although "right" in this sense is all personal opinion :P)
I agree at all with this.
I didn't know: is joomla saving the current password (plaintext or hash) in the JSession's cached JUser object? if yes, that's not good for security, and unneeded! Yes, I think we should implement something like the link you pointed out (https://laravel.com/docs/master/eloquent-serialization) that can be as easy as:
JUser->password='';
//called just before serlializing the current JUser object to the session handler
or better you can modify the JUser->load()
method to never fetch that password field from the db (you need this field only in the core authentication plugin, and can be checked at MySQL side only using the condiction in an SQL query only, i think joomla is already doing that way in the authentication plugin)
But serializing just the $id... is really solving this security issue?
After the load($id), you'll always have an in-memory JUser instance with password field full... and a lot of times having it (hash or plaintext) sent in network datagrams if the database is on another machine
Instead of wasting everyone's time to see if joomla is doing something and
accusing it of bad security why don't you spend a few minutes in looking
for yourself.
On 31 Dec 2015 1:48 pm, "Stefano Gargiulo" notifications@github.com wrote:
As you can see they actually include all the user data with the exception
of the specified information in my link above (in the $hidden attribute)
which at least means passwords are not stored in the saved session data in
between pages. So I personally don't believe that caching is the "right"
solution (although "right" in this sense is all personal opinion :P)I agree at all with this, is joomla saving the current password
(plaintext or hash) in the JSession's cached JUser object? if yes,
that's not good for security, and unneeded, yes, I think we should
implement something like the link you pointed out (
https://laravel.com/docs/master/eloquent-serialization) that can be as
easy as:JUser->password='';called just before serlializing the JUser object to the session handler
or better modify the JUser->load() method to never fetch that password
field from the db (you need it only in the core authentication plugin)But serializing just the $id is really solving the security issue?
After the load($id), you'll always have an in-memory JUser instance with
password field full... and a lot of times having it (hash or plaintext)
sent in network datagrams if the database is on another machine—
Reply to this email directly or view it on GitHub
#8805 (comment).
Stefani, saving a flag in the session can be done by saving a flag IN THE SESSION. No need for another db field. Not to mention that requiring a db table for sessions is wrong but I digress.
What everyone is saying is HOW can we know which users need to be logged out. Don't be fast to answer. It can be any kind of change between the use group assignment (easy to catch) OR a change in the view access levels OR the privileges of any item carrying an ACL asset. The latter makes it impossible and I don't see you covering it.
Having any of these actions set a flag in every session asking Joomla to reload the user is daft. In all practical cases it is equivalent to reloading the user on every page load. BTW this is exactly what I'm doing in Akeeba Subscriptions hence I am so adamant that it is a stupid idea. Been there done that ain't working good.
In my opinion setting any expiration flag in db and reading it back everytime makes it more complicated and less reliable.
I also wonder do we need to refresh the session instance only at page loads, what if there has been a change in any related property that a user expects to be accessible via JFactory::getUser()
in subsequent calls during the same session which modifies it. The change may not be always via JUser
instances.
Some hacky code to support current cache implementation can be seen at places such as \JUserHelper::removeUserFromGroup
or \JUserHelper::addUserToGroup
etc. But for now that was the best that could be done.
Now if we may possibly ignore the fact that somebody may be accessing the session cached instance by any other means than the JFactory::getUser()
then I'd recommend to skip serialization at all and just store userId
in the session and do the cache in JFactory
only. For B/C we can have the session _start
method auto populate a deprecated
stand-in value user
on page load as a reference to the JFactory
's cached value itself.
Additionally, we can add an extra argument to JFactory::getUser()
like JFactory::getUser($id, $reload = false)
that can be used to flush cache anytime.
@mbabker here you invited me to an OT... let's have some nerdy fun, please don't read the following if you're short in time or not in friendly spirit, is just my modest IMO ;)
But frankly, there isn't a reliable manner to tell an application that admin X made a change to user Y's account and that the cached user data in the session must be refreshed
I know and agree, but only if you add PHP to this statement:
there isn't a reliable manner to tell a PHP application that admin X made a change to user Y's account and that the cached user data in the session must be refreshed
I come from J2EE application development, and there you've this kind of features, as you have an application scope see:
http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html
Frankly, I always considered PHP a no-go for serious webapps (for this you can undestand better me when i say that I'll go nodejs or java when i look for 'enterprise' application development and so i consider a waste of time trying to reaching perfection developing a PHP framework for development)
PHP stands for PersonalHomePage, is born like an hack, and nowadays even if it is a complete langague in terms of syntax it still lacks of a solid infrastructure.
Any request is served by a process, no multi-threading, no application scope, no shared memory between workers, no message bus (but just request scope).
This structure is also the main bottleneck of PHP performance IMO.
Every time a request comes to a PHP webserver the whole includes are processed, with PHP and large frameworks you spend more CPU time defining alle the classes, initilaizing constants and variables, instantiating the framework, setting up routing, unserializing the session etc, than the real CPU time spent in processing what you really need to do.
You may find this 'trascurable' but if we talk about memory usage you'll surely agree:
PHP, as it frankly sucks, needs to load and copy an instance of any .so library per each active worker, have you ever tried to profile why your server is so memory-hungry when running PHP apps, I do, and here's for instance a pmap of a single php5-fpm worker (or apache worker) (i need 300 of them to run my Joomla) showing what it has loaded in memory:
# pmap 29756
29756: php-fpm: pool myserver-unixsock
0000000000400000 8516K r-x-- php5-fpm
0000000000e51000 676K r---- php5-fpm
0000000000efa000 52K rw--- php5-fpm
0000000000f07000 124K rw--- [ anon ]
0000000002b37000 4112K rw--- [ anon ]
0000000002f3b000 19836K rw--- [ anon ]
00007f5fa4000000 132K rw--- [ anon ]
00007f5fa4021000 65404K ----- [ anon ]
00007f5faa79f000 4K ----- [ anon ]
00007f5faa7a0000 8192K rw--- [ anon ]
00007f5faafa0000 44K r-x-- libnss_nis-2.21.so
00007f5faafab000 2044K ----- libnss_nis-2.21.so
00007f5fab1aa000 4K r---- libnss_nis-2.21.so
00007f5fab1ab000 4K rw--- libnss_nis-2.21.so
00007f5fab1b0000 92K r-x-- libnsl-2.21.so
00007f5fab1c7000 2044K ----- libnsl-2.21.so
00007f5fab3c6000 4K r---- libnsl-2.21.so
00007f5fab3c7000 4K rw--- libnsl-2.21.so
00007f5fab3c8000 8K rw--- [ anon ]
00007f5fab3d0000 32K r-x-- libnss_compat-2.21.so
00007f5fab3d8000 2044K ----- libnss_compat-2.21.so
00007f5fab5d7000 4K r---- libnss_compat-2.21.so
00007f5fab5d8000 4K rw--- libnss_compat-2.21.so
00007f5fab5e0000 65536K rw-s- zero (deleted)
00007f5faf5e0000 20K r-x-- libnss_dns-2.21.so
00007f5faf5e5000 2044K ----- libnss_dns-2.21.so
00007f5faf7e4000 4K r---- libnss_dns-2.21.so
00007f5faf7e5000 4K rw--- libnss_dns-2.21.so
00007f5faf7e8000 48K r-x-- libnss_files-2.21.so
00007f5faf7f4000 2044K ----- libnss_files-2.21.so
00007f5faf9f3000 4K r---- libnss_files-2.21.so
00007f5faf9f4000 4K rw--- libnss_files-2.21.so
00007f5faf9f8000 84K r-x-- xmlrpc.so
00007f5fafa0d000 2048K ----- xmlrpc.so
00007f5fafc0d000 4K r---- xmlrpc.so
00007f5fafc0e000 4K rw--- xmlrpc.so
00007f5fafc10000 340K r-x-- libtidy-0.99.so.0.0.0
00007f5fafc65000 2048K ----- libtidy-0.99.so.0.0.0
00007f5fafe65000 32K r---- libtidy-0.99.so.0.0.0
00007f5fafe6d000 4K rw--- libtidy-0.99.so.0.0.0
00007f5fafe70000 44K r-x-- tidy.so
00007f5fafe7b000 2048K ----- tidy.so
00007f5fb007b000 4K r---- tidy.so
00007f5fb007c000 4K rw--- tidy.so
00007f5fb0080000 252K r-x-- redis.so
00007f5fb00bf000 2044K ----- redis.so
00007f5fb02be000 4K r---- redis.so
00007f5fb02bf000 12K rw--- redis.so
00007f5fb02c8000 148K r-x-- libtinfo.so.5.9
00007f5fb02ed000 2044K ----- libtinfo.so.5.9
00007f5fb04ec000 16K r---- libtinfo.so.5.9
00007f5fb04f0000 4K rw--- libtinfo.so.5.9
00007f5fb04f8000 204K r-x-- libedit.so.2.0.51
00007f5fb052b000 2048K ----- libedit.so.2.0.51
00007f5fb072b000 8K r---- libedit.so.2.0.51
00007f5fb072d000 4K rw--- libedit.so.2.0.51
00007f5fb072e000 16K rw--- [ anon ]
00007f5fb0738000 28K r-x-- readline.so
00007f5fb073f000 2044K ----- readline.so
00007f5fb093e000 4K r---- readline.so
00007f5fb093f000 4K rw--- readline.so
00007f5fb0940000 28K r-x-- pdo_mysql.so
00007f5fb0947000 2044K ----- pdo_mysql.so
00007f5fb0b46000 4K r---- pdo_mysql.so
00007f5fb0b47000 4K rw--- pdo_mysql.so
00007f5fb0b48000 124K r-x-- mysqli.so
00007f5fb0b67000 2048K ----- mysqli.so
00007f5fb0d67000 20K r---- mysqli.so
00007f5fb0d6c000 4K rw--- mysqli.so
00007f5fb0d70000 44K r-x-- mysql.so
00007f5fb0d7b000 2048K ----- mysql.so
00007f5fb0f7b000 8K r---- mysql.so
00007f5fb0f7d000 4K rw--- mysql.so
00007f5fb0f80000 172K r-x-- libmcrypt.so.4.4.8
00007f5fb0fab000 2044K ----- libmcrypt.so.4.4.8
00007f5fb11aa000 8K r---- libmcrypt.so.4.4.8
00007f5fb11ac000 8K rw--- libmcrypt.so.4.4.8
00007f5fb11ae000 24K rw--- [ anon ]
00007f5fb11b8000 40K r-x-- mcrypt.so
00007f5fb11c2000 2044K ----- mcrypt.so
00007f5fb13c1000 8K r---- mcrypt.so
00007f5fb13c3000 4K rw--- mcrypt.so
00007f5fb13c8000 40K r-x-- libjson-c.so.2.0.0
00007f5fb13d2000 2044K ----- libjson-c.so.2.0.0
00007f5fb15d1000 4K r---- libjson-c.so.2.0.0
00007f5fb15d2000 4K rw--- libjson-c.so.2.0.0
00007f5fb15d8000 32K r-x-- json.so
00007f5fb15e0000 2048K ----- json.so
00007f5fb17e0000 4K r---- json.so
00007f5fb17e1000 4K rw--- json.so
00007f5fb17e8000 48K r-x-- libicuio.so.52.1
00007f5fb17f4000 2044K ----- libicuio.so.52.1
00007f5fb19f3000 8K r---- libicuio.so.52.1
00007f5fb19f5000 4K rw--- libicuio.so.52.1
00007f5fb19f8000 2056K r-x-- libicui18n.so.52.1
00007f5fb1bfa000 2048K ----- libicui18n.so.52.1
00007f5fb1dfa000 56K r---- libicui18n.so.52.1
00007f5fb1e08000 4K rw--- libicui18n.so.52.1
00007f5fb1e09000 4K rw--- [ anon ]
00007f5fb1e10000 360K r-x-- intl.so
00007f5fb1e6a000 2044K ----- intl.so
00007f5fb2069000 28K r---- intl.so
00007f5fb2070000 16K rw--- intl.so
00007f5fb2074000 4K rw--- [ anon ]
00007f5fb2078000 104K r-x-- libaudit.so.1.0.0
00007f5fb2092000 2044K ----- libaudit.so.1.0.0
00007f5fb2291000 4K r---- libaudit.so.1.0.0
00007f5fb2292000 4K rw--- libaudit.so.1.0.0
00007f5fb2293000 40K rw--- [ anon ]
00007f5fb22a0000 52K r-x-- libpam.so.0.83.1
00007f5fb22ad000 2048K ----- libpam.so.0.83.1
00007f5fb24ad000 8K r---- libpam.so.0.83.1
00007f5fb24af000 4K rw--- libpam.so.0.83.1
00007f5fb24b0000 1036K r-x-- libc-client.so.2007e.0
00007f5fb25b3000 2044K ----- libc-client.so.2007e.0
00007f5fb27b2000 12K r---- libc-client.so.2007e.0
00007f5fb27b5000 32K rw--- libc-client.so.2007e.0
00007f5fb27bd000 4K rw--- [ anon ]
00007f5fb27c0000 88K r-x-- imap.so
00007f5fb27d6000 2048K ----- imap.so
00007f5fb29d6000 16K r---- imap.so
00007f5fb29da000 4K rw--- imap.so
00007f5fb29e0000 1076K r-x-- libglib-2.0.so.0.4400.1
00007f5fb2aed000 2044K ----- libglib-2.0.so.0.4400.1
00007f5fb2cec000 4K r---- libglib-2.0.so.0.4400.1
00007f5fb2ced000 4K rw--- libglib-2.0.so.0.4400.1
00007f5fb2cee000 4K rw--- [ anon ]
00007f5fb2cf0000 36K r-x-- libltdl.so.7.3.0
00007f5fb2cf9000 2044K ----- libltdl.so.7.3.0
00007f5fb2ef8000 4K r---- libltdl.so.7.3.0
00007f5fb2ef9000 4K rw--- libltdl.so.7.3.0
00007f5fb2f00000 68K r-x-- libXext.so.6.4.0
00007f5fb2f11000 2044K ----- libXext.so.6.4.0
00007f5fb3110000 4K r---- libXext.so.6.4.0
00007f5fb3111000 4K rw--- libXext.so.6.4.0
00007f5fb3118000 1960K r-x-- libfftw3.so.3.4.4
00007f5fb3302000 2044K ----- libfftw3.so.3.4.4
00007f5fb3501000 80K r---- libfftw3.so.3.4.4
00007f5fb3515000 4K rw--- libfftw3.so.3.4.4
00007f5fb3518000 92K r-x-- liblqr-1.so.0.3.2
00007f5fb352f000 2044K ----- liblqr-1.so.0.3.2
00007f5fb372e000 4K r---- liblqr-1.so.0.3.2
00007f5fb372f000 4K rw--- liblqr-1.so.0.3.2
00007f5fb3730000 328K r-x-- liblcms2.so.2.0.6
00007f5fb3782000 2044K ----- liblcms2.so.2.0.6
00007f5fb3981000 4K r---- liblcms2.so.2.0.6
00007f5fb3982000 16K rw--- liblcms2.so.2.0.6
00007f5fb3986000 4K rw--- [ anon ]
00007f5fb3988000 88K r-x-- libgomp.so.1.0.0
00007f5fb399e000 2044K ----- libgomp.so.1.0.0
00007f5fb3b9d000 4K r---- libgomp.so.1.0.0
00007f5fb3b9e000 4K rw--- libgomp.so.1.0.0
00007f5fb3ba0000 2312K r-x-- libMagickCore-6.Q16.so.2.0.0
00007f5fb3de2000 2048K ----- libMagickCore-6.Q16.so.2.0.0
00007f5fb3fe2000 80K r---- libMagickCore-6.Q16.so.2.0.0
00007f5fb3ff6000 252K rw--- libMagickCore-6.Q16.so.2.0.0
00007f5fb4035000 124K rw--- [ anon ]
00007f5fb4058000 1156K r-x-- libMagickWand-6.Q16.so.2.0.0
00007f5fb4179000 2044K ----- libMagickWand-6.Q16.so.2.0.0
00007f5fb4378000 4K r---- libMagickWand-6.Q16.so.2.0.0
00007f5fb4379000 16K rw--- libMagickWand-6.Q16.so.2.0.0
00007f5fb4380000 316K r-x-- imagick.so
00007f5fb43cf000 2048K ----- imagick.so
00007f5fb45cf000 40K r---- imagick.so
00007f5fb45d9000 24K rw--- imagick.so
00007f5fb45e0000 184K r-x-- libGeoIP.so.1.6.3
00007f5fb460e000 2044K ----- libGeoIP.so.1.6.3
00007f5fb480d000 4K r---- libGeoIP.so.1.6.3
00007f5fb480e000 8K rw--- libGeoIP.so.1.6.3
00007f5fb4810000 20K r-x-- geoip.so
00007f5fb4815000 2044K ----- geoip.so
00007f5fb4a14000 4K r---- geoip.so
00007f5fb4a15000 4K rw--- geoip.so
00007f5fb4a18000 20K r-x-- libXdmcp.so.6.0.0
00007f5fb4a1d000 2044K ----- libXdmcp.so.6.0.0
00007f5fb4c1c000 4K r---- libXdmcp.so.6.0.0
00007f5fb4c1d000 4K rw--- libXdmcp.so.6.0.0
00007f5fb4c20000 8K r-x-- libXau.so.6.0.0
00007f5fb4c22000 2048K ----- libXau.so.6.0.0
00007f5fb4e22000 4K r---- libXau.so.6.0.0
00007f5fb4e23000 4K rw--- libXau.so.6.0.0
00007f5fb4e28000 116K r-x-- libxcb.so.1.1.0
00007f5fb4e45000 2048K ----- libxcb.so.1.1.0
00007f5fb5045000 4K r---- libxcb.so.1.1.0
00007f5fb5046000 4K rw--- libxcb.so.1.1.0
00007f5fb5048000 44K r-x-- libjbig.so.0
00007f5fb5053000 2044K ----- libjbig.so.0
00007f5fb5252000 4K r---- libjbig.so.0
00007f5fb5253000 12K rw--- libjbig.so.0
00007f5fb5258000 152K r-x-- libexpat.so.1.6.0
00007f5fb527e000 2044K ----- libexpat.so.1.6.0
00007f5fb547d000 12K r---- libexpat.so.1.6.0
00007f5fb5480000 4K rw--- libexpat.so.1.6.0
00007f5fb5488000 1228K r-x-- libX11.so.6.3.0
00007f5fb55bb000 2048K ----- libX11.so.6.3.0
00007f5fb57bb000 4K r---- libX11.so.6.3.0
00007f5fb57bc000 16K rw--- libX11.so.6.3.0
00007f5fb57c0000 4K rw--- [ anon ]
00007f5fb57c8000 448K r-x-- libtiff.so.5.2.0
00007f5fb5838000 2044K ----- libtiff.so.5.2.0
00007f5fb5a37000 8K r---- libtiff.so.5.2.0
00007f5fb5a39000 12K rw--- libtiff.so.5.2.0
00007f5fb5a40000 1728K r-x-- libvpx.so.1.3.0
00007f5fb5bf0000 2044K ----- libvpx.so.1.3.0
00007f5fb5def000 8K r---- libvpx.so.1.3.0
00007f5fb5df1000 4K rw--- libvpx.so.1.3.0
00007f5fb5df2000 280K rw--- [ anon ]
00007f5fb5e38000 240K r-x-- libfontconfig.so.1.8.0
00007f5fb5e74000 2044K ----- libfontconfig.so.1.8.0
00007f5fb6073000 8K r---- libfontconfig.so.1.8.0
00007f5fb6075000 4K rw--- libfontconfig.so.1.8.0
00007f5fb6078000 648K r-x-- libfreetype.so.6.11.1
00007f5fb611a000 2044K ----- libfreetype.so.6.11.1
00007f5fb6319000 24K r---- libfreetype.so.6.11.1
00007f5fb631f000 4K rw--- libfreetype.so.6.11.1
00007f5fb6320000 148K r-x-- libpng12.so.0.51.0
00007f5fb6345000 2044K ----- libpng12.so.0.51.0
00007f5fb6544000 4K r---- libpng12.so.0.51.0
00007f5fb6545000 4K rw--- libpng12.so.0.51.0
00007f5fb6548000 268K r-x-- libjpeg.so.8.0.2
00007f5fb658b000 2048K ----- libjpeg.so.8.0.2
00007f5fb678b000 4K r---- libjpeg.so.8.0.2
00007f5fb678c000 4K rw--- libjpeg.so.8.0.2
00007f5fb678d000 64K rw--- [ anon ]
00007f5fb67a0000 64K r-x-- libXpm.so.4.11.0
00007f5fb67b0000 2044K ----- libXpm.so.4.11.0
00007f5fb69af000 4K r---- libXpm.so.4.11.0
00007f5fb69b0000 4K rw--- libXpm.so.4.11.0
00007f5fb69b8000 268K r-x-- libgd.so.3.0.0
00007f5fb69fb000 2044K ----- libgd.so.3.0.0
00007f5fb6bfa000 24K r---- libgd.so.3.0.0
00007f5fb6c00000 124K rw--- libgd.so.3.0.0
00007f5fb6c1f000 20K rw--- [ anon ]
00007f5fb6c28000 88K r-x-- gd.so
00007f5fb6c3e000 2048K ----- gd.so
00007f5fb6e3e000 20K r---- gd.so
00007f5fb6e43000 4K rw--- gd.so
00007f5fb6e48000 36K r-x-- libcrypt-2.21.so
00007f5fb6e51000 2044K ----- libcrypt-2.21.so
00007f5fb7050000 4K r---- libcrypt-2.21.so
00007f5fb7051000 4K rw--- libcrypt-2.21.so
00007f5fb7052000 184K rw--- [ anon ]
00007f5fb7080000 772K r-x-- libsqlite3.so.0.8.6
00007f5fb7141000 2044K ----- libsqlite3.so.0.8.6
00007f5fb7340000 12K r---- libsqlite3.so.0.8.6
00007f5fb7343000 8K rw--- libsqlite3.so.0.8.6
00007f5fb7345000 4K rw--- [ anon ]
00007f5fb7348000 280K r-x-- libhx509.so.5.0.0
00007f5fb738e000 2048K ----- libhx509.so.5.0.0
00007f5fb758e000 8K r---- libhx509.so.5.0.0
00007f5fb7590000 8K rw--- libhx509.so.5.0.0
00007f5fb7592000 4K rw--- [ anon ]
00007f5fb7598000 56K r-x-- libheimbase.so.1.0.0
00007f5fb75a6000 2044K ----- libheimbase.so.1.0.0
00007f5fb77a5000 4K r---- libheimbase.so.1.0.0
00007f5fb77a6000 4K rw--- libheimbase.so.1.0.0
00007f5fb77a8000 160K r-x-- libwind.so.0.0.0
00007f5fb77d0000 2044K ----- libwind.so.0.0.0
00007f5fb79cf000 4K r---- libwind.so.0.0.0
00007f5fb79d0000 4K rw--- libwind.so.0.0.0
00007f5fb79d8000 28K r-x-- libffi.so.6.0.4
00007f5fb79df000 2044K ----- libffi.so.6.0.4
00007f5fb7bde000 4K r---- libffi.so.6.0.4
00007f5fb7bdf000 4K rw--- libffi.so.6.0.4
00007f5fb7be0000 80K r-x-- libroken.so.18.1.0
00007f5fb7bf4000 2044K ----- libroken.so.18.1.0
00007f5fb7df3000 4K r---- libroken.so.18.1.0
00007f5fb7df4000 4K rw--- libroken.so.18.1.0
00007f5fb7df8000 196K r-x-- libhcrypto.so.4.1.0
00007f5fb7e29000 2044K ----- libhcrypto.so.4.1.0
00007f5fb8028000 8K r---- libhcrypto.so.4.1.0
00007f5fb802a000 4K rw--- libhcrypto.so.4.1.0
00007f5fb802b000 4K rw--- [ anon ]
00007f5fb8030000 648K r-x-- libasn1.so.8.0.0
00007f5fb80d2000 2044K ----- libasn1.so.8.0.0
00007f5fb82d1000 4K r---- libasn1.so.8.0.0
00007f5fb82d2000 12K rw--- libasn1.so.8.0.0
00007f5fb82d8000 528K r-x-- libkrb5.so.26.0.0
00007f5fb835c000 2044K ----- libkrb5.so.26.0.0
00007f5fb855b000 12K r---- libkrb5.so.26.0.0
00007f5fb855e000 12K rw--- libkrb5.so.26.0.0
00007f5fb8561000 4K rw--- [ anon ]
00007f5fb8568000 32K r-x-- libheimntlm.so.0.1.0
00007f5fb8570000 2044K ----- libheimntlm.so.0.1.0
00007f5fb876f000 4K r---- libheimntlm.so.0.1.0
00007f5fb8770000 4K rw--- libheimntlm.so.0.1.0
00007f5fb8778000 12K r-x-- libkeyutils.so.1.5
00007f5fb877b000 2044K ----- libkeyutils.so.1.5
00007f5fb897a000 4K r---- libkeyutils.so.1.5
00007f5fb897b000 4K rw--- libkeyutils.so.1.5
00007f5fb8980000 68K r-x-- libtasn1.so.6.3.2
00007f5fb8991000 2048K ----- libtasn1.so.6.3.2
00007f5fb8b91000 8K r---- libtasn1.so.6.3.2
00007f5fb8b93000 4K rw--- libtasn1.so.6.3.2
00007f5fb8b98000 240K r-x-- libp11-kit.so.0.0.0
00007f5fb8bd4000 2044K ----- libp11-kit.so.0.0.0
00007f5fb8dd3000 36K r---- libp11-kit.so.0.0.0
00007f5fb8ddc000 8K rw--- libp11-kit.so.0.0.0
00007f5fb8de0000 240K r-x-- libgssapi.so.3.0.0
00007f5fb8e1c000 2048K ----- libgssapi.so.3.0.0
00007f5fb901c000 4K r---- libgssapi.so.3.0.0
00007f5fb901d000 8K rw--- libgssapi.so.3.0.0
00007f5fb901f000 4K rw--- [ anon ]
00007f5fb9020000 104K r-x-- libsasl2.so.2.0.25
00007f5fb903a000 2044K ----- libsasl2.so.2.0.25
00007f5fb9239000 4K r---- libsasl2.so.2.0.25
00007f5fb923a000 4K rw--- libsasl2.so.2.0.25
00007f5fb9240000 40K r-x-- libkrb5support.so.0.1
00007f5fb924a000 2044K ----- libkrb5support.so.0.1
00007f5fb9449000 4K r---- libkrb5support.so.0.1
00007f5fb944a000 4K rw--- libkrb5support.so.0.1
00007f5fb9450000 12K r-x-- libcom_err.so.2.1
00007f5fb9453000 2044K ----- libcom_err.so.2.1
00007f5fb9652000 4K r---- libcom_err.so.2.1
00007f5fb9653000 4K rw--- libcom_err.so.2.1
00007f5fb9658000 184K r-x-- libk5crypto.so.3.1
00007f5fb9686000 2044K ----- libk5crypto.so.3.1
00007f5fb9885000 8K r---- libk5crypto.so.3.1
00007f5fb9887000 4K rw--- libk5crypto.so.3.1
00007f5fb9888000 4K rw--- [ anon ]
00007f5fb9890000 768K r-x-- libkrb5.so.3.3
00007f5fb9950000 2048K ----- libkrb5.so.3.3
00007f5fb9b50000 52K r---- libkrb5.so.3.3
00007f5fb9b5d000 8K rw--- libkrb5.so.3.3
00007f5fb9b60000 504K r-x-- libgmp.so.10.2.0
00007f5fb9bde000 2048K ----- libgmp.so.10.2.0
00007f5fb9dde000 4K r---- libgmp.so.10.2.0
00007f5fb9ddf000 4K rw--- libgmp.so.10.2.0
00007f5fb9de0000 192K r-x-- libnettle.so.4.7
00007f5fb9e10000 2044K ----- libnettle.so.4.7
00007f5fba00f000 4K r---- libnettle.so.4.7
00007f5fba010000 4K rw--- libnettle.so.4.7
00007f5fba018000 180K r-x-- libhogweed.so.2.5
00007f5fba045000 2044K ----- libhogweed.so.2.5
00007f5fba244000 4K r---- libhogweed.so.2.5
00007f5fba245000 4K rw--- libhogweed.so.2.5
00007f5fba248000 1084K r-x-- libgnutls-deb0.so.28.41.0
00007f5fba357000 2048K ----- libgnutls-deb0.so.28.41.0
00007f5fba557000 36K r---- libgnutls-deb0.so.28.41.0
00007f5fba560000 8K rw--- libgnutls-deb0.so.28.41.0
00007f5fba568000 308K r-x-- libldap_r-2.4.so.2.8.3
00007f5fba5b5000 2048K ----- libldap_r-2.4.so.2.8.3
00007f5fba7b5000 8K r---- libldap_r-2.4.so.2.8.3
00007f5fba7b7000 4K rw--- libldap_r-2.4.so.2.8.3
00007f5fba7b8000 8K rw--- [ anon ]
00007f5fba7c0000 52K r-x-- liblber-2.4.so.2.8.3
00007f5fba7cd000 2048K ----- liblber-2.4.so.2.8.3
00007f5fba9cd000 4K r---- liblber-2.4.so.2.8.3
00007f5fba9ce000 4K rw--- liblber-2.4.so.2.8.3
00007f5fba9d0000 280K r-x-- libgssapi_krb5.so.2.2
00007f5fbaa16000 2044K ----- libgssapi_krb5.so.2.2
00007f5fbac15000 8K r---- libgssapi_krb5.so.2.2
00007f5fbac17000 8K rw--- libgssapi_krb5.so.2.2
00007f5fbac20000 108K r-x-- librtmp.so.1
00007f5fbac3b000 2044K ----- librtmp.so.1
00007f5fbae3a000 4K r---- librtmp.so.1
00007f5fbae3b000 4K rw--- librtmp.so.1
00007f5fbae40000 196K r-x-- libidn.so.11.6.11
00007f5fbae71000 2048K ----- libidn.so.11.6.11
00007f5fbb071000 4K r---- libidn.so.11.6.11
00007f5fbb072000 4K rw--- libidn.so.11.6.11
00007f5fbb078000 416K r-x-- libcurl.so.4.3.0
00007f5fbb0e0000 2044K ----- libcurl.so.4.3.0
00007f5fbb2df000 12K r---- libcurl.so.4.3.0
00007f5fbb2e2000 4K rw--- libcurl.so.4.3.0
00007f5fbb2e6000 4K rw-s- zero (deleted)
00007f5fbb2e7000 4K rw-s- zero (deleted)
00007f5fbb2e8000 80K r-x-- curl.so
00007f5fbb2fc000 2044K ----- curl.so
00007f5fbb4fb000 8K r---- curl.so
00007f5fbb4fd000 4K rw--- curl.so
00007f5fbb4fe000 4K rw-s- zero (deleted)
00007f5fbb4ff000 4K rw-s- zero (deleted)
00007f5fbb500000 104K r-x-- pdo.so
00007f5fbb51a000 2044K ----- pdo.so
00007f5fbb719000 12K r---- pdo.so
00007f5fbb71c000 4K rw--- pdo.so
00007f5fbb71d000 4K rw-s- zero (deleted)
00007f5fbb71e000 4K rw-s- zero (deleted)
00007f5fbb71f000 4K rw-s- zero (deleted)
00007f5fbb720000 248K r-x-- mysqlnd.so
00007f5fbb75e000 2048K ----- mysqlnd.so
00007f5fbb95e000 16K r---- mysqlnd.so
00007f5fbb962000 8K rw--- mysqlnd.so
00007f5fbb964000 4K rw--- [ anon ]
00007f5fbb965000 4K rw-s- zero (deleted)
00007f5fbb966000 4K rw-s- zero (deleted)
00007f5fbb967000 4K rw-s- zero (deleted)
00007f5fbb968000 144K r-x-- opcache.so
00007f5fbb98c000 2048K ----- opcache.so
00007f5fbbb8c000 8K r---- opcache.so
00007f5fbbb8e000 4K rw--- opcache.so
00007f5fbbb8f000 32K rw--- [ anon ]
00007f5fbbb97000 4K rw-s- zero (deleted)
00007f5fbbb98000 2852K r---- locale-archive
00007f5fbbe61000 4K rw-s- zero (deleted)
00007f5fbbe62000 4K rw-s- zero (deleted)
00007f5fbbe63000 4K rw-s- zero (deleted)
00007f5fbbe64000 4K rw-s- zero (deleted)
00007f5fbbe65000 4K rw-s- zero (deleted)
00007f5fbbe66000 4K rw-s- zero (deleted)
00007f5fbbe67000 4K rw-s- zero (deleted)
00007f5fbbe68000 88K r-x-- libgcc_s.so.1
00007f5fbbe7e000 2044K ----- libgcc_s.so.1
00007f5fbc07d000 4K rw--- libgcc_s.so.1
00007f5fbc07e000 4K rw-s- zero (deleted)
00007f5fbc07f000 4K rw-s- zero (deleted)
00007f5fbc080000 960K r-x-- libstdc++.so.6.0.20
00007f5fbc170000 2048K ----- libstdc++.so.6.0.20
00007f5fbc370000 32K r---- libstdc++.so.6.0.20
00007f5fbc378000 8K rw--- libstdc++.so.6.0.20
00007f5fbc37a000 84K rw--- [ anon ]
00007f5fbc38f000 4K rw-s- zero (deleted)
00007f5fbc390000 22960K r-x-- libicudata.so.52.1
00007f5fbd9fc000 2044K ----- libicudata.so.52.1
00007f5fbdbfb000 4K r---- libicudata.so.52.1
00007f5fbdbfc000 4K rw--- libicudata.so.52.1
00007f5fbdbfd000 4K rw-s- zero (deleted)
00007f5fbdbfe000 4K rw-s- zero (deleted)
00007f5fbdbff000 4K rw-s- zero (deleted)
00007f5fbdc00000 68K r-x-- libgpg-error.so.0.13.0
00007f5fbdc11000 2044K ----- libgpg-error.so.0.13.0
00007f5fbde10000 4K r---- libgpg-error.so.0.13.0
00007f5fbde11000 4K rw--- libgpg-error.so.0.13.0
00007f5fbde12000 4K rw-s- zero (deleted)
00007f5fbde13000 4K rw-s- zero (deleted)
00007f5fbde14000 4K rw-s- zero (deleted)
00007f5fbde15000 4K rw-s- zero (deleted)
00007f5fbde16000 4K rw-s- zero (deleted)
00007f5fbde17000 4K rw-s- zero (deleted)
00007f5fbde18000 1440K r-x-- libicuuc.so.52.1
00007f5fbdf80000 2044K ----- libicuuc.so.52.1
00007f5fbe17f000 72K r---- libicuuc.so.52.1
00007f5fbe191000 4K rw--- libicuuc.so.52.1
00007f5fbe192000 16K rw--- [ anon ]
00007f5fbe196000 4K rw-s- zero (deleted)
00007f5fbe197000 4K rw-s- zero (deleted)
00007f5fbe198000 864K r-x-- libgcrypt.so.20.0.2
00007f5fbe270000 2048K ----- libgcrypt.so.20.0.2
00007f5fbe470000 4K r---- libgcrypt.so.20.0.2
00007f5fbe471000 36K rw--- libgcrypt.so.20.0.2
00007f5fbe47a000 4K rw-s- zero (deleted)
00007f5fbe47b000 4K rw-s- zero (deleted)
00007f5fbe47c000 4K rw-s- zero (deleted)
00007f5fbe47d000 4K rw-s- zero (deleted)
00007f5fbe47e000 4K rw-s- zero (deleted)
00007f5fbe47f000 4K rw-s- zero (deleted)
00007f5fbe480000 132K r-x-- liblzma.so.5.0.0
00007f5fbe4a1000 2044K ----- liblzma.so.5.0.0
00007f5fbe6a0000 4K r---- liblzma.so.5.0.0
00007f5fbe6a1000 4K rw--- liblzma.so.5.0.0
00007f5fbe6a2000 4K rw-s- zero (deleted)
00007f5fbe6a3000 4K rw-s- zero (deleted)
00007f5fbe6a4000 4K rw-s- zero (deleted)
00007f5fbe6a5000 4K rw-s- zero (deleted)
00007f5fbe6a6000 4K rw-s- zero (deleted)
00007f5fbe6a7000 4K rw-s- zero (deleted)
00007f5fbe6a8000 1792K r-x-- libc-2.21.so
00007f5fbe868000 2048K ----- libc-2.21.so
00007f5fbea68000 16K r---- libc-2.21.so
00007f5fbea6c000 8K rw--- libc-2.21.so
00007f5fbea6e000 16K rw--- [ anon ]
00007f5fbea72000 4K rw-s- zero (deleted)
00007f5fbea73000 4K rw-s- zero (deleted)
00007f5fbea74000 4K rw-s- zero (deleted)
00007f5fbea75000 4K rw-s- zero (deleted)
00007f5fbea76000 4K rw-s- zero (deleted)
00007f5fbea77000 4K rw-s- zero (deleted)
00007f5fbea78000 96K r-x-- libpthread-2.21.so
00007f5fbea90000 2048K ----- libpthread-2.21.so
00007f5fbec90000 4K r---- libpthread-2.21.so
00007f5fbec91000 4K rw--- libpthread-2.21.so
00007f5fbec92000 16K rw--- [ anon ]
00007f5fbec96000 4K rw-s- zero (deleted)
00007f5fbec97000 4K rw-s- zero (deleted)
00007f5fbec98000 1792K r-x-- libxml2.so.2.9.2
00007f5fbee58000 2048K ----- libxml2.so.2.9.2
00007f5fbf058000 32K r---- libxml2.so.2.9.2
00007f5fbf060000 8K rw--- libxml2.so.2.9.2
00007f5fbf062000 4K rw--- [ anon ]
00007f5fbf063000 4K rw-s- zero (deleted)
00007f5fbf064000 4K rw-s- zero (deleted)
00007f5fbf065000 4K rw-s- zero (deleted)
00007f5fbf066000 4K rw-s- zero (deleted)
00007f5fbf067000 4K rw-s- zero (deleted)
00007f5fbf068000 148K r-x-- libsystemd.so.0.6.0
00007f5fbf08d000 2048K ----- libsystemd.so.0.6.0
00007f5fbf28d000 4K r---- libsystemd.so.0.6.0
00007f5fbf28e000 4K rw--- libsystemd.so.0.6.0
00007f5fbf28f000 4K rw-s- zero (deleted)
00007f5fbf290000 44K r-x-- libapparmor.so.1.2.1
00007f5fbf29b000 2048K ----- libapparmor.so.1.2.1
00007f5fbf49b000 4K r---- libapparmor.so.1.2.1
00007f5fbf49c000 4K rw--- libapparmor.so.1.2.1
00007f5fbf49d000 4K rw-s- zero (deleted)
00007f5fbf49e000 4K rw-s- zero (deleted)
00007f5fbf49f000 4K rw-s- zero (deleted)
00007f5fbf4a0000 12K r-x-- libdl-2.21.so
00007f5fbf4a3000 2044K ----- libdl-2.21.so
00007f5fbf6a2000 4K r---- libdl-2.21.so
00007f5fbf6a3000 4K rw--- libdl-2.21.so
00007f5fbf6a4000 4K rw-s- zero (deleted)
00007f5fbf6a5000 4K rw-s- zero (deleted)
00007f5fbf6a6000 4K rw-s- zero (deleted)
00007f5fbf6a7000 4K rw-s- zero (deleted)
00007f5fbf6a8000 1052K r-x-- libm-2.21.so
00007f5fbf7af000 2044K ----- libm-2.21.so
00007f5fbf9ae000 4K r---- libm-2.21.so
00007f5fbf9af000 4K rw--- libm-2.21.so
00007f5fbf9b0000 28K r-x-- librt-2.21.so
00007f5fbf9b7000 2044K ----- librt-2.21.so
00007f5fbfbb6000 4K r---- librt-2.21.so
00007f5fbfbb7000 4K rw--- librt-2.21.so
00007f5fbfbb8000 432K r-x-- libpcre.so.3.13.1
00007f5fbfc24000 2044K ----- libpcre.so.3.13.1
00007f5fbfe23000 4K r---- libpcre.so.3.13.1
00007f5fbfe24000 4K rw--- libpcre.so.3.13.1
00007f5fbfe25000 4K rw-s- zero (deleted)
00007f5fbfe26000 4K rw-s- zero (deleted)
00007f5fbfe27000 4K rw-s- zero (deleted)
00007f5fbfe28000 60K r-x-- libbz2.so.1.0.4
00007f5fbfe37000 2044K ----- libbz2.so.1.0.4
00007f5fc0036000 4K r---- libbz2.so.1.0.4
00007f5fc0037000 4K rw--- libbz2.so.1.0.4
00007f5fc0038000 1688K r-x-- libdb-5.3.so
00007f5fc01de000 2048K ----- libdb-5.3.so
00007f5fc03de000 28K r---- libdb-5.3.so
00007f5fc03e5000 4K rw--- libdb-5.3.so
00007f5fc03e6000 4K rw-s- zero (deleted)
00007f5fc03e7000 4K rw-s- zero (deleted)
00007f5fc03e8000 344K r-x-- libssl.so.1.0.0
00007f5fc043e000 2044K ----- libssl.so.1.0.0
00007f5fc063d000 16K r---- libssl.so.1.0.0
00007f5fc0641000 28K rw--- libssl.so.1.0.0
00007f5fc0648000 1760K r-x-- libcrypto.so.1.0.0
00007f5fc0800000 2044K ----- libcrypto.so.1.0.0
00007f5fc09ff000 116K r---- libcrypto.so.1.0.0
00007f5fc0a1c000 48K rw--- libcrypto.so.1.0.0
00007f5fc0a28000 16K rw--- [ anon ]
00007f5fc0a2c000 4K rw-s- zero (deleted)
00007f5fc0a2d000 4K rw-s- zero (deleted)
00007f5fc0a2e000 4K rw-s- zero (deleted)
00007f5fc0a2f000 4K rw-s- zero (deleted)
00007f5fc0a30000 92K r-x-- libresolv-2.21.so
00007f5fc0a47000 2048K ----- libresolv-2.21.so
00007f5fc0c47000 8K r---- libresolv-2.21.so
00007f5fc0c49000 4K rw--- libresolv-2.21.so
00007f5fc0c4a000 8K rw--- [ anon ]
00007f5fc0c4c000 4K rw-s- zero (deleted)
00007f5fc0c4d000 4K rw-s- zero (deleted)
00007f5fc0c4e000 4K rw-s- zero (deleted)
00007f5fc0c4f000 4K rw-s- zero (deleted)
00007f5fc0c50000 100K r-x-- libz.so.1.2.8
00007f5fc0c69000 2048K ----- libz.so.1.2.8
00007f5fc0e69000 4K r---- libz.so.1.2.8
00007f5fc0e6a000 4K rw--- libz.so.1.2.8
00007f5fc0e6b000 4K rw-s- zero (deleted)
00007f5fc0e6c000 4K rw-s- zero (deleted)
00007f5fc0e6d000 4K rw-s- zero (deleted)
00007f5fc0e6e000 4K rw-s- zero (deleted)
00007f5fc0e6f000 4K rw-s- zero (deleted)
00007f5fc0e70000 144K r-x-- ld-2.21.so
00007f5fc0e94000 4K rw-s- zero (deleted)
00007f5fc0e95000 4K rw-s- zero (deleted)
00007f5fc0e96000 4K rw-s- zero (deleted)
00007f5fc0e97000 4K rw-s- zero (deleted)
00007f5fc0e98000 4K rw-s- zero (deleted)
00007f5fc0e99000 4K rw-s- zero (deleted)
00007f5fc0e9a000 4K rw-s- zero (deleted)
00007f5fc0e9b000 4K rw-s- zero (deleted)
00007f5fc0e9c000 4K rw-s- zero (deleted)
00007f5fc0e9d000 4K rw-s- zero (deleted)
00007f5fc0e9e000 4K rw-s- zero (deleted)
00007f5fc0e9f000 4K rw-s- zero (deleted)
00007f5fc0ea0000 4K rw-s- zero (deleted)
00007f5fc0ea1000 4K rw-s- zero (deleted)
00007f5fc0ea2000 4K rw-s- zero (deleted)
00007f5fc0ea3000 4K rw-s- zero (deleted)
00007f5fc0ea4000 4K rw-s- zero (deleted)
00007f5fc0ea5000 4K rw-s- zero (deleted)
00007f5fc0ea6000 4K rw-s- zero (deleted)
00007f5fc0ea7000 4K rw-s- zero (deleted)
00007f5fc0ea8000 4K rw-s- zero (deleted)
00007f5fc0ea9000 4K rw-s- zero (deleted)
00007f5fc0eaa000 4K rw-s- zero (deleted)
00007f5fc0eab000 4K rw-s- zero (deleted)
00007f5fc0eac000 4K rw-s- zero (deleted)
00007f5fc0ead000 4K rw-s- zero (deleted)
00007f5fc0eae000 4K rw-s- zero (deleted)
00007f5fc0eaf000 4K rw-s- zero (deleted)
00007f5fc0eb0000 4K rw-s- zero (deleted)
00007f5fc0eb1000 4K rw-s- zero (deleted)
00007f5fc0eb2000 4K rw-s- zero (deleted)
00007f5fc0eb3000 4K rw-s- zero (deleted)
00007f5fc0eb4000 4K rw-s- zero (deleted)
00007f5fc0eb5000 4K rw-s- zero (deleted)
00007f5fc0eb6000 4K rw-s- zero (deleted)
00007f5fc0eb7000 4K rw-s- zero (deleted)
00007f5fc0eb8000 4K rw-s- zero (deleted)
00007f5fc0eb9000 4K rw-s- zero (deleted)
00007f5fc0eba000 4K rw-s- zero (deleted)
00007f5fc0ebb000 4K rw-s- zero (deleted)
00007f5fc0ebc000 4K rw-s- zero (deleted)
00007f5fc0ebd000 4K rw-s- zero (deleted)
00007f5fc0ebe000 4K rw-s- zero (deleted)
00007f5fc0ebf000 4K rw-s- zero (deleted)
00007f5fc0ec0000 4K rw-s- zero (deleted)
00007f5fc0ec1000 4K rw-s- zero (deleted)
00007f5fc0ec2000 4K rw-s- zero (deleted)
00007f5fc0ec3000 4K rw-s- zero (deleted)
00007f5fc0ec4000 4K rw-s- zero (deleted)
00007f5fc0ec5000 4K rw-s- zero (deleted)
00007f5fc0ec6000 4K rw-s- zero (deleted)
00007f5fc0ec7000 4K rw-s- zero (deleted)
00007f5fc0ec8000 4K rw-s- zero (deleted)
00007f5fc0ec9000 4K rw-s- zero (deleted)
00007f5fc0eca000 4K rw-s- zero (deleted)
00007f5fc0ecb000 4K rw-s- zero (deleted)
00007f5fc0ecc000 4K rw-s- zero (deleted)
00007f5fc0ecd000 4K rw-s- zero (deleted)
00007f5fc0ece000 4K rw-s- zero (deleted)
00007f5fc0ecf000 4K rw-s- zero (deleted)
00007f5fc0ed0000 4K rw-s- zero (deleted)
00007f5fc0ed1000 4K rw-s- zero (deleted)
00007f5fc0ed2000 4K rw-s- zero (deleted)
00007f5fc0ed3000 4K rw-s- zero (deleted)
00007f5fc0ed4000 4K rw-s- zero (deleted)
00007f5fc0ed5000 4K rw-s- zero (deleted)
00007f5fc0ed6000 4K rw-s- zero (deleted)
00007f5fc0ed7000 4K rw-s- zero (deleted)
00007f5fc0ed8000 4K rw-s- zero (deleted)
00007f5fc0ed9000 4K rw-s- zero (deleted)
00007f5fc0eda000 4K rw-s- zero (deleted)
00007f5fc0edb000 4K rw-s- zero (deleted)
00007f5fc0edc000 4K rw-s- zero (deleted)
00007f5fc0edd000 4K rw-s- zero (deleted)
00007f5fc0ede000 4K rw-s- zero (deleted)
00007f5fc0edf000 4K rw-s- zero (deleted)
00007f5fc0ee0000 28K r--s- gconv-modules.cache
00007f5fc0ee7000 4K rw-s- zero (deleted)
00007f5fc0ee8000 4K rw-s- zero (deleted)
00007f5fc0ee9000 4K rw-s- zero (deleted)
00007f5fc0eea000 4K rw-s- zero (deleted)
00007f5fc0eeb000 4K rw-s- zero (deleted)
00007f5fc0eec000 4K rw-s- zero (deleted)
00007f5fc0eed000 1644K rw--- [ anon ]
00007f5fc1088000 4K rw-s- zero (deleted)
00007f5fc1089000 4K rw-s- zero (deleted)
00007f5fc108a000 4K rw-s- zero (deleted)
00007f5fc108b000 4K rw-s- zero (deleted)
00007f5fc108c000 4K rw-s- zero (deleted)
00007f5fc108d000 4K rw-s- zero (deleted)
00007f5fc108e000 4K rw-s- zero (deleted)
00007f5fc108f000 4K rw-s- zero (deleted)
00007f5fc1090000 4K rw-s- zero (deleted)
00007f5fc1091000 8K rw--- [ anon ]
00007f5fc1093000 4K r---- ld-2.21.so
00007f5fc1094000 4K rw--- ld-2.21.so
00007f5fc1095000 8K rw--- [ anon ]
00007f5fc1097000 12K rw--- [ anon ]
00007fff4d8cb000 132K rw--- [ stack ]
00007fff4d9c8000 8K r---- [ anon ]
00007fff4d9ca000 8K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 467532K
See that total?
467532K = 58,4 MB of server memory, in-and-out, just to serve an request doing nothing (e.g. die();)
Try that pmap command, you'll hate PHP and recognize that it sucks. I'm sure.
So that's way I hate PHP Frameworks, I'm paranoid about any single second of a PHP worker doing even a simple job (that 20ms locking 58+MB of RAM memory and CPU usage), and i told you on other threads that Joomla for me should aim to be the best PHP CMS, but not a PHP framework, it's a waste of time.
Check also a similar post i did in Moodle issue tracker, years ago:
https://tracker.moodle.org/browse/MDL-26928
I repeat, I'm not against Joomla, i'm just aware of how PHP sucks (but I've to use it as there's no good CMS in other langages).
Yes, you can (MUST) use the opcode chacing, true, but that's an hack, way far to having an application 'running' in memory, classes defined only once, shared libraries, with shared variables, singletons, connection pool etc.
I'm not a PHP developer, but i started to be a bit after falling in love with Joomla, one day my boss told me: write a Joomla plugin, then now using in Joomla just because I liked it's internal infrastracture, the event-driven plugin chain is awesome, first time i saw it i said: Oh, that guys implemented a good instrastracture for a PHP application, better than any CMS (Liferay in java sucks, and there are no nodejs/ruby mature CMS in open source), I just told myself what's a pity that Joomla is written in PHP so those events, those 'pseudo-singletons' like JDatabase, JFactory etc, are just 'request scoped' and cannot be 'application scoped' like it should be to make sense, like it was possible to make them in a ruby/java/nodejs app running in a container.
I dream the whole Joomla, rewritten as it is now, in node.js. That will be the perfect, modern CMS IMO.
@nikosdion >Stefani, saving a flag in the session can be done by saving a flag IN THE SESSION. No need for another db field. Not to mention that requiring a db table for sessions is wrong but I digress.
True, but only if you're using database as session handler, but you forgot or don't know that Joomla has this issue: it always use #__session table even if session storage handler is set to file, memcached, or whatever so adding a database column in the current scenario will be the best point to add this flag (anyway i suggest to get rid of this #__session table at all if a better solution will come)
So the point is to fix also that, I'm not wasting your time, i'm trying to help you to find and bring in the light something that is not clear (to many of you) but it's in joomla, to improve the project
Instead of wasting everyone's time to see if joomla is doing something and
accusing it of bad security why don't you spend a few minutes in looking
for yourself.
Can you be more clear? What i should look myself...? Please remember that I'm wasting primary my time trying to help, not to criticize, so please be kind, and read why I answered that after reading the link that was pointed me out, I talked about the hidden password field, it's a best pratice, as I'd a 'secure programming' course years ago at TERENA and they told me also that should be avoided (it's not a severe issue, but to be paranoid better to avoid it, even if hashed, it's also a redundancy as you don't need it in-memory), this it's not accusing, it's talking with passion for this project, sharing my point of view and minutes of thinking, you're free to ignore me, I'm nobody, unlike you probably that are a great expert, but I wasn't talking about you, but about Joomla, that is great, but as any piece of software imperfect.
First, please check who are you talking to. Not only am I fully aware how the session works, I am one of the two developers that fixed the massive cockup in Joomla's session last week. I think I am more qualified than you to express an opinion on the subject: I do know how the code works, I do write core code, I have been contributing to the core for over 6 years.
On the matter at hand, please read my answer again. I said that what Joomla currently does (tie a table to the session) is wrong, implying that we have to fix it - something discussed over years and in length in public lists where everyone agrees on it. Therefore introducing a solution that hinges on the table is shortsighted and increases the technical debt moving forward. On top of that, it's not even necessary.
Let alone that your idea as a whole is, as I said, BAD. As I said, I HAVE tried it and I DO have published code using it. It only works very partially because you can't know which session is tied to which user without introducing technical debt. Even if you did, finding which users need reloading means that after every ACL operation you have to go through each and every user TWICE and see if their privileges got touched and their sessions need reload. While this may work on a site with five groups and 100 users it won't work on a site with 60 groups and 70,000 users for OBVIOUS reasons. Right now my code limits itself to doing a user reloading only when the user's group assignment changes. As you learned reading my previous comment that's one third of the solution and does not cover the tough third (why it doesn't I explained in this very paragraph).
So unless you have some non-bullshit opinion to share I suggest that you show us the code that goes with it. Otherwise I would kindly request that you shut up and start reading the code; maybe you'll learn something.
What everyone is saying is HOW can we know which users need to be logged out. Don't be fast to answer.
inline
It can be any kind of change between the use group assignment (easy to catch)
that's covered
OR a change in the view access levels OR the privileges of any item carrying an ACL asset. The latter makes it impossible and I don't see you covering it.
it's easy to cover it: you can mark the 'refresh' flag for any active user:
/*this should be executed at onPermissionChange (new event to be triggered at each ACL change, globally or at item level)*/
"UPDATE #__session SET juser_needs_refresh=1";
What you'll get with that? I know: lots of refreshes, but is always 1 single refresh for any active user session (
As you can see I'm skipping the 'recursive finding of what user need to be refreshed' as too complex - KISS rule - better in this case to trigger an huge overhead, but * only a single time * per session, not indefinitely.), I know that is hugly too, and has a computational cost, but surely better of with the original solution proposed in this #8805 where this same computational cost, is going to be applied at each https request for any user.
Really you cannot see the difference from an 'event-driven' action triggered by 'piggyback ', and a 'compulsive poller' redoing the same action infiniteley and when there is no need too?
This is the best you can do in PHP, if Joomla was in Java or Ruby or Node.js I'd proposed to implement a 'message bus' and not that 'piggyback' on existing db reads, I'm trying to propose what is feasible with ease, please don't be fast to mark me as a troll, I reasoned a lot about that, even before this PR, by myself.
Having any of these actions set a flag in every session asking Joomla to reload the user is daft. In all practical cases it is equivalent to reloading the user on every page load.
I cannot belive you really thing that. You can benchmark it and see the difference between execting a needed action only once after each change and execting the same action always, also when there is no change at all (not all site vistitors are buying akeeba subscriptions, sadly for site owners) there are also logged users doing other in an average Joomla site...
BTW this is exactly what I'm doing in Akeeba Subscriptions hence I am so adamant that it is a stupid idea. Been there done that ain't working good.
So better to reload the JUser at each page load, that's not an hack? I think that the akeeba solution is smartest - with no offence - than this PR. But I'm nobody, I'll stop trolling you if you think I'm.. It's not a talent show here, I've simply interest to keep Joomla good as I work with it. So I try to 'trigger' some discussion, rasing a different point of view. Really don't worry, this is my last message, I'll not disturb anymore.
Best Regards,
And Respect for you all.
I already told you that force reloading across all sessions ends up being equivalent to George's solution in all practical cases. Moreover, it requires every 3pd who goes through ACL management of core or own items to add code to mark all sessions as needing reloading. Finally, it does require cementing the relationship between the session and the database which increases technical debt and makes use of Joomla problematic on high volume sites without a caching proxy in front (a moot point if said sites require users to be logged in).
Look, your idea can be somewhat implemented as a system plugin. Instead of marking sessions we can simply store the time stamp of the last ACL change. If the last time a session was loaded was before that time force load JUser onAfterInitialize. This reduces the technical debt but it's not faster than George's solution on real world sites so we're back at square one.
Look, I don't want to fight over this. I see that you are wondering the same things I was wondering 3-4 years ago. Then I started doing POCs and saw the limitations. I suggest you do the same. You'll learn how that part of Joomla works inside and out and maybe you'll have the epiphany that eludes me, George, Michael and all the other developers over the years who've tried to solve this elegantly.
First, please check who are you talking to. Not only am I fully aware how the session works, I am one of the two developers that fixed the massive cockup in Joomla's session last week. I think I am more qualified than you to express an opinion on the subject: I do know how the code works, I do write core code, I have been contributing to the core for over 6 years.
I said, respect for you all. I don't want my ideas to be considered to be 'merged' I just trying to give another point of view. You can misunderstand me due my bad english, I don't care about who I'm talking to, but I respect you all (and you more now that I know you're the Akeeba developer) but, you know, somebody also a non-expert can give a draft idea to an expert so why i shoould shut up (e.g. my wife doesn't know anything about IT but inspired me many times with her stupid comment), then let me the stupid voice, but reason honestly on what i raise, the nobodies like me can have wrong or good ideas, then the experts can ignore them (with no need to tell shut up) or elabortate then and make them great adding their knowledge. It's not my role to be an expert, and I'm done, I don't want any credits, I don't aim to enter in the developer circle (I'm not a good PHP developer), I'm here just to give my 2 cents.
Instead of marking sessions we can simply store the time stamp of the last ACL change.
Yes this IMO (a poor man opinion) can be the best solution.
Look, I don't want to fight over this. I see that you are wondering the same things I was wondering 3-4 years ago. Then I started doing POCs and saw the limitations. I suggest you do the same. You'll learn how that part of Joomla works inside and out and maybe you'll have the epiphany that eludes me, George, Michael and all the other developers over the years who've tried to solve this elegantly.
Sorry if i seemed offensive, I repeat, I don't want to lack respect, I respect you all Joomla developers, as I repeat Joomla is for me the best php software ever, frankly.
But I'm simply one that think that everybody can talk even with Obama, or God, without having to hide his ideas. A dreamer (in its negative connotation).
Reading the whole discussion above, and the code I think the code suggested by @wilsonge is better and just needs to address following two issues:
JUser
in the session, but the code expects array('id' => NNN)
resulting in an error.@creativeprogramming Loved your last statement about not hiding ideas :-)
@nikosdion Talking about the fixes in Joomla session last week, I see the bug is not only persistent till date, rather J3.4.8 actually served (almost) no purpose. That turned out to be a quick workaround only by providing unnecessary (I think so) automatic logout for only the user performing the update. It doesn't work for rest of the users anyway.
Actually 3.4.8 fixed a massive issue. It was not a quick workaround. It was bound by the decision to have session data migration - with which I disagree and if the JSST agrees I can publicly share the email where I call this decision moronic. I was ignored and stuff broke. Then I wasted two days of my entire company's staff time, paid from my own pocket, fixing what Joomla! broke by ignoring me. On Christmas Eve. You're welcome.
Also, upon upgrade it's not just the current user logged out. All sessions are destroyed to work around the partial migration in 3.4.7. The alternative was far messier. However, once it's done once the next update shouldn't cause the log out again.
Moreover we did fix a massive bug that caused JSession to throw a fatal error when spawned outside JApplicationCms, eg JApplicationWeb used by developers to offer directly web accessible entry points or JApplicationCli used for all CLI scripts.
What isn't "fixed" is the necessity of base64 encode and decode. However, this is a requirement of Joomla! since 1.6 released in late 2010, more than 5 years ago. If your host doesn't meet Joomla!'s requirements the last 5+ years I suggest you change hosts instead of telling us that we didn't "fix" what has been a requirement all along ;)
upon upgrade it's not just the current user logged out. All sessions are destroyed to work around the partial migration in 3.4.7
That's what it says, but not true. I tested it all myself with 3.4.5
/ 3.4.6
=> 3.4.7
/ 3.4.8
all combinations. See #8777 (comment)
The alternative was far messier.
What were the proposed alternatives, please let me know if I'm missing something.
However, once it's done once the next update shouldn't cause the log out again.
Yeah, I understand.
And I know the hosts not supporting base64
functions are to blame, not Joomla. Thats too narrow as a security measure.
From where I see, all those permission issues are because we did not migrate registry
key from old session. I don't know it was for some reason, please let me. But at least we could set it to empty registry
and everything could be fine. No need to logout anybody. See #8782 for detail. JApplicationCms::setUserState
depends on registry
key.
PS: I can happily share a video of my test experience if at all needed.
@izharaazmi If you believe that you can magically fix the sites with broken sessions (upgraded from 3.4.6 to 3.4.7) without destroying the sessions please show me your code.
BE CAREFUL! Your solution MUST NOT degrade security, i.e. it must not allow a crafted session to be "migrated" in a way that causes privilege escalation. Ah! See the problem now? Indeed we came up with a solution that's not very sexy (it kicks everyone with a migrated session out) but it does solve the three issues introduced in 3.4.7 without causing a new security issue.
As I said, you're welcome and have a happy new year too.
@nikosdion I have added my solution code and details in the PR #8782 as it was more relevant to that one than this one. Please look at my comment here #8782 (comment) and advise.
I hope it does not degrade security.
Thank you and I wish you and every Joomler, a very Happy New Year :-)
@wilsonge should this be closed
Status | Pending | ⇒ | Information Required |
No. It should be tested
The comments above are not favourable or am I misreading it.
On 1 Mar 2016 12:15 pm, "George Wilson" notifications@github.com wrote:
No. It should be tested
—
Reply to this email directly or view it on GitHub
#8805 (comment).
I think its a mixed bag - i'd definitely refer it to a PLT vote for approval once it's had it's tests - but @nikosdion and @mbabker are definitely in favour of it
I guess I misread the comments then
On 1 Mar 2016 2:29 pm, "Izhar Aazmi" notifications@github.com wrote:
@wilsonge https://github.com/wilsonge Count me too [image: ] [image:
]—
Reply to this email directly or view it on GitHub
#8805 (comment).
One or two comments above by me discuss a bit related to other issue regarding the fix in J! 3.4.8 that has been enough discussed already. Nothing more on that.
For this one, I'd just quote #8805 (comment). Remaining can be ignored safely.
I will investigate the first point you raised.
The second point is invalid (I believe). If are the logged in user then as long as you access the user through JFactory::getUser (like you should do anyhow now) then it will be updated in the current page load (e.g. like what happens here: https://github.com/joomla/joomla-cms/blob/staging/libraries/joomla/user/helper.php#L67)
The way Joomla's structured now the user object will be loaded pretty much first thing in the application's execute method.
Status | Information Required | ⇒ | Pending |
Category | ⇒ | Libraries |
Milestone |
Added: |
After reading this piece of poetry, I agree that this should be merged. Understandably there is a performance penalty. In the case this really blows things up we can look at how to deal with it then.
Thank you all for participating.
Status | Pending | ⇒ | Fixed in Code Base |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2016-05-08 15:59:55 |
Closed_By | ⇒ | roland-d |
<3
Should testing also include the different session handlers?