ownCloud shares are removed temporarily when LDAP server is not available
Today I needed to reboot my LDAP server. The reboot caused the LDAP connection to be broken, but what made matters worse is that shares created by LDAP users are removed for non-LDAP enabled accounts.
Consider this setup:
- User
Ais authenticated against LDAP - User
Bhas a normal ownCloud account - User
Ashares a directoryDto userB - User
Bsyncs using his or her ownCloud client ,Dis downloaded - The LDAP server is rebooted, hence the connection is lost and
Ais unable to authenticate -
The ownCloud client of user
Bnotifies the user thatDhas been unshared and deletesDfrom disk - LDAP server comes back online
- Shares are restored
- User
Bneeds to redownloadD
The problem is that D contains about 20 GB of files, and these 20GB are added to our allotted network bandwidth. Consider you need to reboot LDAP quite often, it always causes those 20GB to be deleted and redownloaded a couple of minutes later.
Expected behavior. share is still mounted but inaccessible with "503 Storage Not Available"
@butonic @tomneedham
Ok, but does step 6 really need to delete all files from disk? IMHO Storage Not Available does not mean that the share was actually removed.
Internally "Storage Not Available" tells any clients to "leave everything as it is" so no deletion would happen.
and with "Storage Not Available" it is meant "Storage Temporarily Not Available, Please Try Again Later"
If I understand you correctly this is a client issue?
No. The problem is likely that the server does not correctly return the status code "503 Storage Temporarily Not Available" for said folder or even fails to mount them to the filesystem view.
The clients do not see the folders any more so they believe they are deleted so they delete it locally.
The correct behavior is to keep the mounts visible (incoming shares are mounts) but when explored they should return the 503 error.
OK, who should I contact about this? owncloud/core?
It is not clear yet whether this is a core issue or LDAP. It all depends how LDAP users are exposed at the moment the server becomes unavialable.
I'd expect the users to continue existing anyway due to the oc_account tables...
... wait a minute, you didn't post your ownCloud version ? I'm talking about OC 10.0 where I expect this problem to be resolved already with the oc_accounts table which was specifically introduced to avoid this kind of problems.
Please use the issue template https://raw.githubusercontent.com/owncloud/core/master/.github/issue_template.md
Talking about 10.0.4. The table exists.
$ docker exec -it owncloud_mariadb_1 mysql -uroot '-psomething' -e 'select * from owncloud.oc_accounts where user_id="agross";'
+----+-------------------------+---------+---------------+----------------+-------+------------+--------------------------+---------------------------+-------+
| id | email | user_id | lower_user_id | display_name | quota | last_login | backend | home | state |
+----+-------------------------+---------+---------------+----------------+-------+------------+--------------------------+---------------------------+-------+
| 1 | [email protected] | agross | agross | Alexander Gro� | NULL | 1517698680 | OCA\User_LDAP\User_Proxy | /var/www/html/data/agross | 1 |
+----+-------------------------+---------+---------------+----------------+-------+------------+--------------------------+---------------------------+-------+
FYI, the issue template in core does not apply to users_ldap.
The table should contain the users from the LDAP users that disappeared when the LDAP server went away.
Did you also setup the cron job that runs occ user:sync as per documentation ?
I wonder whether said command properly detects missing servers and doesn't try to sync the disappeared users. Maybe the cron output from that moment contains some clues ?
- I wasn't aware of
occ user:syncand couldn't find any information on this doing a quick search in the admin docs, here or here. Where is that documented? - I don't really care about added users that
occ users:syncmight add to oC, I guess sync allows to share stuff with users that never logged in, but we don't need that ATM. - It's just that the LDAP server connection is interrupted that causes shares to be considered gone by either the server or the client.
@agross
you've searched in the 9.1 docs for the user:sync - you find it documented here:
https://doc.owncloud.org/server/latest/admin_manual/configuration/server/occ_command.html#syncing-user-accounts-label
@patrickjahns Thanks. As far as I understand it, syncing users is optional with a small number of users. We have about 10, which I consider small.
FYI, this is what I tried earlier today to find the docs you mentioned. And yes, I was searching the latest docs.
https://doc.owncloud.org/server/latest/admin_manual/search.html?q=user%3Async
I just failed to reproduce this. When ldap is down A cannot login. B being a database user still can. He can also up and download files into D.
@agross What you describe sounds like B was disabled. That only happens when syncing users. Any errors in the logfile? Can you send a log file with debugging enabled? Is D a federated share?
{"reqId":"5a0e0645-e8aa-49fe-b927-8f90d27e0b47",
"level":3,
"time":"2018-02-07T22:55:59+00:00",
"remoteAddr":"172.19.0.1",
"user":"agross",
"app":"user_ldap",
"method":"PROPFIND",
"url":"/remote.php/dav/files/agross/",
"message":"Exception: {"Exception":"OC\ServerNotAvailableException",
"Message":"Lost connection to LDAP server.",
"Code":0,
"Trace":"#0 /var/www/html/apps/user_ldap/lib/LDAP.php(279): OCA\User_LDAP\LDAP->postFunctionCall()\
#1 /var/www/html/apps/user_ldap/lib/LDAP.php(43): OCA\User_LDAP\LDAP->invokeLDAPMethod('bind', Resource id #70, 'uid=owncloud,cn...', 'bind password...')\
#2 /var/www/html/apps/user_ldap/lib/Connection.php(540): OCA\User_LDAP\LDAP->bind(Resource id #70, 'uid=owncloud,cn...', 'HIs$9X4ECR?!I+V...')\
#3 /var/www/html/apps/user_ldap/lib/Connection.php(167): OCA\User_LDAP\Connection->establishConnection()\
#4 /var/www/html/apps/user_ldap/lib/Connection.php(176): OCA\User_LDAP\Connection->init()\
#5 /var/www/html/apps/user_ldap/lib/Access.php(989): OCA\User_LDAP\Connection->getConnectionResource()\
#6 /var/www/html/apps/user_ldap/lib/Access.php(1156): OCA\User_LDAP\Access->executeSearch('(&(|(uid=agross...', Array, Array, NULL, NULL)\
#7 /var/www/html/apps/user_ldap/lib/Access.php(925): OCA\User_LDAP\Access->search('(&(|(uid=agross...', Array, Array, NULL, NULL)\
#8 /var/www/html/apps/user_ldap/lib/Access.php(821): OCA\User_LDAP\Access->searchUsers('(&(|(uid=agross...', Array, NULL, NULL)\
#9 /var/www/html/apps/user_ldap/lib/Access.php(794): OCA\User_LDAP\Access->fetchListOfUsers('(&(|(uid=agross...', Array)\
#10 /var/www/html/apps/user_ldap/lib/User/Manager.php(526): OCA\User_LDAP\Access->fetchUsersByLoginName('agross', Array)\
#11 /var/www/html/apps/user_ldap/lib/User_LDAP.php(140): OCA\User_LDAP\User\Manager->getLDAPUserByLoginName('agross')\
#12 [internal function]: OCA\User_LDAP\User_LDAP->checkPassword(*** sensitive parameters replaced ***)\
#13 /var/www/html/apps/user_ldap/lib/User_Proxy.php(75): call_user_func_array(Array, Array)\
#14 /var/www/html/apps/user_ldap/lib/Proxy.php(140): OCA\User_LDAP\User_Proxy->walkBackends('agross', 'checkPassword', Array)\
#15 /var/www/html/apps/user_ldap/lib/User_Proxy.php(180): OCA\User_LDAP\Proxy->handleRequest('agross', 'checkPassword', Array)\
#16 /var/www/html/lib/private/User/Manager.php(215): OCA\User_LDAP\User_Proxy->checkPassword(*** sensitive parameters replaced ***)\
#17 /var/www/html/lib/private/User/BasicAuthModule.php(49): OC\User\Manager->checkPassword(*** sensitive parameters replaced ***)\
#18 /var/www/html/lib/private/User/Session.php(883): OC\User\BasicAuthModule->auth(Object(OC\AppFramework\Http\Request))\
#19 /var/www/html/apps/dav/lib/Connector/Sabre/Auth.php(116): OC\User\Session->verifyAuthHeaders(Object(OC\AppFramework\Http\Request))\
#20 /var/www/html/lib/composer/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php(105): OCA\DAV\Connector\Sabre\Auth->validateUserPass(*** sensitive parameters replaced ***)\
#21 /var/www/html/apps/dav/lib/Connector/Sabre/Auth.php(246): Sabre\DAV\Auth\Backend\AbstractBasic->check(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))\
#22 /var/www/html/apps/dav/lib/Connector/Sabre/Auth.php(150): OCA\DAV\Connector\Sabre\Auth->auth(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))\
#23 /var/www/html/lib/composer/sabre/dav/lib/DAV/Auth/Plugin.php(201): OCA\DAV\Connector\Sabre\Auth->check(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))\
#24 /var/www/html/lib/composer/sabre/dav/lib/DAV/Auth/Plugin.php(150): Sabre\DAV\Auth\Plugin->check(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))\
#25 [internal function]: Sabre\DAV\Auth\Plugin->beforeMethod(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))\
#26 /var/www/html/lib/composer/sabre/event/lib/EventEmitterTrait.php(105): call_user_func_array(Array, Array)\
#27 /var/www/html/lib/composer/sabre/dav/lib/DAV/Server.php(466): Sabre\Event\EventEmitter->emit('beforeMethod', Array)\
#28 /var/www/html/lib/composer/sabre/dav/lib/DAV/Server.php(254): Sabre\DAV\Server->invokeMethod(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))\
#29 /var/www/html/apps/dav/lib/Server.php(256): Sabre\DAV\Server->exec()\
#30 /var/www/html/apps/dav/appinfo/v2/remote.php(31): OCA\DAV\Server->exec()\
#31 /var/www/html/remote.php(165): require_once('/var/www/html/a...')\
#32 {main}",
"File":"/var/www/html/apps/user_ldap/lib/LDAP.php",
"Line":310}"}
{"reqId":"5a0e0645-e8aa-49fe-b927-8f90d27e0b47",
"level":4,
"time":"2018-02-07T22:58:10+00:00",
"remoteAddr":"172.19.0.1",
"user":"agross",
"app":"webdav",
"method":"PROPFIND",
"url":"/remote.php/dav/files/agross/",
"message":"Exception: {"Message":"HTTP/1.1 503 OC\ServerNotAvailableException: Lost connection to LDAP server.",
"Exception":"Sabre\DAV\Exception\ServiceUnavailable",
"Code":0,
"Trace":"#0 /var/www/html/lib/composer/sabre/dav/lib/DAV/Auth/Plugin.php(201): OCA\DAV\Connector\Sabre\Auth->check(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))\
#1 /var/www/html/lib/composer/sabre/dav/lib/DAV/Auth/Plugin.php(150): Sabre\DAV\Auth\Plugin->check(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))\
#2 [internal function]: Sabre\DAV\Auth\Plugin->beforeMethod(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))\
#3 /var/www/html/lib/composer/sabre/event/lib/EventEmitterTrait.php(105): call_user_func_array(Array, Array)\
#4 /var/www/html/lib/composer/sabre/dav/lib/DAV/Server.php(466): Sabre\Event\EventEmitter->emit('beforeMethod', Array)\
#5 /var/www/html/lib/composer/sabre/dav/lib/DAV/Server.php(254): Sabre\DAV\Server->invokeMethod(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))\
#6 /var/www/html/apps/dav/lib/Server.php(256): Sabre\DAV\Server->exec()\
#7 /var/www/html/apps/dav/appinfo/v2/remote.php(31): OCA\DAV\Server->exec()\
#8 /var/www/html/remote.php(165): require_once('/var/www/html/a...')\
#9 {main}",
"File":"/var/www/html/apps/dav/lib/Connector/Sabre/Auth.php",
"Line":157,
"User":"agross"}"}
This is what gets logged.
What you describe sounds like
Bwas disabled.
All I can say is that B no longer sees the share (confirmed using the web UI) and his Windows client deletes the D from disk. The share returns once LDAP is back up and A is able to login.
Is
Da federated share?
No, just a normal share.
@agross
syncing users is optional with a small number of users. We have about 10, which I consider small.
Slight caveat: if they have never logged in, they won't be available for any sharing - hence the recommendation of syncing them straight away.
if they have never logged in, they won't be available for any sharing
I know. As I said, not a problem for us. Our user count is rather stable (changed once in a few years).
what exact version of user_ldap are you using?
user_ldap: 0.10.0