diff options
author | Jörn Friedrich Dreyer <jfd@butonic.de> | 2012-08-25 00:05:07 +0200 |
---|---|---|
committer | Jörn Friedrich Dreyer <jfd@butonic.de> | 2012-08-25 00:05:07 +0200 |
commit | c8255a170c2d7449b4e7728edd2237eea71dca80 (patch) | |
tree | e5a3854ec472be9700064bc7b689b8adf7c7f692 /apps/user_ldap | |
parent | 0c0ae928dcd483211a92303eb2b202453d02a86e (diff) | |
parent | 46d6fd15e4cc02d45079ffc688be0684e61f1434 (diff) | |
download | nextcloud-server-c8255a170c2d7449b4e7728edd2237eea71dca80.tar.gz nextcloud-server-c8255a170c2d7449b4e7728edd2237eea71dca80.zip |
Merge branch 'master' of git://gitorious.org/owncloud/owncloud into oracle-support
Conflicts:
3rdparty/Sabre/CardDAV/Plugin.php
3rdparty/smb4php/smb.php
apps/bookmarks/ajax/addBookmark.php
apps/bookmarks/ajax/editBookmark.php
apps/bookmarks/appinfo/migrate.php
apps/calendar/ajax/calendar/edit.form.php
apps/calendar/ajax/changeview.php
apps/calendar/ajax/import/import.php
apps/calendar/ajax/settings/guesstimezone.php
apps/calendar/ajax/settings/setfirstday.php
apps/calendar/ajax/settings/settimeformat.php
apps/calendar/ajax/share/changepermission.php
apps/calendar/ajax/share/share.php
apps/calendar/ajax/share/unshare.php
apps/calendar/appinfo/app.php
apps/calendar/appinfo/remote.php
apps/calendar/appinfo/update.php
apps/calendar/appinfo/version
apps/calendar/js/calendar.js
apps/calendar/l10n/da.php
apps/calendar/l10n/de.php
apps/calendar/l10n/fi_FI.php
apps/calendar/l10n/gl.php
apps/calendar/l10n/he.php
apps/calendar/l10n/hr.php
apps/calendar/l10n/ja_JP.php
apps/calendar/l10n/lb.php
apps/calendar/l10n/lt_LT.php
apps/calendar/l10n/nb_NO.php
apps/calendar/l10n/pl.php
apps/calendar/l10n/pt_PT.php
apps/calendar/l10n/ro.php
apps/calendar/l10n/ru.php
apps/calendar/l10n/sv.php
apps/calendar/l10n/zh_CN.php
apps/calendar/l10n/zh_TW.php
apps/calendar/lib/app.php
apps/calendar/lib/calendar.php
apps/calendar/lib/object.php
apps/calendar/lib/share.php
apps/calendar/templates/part.choosecalendar.rowfields.php
apps/calendar/templates/part.import.php
apps/calendar/templates/settings.php
apps/contacts/ajax/activation.php
apps/contacts/ajax/addressbook/delete.php
apps/contacts/ajax/contact/add.php
apps/contacts/ajax/contact/addproperty.php
apps/contacts/ajax/contact/delete.php
apps/contacts/ajax/contact/deleteproperty.php
apps/contacts/ajax/contact/saveproperty.php
apps/contacts/ajax/createaddressbook.php
apps/contacts/ajax/cropphoto.php
apps/contacts/ajax/currentphoto.php
apps/contacts/ajax/importaddressbook.php
apps/contacts/ajax/oc_photo.php
apps/contacts/ajax/savecrop.php
apps/contacts/ajax/selectaddressbook.php
apps/contacts/ajax/updateaddressbook.php
apps/contacts/ajax/uploadimport.php
apps/contacts/ajax/uploadphoto.php
apps/contacts/appinfo/migrate.php
apps/contacts/appinfo/remote.php
apps/contacts/css/contacts.css
apps/contacts/import.php
apps/contacts/index.php
apps/contacts/js/contacts.js
apps/contacts/l10n/ca.php
apps/contacts/l10n/cs_CZ.php
apps/contacts/l10n/da.php
apps/contacts/l10n/de.php
apps/contacts/l10n/el.php
apps/contacts/l10n/eo.php
apps/contacts/l10n/es.php
apps/contacts/l10n/et_EE.php
apps/contacts/l10n/eu.php
apps/contacts/l10n/fa.php
apps/contacts/l10n/fi_FI.php
apps/contacts/l10n/fr.php
apps/contacts/l10n/he.php
apps/contacts/l10n/hr.php
apps/contacts/l10n/hu_HU.php
apps/contacts/l10n/ia.php
apps/contacts/l10n/it.php
apps/contacts/l10n/ja_JP.php
apps/contacts/l10n/ko.php
apps/contacts/l10n/lb.php
apps/contacts/l10n/mk.php
apps/contacts/l10n/nb_NO.php
apps/contacts/l10n/nl.php
apps/contacts/l10n/pl.php
apps/contacts/l10n/pt_BR.php
apps/contacts/l10n/pt_PT.php
apps/contacts/l10n/ro.php
apps/contacts/l10n/ru.php
apps/contacts/l10n/sk_SK.php
apps/contacts/l10n/sl.php
apps/contacts/l10n/sv.php
apps/contacts/l10n/th_TH.php
apps/contacts/l10n/tr.php
apps/contacts/l10n/zh_CN.php
apps/contacts/l10n/zh_TW.php
apps/contacts/lib/addressbook.php
apps/contacts/lib/hooks.php
apps/contacts/lib/vcard.php
apps/contacts/photo.php
apps/contacts/templates/part.contact.php
apps/contacts/templates/part.contacts.php
apps/contacts/templates/part.cropphoto.php
apps/contacts/templates/part.importaddressbook.php
apps/contacts/templates/part.selectaddressbook.php
apps/contacts/thumbnail.php
apps/files/ajax/download.php
apps/files/ajax/newfile.php
apps/files/ajax/timezone.php
apps/files/appinfo/update.php
apps/files/appinfo/version
apps/files/index.php
apps/files/js/fileactions.js
apps/files/js/filelist.js
apps/files/js/files.js
apps/files/l10n/ar.php
apps/files/l10n/bg_BG.php
apps/files/l10n/ca.php
apps/files/l10n/cs_CZ.php
apps/files/l10n/da.php
apps/files/l10n/de.php
apps/files/l10n/el.php
apps/files/l10n/eo.php
apps/files/l10n/es.php
apps/files/l10n/et_EE.php
apps/files/l10n/eu.php
apps/files/l10n/fa.php
apps/files/l10n/fi_FI.php
apps/files/l10n/fr.php
apps/files/l10n/gl.php
apps/files/l10n/he.php
apps/files/l10n/hr.php
apps/files/l10n/hu_HU.php
apps/files/l10n/ia.php
apps/files/l10n/id.php
apps/files/l10n/it.php
apps/files/l10n/ja_JP.php
apps/files/l10n/ko.php
apps/files/l10n/lb.php
apps/files/l10n/lt_LT.php
apps/files/l10n/mk.php
apps/files/l10n/ms_MY.php
apps/files/l10n/nb_NO.php
apps/files/l10n/nl.php
apps/files/l10n/nn_NO.php
apps/files/l10n/pl.php
apps/files/l10n/pt_BR.php
apps/files/l10n/pt_PT.php
apps/files/l10n/ro.php
apps/files/l10n/ru.php
apps/files/l10n/sk_SK.php
apps/files/l10n/sl.php
apps/files/l10n/sr.php
apps/files/l10n/sr@latin.php
apps/files/l10n/sv.php
apps/files/l10n/th_TH.php
apps/files/l10n/tr.php
apps/files/l10n/uk.php
apps/files/l10n/zh_CN.php
apps/files/l10n/zh_TW.php
apps/files_archive/js/archive.js
apps/files_encryption/lib/cryptstream.php
apps/files_encryption/lib/proxy.php
apps/files_encryption/tests/proxy.php
apps/files_external/appinfo/app.php
apps/files_external/lib/smb.php
apps/files_external/lib/streamwrapper.php
apps/files_external/tests/config.php
apps/files_external/tests/smb.php
apps/files_sharing/ajax/email.php
apps/files_sharing/ajax/getitem.php
apps/files_sharing/ajax/setpermissions.php
apps/files_sharing/ajax/share.php
apps/files_sharing/ajax/toggleresharing.php
apps/files_sharing/ajax/unshare.php
apps/files_sharing/ajax/userautocomplete.php
apps/files_sharing/js/settings.js
apps/files_sharing/js/share.js
apps/files_sharing/lib_share.php
apps/files_sharing/settings.php
apps/files_sharing/sharedstorage.php
apps/files_sharing/templates/settings.php
apps/files_versions/ajax/rollbackVersion.php
apps/files_versions/versions.php
apps/gallery/ajax/thumbnail.php
apps/gallery/appinfo/app.php
apps/gallery/appinfo/update.php
apps/gallery/appinfo/version
apps/gallery/css/styles.css
apps/gallery/index.php
apps/gallery/js/pictures.js
apps/gallery/l10n/ca.php
apps/gallery/l10n/cs_CZ.php
apps/gallery/l10n/de.php
apps/gallery/l10n/el.php
apps/gallery/l10n/es.php
apps/gallery/l10n/fi_FI.php
apps/gallery/l10n/fr.php
apps/gallery/l10n/it.php
apps/gallery/l10n/pl.php
apps/gallery/l10n/pt_PT.php
apps/gallery/l10n/ru.php
apps/gallery/l10n/sl.php
apps/gallery/l10n/sv.php
apps/gallery/l10n/th_TH.php
apps/gallery/l10n/tr.php
apps/gallery/l10n/zh_CN.php
apps/gallery/lib/album.php
apps/gallery/lib/hooks_handlers.php
apps/gallery/lib/managers.php
apps/gallery/lib/photo.php
apps/gallery/lib/tiles.php
apps/gallery/lib/tiles_test.php
apps/gallery/templates/index.php
apps/media/lib_ampache.php
apps/media/lib_collection.php
apps/media/lib_media.php
apps/remoteStorage/lib_remoteStorage.php
apps/tasks/ajax/addtaskform.php
apps/tasks/ajax/edittask.php
apps/user_ldap/appinfo/update.php
apps/user_ldap/group_ldap.php
apps/user_ldap/lib_ldap.php
apps/user_ldap/settings.php
apps/user_ldap/templates/settings.php
apps/user_ldap/user_ldap.php
apps/user_migrate/appinfo/app.php
apps/user_migrate/templates/settings.php
apps/user_webfinger/host-meta.php
config/config.sample.php
core/js/js.js
core/l10n/da.php
core/l10n/de.php
core/l10n/fi_FI.php
core/l10n/gl.php
core/l10n/he.php
core/l10n/hr.php
core/l10n/id.php
core/l10n/ja_JP.php
core/l10n/lb.php
core/l10n/lt_LT.php
core/l10n/nb_NO.php
core/l10n/pl.php
core/l10n/pt_PT.php
core/l10n/ro.php
core/l10n/ru.php
core/l10n/sv.php
core/lostpassword/index.php
core/templates/layout.user.php
core/templates/login.php
db_structure.xml
index.php
l10n/af/calendar.po
l10n/af/contacts.po
l10n/af/core.po
l10n/af/files.po
l10n/af/settings.po
l10n/ar/calendar.po
l10n/ar/contacts.po
l10n/ar/core.po
l10n/ar/files.po
l10n/ar/media.po
l10n/ar/settings.po
l10n/bg_BG/calendar.po
l10n/bg_BG/contacts.po
l10n/bg_BG/core.po
l10n/bg_BG/files.po
l10n/bg_BG/media.po
l10n/bg_BG/settings.po
l10n/ca/calendar.po
l10n/ca/contacts.po
l10n/ca/core.po
l10n/ca/files.po
l10n/ca/gallery.po
l10n/ca/settings.po
l10n/cs_CZ/calendar.po
l10n/cs_CZ/contacts.po
l10n/cs_CZ/core.po
l10n/cs_CZ/files.po
l10n/cs_CZ/gallery.po
l10n/cs_CZ/settings.po
l10n/da/calendar.po
l10n/da/contacts.po
l10n/da/core.po
l10n/da/files.po
l10n/da/settings.po
l10n/de/calendar.po
l10n/de/contacts.po
l10n/de/core.po
l10n/de/files.po
l10n/de/gallery.po
l10n/de/settings.po
l10n/el/calendar.po
l10n/el/contacts.po
l10n/el/core.po
l10n/el/files.po
l10n/el/gallery.po
l10n/el/settings.po
l10n/eo/calendar.po
l10n/eo/contacts.po
l10n/eo/core.po
l10n/eo/files.po
l10n/eo/media.po
l10n/eo/settings.po
l10n/es/calendar.po
l10n/es/contacts.po
l10n/es/core.po
l10n/es/files.po
l10n/es/gallery.po
l10n/es/settings.po
l10n/et_EE/calendar.po
l10n/et_EE/contacts.po
l10n/et_EE/core.po
l10n/et_EE/files.po
l10n/et_EE/settings.po
l10n/eu/calendar.po
l10n/eu/contacts.po
l10n/eu/core.po
l10n/eu/files.po
l10n/eu/settings.po
l10n/fa/calendar.po
l10n/fa/contacts.po
l10n/fa/core.po
l10n/fa/files.po
l10n/fa/settings.po
l10n/fi_FI/calendar.po
l10n/fi_FI/contacts.po
l10n/fi_FI/core.po
l10n/fi_FI/files.po
l10n/fi_FI/gallery.po
l10n/fi_FI/settings.po
l10n/fr/calendar.po
l10n/fr/contacts.po
l10n/fr/core.po
l10n/fr/files.po
l10n/fr/gallery.po
l10n/fr/media.po
l10n/fr/settings.po
l10n/gl/calendar.po
l10n/gl/contacts.po
l10n/gl/core.po
l10n/gl/files.po
l10n/gl/settings.po
l10n/he/calendar.po
l10n/he/contacts.po
l10n/he/core.po
l10n/he/files.po
l10n/he/settings.po
l10n/hr/calendar.po
l10n/hr/contacts.po
l10n/hr/core.po
l10n/hr/files.po
l10n/hr/settings.po
l10n/hu_HU/calendar.po
l10n/hu_HU/contacts.po
l10n/hu_HU/core.po
l10n/hu_HU/files.po
l10n/hu_HU/settings.po
l10n/hy/calendar.po
l10n/hy/contacts.po
l10n/hy/core.po
l10n/hy/files.po
l10n/hy/settings.po
l10n/ia/calendar.po
l10n/ia/contacts.po
l10n/ia/core.po
l10n/ia/files.po
l10n/ia/settings.po
l10n/id/calendar.po
l10n/id/contacts.po
l10n/id/core.po
l10n/id/files.po
l10n/id/settings.po
l10n/it/calendar.po
l10n/it/contacts.po
l10n/it/core.po
l10n/it/files.po
l10n/it/gallery.po
l10n/it/settings.po
l10n/ja_JP/calendar.po
l10n/ja_JP/contacts.po
l10n/ja_JP/core.po
l10n/ja_JP/files.po
l10n/ja_JP/settings.po
l10n/ko/calendar.po
l10n/ko/contacts.po
l10n/ko/core.po
l10n/ko/files.po
l10n/ko/settings.po
l10n/lb/calendar.po
l10n/lb/contacts.po
l10n/lb/core.po
l10n/lb/files.po
l10n/lb/settings.po
l10n/lt_LT/calendar.po
l10n/lt_LT/contacts.po
l10n/lt_LT/core.po
l10n/lt_LT/files.po
l10n/lt_LT/settings.po
l10n/mk/calendar.po
l10n/mk/contacts.po
l10n/mk/core.po
l10n/mk/files.po
l10n/mk/settings.po
l10n/ms_MY/calendar.po
l10n/ms_MY/contacts.po
l10n/ms_MY/core.po
l10n/ms_MY/files.po
l10n/ms_MY/settings.po
l10n/nb_NO/calendar.po
l10n/nb_NO/contacts.po
l10n/nb_NO/core.po
l10n/nb_NO/files.po
l10n/nb_NO/settings.po
l10n/nl/calendar.po
l10n/nl/contacts.po
l10n/nl/core.po
l10n/nl/files.po
l10n/nl/settings.po
l10n/nn_NO/calendar.po
l10n/nn_NO/contacts.po
l10n/nn_NO/core.po
l10n/nn_NO/files.po
l10n/nn_NO/settings.po
l10n/pl/calendar.po
l10n/pl/contacts.po
l10n/pl/core.po
l10n/pl/files.po
l10n/pl/gallery.po
l10n/pl/settings.po
l10n/pt_BR/calendar.po
l10n/pt_BR/contacts.po
l10n/pt_BR/core.po
l10n/pt_BR/files.po
l10n/pt_BR/settings.po
l10n/pt_PT/calendar.po
l10n/pt_PT/contacts.po
l10n/pt_PT/core.po
l10n/pt_PT/files.po
l10n/pt_PT/gallery.po
l10n/pt_PT/settings.po
l10n/ro/calendar.po
l10n/ro/contacts.po
l10n/ro/core.po
l10n/ro/files.po
l10n/ro/settings.po
l10n/ru/calendar.po
l10n/ru/contacts.po
l10n/ru/core.po
l10n/ru/files.po
l10n/ru/gallery.po
l10n/ru/settings.po
l10n/sk_SK/calendar.po
l10n/sk_SK/contacts.po
l10n/sk_SK/core.po
l10n/sk_SK/files.po
l10n/sk_SK/settings.po
l10n/sl/calendar.po
l10n/sl/contacts.po
l10n/sl/core.po
l10n/sl/files.po
l10n/sl/gallery.po
l10n/sl/settings.po
l10n/sr/calendar.po
l10n/sr/contacts.po
l10n/sr/core.po
l10n/sr/files.po
l10n/sr/settings.po
l10n/sr@latin/calendar.po
l10n/sr@latin/contacts.po
l10n/sr@latin/core.po
l10n/sr@latin/files.po
l10n/sr@latin/settings.po
l10n/sv/calendar.po
l10n/sv/contacts.po
l10n/sv/core.po
l10n/sv/files.po
l10n/sv/gallery.po
l10n/sv/media.po
l10n/sv/settings.po
l10n/templates/bookmarks.pot
l10n/templates/calendar.pot
l10n/templates/contacts.pot
l10n/templates/core.pot
l10n/templates/files.pot
l10n/templates/gallery.pot
l10n/templates/media.pot
l10n/templates/settings.pot
l10n/th_TH/calendar.po
l10n/th_TH/contacts.po
l10n/th_TH/core.po
l10n/th_TH/files.po
l10n/th_TH/gallery.po
l10n/th_TH/settings.po
l10n/tr/calendar.po
l10n/tr/contacts.po
l10n/tr/core.po
l10n/tr/files.po
l10n/tr/gallery.po
l10n/tr/settings.po
l10n/uk/calendar.po
l10n/uk/contacts.po
l10n/uk/core.po
l10n/uk/files.po
l10n/uk/media.po
l10n/uk/settings.po
l10n/zh_CN/calendar.po
l10n/zh_CN/contacts.po
l10n/zh_CN/core.po
l10n/zh_CN/files.po
l10n/zh_CN/gallery.po
l10n/zh_CN/settings.po
l10n/zh_TW/calendar.po
l10n/zh_TW/contacts.po
l10n/zh_TW/core.po
l10n/zh_TW/files.po
l10n/zh_TW/settings.po
lib/app.php
lib/base.php
lib/connector/sabre/file.php
lib/connector/sabre/locks.php
lib/connector/sabre/node.php
lib/db.php
lib/filecache.php
lib/fileproxy/quota.php
lib/files.php
lib/filestorage/local.php
lib/filesystemview.php
lib/group/database.php
lib/helper.php
lib/installer.php
lib/json.php
lib/l10n.php
lib/migrate.php
lib/mimetypes.fixlist.php
lib/ocs.php
lib/preferences.php
lib/public/json.php
lib/public/util.php
lib/template.php
lib/user.php
lib/user/database.php
lib/util.php
lib/vcategories.php
ocs/providers.php
settings/admin.php
settings/ajax/lostpassword.php
settings/ajax/removeuser.php
settings/ajax/setbackgroundjobsmode.php
settings/ajax/setlanguage.php
settings/ajax/setquota.php
settings/ajax/togglegroups.php
settings/apps.php
settings/css/settings.css
settings/js/apps.js
settings/js/users.js
settings/l10n/bg_BG.php
settings/l10n/ca.php
settings/l10n/cs_CZ.php
settings/l10n/da.php
settings/l10n/de.php
settings/l10n/el.php
settings/l10n/eo.php
settings/l10n/es.php
settings/l10n/et_EE.php
settings/l10n/eu.php
settings/l10n/fa.php
settings/l10n/fi_FI.php
settings/l10n/fr.php
settings/l10n/gl.php
settings/l10n/he.php
settings/l10n/hr.php
settings/l10n/hu_HU.php
settings/l10n/it.php
settings/l10n/ja_JP.php
settings/l10n/ko.php
settings/l10n/lt_LT.php
settings/l10n/mk.php
settings/l10n/ms_MY.php
settings/l10n/nb_NO.php
settings/l10n/nl.php
settings/l10n/nn_NO.php
settings/l10n/pl.php
settings/l10n/pt_BR.php
settings/l10n/pt_PT.php
settings/l10n/ru.php
settings/l10n/sk_SK.php
settings/l10n/sl.php
settings/l10n/sv.php
settings/l10n/th_TH.php
settings/l10n/tr.php
settings/l10n/zh_CN.php
settings/personal.php
settings/templates/admin.php
settings/templates/users.php
Diffstat (limited to 'apps/user_ldap')
34 files changed, 2052 insertions, 918 deletions
diff --git a/apps/user_ldap/ajax/testConfiguration.php b/apps/user_ldap/ajax/testConfiguration.php new file mode 100644 index 00000000000..a82f7e4c17b --- /dev/null +++ b/apps/user_ldap/ajax/testConfiguration.php @@ -0,0 +1,39 @@ +<?php + +/** + * ownCloud - user_ldap + * + * @author Arthur Schiwon + * @copyright 2012 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +// Check user and app status +OCP\JSON::checkAdminUser(); +OCP\JSON::checkAppEnabled('user_ldap'); +OCP\JSON::callCheck(); + +$connection = new \OCA\user_ldap\lib\Connection(null); +if($connection->setConfiguration($_POST)) { + //Configuration is okay + if($connection->bind()) { + OCP\JSON::success(array('message' => 'The configuration is valid and the connection could be established!')); + } else { + OCP\JSON::error(array('message' => 'The configuration is valid, but the Bind failed. Please check the server settings and credentials.')); + } +} else { + OCP\JSON::error(array('message' => 'The configuration is invalid. Please look in the ownCloud log for further details.')); +} diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php index 330574c1d42..0eec7829a4a 100644 --- a/apps/user_ldap/appinfo/app.php +++ b/apps/user_ldap/appinfo/app.php @@ -21,15 +21,17 @@ * */ -require_once('apps/user_ldap/lib_ldap.php'); -require_once('apps/user_ldap/user_ldap.php'); -require_once('apps/user_ldap/group_ldap.php'); +OCP\App::registerAdmin('user_ldap', 'settings'); -OCP\App::registerAdmin('user_ldap','settings'); +$connector = new OCA\user_ldap\lib\Connection('user_ldap'); +$userBackend = new OCA\user_ldap\USER_LDAP(); +$userBackend->setConnector($connector); +$groupBackend = new OCA\user_ldap\GROUP_LDAP(); +$groupBackend->setConnector($connector); // register user backend -OC_User::useBackend( 'LDAP' ); -OC_Group::useBackend( new OC_GROUP_LDAP() ); +OC_User::useBackend($userBackend); +OC_Group::useBackend($groupBackend); // add settings page to navigation $entry = array( @@ -38,3 +40,5 @@ $entry = array( 'href' => OCP\Util::linkTo( 'user_ldap', 'settings.php' ), 'name' => 'LDAP' ); + +OCP\Backgroundjob::addRegularTask('OCA\user_ldap\lib\Jobs', 'updateGroups'); diff --git a/apps/user_ldap/appinfo/database.xml b/apps/user_ldap/appinfo/database.xml index b228fa2796d..a785bbf4221 100644 --- a/apps/user_ldap/appinfo/database.xml +++ b/apps/user_ldap/appinfo/database.xml @@ -28,6 +28,14 @@ <default></default> </field> + <field> + <name>directory_uuid</name> + <type>text</type> + <notnull>true</notnull> + <length>255</length> + <default></default> + </field> + <index> <name>ldap_dn_users</name> <unique>true</unique> @@ -71,6 +79,14 @@ <default></default> </field> + <field> + <name>directory_uuid</name> + <type>text</type> + <notnull>true</notnull> + <length>255</length> + <default></default> + </field> + <index> <name>ldap_dn_groups</name> <unique>true</unique> @@ -92,4 +108,37 @@ </table> + + <table> + + <name>*dbprefix*ldap_group_members</name> + + <declaration> + + <field> + <name>owncloudname</name> + <type>text</type> + <notnull>true</notnull> + <length>255</length> + <default></default> + </field> + + <field> + <name>owncloudusers</name> + <type>clob</type> + <notnull>true</notnull> + </field> + + <index> + <name>ldap_group_members</name> + <unique>true</unique> + <field> + <name>owncloudname</name> + </field> + </index> + + </declaration> + + </table> + </database>
\ No newline at end of file diff --git a/apps/user_ldap/appinfo/update.php b/apps/user_ldap/appinfo/update.php index 3ebb19c2fca..9cf1814cf6f 100644 --- a/apps/user_ldap/appinfo/update.php +++ b/apps/user_ldap/appinfo/update.php @@ -2,6 +2,11 @@ //from version 0.1 to 0.2 +//ATTENTION +//Upgrade from ownCloud 3 (LDAP backend 0.1) to ownCloud 4.5 (LDAP backend 0.3) is not supported!! +//You must do upgrade to ownCloud 4.0 first! +//The upgrade stuff in the section from 0.1 to 0.2 is just to minimize the bad efffects. + //settings $pw = OCP\Config::getAppValue('user_ldap', 'ldap_password'); if(!is_null($pw)) { @@ -12,25 +17,37 @@ if(!is_null($pw)) { //detect if we can switch on naming guidelines. We won't do it on conflicts. //it's a bit spaghetti, but hey. -$state = OCP\Config::getSystemValue('ldapIgnoreNamingRules', 'doCheck'); -if($state == 'doCheck'){ - $sqlCleanMap = 'DELETE FROM `*PREFIX*ldap_user_mapping`'; - - require_once(OC::$APPSROOT.'/apps/user_ldap/lib_ldap.php'); - require_once(OC::$APPSROOT.'/apps/user_ldap/user_ldap.php'); - - OCP\Config::setSystemValue('ldapIgnoreNamingRules', true); - $LDAP_USER = new OC_USER_LDAP(); - $users_old = $LDAP_USER->getUsers(); - $query = OCP\DB::prepare($sqlCleanMap); - $query->execute(); +$state = OCP\Config::getSystemValue('ldapIgnoreNamingRules', 'unset'); +if($state == 'unset'){ OCP\Config::setSystemValue('ldapIgnoreNamingRules', false); - OC_LDAP::init(true); - $users_new = $LDAP_USER->getUsers(); - $query = OCP\DB::prepare($sqlCleanMap); - $query->execute(); - if($users_old !== $users_new) { - //we don't need to check Groups, because they were not supported in 3' - OCP\Config::setSystemValue('ldapIgnoreNamingRules', true); +} + +// ### SUPPORTED upgrade path starts here ### + +//from version 0.2 to 0.3 (0.2.0.x dev version) +$objects = array('user', 'group'); + +$connector = new \OCA\user_ldap\lib\Connection('user_ldap'); +$userBE = new \OCA\user_ldap\USER_LDAP(); +$userBE->setConnector($connector); +$groupBE = new \OCA\user_ldap\GROUP_LDAP(); +$groupBE->setConnector($connector); + +foreach($objects as $object) { + $fetchDNSql = 'SELECT ldap_dn from *PREFIX*ldap_'.$object.'_mapping'; + $updateSql = 'UPDATE *PREFIX*ldap_'.$object.'_mapping SET ldap_DN = ?, directory_uuid = ? WHERE ldap_dn = ?'; + + $query = OCP\DB::prepare($fetchDNSql); + $res = $query->execute(); + $DNs = $res->fetchAll(); + $updateQuery = OCP\DB::prepare($updateSql); + foreach($DNs as $dn) { + $newDN = mb_strtolower($dn['ldap_dn'], 'UTF-8'); + if($object == 'user') { + $uuid = $userBE->getUUID($newDN); + } else { + $uuid = $groupBE->getUUID($newDN); + } + $updateQuery->execute(array($newDN, $uuid, $dn['ldap_dn'])); } -}
\ No newline at end of file +} diff --git a/apps/user_ldap/appinfo/version b/apps/user_ldap/appinfo/version index 2f4536184bc..e689e4949ef 100644 --- a/apps/user_ldap/appinfo/version +++ b/apps/user_ldap/appinfo/version @@ -1 +1 @@ -0.2
\ No newline at end of file +0.2.0.26
\ No newline at end of file diff --git a/apps/user_ldap/css/settings.css b/apps/user_ldap/css/settings.css new file mode 100644 index 00000000000..30c5c175c9b --- /dev/null +++ b/apps/user_ldap/css/settings.css @@ -0,0 +1,10 @@ +#ldap fieldset p label { + width: 20%; + max-width: 200px; + display: inline-block; +} + +#ldap fieldset input { + width: 70%; + display: inline-block; +}
\ No newline at end of file diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index a3117b5a41e..b29ebe30c51 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -21,24 +21,17 @@ * */ -class OC_GROUP_LDAP extends OC_Group_Backend { -// //group specific settings - protected $ldapGroupFilter; - protected $ldapGroupMemberAssocAttr; - protected $configured = false; +namespace OCA\user_ldap; - protected $_group_user = array(); - protected $_user_groups = array(); - protected $_group_users = array(); - protected $_groups = array(); +class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { + protected $enabled = false; - public function __construct() { - $this->ldapGroupFilter = OCP\Config::getAppValue('user_ldap', 'ldap_group_filter', '(objectClass=posixGroup)'); - $this->ldapGroupMemberAssocAttr = OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'); - - if(!empty($this->ldapGroupFilter) && !empty($this->ldapGroupMemberAssocAttr)) { - $this->configured = true; + public function setConnector(lib\Connection &$connection) { + parent::setConnector($connection); + if(empty($this->connection->ldapGroupFilter) || empty($this->connection->ldapGroupMemberAssocAttr)) { + $this->enabled = false; } + $this->enabled = true; } /** @@ -50,31 +43,33 @@ class OC_GROUP_LDAP extends OC_Group_Backend { * Checks whether the user is member of a group or not. */ public function inGroup($uid, $gid) { - if(!$this->configured) { + if(!$this->enabled) { return false; } - if(isset($this->_group_user[$gid][$uid])) { - return $this->_group_user[$gid][$uid]; + if($this->connection->isCached('inGroup'.$uid.':'.$gid)) { + return $this->connection->getFromCache('inGroup'.$uid.':'.$gid); } - $dn_user = OC_LDAP::username2dn($uid); - $dn_group = OC_LDAP::groupname2dn($gid); + $dn_user = $this->username2dn($uid); + $dn_group = $this->groupname2dn($gid); // just in case if(!$dn_group || !$dn_user) { + $this->connection->writeToCache('inGroup'.$uid.':'.$gid, false); return false; } //usually, LDAP attributes are said to be case insensitive. But there are exceptions of course. - $members = OC_LDAP::readAttribute($dn_group, $this->ldapGroupMemberAssocAttr); + $members = $this->readAttribute($dn_group, $this->connection->ldapGroupMemberAssocAttr); if(!$members) { + $this->connection->writeToCache('inGroup'.$uid.':'.$gid, false); return false; } //extra work if we don't get back user DNs //TODO: this can be done with one LDAP query - if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') { + if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') { $dns = array(); foreach($members as $mid) { - $filter = str_replace('%uid', $mid, OC_LDAP::conf('ldapLoginFilter')); - $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn'); + $filter = str_replace('%uid', $mid, $this->connection->ldapLoginFilter); + $ldap_users = $this->fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { continue; } @@ -83,8 +78,10 @@ class OC_GROUP_LDAP extends OC_Group_Backend { $members = $dns; } - $this->_group_user[$gid][$uid] = in_array($dn_user, $members); - return $this->_group_user[$gid][$uid]; + $isInGroup = in_array($dn_user, $members); + $this->connection->writeToCache('inGroup'.$uid.':'.$gid, $isInGroup); + + return $isInGroup; } /** @@ -96,86 +93,105 @@ class OC_GROUP_LDAP extends OC_Group_Backend { * if the user exists at all. */ public function getUserGroups($uid) { - if(!$this->configured) { + if(!$this->enabled) { return array(); } - if(isset($this->_user_groups[$uid])) { - return $this->_user_groups[$uid]; + if($this->connection->isCached('getUserGroups'.$uid)) { + return $this->connection->getFromCache('getUserGroups'.$uid); } - $userDN = OC_LDAP::username2dn($uid); + $userDN = $this->username2dn($uid); if(!$userDN) { - $this->_user_groups[$uid] = array(); + $this->connection->writeToCache('getUserGroups'.$uid, array()); return array(); } //uniqueMember takes DN, memberuid the uid, so we need to distinguish - if((strtolower($this->ldapGroupMemberAssocAttr) == 'uniquemember') - || (strtolower($this->ldapGroupMemberAssocAttr) == 'member')) { + if((strtolower($this->connection->ldapGroupMemberAssocAttr) == 'uniquemember') + || (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'member') + ) { $uid = $userDN; - } else if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') { - $result = OC_LDAP::readAttribute($userDN, 'uid'); + } else if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') { + $result = $this->readAttribute($userDN, 'uid'); $uid = $result[0]; } else { // just in case $uid = $userDN; } - $filter = OC_LDAP::combineFilterWithAnd(array( - $this->ldapGroupFilter, - $this->ldapGroupMemberAssocAttr.'='.$uid + $filter = $this->combineFilterWithAnd(array( + $this->connection->ldapGroupFilter, + $this->connection->ldapGroupMemberAssocAttr.'='.$uid )); - $groups = OC_LDAP::fetchListOfGroups($filter, array(OC_LDAP::conf('ldapGroupDisplayName'),'dn')); - $this->_user_groups[$uid] = array_unique(OC_LDAP::ownCloudGroupNames($groups), SORT_LOCALE_STRING); + $groups = $this->fetchListOfGroups($filter, array($this->connection->ldapGroupDisplayName,'dn')); + $groups = array_unique($this->ownCloudGroupNames($groups), SORT_LOCALE_STRING); + $this->connection->writeToCache('getUserGroups'.$uid, $groups); - return $this->_user_groups[$uid]; + return $groups; } /** * @brief get a list of all users in a group * @returns array with user ids */ - public function usersInGroup($gid) { - if(!$this->configured) { + public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { + if(!$this->enabled) { return array(); } - if(isset($this->_group_users[$gid])) { - return $this->_group_users[$gid]; + $this->groupSearch = $search; + if($this->connection->isCached('usersInGroup'.$gid)) { + $groupUsers = $this->connection->getFromCache('usersInGroup'.$gid); + if(!empty($this->groupSearch)) { + $groupUsers = array_filter($groupUsers, array($this, 'groupMatchesFilter')); + } + if($limit = -1) { + $limit = null; + } + return array_slice($groupUsers, $offset, $limit); } - $groupDN = OC_LDAP::groupname2dn($gid); + $groupDN = $this->groupname2dn($gid); if(!$groupDN) { - $this->_group_users[$gid] = array(); + $this->connection->writeToCache('usersInGroup'.$gid, array()); return array(); } - $members = OC_LDAP::readAttribute($groupDN, $this->ldapGroupMemberAssocAttr); + $members = $this->readAttribute($groupDN, $this->connection->ldapGroupMemberAssocAttr); if(!$members) { - $this->_group_users[$gid] = array(); + $this->connection->writeToCache('usersInGroup'.$gid, array()); return array(); } $result = array(); - $isMemberUid = (strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid'); + $isMemberUid = (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid'); foreach($members as $member) { if($isMemberUid) { - $filter = str_replace('%uid', $member, OC_LDAP::conf('ldapLoginFilter')); - $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn'); + $filter = \OCP\Util::mb_str_replace('%uid', $member, $this->connection->ldapLoginFilter, 'UTF-8'); + $ldap_users = $this->fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { continue; } - $result[] = OC_LDAP::dn2username($ldap_users[0]); + $result[] = $this->dn2username($ldap_users[0]); continue; } else { - if($ocname = OC_LDAP::dn2username($member)){ + if($ocname = $this->dn2username($member)) { $result[] = $ocname; } } } if(!$isMemberUid) { - $result = array_intersect($result, OCP\User::getUsers()); + $result = array_intersect($result, \OCP\User::getUsers()); } - $this->_group_users[$gid] = array_unique($result, SORT_LOCALE_STRING); - return $this->_group_users[$gid]; + $groupUsers = array_unique($result, SORT_LOCALE_STRING); + $this->connection->writeToCache('usersInGroup'.$gid, $groupUsers); + + if(!empty($this->groupSearch)) { + $groupUsers = array_filter($groupUsers, array($this, 'groupMatchesFilter')); + } + if($limit = -1) { + $limit = null; + } + return array_slice($groupUsers, $offset, $limit); + } /** @@ -184,15 +200,30 @@ class OC_GROUP_LDAP extends OC_Group_Backend { * * Returns a list with all groups */ - public function getGroups() { - if(!$this->configured) { + public function getGroups($search = '', $limit = -1, $offset = 0) { + if(!$this->enabled) { return array(); } - if(empty($this->_groups)) { - $ldap_groups = OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn')); - $this->_groups = OC_LDAP::ownCloudGroupNames($ldap_groups); + + if($this->connection->isCached('getGroups')) { + $ldap_groups = $this->connection->getFromCache('getGroups'); + } else { + $ldap_groups = $this->fetchListOfGroups($this->connection->ldapGroupFilter, array($this->connection->ldapGroupDisplayName, 'dn')); + $ldap_groups = $this->ownCloudGroupNames($ldap_groups); + $this->connection->writeToCache('getGroups', $ldap_groups); + } + $this->groupSearch = $search; + if(!empty($this->groupSearch)) { + $ldap_groups = array_filter($ldap_groups, array($this, 'groupMatchesFilter')); } - return $this->_groups; + if($limit = -1) { + $limit = null; + } + return array_slice($ldap_groups, $offset, $limit); + } + + public function groupMatchesFilter($group) { + return (strripos($group, $this->groupSearch) !== false); } /** @@ -203,4 +234,17 @@ class OC_GROUP_LDAP extends OC_Group_Backend { public function groupExists($gid){ return in_array($gid, $this->getGroups()); } + + /** + * @brief Check if backend implements actions + * @param $actions bitwise-or'ed actions + * @returns boolean + * + * Returns the supported actions as int to be + * compared with OC_USER_BACKEND_CREATE_USER etc. + */ + public function implementsActions($actions) { + //always returns false, because possible actions are modifying actions. We do not write to LDAP, at least for now. + return false; + } }
\ No newline at end of file diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js index cae9655e3df..7063eead96a 100644 --- a/apps/user_ldap/js/settings.js +++ b/apps/user_ldap/js/settings.js @@ -1,3 +1,24 @@ $(document).ready(function() { $('#ldapSettings').tabs(); + $('#ldap_action_test_connection').button(); + $('#ldap_action_test_connection').click(function(event){ + event.preventDefault(); + $.post( + OC.filePath('user_ldap','ajax','testConfiguration.php'), + $('#ldap').serialize(), + function (result) { + if (result.status == 'success') { + OC.dialogs.alert( + result.message, + 'Connection test succeeded' + ); + } else { + OC.dialogs.alert( + result.message, + 'Connection test failed' + ); + } + } + ); + }); });
\ No newline at end of file diff --git a/apps/user_ldap/l10n/.gitkeep b/apps/user_ldap/l10n/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/apps/user_ldap/l10n/.gitkeep diff --git a/apps/user_ldap/l10n/ca.php b/apps/user_ldap/l10n/ca.php new file mode 100644 index 00000000000..04b0f8997db --- /dev/null +++ b/apps/user_ldap/l10n/ca.php @@ -0,0 +1,36 @@ +<?php $TRANSLATIONS = array( +"Host" => "Màquina", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Podeu ometre el protocol, excepte si requeriu SSL. Llavors comenceu amb ldaps://", +"Base DN" => "DN Base", +"You can specify Base DN for users and groups in the Advanced tab" => "Podeu especificar DN Base per usuaris i grups a la pestanya Avançat", +"User DN" => "DN Usuari", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "La DN de l'usuari client amb la que s'haurà de fer, per exemple uid=agent,dc=exemple,dc=com. Per un accés anònim, deixeu la DN i la contrasenya en blanc.", +"Password" => "Contrasenya", +"For anonymous access, leave DN and Password empty." => "Per un accés anònim, deixeu la DN i la contrasenya en blanc.", +"User Login Filter" => "Filtre d'inici de sessió d'usuari", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "Defineix el filtre a aplicar quan s'intenta l'inici de sessió. %%uid reemplaça el nom d'usuari en l'acció d'inici de sessió.", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "useu el paràmetre de substitució %%uid, per exemple \"uid=%%uid\"", +"User List Filter" => "Llista de filtres d'usuari", +"Defines the filter to apply, when retrieving users." => "Defineix el filtre a aplicar quan es mostren usuaris", +"without any placeholder, e.g. \"objectClass=person\"." => "sense cap paràmetre de substitució, per exemple \"objectClass=persona\"", +"Group Filter" => "Filtre de grup", +"Defines the filter to apply, when retrieving groups." => "Defineix el filtre a aplicar quan es mostren grups.", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "sense cap paràmetre de substitució, per exemple \"objectClass=grupPosix\".", +"Port" => "Port", +"Base User Tree" => "Arbre base d'usuaris", +"Base Group Tree" => "Arbre base de grups", +"Group-Member association" => "Associació membres-grup", +"Use TLS" => "Usa TLS", +"Do not use it for SSL connections, it will fail." => "No ho useu en connexions SSL, fallarà.", +"Case insensitve LDAP server (Windows)" => "Servidor LDAP sense distinció entre majúscules i minúscules (Windows)", +"Turn off SSL certificate validation." => "Desactiva la validació de certificat SSL.", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "Si la connexió només funciona amb aquesta opció, importeu el certificat SSL del servidor LDAP en el vostre servidor ownCloud.", +"Not recommended, use for testing only." => "No recomanat, ús només per proves.", +"User Display Name Field" => "Camp per mostrar el nom d'usuari", +"The LDAP attribute to use to generate the user`s ownCloud name." => "Atribut LDAP a usar per generar el nom d'usuari ownCloud.", +"Group Display Name Field" => "Camp per mostrar el nom del grup", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "Atribut LDAP a usar per generar el nom de grup ownCloud.", +"in bytes" => "en bytes", +"in seconds. A change empties the cache." => "en segons. Un canvi buidarà la memòria de cau.", +"Help" => "Ajuda" +); diff --git a/apps/user_ldap/l10n/cs_CZ.php b/apps/user_ldap/l10n/cs_CZ.php new file mode 100644 index 00000000000..6c0f227fa7a --- /dev/null +++ b/apps/user_ldap/l10n/cs_CZ.php @@ -0,0 +1,36 @@ +<?php $TRANSLATIONS = array( +"Host" => "Hostitel", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Nelze vynechat protokol vyžadující SSL. Začněte s ldaps://", +"Base DN" => "Base DN", +"You can specify Base DN for users and groups in the Advanced tab" => "V Rozšířeném nastavení můžete specifikovat pro své uživatele a skupiny element Base DN", +"User DN" => "DN uživatele", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN klentského uživatele ke kterému tvoříte vazbu, např. uid=agent,dc=example,dc=com. Pro anonymní přístup ponechte údaje DN and Heslo prázdné.", +"Password" => "Heslo", +"For anonymous access, leave DN and Password empty." => "Pro anonymní přístup ponechte údaje DN and Heslo prázdné.", +"User Login Filter" => "Filtr uživatelských loginů", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "Definuje filtr, který je aplikován v průběhu logování. %%uid nahrazuje uživatelské jméno během logování.", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "použijte %%uid pro rezervované místo, např. \"uid=%%uid\"", +"User List Filter" => "Filtr uživateslkých seznamů", +"Defines the filter to apply, when retrieving users." => "Defunije filtr, který je plaikován při návratu uživatelů.", +"without any placeholder, e.g. \"objectClass=person\"." => "bez rezervace místa, např. \"objectClass=person\".", +"Group Filter" => "Filtr skupiny", +"Defines the filter to apply, when retrieving groups." => "Definuje filtr, který je aplikován při návratu skupin", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "bez rezervace místa, např. \"objectClass=posixGroup\".", +"Port" => "Port", +"Base User Tree" => "Základní uživatelský strom", +"Base Group Tree" => "Základní skupinový strom", +"Group-Member association" => "Asociace člena skupiny", +"Use TLS" => "Použijte TLS", +"Do not use it for SSL connections, it will fail." => "Nepoužívejte pro SSL připojení, připojení selže.", +"Case insensitve LDAP server (Windows)" => "LDAP server nerozlišující velikost znaků (Windows)", +"Turn off SSL certificate validation." => "Vypněte ověřování SSL certifikátu", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "pokud pracuje připojení pouze pokud je teto volba aktivní, importujte SSL certifikát LDAP serveru do Vašeho serveru ownCloud.", +"Not recommended, use for testing only." => "Není doporučeno, pouze pro účely testování.", +"User Display Name Field" => "Pole pro zobrazované jméno uživatele", +"The LDAP attribute to use to generate the user`s ownCloud name." => "Atribut LDAP použitý k vytvoření jména uživatele ownCloud", +"Group Display Name Field" => "Pole pro zobrazení jména skupiny", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "Atribut LDAP použitý k vytvoření jména skupiny ownCloud", +"in bytes" => "v bytech", +"in seconds. A change empties the cache." => "ve vteřinách. Změna vyprázdní dočasnou paměť.", +"Help" => "Nápověda" +); diff --git a/apps/user_ldap/l10n/da.php b/apps/user_ldap/l10n/da.php new file mode 100644 index 00000000000..f01c7b71108 --- /dev/null +++ b/apps/user_ldap/l10n/da.php @@ -0,0 +1,9 @@ +<?php $TRANSLATIONS = array( +"Host" => "Host", +"Base DN" => "Base DN", +"Password" => "Kodeord", +"Port" => "Port", +"Use TLS" => "Brug TLS", +"Not recommended, use for testing only." => "Anbefales ikke, brug kun for at teste.", +"Help" => "Hjælp" +); diff --git a/apps/user_ldap/l10n/de.php b/apps/user_ldap/l10n/de.php new file mode 100644 index 00000000000..9f917f277c4 --- /dev/null +++ b/apps/user_ldap/l10n/de.php @@ -0,0 +1,36 @@ +<?php $TRANSLATIONS = array( +"Host" => "Host", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Sie können das Protokoll auslassen, außer wenn Sie SSL benötigen. Beginnen Sie dann mit ldaps://", +"Base DN" => "Basis-DN", +"You can specify Base DN for users and groups in the Advanced tab" => "Sie können Basis-DN für Benutzer und Gruppen in dem \"Erweitert\"-Reiter konfigurieren", +"User DN" => "Benutzer-DN", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Der DN des Benutzers für LDAP-Bind, z.B.: uid=agent,dc=example,dc=com. Für anonymen Zugriff lassen Sie DN und Passwort leer.", +"Password" => "Passwort", +"For anonymous access, leave DN and Password empty." => "Lassen Sie die Felder von DN und Passwort für anonymen Zugang leer.", +"User Login Filter" => "Benutzer-Login-Filter", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "Bestimmt den angewendeten Filter, wenn eine Anmeldung versucht wird. %%uid ersetzt den Benutzernamen bei dem Anmeldeversuch.", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "verwende %%uid Platzhalter, z. B. \"uid=%%uid\"", +"User List Filter" => "Benutzer-Filter-Liste", +"Defines the filter to apply, when retrieving users." => "Definiert den Filter für die Anfrage der Benutzer.", +"without any placeholder, e.g. \"objectClass=person\"." => "ohne Platzhalter, z.B.: \"objectClass=person\"", +"Group Filter" => "Gruppen-Filter", +"Defines the filter to apply, when retrieving groups." => "Definiert den Filter für die Anfrage der Gruppen.", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "ohne Platzhalter, z.B.: \"objectClass=posixGroup\"", +"Port" => "Port", +"Base User Tree" => "Basis-Benutzerbaum", +"Base Group Tree" => "Basis-Gruppenbaum", +"Group-Member association" => "Assoziation zwischen Gruppe und Benutzer", +"Use TLS" => "Nutze TLS", +"Do not use it for SSL connections, it will fail." => "Verwenden Sie es nicht für SSL-Verbindungen, es wird fehlschlagen.", +"Case insensitve LDAP server (Windows)" => "LDAP-Server (Windows: Groß- und Kleinschreibung bleibt unbeachtet)", +"Turn off SSL certificate validation." => "Schalte die SSL Zertifikatsprüfung aus.", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "Falls die Verbindung es erfordert, wird das SSL-Zertifikat des LDAP-Server importiert werden.", +"Not recommended, use for testing only." => "Nicht empfohlen, nur zu Testzwecken.", +"User Display Name Field" => "Feld für den Anzeigenamen des Benutzers", +"The LDAP attribute to use to generate the user`s ownCloud name." => "Das LDAP-Attribut für die Generierung des Benutzernamens in ownCloud. ", +"Group Display Name Field" => "Feld für den Anzeigenamen der Gruppe", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "Das LDAP-Attribut für die Generierung des Gruppennamens in ownCloud. ", +"in bytes" => "in Bytes", +"in seconds. A change empties the cache." => "in Sekunden. Eine Änderung leert den Cache.", +"Help" => "Hilfe" +); diff --git a/apps/user_ldap/l10n/el.php b/apps/user_ldap/l10n/el.php new file mode 100644 index 00000000000..2f3c747a672 --- /dev/null +++ b/apps/user_ldap/l10n/el.php @@ -0,0 +1,6 @@ +<?php $TRANSLATIONS = array( +"Password" => "Συνθηματικό", +"Port" => "Θύρα", +"in bytes" => "σε bytes", +"Help" => "Βοήθεια" +); diff --git a/apps/user_ldap/l10n/eo.php b/apps/user_ldap/l10n/eo.php new file mode 100644 index 00000000000..6f18506b095 --- /dev/null +++ b/apps/user_ldap/l10n/eo.php @@ -0,0 +1,32 @@ +<?php $TRANSLATIONS = array( +"Host" => "Gastigo", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Vi povas neglekti la protokolon, escepte se vi bezonas SSL-on. Tiuokaze, komencu per ldaps://", +"Base DN" => "Baz-DN", +"User DN" => "Uzanto-DN", +"Password" => "Pasvorto", +"For anonymous access, leave DN and Password empty." => "Por sennoman aliron, lasu DN-on kaj Pasvorton malplenaj.", +"User Login Filter" => "Filtrilo de uzantensaluto", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "Ĝi difinas la filtrilon aplikotan, kiam oni provas ensaluti. %%uid anstataŭigas la uzantonomon en la ensaluta ago.", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "uzu la referencilon %%uid, ekz.: \"uid=%%uid\"", +"User List Filter" => "Filtrilo de uzantolisto", +"Defines the filter to apply, when retrieving users." => "Ĝi difinas la filtrilon aplikotan, kiam veniĝas uzantoj.", +"without any placeholder, e.g. \"objectClass=person\"." => "sen ajna referencilo, ekz.: \"objectClass=person\".", +"Group Filter" => "Filtrilo de grupo", +"Defines the filter to apply, when retrieving groups." => "Ĝi difinas la filtrilon aplikotan, kiam veniĝas grupoj.", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "sen ajna referencilo, ekz.: \"objectClass=posixGroup\".", +"Port" => "Pordo", +"Base User Tree" => "Baza uzantarbo", +"Base Group Tree" => "Baza gruparbo", +"Use TLS" => "Uzi TLS-on", +"Do not use it for SSL connections, it will fail." => "Ne uzu ĝin por SSL-konektoj, ĝi malsukcesos.", +"Case insensitve LDAP server (Windows)" => "LDAP-servilo blinda je litergrandeco (Vindozo)", +"Turn off SSL certificate validation." => "Malkapabligi validkontrolon de SSL-atestiloj.", +"Not recommended, use for testing only." => "Ne rekomendata, uzu ĝin nur por testoj.", +"User Display Name Field" => "Kampo de vidignomo de uzanto", +"The LDAP attribute to use to generate the user`s ownCloud name." => "La atributo de LDAP uzota por generi la ownCloud-an nomon de la uzanto.", +"Group Display Name Field" => "Kampo de vidignomo de grupo", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "La atributo de LDAP uzota por generi la ownCloud-an nomon de la grupo.", +"in bytes" => "duumoke", +"in seconds. A change empties the cache." => "sekunde. Ajna ŝanĝo malplenigas la kaŝmemoron.", +"Help" => "Helpo" +); diff --git a/apps/user_ldap/l10n/es.php b/apps/user_ldap/l10n/es.php new file mode 100644 index 00000000000..55abf7b88e0 --- /dev/null +++ b/apps/user_ldap/l10n/es.php @@ -0,0 +1,7 @@ +<?php $TRANSLATIONS = array( +"Password" => "Contraseña", +"Port" => "Puerto", +"Use TLS" => "Usar TLS", +"in bytes" => "en bytes", +"Help" => "Ayuda" +); diff --git a/apps/user_ldap/l10n/fi_FI.php b/apps/user_ldap/l10n/fi_FI.php new file mode 100644 index 00000000000..f6d16f3acc1 --- /dev/null +++ b/apps/user_ldap/l10n/fi_FI.php @@ -0,0 +1,31 @@ +<?php $TRANSLATIONS = array( +"Host" => "Isäntä", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Voit jättää protokollan määrittämättä, paitsi kun käytät SSL:ää. Aloita silloin ldaps://", +"Base DN" => "Oletus DN", +"You can specify Base DN for users and groups in the Advanced tab" => "Voit määrittää käyttäjien ja ryhmien oletus DN:n (distinguished name) 'tarkemmat asetukset' välilehdeltä ", +"User DN" => "Käyttäjän DN", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Asiakasohjelman DN, jolla yhdistäminen tehdään, ts. uid=agent,dc=example,dc=com. Mahdollistaaksesi anonyymin yhteyden, jätä DN ja salasana tyhjäksi.", +"Password" => "Salasana", +"For anonymous access, leave DN and Password empty." => "Jos haluat mahdollistaa anonyymin pääsyn, jätä DN ja Salasana tyhjäksi ", +"User Login Filter" => "Login suodatus", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "käytä %%uid paikanvaraajaa, ts. \"uid=%%uid\"", +"User List Filter" => "Käyttäjien suodatus", +"Defines the filter to apply, when retrieving users." => "Määrittelee käytettävän suodattimen, kun käyttäjiä haetaan. ", +"without any placeholder, e.g. \"objectClass=person\"." => "ilman paikanvaraustermiä, ts. \"objectClass=person\".", +"Group Filter" => "Ryhmien suodatus", +"Defines the filter to apply, when retrieving groups." => "Määrittelee käytettävän suodattimen, kun ryhmiä haetaan. ", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "ilman paikanvaraustermiä, ts. \"objectClass=posixGroup\".", +"Port" => "Portti", +"Base User Tree" => "Oletus käyttäjäpuu", +"Base Group Tree" => "Ryhmien juuri", +"Group-Member association" => "Ryhmä-jäsen assosiaatio (yhteys)", +"Use TLS" => "Käytä TLS:ää", +"Do not use it for SSL connections, it will fail." => "Älä käytä SSL yhteyttä varten, se epäonnistuu. ", +"Case insensitve LDAP server (Windows)" => "Kirjainkoosta piittamaton LDAP-palvelin (Windows)", +"Turn off SSL certificate validation." => "Sulje SSL sertifikaatin käyttö", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "Jos yhteys toimii vain tällä optiolla, siirrä LDAP palvelimen SSL sertifikaatti onwCloud palvelimellesi. ", +"Not recommended, use for testing only." => "Ei suositella, käytä vain testausta varten.", +"in bytes" => "tavuissa", +"in seconds. A change empties the cache." => "sekunneissa. Muutos tyhjentää välimuistin.", +"Help" => "Ohje" +); diff --git a/apps/user_ldap/l10n/fr.php b/apps/user_ldap/l10n/fr.php new file mode 100644 index 00000000000..64edf3b4680 --- /dev/null +++ b/apps/user_ldap/l10n/fr.php @@ -0,0 +1,32 @@ +<?php $TRANSLATIONS = array( +"Host" => "Hôte", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Vous pouvez omettre le protocole, sauf si vous avez besoin de SSL. Dans ce cas préfixez avec ldaps://", +"Base DN" => "DN de base", +"You can specify Base DN for users and groups in the Advanced tab" => "Vous pouvez spécifier le DN de base pour les utilisateurs et les groupes dans l'onglet Avancé", +"User DN" => "DN Utilisateur", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Le DN de l'utilisateur client avec lequel la liaison doit se faire, par exemple uid=agent,dc=example,dc=com. Pour l'accès anonyme, laisser le DN et le mot de passe vides.", +"Password" => "Mot de passe", +"For anonymous access, leave DN and Password empty." => "Pour l'accès anonyme, laisser le DN et le mot de passe vides.", +"User Login Filter" => "Filtre d'identifiants utilisateur", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "Définit le filtre à appliquer lors d'une tentative de connexion. %%uid remplace le nom d'utilisateur lors de la connexion.", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "veuillez utiliser le champ %%uid , ex.: \"uid=%%uid\"", +"User List Filter" => "Filtre d'utilisateurs", +"Defines the filter to apply, when retrieving users." => "Définit le filtre à appliquer lors de la récupération des utilisateurs.", +"without any placeholder, e.g. \"objectClass=person\"." => "sans élément de substitution, par exemple \"objectClass=person\".", +"Group Filter" => "Filtre de groupes", +"Defines the filter to apply, when retrieving groups." => "Définit le filtre à appliquer lors de la récupération des groupes.", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "sans élément de substitution, par exemple \"objectClass=posixGroup\".", +"Port" => "Port", +"Group-Member association" => "Association groupe-membre", +"Use TLS" => "Utiliser TLS", +"Do not use it for SSL connections, it will fail." => "Ne pas utiliser pour les connexions SSL, car cela échouera.", +"Case insensitve LDAP server (Windows)" => "Serveur LDAP insensible à la casse (Windows)", +"Turn off SSL certificate validation." => "Désactiver la validation du certificat SSL", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "Si la connexion ne fonctionne qu'avec cette option, importez le certificat SSL du serveur LDAP dans le serveur ownCloud.", +"Not recommended, use for testing only." => "Non recommendé, utilisation pour tests uniquement.", +"The LDAP attribute to use to generate the user`s ownCloud name." => "L'attribut LDAP utilisé pour générer les noms d'utilisateurs d'ownCloud", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "L'attribut LDAP utilisé pour générer les noms de groupes d'ownCloud", +"in bytes" => "en octets", +"in seconds. A change empties the cache." => "en secondes. Tout changement vide le cache.", +"Help" => "Aide" +); diff --git a/apps/user_ldap/l10n/it.php b/apps/user_ldap/l10n/it.php new file mode 100644 index 00000000000..c86b4ea2a57 --- /dev/null +++ b/apps/user_ldap/l10n/it.php @@ -0,0 +1,36 @@ +<?php $TRANSLATIONS = array( +"Host" => "Host", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "È possibile omettere il protocollo, ad eccezione se è necessario SSL. Quindi inizia con ldaps://", +"Base DN" => "DN base", +"You can specify Base DN for users and groups in the Advanced tab" => "Puoi specificare una DN base per gli utenti ed i gruppi nella scheda Avanzate", +"User DN" => "DN utente", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Il DN per il client dell'utente con cui deve essere associato, ad esempio uid=agent,dc=example,dc=com. Per l'accesso anonimo, lasciare vuoti i campi DN e Password", +"Password" => "Password", +"For anonymous access, leave DN and Password empty." => "Per l'accesso anonimo, lasciare vuoti i campi DN e Password", +"User Login Filter" => "Filtro per l'accesso utente", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "Specifica quale filtro utilizzare quando si tenta l'accesso. %%uid sostituisce il nome utente all'atto dell'accesso.", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "utilizza il segnaposto %%uid, ad esempio \"uid=%%uid\"", +"User List Filter" => "Filtro per l'elenco utenti", +"Defines the filter to apply, when retrieving users." => "Specifica quale filtro utilizzare durante il recupero degli utenti.", +"without any placeholder, e.g. \"objectClass=person\"." => "senza nessun segnaposto, per esempio \"objectClass=person\".", +"Group Filter" => "Filtro per il gruppo", +"Defines the filter to apply, when retrieving groups." => "Specifica quale filtro utilizzare durante il recupero dei gruppi.", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "senza nessun segnaposto, per esempio \"objectClass=posixGroup\".", +"Port" => "Porta", +"Base User Tree" => "Struttura base dell'utente", +"Base Group Tree" => "Struttura base del gruppo", +"Group-Member association" => "Associazione gruppo-utente ", +"Use TLS" => "Usa TLS", +"Do not use it for SSL connections, it will fail." => "Non utilizzare per le connessioni SSL, fallirà.", +"Case insensitve LDAP server (Windows)" => "Case insensitve LDAP server (Windows)", +"Turn off SSL certificate validation." => "Disattiva il controllo del certificato SSL.", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "Se la connessione funziona esclusivamente con questa opzione, importa il certificato SSL del server LDAP nel tuo server ownCloud.", +"Not recommended, use for testing only." => "Non consigliato, utilizzare solo per test.", +"User Display Name Field" => "Campo per la visualizzazione del nome utente", +"The LDAP attribute to use to generate the user`s ownCloud name." => "L'attributo LDAP da usare per generare il nome dell'utente ownCloud.", +"Group Display Name Field" => "Campo per la visualizzazione del nome del gruppo", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "L'attributo LDAP da usare per generare il nome del gruppo ownCloud.", +"in bytes" => "in byte", +"in seconds. A change empties the cache." => "in secondi. Il cambio svuota la cache.", +"Help" => "Aiuto" +); diff --git a/apps/user_ldap/l10n/ja_JP.php b/apps/user_ldap/l10n/ja_JP.php new file mode 100644 index 00000000000..8d4473b4e28 --- /dev/null +++ b/apps/user_ldap/l10n/ja_JP.php @@ -0,0 +1,36 @@ +<?php $TRANSLATIONS = array( +"Host" => "ホスト", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "SSL通信しない場合には、プロトコル名を省略することができます。そうでない場合には、ldaps:// から始めてください。", +"Base DN" => "ベースDN", +"You can specify Base DN for users and groups in the Advanced tab" => "拡張タブでユーザとグループのベースDNを指定することができます。", +"User DN" => "ユーザDN", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "クライアントユーザーのDNは、特定のものに結びつけることはしません。 例えば uid=agent,dc=example,dc=com. だと匿名アクセスの場合、DNとパスワードは空のままです。", +"Password" => "パスワード", +"For anonymous access, leave DN and Password empty." => "匿名アクセスの場合は、DNとパスワードを空にしてください。", +"User Login Filter" => "ユーザログインフィルタ", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "ログインするときに適用するフィルターを定義する。%%uid がログイン時にユーザー名に置き換えられます。", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "%%uid プレースホルダーを利用してください。例 \"uid=%%uid\"", +"User List Filter" => "ユーザリストフィルタ", +"Defines the filter to apply, when retrieving users." => "ユーザーを取得するときに適用するフィルターを定義する。", +"without any placeholder, e.g. \"objectClass=person\"." => "プレースホルダーを利用しないでください。例 \"objectClass=person\"", +"Group Filter" => "グループフィルタ", +"Defines the filter to apply, when retrieving groups." => "グループを取得するときに適用するフィルターを定義する。", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "プレースホルダーを利用しないでください。例 \"objectClass=posixGroup\"", +"Port" => "ポート", +"Base User Tree" => "ベースユーザツリー", +"Base Group Tree" => "ベースグループツリー", +"Group-Member association" => "グループとメンバーの関連付け", +"Use TLS" => "TLSを利用", +"Do not use it for SSL connections, it will fail." => "SSL接続に利用しないでください、失敗します。", +"Case insensitve LDAP server (Windows)" => "大文字/小文字を区別しないLDAPサーバ(Windows)", +"Turn off SSL certificate validation." => "SSL証明書の確認を無効にする。", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "接続がこのオプションでのみ動作する場合は、LDAPサーバのSSL証明書をownCloudサーバにインポートしてください。", +"Not recommended, use for testing only." => "推奨しません、テスト目的でのみ利用してください。", +"User Display Name Field" => "ユーザ表示名のフィールド", +"The LDAP attribute to use to generate the user`s ownCloud name." => "ユーザのownCloud名の生成に利用するLDAP属性。", +"Group Display Name Field" => "グループ表示名のフィールド", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "グループのownCloud名の生成に利用するLDAP属性。", +"in bytes" => "バイト", +"in seconds. A change empties the cache." => "秒。変更後にキャッシュがクリアされます。", +"Help" => "ヘルプ" +); diff --git a/apps/user_ldap/l10n/lt_LT.php b/apps/user_ldap/l10n/lt_LT.php new file mode 100644 index 00000000000..809ed571bd0 --- /dev/null +++ b/apps/user_ldap/l10n/lt_LT.php @@ -0,0 +1,9 @@ +<?php $TRANSLATIONS = array( +"Password" => "Slaptažodis", +"Group Filter" => "Grupės filtras", +"Port" => "Prievadas", +"Use TLS" => "Naudoti TLS", +"Turn off SSL certificate validation." => "Išjungti SSL sertifikato tikrinimą.", +"Not recommended, use for testing only." => "Nerekomenduojama, naudokite tik testavimui.", +"Help" => "Pagalba" +); diff --git a/apps/user_ldap/l10n/pl.php b/apps/user_ldap/l10n/pl.php new file mode 100644 index 00000000000..fa7618d68dc --- /dev/null +++ b/apps/user_ldap/l10n/pl.php @@ -0,0 +1,36 @@ +<?php $TRANSLATIONS = array( +"Host" => "Host", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Można pominąć protokół, z wyjątkiem wymaganego protokołu SSL. Następnie uruchom z ldaps://", +"Base DN" => "Baza DN", +"You can specify Base DN for users and groups in the Advanced tab" => "Bazę DN można określić dla użytkowników i grup w karcie Zaawansowane", +"User DN" => "Użytkownik DN", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN użytkownika klienta, z którym powiązanie wykonuje się, np. uid=agent,dc=example,dc=com. Dla dostępu anonimowego pozostawić DN i hasło puste", +"Password" => "Hasło", +"For anonymous access, leave DN and Password empty." => "Dla dostępu anonimowego pozostawić DN i hasło puste.", +"User Login Filter" => "Filtr logowania użytkownika", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "Definiuje filtr do zastosowania, gdy podejmowana jest próba logowania. %%uid zastępuje nazwę użytkownika w działaniu logowania.", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "Użyj %%uid zastępczy, np. \"uid=%%uid\"", +"User List Filter" => "Lista filtrów użytkownika", +"Defines the filter to apply, when retrieving users." => "Definiuje filtry do zastosowania, podczas pobierania użytkowników.", +"without any placeholder, e.g. \"objectClass=person\"." => "bez żadnych symboli zastępczych np. \"objectClass=person\".", +"Group Filter" => "Grupa filtrów", +"Defines the filter to apply, when retrieving groups." => "Definiuje filtry do zastosowania, podczas pobierania grup.", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "bez żadnych symboli zastępczych np. \"objectClass=posixGroup\".", +"Port" => "Port", +"Base User Tree" => "Drzewo bazy użytkowników", +"Base Group Tree" => "Drzewo bazy grup", +"Group-Member association" => "Członek grupy stowarzyszenia", +"Use TLS" => "Użyj TLS", +"Do not use it for SSL connections, it will fail." => "Nie używaj SSL dla połączeń, jeśli się nie powiedzie.", +"Case insensitve LDAP server (Windows)" => "Wielkość liter serwera LDAP (Windows)", +"Turn off SSL certificate validation." => "Wyłączyć sprawdzanie poprawności certyfikatu SSL.", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "Jeśli połączenie działa tylko z tą opcją, zaimportuj certyfikat SSL serwera LDAP w serwerze ownCloud.", +"Not recommended, use for testing only." => "Niezalecane, użyj tylko testowo.", +"User Display Name Field" => "Pole wyświetlanej nazwy użytkownika", +"The LDAP attribute to use to generate the user`s ownCloud name." => "Atrybut LDAP służy do generowania nazwy użytkownika ownCloud.", +"Group Display Name Field" => "Pole wyświetlanej nazwy grupy", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "Atrybut LDAP służy do generowania nazwy grup ownCloud.", +"in bytes" => "w bajtach", +"in seconds. A change empties the cache." => "w sekundach. Zmiana opróżnia pamięć podręczną.", +"Help" => "Pomoc" +); diff --git a/apps/user_ldap/l10n/ro.php b/apps/user_ldap/l10n/ro.php new file mode 100644 index 00000000000..326e47f96fe --- /dev/null +++ b/apps/user_ldap/l10n/ro.php @@ -0,0 +1,36 @@ +<?php $TRANSLATIONS = array( +"Host" => "Gazdă", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Puteți omite protocolul, decât dacă folosiți SSL. Atunci se începe cu ldaps://", +"Base DN" => "DN de bază", +"You can specify Base DN for users and groups in the Advanced tab" => "Puteți să specificați DN de bază pentru utilizatori și grupuri în fila Avansat", +"User DN" => "DN al utilizatorului", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN-ul clientului utilizator cu care se va efectua conectarea, d.e. uid=agent,dc=example,dc=com. Pentru acces anonim, lăsăți DN și Parolă libere.", +"Password" => "Parolă", +"For anonymous access, leave DN and Password empty." => "Pentru acces anonim, lăsați DN și Parolă libere.", +"User Login Filter" => "Filtrare după Nume Utilizator", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "Definește fitrele care trebuie aplicate, când se încearcă conectarea. %%uid înlocuiește numele utilizatorului în procesul de conectare.", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "folosiți substituentul %%uid , d.e. \"uid=%%uid\"", +"User List Filter" => "Filtrarea după lista utilizatorilor", +"Defines the filter to apply, when retrieving users." => "Definește filtrele care trebui aplicate, când se peiau utilzatorii.", +"without any placeholder, e.g. \"objectClass=person\"." => "fără substituenți, d.e. \"objectClass=person\".", +"Group Filter" => "Fitrare Grup", +"Defines the filter to apply, when retrieving groups." => "Definește filtrele care se aplică, când se preiau grupurile.", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "fără substituenți, d.e. \"objectClass=posixGroup\"", +"Port" => "Portul", +"Base User Tree" => "Arborele de bază al Utilizatorilor", +"Base Group Tree" => "Arborele de bază al Grupurilor", +"Group-Member association" => "Asocierea Grup-Membru", +"Use TLS" => "Utilizează TLS", +"Do not use it for SSL connections, it will fail." => "A nu se utiliza pentru conexiuni SSL, va eșua.", +"Case insensitve LDAP server (Windows)" => "Server LDAP insensibil la majuscule (Windows)", +"Turn off SSL certificate validation." => "Oprește validarea certificatelor SSL ", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "Dacă conexiunea lucrează doar cu această opțiune, importează certificatul SSL al serverului LDAP în serverul ownCloud.", +"Not recommended, use for testing only." => "Nu este recomandat, a se utiliza doar pentru testare.", +"User Display Name Field" => "Câmpul cu numele vizibil al utilizatorului", +"The LDAP attribute to use to generate the user`s ownCloud name." => "Atributul LDAP folosit pentru a genera numele de utilizator din ownCloud.", +"Group Display Name Field" => "Câmpul cu numele grupului", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "Atributul LDAP folosit pentru a genera numele grupurilor din ownCloud", +"in bytes" => "în octeți", +"in seconds. A change empties the cache." => "în secunde. O schimbare curăță memoria tampon.", +"Help" => "Ajutor" +); diff --git a/apps/user_ldap/l10n/sl.php b/apps/user_ldap/l10n/sl.php new file mode 100644 index 00000000000..312346958be --- /dev/null +++ b/apps/user_ldap/l10n/sl.php @@ -0,0 +1,36 @@ +<?php $TRANSLATIONS = array( +"Host" => "Gostitelj", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Protokol lahko izpustite, razen če zahtevate SSL. V tem primeru začnite z ldaps://", +"Base DN" => "Osnovni DN", +"You can specify Base DN for users and groups in the Advanced tab" => "Osnovni DN za uporabnike in skupine lahko določite v zavihku Napredno", +"User DN" => "Uporabnik DN", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN uporabnikovega odjemalca, s katerim naj se opravi vezava, npr. uid=agent,dc=example,dc=com. Za anonimni dostop pustite polji DN in geslo prazni.", +"Password" => "Geslo", +"For anonymous access, leave DN and Password empty." => "Za anonimni dostop pustite polji DN in geslo prazni.", +"User Login Filter" => "Filter prijav uporabnikov", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "Določi filter uporabljen pri prijavi. %%uid nadomesti uporaniško ime pri prijavi.", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "Uporabite ogrado %%uid, npr. \"uid=%%uid\".", +"User List Filter" => "Filter seznama uporabnikov", +"Defines the filter to apply, when retrieving users." => "Določi filter za uporabo med pridobivanjem uporabnikov.", +"without any placeholder, e.g. \"objectClass=person\"." => "Brez katerekoli ograde, npr. \"objectClass=person\".", +"Group Filter" => "Filter skupin", +"Defines the filter to apply, when retrieving groups." => "Določi filter za uporabo med pridobivanjem skupin.", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "Brez katerekoli ograde, npr. \"objectClass=posixGroup\".", +"Port" => "Vrata", +"Base User Tree" => "Osnovno uporabniško drevo", +"Base Group Tree" => "Osnovno drevo skupine", +"Group-Member association" => "Povezava člana skupine", +"Use TLS" => "Uporabi TLS", +"Do not use it for SSL connections, it will fail." => "Ne uporabljajte ga za SSL povezave, saj ne bo delovalo.", +"Case insensitve LDAP server (Windows)" => "LDAP strežnik je neobčutljiv na velikost črk (Windows)", +"Turn off SSL certificate validation." => "Onemogoči potrditev veljavnosti SSL certifikata.", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "Če povezava deluje samo s to možnostjo, uvozite SSL potrdilo iz LDAP strežnika v vaš ownCloud strežnik.", +"Not recommended, use for testing only." => "Odsvetovano, uporabite le v namene preizkušanja.", +"User Display Name Field" => "Polje za uporabnikovo prikazano ime", +"The LDAP attribute to use to generate the user`s ownCloud name." => "LDAP atribut uporabljen pri ustvarjanju ownCloud uporabniških imen.", +"Group Display Name Field" => "Polje za prikazano ime skupine", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "LDAP atribut uporabljen pri ustvarjanju ownCloud imen skupin.", +"in bytes" => "v bajtih", +"in seconds. A change empties the cache." => "v sekundah. Sprememba izprazni predpomnilnik.", +"Help" => "Pomoč" +); diff --git a/apps/user_ldap/l10n/sv.php b/apps/user_ldap/l10n/sv.php new file mode 100644 index 00000000000..a23cc094b4d --- /dev/null +++ b/apps/user_ldap/l10n/sv.php @@ -0,0 +1,36 @@ +<?php $TRANSLATIONS = array( +"Host" => "Server", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Du behöver inte ange protokoll förutom om du använder SSL. Starta då med ldaps://", +"Base DN" => "Start DN", +"You can specify Base DN for users and groups in the Advanced tab" => "Du kan ange start DN för användare och grupper under fliken Avancerat", +"User DN" => "Användare DN", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN för användaren som skall användas, t.ex. uid=agent, dc=example, dc=com. För anonym åtkomst, lämna DN och lösenord tomt.", +"Password" => "Lösenord", +"For anonymous access, leave DN and Password empty." => "För anonym åtkomst, lämna DN och lösenord tomt.", +"User Login Filter" => "Filter logga in användare", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "Definierar filter att tillämpa vid inloggningsförsök. %% uid ersätter användarnamn i loginåtgärden.", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "använd platshållare %%uid, t ex \"uid=%%uid\"", +"User List Filter" => "Filter lista användare", +"Defines the filter to apply, when retrieving users." => "Definierar filter att tillämpa vid listning av användare.", +"without any placeholder, e.g. \"objectClass=person\"." => "utan platshållare, t.ex. \"objectClass=person\".", +"Group Filter" => "Gruppfilter", +"Defines the filter to apply, when retrieving groups." => "Definierar filter att tillämpa vid listning av grupper.", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "utan platshållare, t.ex. \"objectClass=posixGroup\".", +"Port" => "Port", +"Base User Tree" => "Bas för användare i katalogtjänst", +"Base Group Tree" => "Bas för grupper i katalogtjänst", +"Group-Member association" => "Attribut för gruppmedlemmar", +"Use TLS" => "Använd TLS", +"Do not use it for SSL connections, it will fail." => "Använd inte för SSL-anslutningar, det kommer inte att fungera.", +"Case insensitve LDAP server (Windows)" => "LDAP-servern är okänslig för gemener och versaler (Windows)", +"Turn off SSL certificate validation." => "Stäng av verifiering av SSL-certifikat.", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "Om anslutningen bara fungerar med det här alternativet, importera LDAP-serverns SSL-certifikat i din ownCloud-server.", +"Not recommended, use for testing only." => "Rekommenderas inte, använd bara för test. ", +"User Display Name Field" => "Attribut för användarnamn", +"The LDAP attribute to use to generate the user`s ownCloud name." => "Attribut som används för att generera användarnamn i ownCloud.", +"Group Display Name Field" => "Attribut för gruppnamn", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "Attribut som används för att generera gruppnamn i ownCloud.", +"in bytes" => "i bytes", +"in seconds. A change empties the cache." => "i sekunder. En förändring tömmer cache.", +"Help" => "Hjälp" +); diff --git a/apps/user_ldap/l10n/th_TH.php b/apps/user_ldap/l10n/th_TH.php new file mode 100644 index 00000000000..a1baa648135 --- /dev/null +++ b/apps/user_ldap/l10n/th_TH.php @@ -0,0 +1,36 @@ +<?php $TRANSLATIONS = array( +"Host" => "โฮสต์", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "คุณสามารถปล่อยช่องโปรโตคอลเว้นไว้ได้, ยกเว้นกรณีที่คุณต้องการใช้ SSL จากนั้นเริ่มต้นด้วย ldaps://", +"Base DN" => "DN ฐาน", +"You can specify Base DN for users and groups in the Advanced tab" => "คุณสามารถระบุ DN หลักสำหรับผู้ใช้งานและกลุ่มต่างๆในแท็บขั้นสูงได้", +"User DN" => "DN ของผู้ใช้งาน", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN ของผู้ใช้งานที่เป็นลูกค้าอะไรก็ตามที่ผูกอยู่ด้วย เช่น uid=agent, dc=example, dc=com, สำหรับการเข้าถึงโดยบุคคลนิรนาม, ให้เว้นว่าง DN และ รหัสผ่านเอาไว้", +"Password" => "รหัสผ่าน", +"For anonymous access, leave DN and Password empty." => "สำหรับการเข้าถึงโดยบุคคลนิรนาม ให้เว้นว่าง DN และรหัสผ่านไว้", +"User Login Filter" => "ตัวกรองข้อมูลการเข้าสู่ระบบของผู้ใช้งาน", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action." => "กำหนดตัวกรองข้อมูลที่ต้องการนำไปใช้งาน, เมื่อมีความพยายามในการเข้าสู่ระบบ %%uid จะถูกนำไปแทนที่ชื่อผู้ใช้งานในการกระทำของการเข้าสู่ระบบ", +"use %%uid placeholder, e.g. \"uid=%%uid\"" => "ใช้ตัวยึด %%uid, เช่น \"uid=%%uid\"", +"User List Filter" => "ตัวกรองข้อมูลรายชื่อผู้ใช้งาน", +"Defines the filter to apply, when retrieving users." => "ระบุตัวกรองข้อมูลที่ต้องการนำไปใช้งาน, เมื่อดึงข้อมูลผู้ใช้งาน", +"without any placeholder, e.g. \"objectClass=person\"." => "โดยไม่ต้องมีตัวยึดใดๆ, เช่น \"objectClass=person\",", +"Group Filter" => "ตัวกรองข้อมูลกลุ่ม", +"Defines the filter to apply, when retrieving groups." => "ระบุตัวกรองข้อมูลที่ต้องการนำไปใช้งาน, เมื่อดึงข้อมูลกลุ่ม", +"without any placeholder, e.g. \"objectClass=posixGroup\"." => "โดยไม่ต้องมีตัวยึดใดๆ, เช่น \"objectClass=posixGroup\",", +"Port" => "พอร์ต", +"Base User Tree" => "รายการผู้ใช้งานหลักแบบ Tree", +"Base Group Tree" => "รายการกลุ่มหลักแบบ Tree", +"Group-Member association" => "ความสัมพันธ์ของสมาชิกในกลุ่ม", +"Use TLS" => "ใช้ TLS", +"Do not use it for SSL connections, it will fail." => "กรุณาอย่าใช้การเชื่อมต่อแบบ SSL การเชื่อมต่อจะเกิดการล้มเหลว", +"Case insensitve LDAP server (Windows)" => "เซิร์ฟเวอร์ LDAP ประเภท Case insensitive (วินโดวส์)", +"Turn off SSL certificate validation." => "ปิดใช้งานการตรวจสอบความถูกต้องของใบรับรองความปลอดภัย SSL", +"If connection only works with this option, import the LDAP server's SSL certificate in your ownCloud server." => "หากการเชื่อมต่อสามารถทำงานได้เฉพาะกับตัวเลือกนี้เท่านั้น, ให้นำเข้าข้อมูลใบรับรองความปลอดภัยแบบ SSL ของเซิร์ฟเวอร์ LDAP ดังกล่าวเข้าไปไว้ในเซิร์ฟเวอร์ ownCloud", +"Not recommended, use for testing only." => "ไม่แนะนำให้ใช้งาน, ใช้สำหรับการทดสอบเท่านั้น", +"User Display Name Field" => "ช่องแสดงชื่อผู้ใช้งานที่ต้องการ", +"The LDAP attribute to use to generate the user`s ownCloud name." => "คุณลักษณะ LDAP ที่ต้องการใช้สำหรับสร้างชื่อของผู้ใช้งาน ownCloud", +"Group Display Name Field" => "ช่องแสดงชื่อกลุ่มที่ต้องการ", +"The LDAP attribute to use to generate the groups`s ownCloud name." => "คุณลักษณะ LDAP ที่ต้องการใช้สร้างชื่อกลุ่มของ ownCloud", +"in bytes" => "ในหน่วยไบต์", +"in seconds. A change empties the cache." => "ในอีกไม่กี่วินาที ระบบจะเปลี่ยนแปลงข้อมูลในแคชให้ว่างเปล่า", +"Help" => "ช่วยเหลือ" +); diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php new file mode 100644 index 00000000000..be9aa21c3d2 --- /dev/null +++ b/apps/user_ldap/lib/access.php @@ -0,0 +1,676 @@ +<?php + +/** + * ownCloud – LDAP Access + * + * @author Arthur Schiwon + * @copyright 2012 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\user_ldap\lib; + +abstract class Access { + protected $connection; + + public function setConnector(Connection &$connection) { + $this->connection = $connection; + } + + private function checkConnection() { + return ($this->connection instanceof Connection); + } + + /** + * @brief reads a given attribute for an LDAP record identified by a DN + * @param $dn the record in question + * @param $attr the attribute that shall be retrieved + * @returns the values in an array on success, false otherwise + * + * Reads an attribute from an LDAP entry + */ + public function readAttribute($dn, $attr) { + if(!$this->checkConnection()) { + \OCP\Util::writeLog('user_ldap', 'No LDAP Connector assigned, access impossible for readAttribute.', \OCP\Util::WARN); + return false; + } + $cr = $this->connection->getConnectionResource(); + if(!is_resource($cr)) { + //LDAP not available + \OCP\Util::writeLog('user_ldap', 'LDAP resource not available.', \OCP\Util::DEBUG); + return false; + } + $rr = @ldap_read($cr, $dn, 'objectClass=*', array($attr)); + if(!is_resource($rr)) { + \OCP\Util::writeLog('user_ldap', 'readAttribute '.$attr.' failed for DN '.$dn, \OCP\Util::DEBUG); + //in case an error occurs , e.g. object does not exist + return false; + } + $er = ldap_first_entry($cr, $rr); + //LDAP attributes are not case sensitive + $result = \OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8'); + $attr = mb_strtolower($attr, 'UTF-8'); + + if(isset($result[$attr]) && $result[$attr]['count'] > 0) { + $values = array(); + for($i=0;$i<$result[$attr]['count'];$i++) { + $values[] = $this->resemblesDN($attr) ? $this->sanitizeDN($result[$attr][$i]) : $result[$attr][$i]; + } + return $values; + } + \OCP\Util::writeLog('user_ldap', 'Requested attribute '.$attr.' not found for '.$dn, \OCP\Util::DEBUG); + return false; + } + + /** + * @brief checks wether the given attribute`s valua is probably a DN + * @param $attr the attribute in question + * @return if so true, otherwise false + */ + private function resemblesDN($attr) { + $resemblingAttributes = array( + 'dn', + 'uniquemember', + 'member' + ); + return in_array($attr, $resemblingAttributes); + } + + /** + * @brief sanitizes a DN received from the LDAP server + * @param $dn the DN in question + * @return the sanitized DN + */ + private function sanitizeDN($dn) { + //OID sometimes gives back DNs with whitespace after the comma a la "uid=foo, cn=bar, dn=..." We need to tackle this! + $dn = preg_replace('/([^\\\]),(\s+)/u', '\1,', $dn); + + //make comparisons and everything work + $dn = mb_strtolower($dn, 'UTF-8'); + + return $dn; + } + + /** + * gives back the database table for the query + */ + private function getMapTable($isUser) { + if($isUser) { + return '*PREFIX*ldap_user_mapping'; + } else { + return '*PREFIX*ldap_group_mapping'; + } + } + + /** + * @brief returns the LDAP DN for the given internal ownCloud name of the group + * @param $name the ownCloud name in question + * @returns string with the LDAP DN on success, otherwise false + * + * returns the LDAP DN for the given internal ownCloud name of the group + */ + public function groupname2dn($name) { + return $this->ocname2dn($name, false); + } + + /** + * @brief returns the LDAP DN for the given internal ownCloud name of the user + * @param $name the ownCloud name in question + * @returns string with the LDAP DN on success, otherwise false + * + * returns the LDAP DN for the given internal ownCloud name of the user + */ + public function username2dn($name) { + $dn = $this->ocname2dn($name, true); + if($dn) { + return $dn; + } else { + //fallback: user is not mapped + $filter = $this->combineFilterWithAnd(array( + $this->connection->ldapUserFilter, + $this->connection->ldapUserDisplayName . '=' . $name, + )); + $result = $this->searchUsers($filter, 'dn'); + if(isset($result[0]['dn'])) { + $this->mapComponent($result[0], $name, true); + return $result[0]; + } + } + + return false; + } + + /** + * @brief returns the LDAP DN for the given internal ownCloud name + * @param $name the ownCloud name in question + * @param $isUser is it a user? otherwise group + * @returns string with the LDAP DN on success, otherwise false + * + * returns the LDAP DN for the given internal ownCloud name + */ + private function ocname2dn($name, $isUser) { + $table = $this->getMapTable($isUser); + + $query = \OCP\DB::prepare(' + SELECT ldap_dn + FROM '.$table.' + WHERE owncloud_name = ? + '); + + $record = $query->execute(array($name))->fetchOne(); + return $record; + } + + /** + * @brief returns the internal ownCloud name for the given LDAP DN of the group + * @param $dn the dn of the group object + * @param $ldapname optional, the display name of the object + * @returns string with with the name to use in ownCloud, false on DN outside of search DN + * + * returns the internal ownCloud name for the given LDAP DN of the group, false on DN outside of search DN or failure + */ + public function dn2groupname($dn, $ldapname = null) { + if(mb_strripos($dn, $this->sanitizeDN($this->connection->ldapBaseGroups), 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($this->sanitizeDN($this->connection->ldapBaseGroups), 'UTF-8'))) { + return false; + } + return $this->dn2ocname($dn, $ldapname, false); + } + + /** + * @brief returns the internal ownCloud name for the given LDAP DN of the user + * @param $dn the dn of the user object + * @param $ldapname optional, the display name of the object + * @returns string with with the name to use in ownCloud + * + * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN or failure + */ + public function dn2username($dn, $ldapname = null) { + if(mb_strripos($dn, $this->sanitizeDN($this->connection->ldapBaseUsers), 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($this->sanitizeDN($this->connection->ldapBaseUsers), 'UTF-8'))) { + return false; + } + return $this->dn2ocname($dn, $ldapname, true); + } + + /** + * @brief returns an internal ownCloud name for the given LDAP DN + * @param $dn the dn of the user object + * @param $ldapname optional, the display name of the object + * @param $isUser optional, wether it is a user object (otherwise group assumed) + * @returns string with with the name to use in ownCloud + * + * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN + */ + public function dn2ocname($dn, $ldapname = null, $isUser = true) { + $dn = $this->sanitizeDN($dn); + $table = $this->getMapTable($isUser); + if($isUser) { + $nameAttribute = $this->connection->ldapUserDisplayName; + } else { + $nameAttribute = $this->connection->ldapGroupDisplayName; + } + + $query = \OCP\DB::prepare(' + SELECT owncloud_name + FROM '.$table.' + WHERE ldap_dn = ? + '); + + //let's try to retrieve the ownCloud name from the mappings table + $component = $query->execute(array($dn))->fetchOne(); + if($component) { + return $component; + } + + //second try: get the UUID and check if it is known. Then, update the DN and return the name. + $uuid = $this->getUUID($dn); + if($uuid) { + $query = \OCP\DB::prepare(' + SELECT owncloud_name + FROM '.$table.' + WHERE directory_uuid = ? + '); + $component = $query->execute(array($uuid))->fetchOne(); + if($component) { + $query = \OCP\DB::prepare(' + UPDATE '.$table.' + SET ldap_dn = ? + WHERE directory_uuid = ? + '); + $query->execute(array($dn, $uuid)); + return $component; + } + } + + if(is_null($ldapname)) { + $ldapname = $this->readAttribute($dn, $nameAttribute); + if(!isset($ldapname[0]) && empty($ldapname[0])) { + \OCP\Util::writeLog('user_ldap', 'No or empty name for '.$dn.'.', \OCP\Util::INFO); + return false; + } + $ldapname = $ldapname[0]; + } + $ldapname = $this->sanitizeUsername($ldapname); + + //a new user/group! Then let's try to add it. We're shooting into the blue with the user/group name, assuming that in most cases there will not be a conflict. Otherwise an error will occur and we will continue with our second shot. + if($this->mapComponent($dn, $ldapname, $isUser)) { + return $ldapname; + } + + //doh! There is a conflict. We need to distinguish between users/groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this object is located. + $oc_name = $this->alternateOwnCloudName($ldapname, $dn); + if($this->mapComponent($dn, $oc_name, $isUser)) { + return $oc_name; + } + + //if everything else did not help.. + \OCP\Util::writeLog('user_ldap', 'Could not create unique ownCloud name for '.$dn.'.', \OCP\Util::INFO); + } + + /** + * @brief gives back the user names as they are used ownClod internally + * @param $ldapGroups an array with the ldap Users result in style of array ( array ('dn' => foo, 'uid' => bar), ... ) + * @returns an array with the user names to use in ownCloud + * + * gives back the user names as they are used ownClod internally + */ + public function ownCloudUserNames($ldapUsers) { + return $this->ldap2ownCloudNames($ldapUsers, true); + } + + /** + * @brief gives back the group names as they are used ownClod internally + * @param $ldapGroups an array with the ldap Groups result in style of array ( array ('dn' => foo, 'cn' => bar), ... ) + * @returns an array with the group names to use in ownCloud + * + * gives back the group names as they are used ownClod internally + */ + public function ownCloudGroupNames($ldapGroups) { + return $this->ldap2ownCloudNames($ldapGroups, false); + } + + private function ldap2ownCloudNames($ldapObjects, $isUsers) { + if($isUsers) { + $knownObjects = $this->mappedUsers(); + $nameAttribute = $this->connection->ldapUserDisplayName; + } else { + $knownObjects = $this->mappedGroups(); + $nameAttribute = $this->connection->ldapGroupDisplayName; + } + $ownCloudNames = array(); + + foreach($ldapObjects as $ldapObject) { + $key = \OCP\Util::recursiveArraySearch($knownObjects, $ldapObject['dn']); + + //everything is fine when we know the group + if($key !== false) { + $ownCloudNames[] = $knownObjects[$key]['owncloud_name']; + continue; + } + + //we do not take empty usernames + if(!isset($ldapObject[$nameAttribute]) || empty($ldapObject[$nameAttribute])) { + \OCP\Util::writeLog('user_ldap', 'No or empty name for '.$ldapObject['dn'].', skipping.', \OCP\Util::INFO); + continue; + } + + //a new group! Then let's try to add it. We're shooting into the blue with the group name, assuming that in most cases there will not be a conflict. But first make sure, that the display name contains only allowed characters. + $ocname = $this->sanitizeUsername($ldapObject[$nameAttribute]); + if($this->mapComponent($ldapObject['dn'], $ocname, $isUsers)) { + $ownCloudNames[] = $ocname; + continue; + } + + //doh! There is a conflict. We need to distinguish between groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this entry is located. + $ocname = $this->alternateOwnCloudName($ocname, $ldapObject['dn']); + if($this->mapComponent($ldapObject['dn'], $ocname, $isUsers)) { + $ownCloudNames[] = $ocname; + continue; + } + + //if everything else did not help.. + \OCP\Util::writeLog('user_ldap', 'Could not create unique ownCloud name for '.$ldapObject['dn'].', skipping.', \OCP\Util::INFO); + } + return $ownCloudNames; + } + + /** + * @brief creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object + * @param $name the display name of the object + * @param $dn the dn of the object + * @returns string with with the name to use in ownCloud + * + * creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object + */ + private function alternateOwnCloudName($name, $dn) { + $ufn = ldap_dn2ufn($dn); + $name = $name . '@' . trim(\OCP\Util::mb_substr_replace($ufn, '', 0, mb_strpos($ufn, ',', 0, 'UTF-8'), 'UTF-8')); + $name = $this->sanitizeUsername($name); + return $name; + } + + /** + * @brief retrieves all known groups from the mappings table + * @returns array with the results + * + * retrieves all known groups from the mappings table + */ + private function mappedGroups() { + return $this->mappedComponents(false); + } + + /** + * @brief retrieves all known users from the mappings table + * @returns array with the results + * + * retrieves all known users from the mappings table + */ + private function mappedUsers() { + return $this->mappedComponents(true); + } + + private function mappedComponents($isUsers) { + $table = $this->getMapTable($isUsers); + + $query = \OCP\DB::prepare(' + SELECT ldap_dn, owncloud_name + FROM '. $table + ); + + return $query->execute()->fetchAll(); + } + + /** + * @brief inserts a new user or group into the mappings table + * @param $dn the record in question + * @param $ocname the name to use in ownCloud + * @param $isUser is it a user or a group? + * @returns true on success, false otherwise + * + * inserts a new user or group into the mappings table + */ + private function mapComponent($dn, $ocname, $isUser = true) { + $table = $this->getMapTable($isUser); + $dn = $this->sanitizeDN($dn); + + $sqlAdjustment = ''; + $dbtype = \OCP\Config::getSystemValue('dbtype'); + if($dbtype == 'mysql') { + $sqlAdjustment = 'FROM dual'; + } + + $insert = \OCP\DB::prepare(' + INSERT INTO '.$table.' (ldap_dn, owncloud_name, directory_uuid) + SELECT ?,?,? + '.$sqlAdjustment.' + WHERE NOT EXISTS ( + SELECT 1 + FROM '.$table.' + WHERE ldap_dn = ? + OR owncloud_name = ?) + '); + + //feed the DB + $res = $insert->execute(array($dn, $ocname, $this->getUUID($dn), $dn, $ocname)); + + if(\OCP\DB::isError($res)) { + return false; + } + + $insRows = $res->numRows(); + + if($insRows == 0) { + return false; + } + + return true; + } + + public function fetchListOfUsers($filter, $attr) { + return $this->fetchList($this->searchUsers($filter, $attr), (count($attr) > 1)); + } + + public function fetchListOfGroups($filter, $attr) { + return $this->fetchList($this->searchGroups($filter, $attr), (count($attr) > 1)); + } + + private function fetchList($list, $manyAttributes) { + if(is_array($list)) { + if($manyAttributes) { + return $list; + } else { + return array_unique($list, SORT_LOCALE_STRING); + } + } + + //error cause actually, maybe throw an exception in future. + return array(); + } + + /** + * @brief executes an LDAP search, optimized for Users + * @param $filter the LDAP filter for the search + * @param $attr optional, when a certain attribute shall be filtered out + * @returns array with the search result + * + * Executes an LDAP search + */ + public function searchUsers($filter, $attr = null) { + return $this->search($filter, $this->connection->ldapBaseUsers, $attr); + } + + /** + * @brief executes an LDAP search, optimized for Groups + * @param $filter the LDAP filter for the search + * @param $attr optional, when a certain attribute shall be filtered out + * @returns array with the search result + * + * Executes an LDAP search + */ + public function searchGroups($filter, $attr = null) { + return $this->search($filter, $this->connection->ldapBaseGroups, $attr); + } + + /** + * @brief executes an LDAP search + * @param $filter the LDAP filter for the search + * @param $base the LDAP subtree that shall be searched + * @param $attr optional, when a certain attribute shall be filtered out + * @returns array with the search result + * + * Executes an LDAP search + */ + private function search($filter, $base, $attr = null) { + if(!is_null($attr) && !is_array($attr)) { + $attr = array(mb_strtolower($attr, 'UTF-8')); + } + + // See if we have a resource + $link_resource = $this->connection->getConnectionResource(); + if(is_resource($link_resource)) { + $sr = ldap_search($link_resource, $base, $filter, $attr); + $findings = ldap_get_entries($link_resource, $sr ); + + // if we're here, probably no connection resource is returned. + // to make ownCloud behave nicely, we simply give back an empty array. + if(is_null($findings)) { + return array(); + } + } else { + // Seems like we didn't find any resource. + // Return an empty array just like before. + \OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG); + return array(); + } + + if(!is_null($attr)) { + $selection = array(); + $multiarray = false; + if(count($attr) > 1) { + $multiarray = true; + $i = 0; + } + foreach($findings as $item) { + if(!is_array($item)) { + continue; + } + $item = \OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8'); + + if($multiarray) { + foreach($attr as $key) { + $key = mb_strtolower($key, 'UTF-8'); + if(isset($item[$key])) { + if($key != 'dn') { + $selection[$i][$key] = $this->resemblesDN($key) ? $this->sanitizeDN($item[$key][0]) : $item[$key][0]; + } else { + $selection[$i][$key] = $this->sanitizeDN($item[$key]); + } + } + + } + $i++; + } else { + //tribute to case insensitivity + $key = mb_strtolower($attr[0], 'UTF-8'); + + if(isset($item[$key])) { + if($this->resemblesDN($key)) { + $selection[] = $this->sanitizeDN($item[$key]); + } else { + $selection[] = $item[$key]; + } + } + } + } + return $selection; + } + return $findings; + } + + public function sanitizeUsername($name) { + if($this->connection->ldapIgnoreNamingRules) { + return $name; + } + + //REPLACEMENTS + $name = \OCP\Util::mb_str_replace(' ', '_', $name, 'UTF-8'); + + //every remaining unallowed characters will be removed + $name = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $name); + + return $name; + } + + /** + * @brief combines the input filters with AND + * @param $filters array, the filters to connect + * @returns the combined filter + * + * Combines Filter arguments with AND + */ + public function combineFilterWithAnd($filters) { + return $this->combineFilter($filters, '&'); + } + + /** + * @brief combines the input filters with AND + * @param $filters array, the filters to connect + * @returns the combined filter + * + * Combines Filter arguments with AND + */ + public function combineFilterWithOr($filters) { + return $this->combineFilter($filters, '|'); + } + + /** + * @brief combines the input filters with given operator + * @param $filters array, the filters to connect + * @param $operator either & or | + * @returns the combined filter + * + * Combines Filter arguments with AND + */ + private function combineFilter($filters, $operator) { + $combinedFilter = '('.$operator; + foreach($filters as $filter) { + if($filter[0] != '(') { + $filter = '('.$filter.')'; + } + $combinedFilter.=$filter; + } + $combinedFilter.=')'; + return $combinedFilter; + } + + public function areCredentialsValid($name, $password) { + $testConnection = clone $this->connection; + $credentials = array( + 'ldapAgentName' => $name, + 'ldapAgentPassword' => $password + ); + if(!$testConnection->setConfiguration($credentials)) { + return false; + } + return $testConnection->bind(); + } + + /** + * @brief auto-detects the directory's UUID attribute + * @param $dn a known DN used to check against + * @param $force the detection should be run, even if it is not set to auto + * @returns true on success, false otherwise + */ + private function detectUuidAttribute($dn, $force = false) { + if(($this->connection->ldapUuidAttribute != 'auto') && !$force) { + return true; + } + + //for now, supported (known) attributes are entryUUID, nsuniqueid, objectGUID + $testAttributes = array('entryuuid', 'nsuniqueid', 'objectguid'); + + foreach($testAttributes as $attribute) { + \OCP\Util::writeLog('user_ldap', 'Testing '.$attribute.' as UUID attr', \OCP\Util::DEBUG); + + $value = $this->readAttribute($dn, $attribute); + if(is_array($value) && isset($value[0]) && !empty($value[0])) { + \OCP\Util::writeLog('user_ldap', 'Setting '.$attribute.' as UUID attr', \OCP\Util::DEBUG); + $this->connection->ldapUuidAttribute = $attribute; + return true; + } + \OCP\Util::writeLog('user_ldap', 'The looked for uuid attr is not '.$attribute.', result was '.print_r($value,true), \OCP\Util::DEBUG); + } + + return false; + } + + public function getUUID($dn) { + if($this->detectUuidAttribute($dn)) { + $uuid = $this->readAttribute($dn, $this->connection->ldapUuidAttribute); + if(!is_array($uuid) && $this->connection->ldapOverrideUuidAttribute) { + $this->detectUuidAttribute($dn, true); + $uuid = $this->readAttribute($dn, $this->connection->ldapUuidAttribute); + } + if(is_array($uuid) && isset($uuid[0]) && !empty($uuid[0])) { + $uuid = $uuid[0]; + } else { + $uuid = false; + } + } else { + $uuid = false; + } + return $uuid; + } +}
\ No newline at end of file diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php new file mode 100644 index 00000000000..dc160a1642d --- /dev/null +++ b/apps/user_ldap/lib/connection.php @@ -0,0 +1,358 @@ +<?php + +/** + * ownCloud – LDAP Access + * + * @author Arthur Schiwon + * @copyright 2012 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\user_ldap\lib; + +class Connection { + private $ldapConnectionRes = null; + private $configID; + private $configured = false; + + //cache handler + protected $cache; + + //settings + protected $config = array( + 'ldapHost' => null, + 'ldapPort' => null, + 'ldapBase' => null, + 'ldapBaseUsers' => null, + 'ldapBaseGroups' => null, + 'ldapAgentName' => null, + 'ldapAgentPassword' => null, + 'ldapTLS' => null, + 'ldapNoCase' => null, + 'turnOffCertCheck' => null, + 'ldapIgnoreNamingRules' => null, + 'ldapUserDisplayName' => null, + 'ldapUserFilter' => null, + 'ldapGroupFilter' => null, + 'ldapGroupDisplayName' => null, + 'ldapLoginFilter' => null, + 'ldapQuotaAttribute' => null, + 'ldapQuotaDefault' => null, + 'ldapEmailAttribute' => null, + 'ldapCacheTTL' => null, + 'ldapUuidAttribute' => null, + 'ldapOverrideUuidAttribute' => null, + ); + + public function __construct($configID = 'user_ldap') { + $this->configID = $configID; + $this->cache = \OC_Cache::getGlobalCache(); + } + + public function __destruct() { + @ldap_unbind($this->ldapConnectionRes); + } + + public function __get($name) { + if(!$this->configured) { + $this->readConfiguration(); + } + + if(isset($this->config[$name])) { + return $this->config[$name]; + } + } + + public function __set($name, $value) { + $changed = false; + //omly few options are writable + if($name == 'ldapUuidAttribute') { + \OCP\Util::writeLog('user_ldap', 'Set config ldapUuidAttribute to '.$value, \OCP\Util::DEBUG); + $this->config[$name] = $value; + if(!empty($this->configID)) { + \OCP\Config::getAppValue($this->configID, 'ldap_uuid_attribute', $value); + } + $changed = true; + } + if($changed) { + $this->validateConfiguration(); + } + } + + /** + * @brief initializes the LDAP backend + * @param $force read the config settings no matter what + * + * initializes the LDAP backend + */ + public function init($force = false) { + $this->readConfiguration($force); + $this->establishConnection(); + } + + /** + * Returns the LDAP handler + */ + public function getConnectionResource() { + if(!$this->ldapConnectionRes) { + $this->init(); + } else if(!is_resource($this->ldapConnectionRes)) { + $this->ldapConnectionRes = null; + $this->establishConnection(); + } + if(is_null($this->ldapConnectionRes)) { + \OCP\Util::writeLog('user_ldap', 'Connection could not be established', \OCP\Util::ERROR); + } + return $this->ldapConnectionRes; + } + + private function getCacheKey($key) { + $prefix = 'LDAP-'.$this->configID.'-'; + if(is_null($key)) { + return $prefix; + } + return $prefix.md5($key); + } + + public function getFromCache($key) { + if(!$this->configured) { + $this->readConfiguration(); + } + if(!$this->config['ldapCacheTTL']) { + return null; + } + if(!$this->isCached($key)) { + return null; + + } + $key = $this->getCacheKey($key); + + return unserialize(base64_decode($this->cache->get($key))); + } + + public function isCached($key) { + if(!$this->configured) { + $this->readConfiguration(); + } + if(!$this->config['ldapCacheTTL']) { + return false; + } + $key = $this->getCacheKey($key); + return $this->cache->hasKey($key); + } + + public function writeToCache($key, $value) { + if(!$this->configured) { + $this->readConfiguration(); + } + if(!$this->config['ldapCacheTTL']) { + return null; + } + $key = $this->getCacheKey($key); + $value = base64_encode(serialize($value)); + $this->cache->set($key, $value, $this->config['ldapCacheTTL']); + } + + public function clearCache() { + $this->cache->clear($this->getCacheKey(null)); + } + + /** + * Caches the general LDAP configuration. + */ + private function readConfiguration($force = false) { + \OCP\Util::writeLog('user_ldap','Checking conf state: isConfigured? '.print_r($this->configured, true).' isForce? '.print_r($force, true).' configID? '.print_r($this->configID, true), \OCP\Util::DEBUG); + if((!$this->configured || $force) && !is_null($this->configID)) { + \OCP\Util::writeLog('user_ldap','Reading the configuration', \OCP\Util::DEBUG); + $this->config['ldapHost'] = \OCP\Config::getAppValue($this->configID, 'ldap_host', ''); + $this->config['ldapPort'] = \OCP\Config::getAppValue($this->configID, 'ldap_port', 389); + $this->config['ldapAgentName'] = \OCP\Config::getAppValue($this->configID, 'ldap_dn',''); + $this->config['ldapAgentPassword'] = base64_decode(\OCP\Config::getAppValue($this->configID, 'ldap_agent_password','')); + $this->config['ldapBase'] = \OCP\Config::getAppValue($this->configID, 'ldap_base', ''); + $this->config['ldapBaseUsers'] = \OCP\Config::getAppValue($this->configID, 'ldap_base_users',$this->config['ldapBase']); + $this->config['ldapBaseGroups'] = \OCP\Config::getAppValue($this->configID, 'ldap_base_groups', $this->config['ldapBase']); + $this->config['ldapTLS'] = \OCP\Config::getAppValue($this->configID, 'ldap_tls',0); + $this->config['ldapNoCase'] = \OCP\Config::getAppValue($this->configID, 'ldap_nocase', 0); + $this->config['turnOffCertCheck'] = \OCP\Config::getAppValue($this->configID, 'ldap_turn_off_cert_check', 0); + $this->config['ldapUserDisplayName'] = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_display_name', 'uid'), 'UTF-8'); + $this->config['ldapUserFilter'] = \OCP\Config::getAppValue($this->configID, 'ldap_userlist_filter','objectClass=person'); + $this->config['ldapGroupFilter'] = \OCP\Config::getAppValue($this->configID, 'ldap_group_filter','(objectClass=posixGroup)'); + $this->config['ldapLoginFilter'] = \OCP\Config::getAppValue($this->configID, 'ldap_login_filter', '(uid=%uid)'); + $this->config['ldapGroupDisplayName'] = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_group_display_name', 'uid'), 'UTF-8'); + $this->config['ldapQuotaAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_quota_attr', ''); + $this->config['ldapQuotaDefault'] = \OCP\Config::getAppValue($this->configID, 'ldap_quota_def', ''); + $this->config['ldapEmailAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_email_attr', ''); + $this->config['ldapGroupMemberAssocAttr'] = \OCP\Config::getAppValue($this->configID, 'ldap_group_member_assoc_attribute', 'uniqueMember'); + $this->config['ldapIgnoreNamingRules'] = \OCP\Config::getSystemValue('ldapIgnoreNamingRules', false); + $this->config['ldapCacheTTL'] = \OCP\Config::getAppValue($this->configID, 'ldap_cache_ttl', 10*60); + $this->config['ldapUuidAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_uuid_attribute', 'auto'); + $this->config['ldapOverrideUuidAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_override_uuid_attribute', 0); + + $this->configured = $this->validateConfiguration(); + } + } + + /** + * @brief set LDAP configuration with values delivered by an array, not read from configuration + * @param $config array that holds the config parameters in an associated array + * @param &$setParameters optional; array where the set fields will be given to + * @return true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters + */ + public function setConfiguration($config, &$setParameters = null) { + if(!is_array($config)) { + return false; + } + + $params = array('ldap_host'=>'ldapHost', 'ldap_port'=>'ldapPort', 'ldap_dn'=>'ldapAgentName', 'ldap_agent_password'=>'ldapAgentPassword', 'ldap_base'=>'ldapBase', 'ldap_base_users'=>'ldapBaseUsers', 'ldap_base_groups'=>'ldapBaseGroups', 'ldap_userlist_filter'=>'ldapUserFilter', 'ldap_login_filter'=>'ldapLoginFilter', 'ldap_group_filter'=>'ldapGroupFilter', 'ldap_display_name'=>'ldapUserDisplayName', 'ldap_group_display_name'=>'ldapGroupDisplayName', + + 'ldap_tls'=>'ldapTLS', 'ldap_nocase'=>'ldapNoCase', 'ldap_quota_def'=>'ldapQuotaDefault', 'ldap_quota_attr'=>'ldapQuotaAttribute', 'ldap_email_attr'=>'ldapEmailAttribute', 'ldap_group_member_assoc_attribute'=>'ldapGroupMemberAssocAttr', 'ldap_cache_ttl'=>'ldapCacheTTL'); + + foreach($config as $parameter => $value) { + if(isset($this->config[$parameter])) { + $this->config[$parameter] = $value; + if(is_array($setParameters)) { + $setParameters[] = $parameter; + } + } else if(isset($params[$parameter])) { + $this->config[$params[$parameter]] = $value; + if(is_array($setParameters)) { + $setParameters[] = $params[$parameter]; + } + } + } + + $this->configured = $this->validateConfiguration(); + + return $this->configured; + } + + /** + * @brief Validates the user specified configuration + * @returns true if configuration seems OK, false otherwise + */ + private function validateConfiguration() { + //first step: "soft" checks: settings that are not really necessary, but advisable. If left empty, give an info message + if(empty($this->config['ldapBaseUsers'])) { + \OCP\Util::writeLog('user_ldap', 'Base tree for Users is empty, using Base DN', \OCP\Util::INFO); + $this->config['ldapBaseUsers'] = $this->config['ldapBase']; + } + if(empty($this->config['ldapBaseGroups'])) { + \OCP\Util::writeLog('user_ldap', 'Base tree for Groups is empty, using Base DN', \OCP\Util::INFO); + $this->config['ldapBaseGroups'] = $this->config['ldapBase']; + } + if(empty($this->config['ldapGroupFilter']) && empty($this->config['ldapGroupMemberAssocAttr'])) { + \OCP\Util::writeLog('user_ldap', 'No group filter is specified, LDAP group feature will not be used.', \OCP\Util::INFO); + } + if(!in_array($this->config['ldapUuidAttribute'], array('auto','entryuuid', 'nsuniqueid', 'objectguid'))) { + \OCP\Config::setAppValue($this->configID, 'ldap_uuid_attribute', 'auto'); + \OCP\Util::writeLog('user_ldap', 'Illegal value for the UUID Attribute, reset to autodetect.', \OCP\Util::INFO); + } + + + //second step: critical checks. If left empty or filled wrong, set as unconfigured and give a warning. + $configurationOK = true; + if(empty($this->config['ldapHost'])) { + \OCP\Util::writeLog('user_ldap', 'No LDAP host given, won`t connect.', \OCP\Util::WARN); + $configurationOK = false; + } + if(empty($this->config['ldapPort'])) { + \OCP\Util::writeLog('user_ldap', 'No LDAP Port given, won`t connect.', \OCP\Util::WARN); + $configurationOK = false; + } + if((empty($this->config['ldapAgentName']) && !empty($this->config['ldapAgentPassword'])) + || (!empty($this->config['ldapAgentName']) && empty($this->config['ldapAgentPassword']))) { + \OCP\Util::writeLog('user_ldap', 'Either no password given for the user agent or a password is given, but no LDAP agent; won`t connect.', \OCP\Util::WARN); + $configurationOK = false; + } + //TODO: check if ldapAgentName is in DN form + if(empty($this->config['ldapBase']) && (empty($this->config['ldapBaseUsers']) && empty($this->config['ldapBaseGroups']))) { + \OCP\Util::writeLog('user_ldap', 'No Base DN given, won`t connect.', \OCP\Util::WARN); + $configurationOK = false; + } + if(empty($this->config['ldapUserDisplayName'])) { + \OCP\Util::writeLog('user_ldap', 'No user display name attribute specified, won`t connect.', \OCP\Util::WARN); + $configurationOK = false; + } + if(empty($this->config['ldapGroupDisplayName'])) { + \OCP\Util::writeLog('user_ldap', 'No group display name attribute specified, won`t connect.', \OCP\Util::WARN); + $configurationOK = false; + } + if(empty($this->config['ldapLoginFilter'])) { + \OCP\Util::writeLog('user_ldap', 'No login filter specified, won`t connect.', \OCP\Util::WARN); + $configurationOK = false; + } + if(mb_strpos($this->config['ldapLoginFilter'], '%uid', 0, 'UTF-8') === false) { + \OCP\Util::writeLog('user_ldap', 'Login filter does not contain %uid place holder, won`t connect.', \OCP\Util::WARN); + \OCP\Util::writeLog('user_ldap', 'Login filter was ' . $this->config['ldapLoginFilter'], \OCP\Util::DEBUG); + $configurationOK = false; + } + + return $configurationOK; + } + + /** + * Connects and Binds to LDAP + */ + private function establishConnection() { + static $phpLDAPinstalled = true; + if(!$phpLDAPinstalled) { + return false; + } + if(!$this->configured) { + \OCP\Util::writeLog('user_ldap', 'Configuration is invalid, cannot connect', \OCP\Util::WARN); + return false; + } + if(!$this->ldapConnectionRes) { + if(!function_exists('ldap_connect')) { + $phpLDAPinstalled = false; + \OCP\Util::writeLog('user_ldap', 'function ldap_connect is not available. Make sure that the PHP ldap module is installed.', \OCP\Util::ERROR); + + return false; + } + if($this->config['turnOffCertCheck']) { + if(putenv('LDAPTLS_REQCERT=never')) { + \OCP\Util::writeLog('user_ldap', 'Turned off SSL certificate validation successfully.', \OCP\Util::WARN); + } else { + \OCP\Util::writeLog('user_ldap', 'Could not turn off SSL certificate validation.', \OCP\Util::WARN); + } + } + $this->ldapConnectionRes = ldap_connect($this->config['ldapHost'], $this->config['ldapPort']); + if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) { + if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) { + if($this->config['ldapTLS']) { + ldap_start_tls($this->ldapConnectionRes); + } + } + } + + return $this->bind(); + } + } + + /** + * Binds to LDAP + */ + public function bind() { + $ldapLogin = @ldap_bind($this->getConnectionResource(), $this->config['ldapAgentName'], $this->config['ldapAgentPassword']); + if(!$ldapLogin) { + \OCP\Util::writeLog('user_ldap', 'Bind failed: ' . ldap_errno($this->ldapConnectionRes) . ': ' . ldap_error($this->ldapConnectionRes), \OCP\Util::ERROR); + $this->ldapConnectionRes = null; + return false; + } + return true; + } + +}
\ No newline at end of file diff --git a/apps/user_ldap/lib/jobs.php b/apps/user_ldap/lib/jobs.php new file mode 100644 index 00000000000..d478731b84c --- /dev/null +++ b/apps/user_ldap/lib/jobs.php @@ -0,0 +1,157 @@ +<?php + +/** + * ownCloud – LDAP Background Jobs + * + * @author Arthur Schiwon + * @copyright 2012 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\user_ldap\lib; + +class Jobs { + static private $groupsFromDB; + + static private $groupBE; + static private $connector; + + static public function updateGroups() { + \OCP\Util::writeLog('user_ldap', 'Run background job "updateGroups"', \OCP\Util::DEBUG); + $lastUpdate = \OCP\Config::getAppValue('user_ldap', 'bgjUpdateGroupsLastRun', 0); + if((time() - $lastUpdate) < self::getRefreshInterval()) { + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – last run too fresh, aborting.', \OCP\Util::DEBUG); + //komm runter Werner die Maurer geben ein aus + return; + } + + $knownGroups = array_keys(self::getKnownGroups()); + $actualGroups = self::getGroupBE()->getGroups(); + + if(empty($actualGroups) && empty($knownGroups)) { + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – groups do not seem to be configured properly, aborting.', \OCP\Util::INFO); + \OCP\setAppValue('user_ldap', 'bgjUpdateGroupsLastRun', time()); + return; + } + + self::handleKnownGroups(array_intersect($actualGroups, $knownGroups)); + self::handleCreatedGroups(array_diff($actualGroups, $knownGroups)); + self::handleRemovedGroups(array_diff($knownGroups, $actualGroups)); + + \OCP\Config::setAppValue('user_ldap', 'bgjUpdateGroupsLastRun', time()); + + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – Finished.', \OCP\Util::DEBUG); + } + + static private function getRefreshInterval() { + //defaults to every hour + return \OCP\Config::getAppValue('user_ldap', 'bgjRefreshInterval', 3600); + } + + static private function handleKnownGroups($groups) { + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – Dealing with known Groups.', \OCP\Util::DEBUG); + $query = \OCP\DB::prepare(' + UPDATE *PREFIX*ldap_group_members + SET owncloudusers = ? + WHERE owncloudname = ? + '); + foreach($groups as $group) { + //we assume, that self::$groupsFromDB has been retrieved already + $knownUsers = unserialize(self::$groupsFromDB[$group]['owncloudusers']); + $actualUsers = self::getGroupBE()->usersInGroup($group); + $hasChanged = false; + foreach(array_diff($knownUsers, $actualUsers) as $removedUser) { + \OCP\Util::emitHook('OC_User', 'post_removeFromGroup', array('uid' => $removedUser, 'gid' => $group)); + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – "'.$removedUser.'" removed from "'.$group.'".', \OCP\Util::INFO); + $hasChanged = true; + } + foreach(array_diff($actualUsers, $knownUsers) as $addedUser) { + \OCP\Util::emitHook('OC_User', 'post_addFromGroup', array('uid' => $addedUser, 'gid' => $group)); + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – "'.$addedUser.'" added to "'.$group.'".', \OCP\Util::INFO); + $hasChanged = true; + } + if($hasChanged) { + $query->execute(array(serialize($actualUsers), $group)); + } + } + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – FINISHED dealing with known Groups.', \OCP\Util::DEBUG); + } + + static private function handleCreatedGroups($createdGroups) { + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – dealing with created Groups.', \OCP\Util::DEBUG); + $query = \OCP\DB::prepare(' + INSERT + INTO *PREFIX*ldap_group_members (owncloudname, owncloudusers) + VALUES (?, ?) + '); + foreach($createdGroups as $createdGroup) { + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – new group "'.$createdGroup.'" found.', \OCP\Util::INFO); + $users = serialize(self::getGroupBE()->usersInGroup($createdGroup)); + $query->execute(array($createdGroup, $users)); + } + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – FINISHED dealing with created Groups.', \OCP\Util::DEBUG); + } + + static private function handleRemovedGroups($removedGroups) { + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – dealing with removed groups.', \OCP\Util::DEBUG); + $query = \OCP\DB::prepare(' + DELETE + FROM *PREFIX*ldap_group_members + WHERE owncloudname = ? + '); + foreach($removedGroups as $removedGroup) { + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – group "'.$createdGroup.'" was removed.', \OCP\Util::INFO); + $query->execute(array($removedGroup)); + } + \OCP\Util::writeLog('user_ldap', 'bgJ "updateGroups" – FINISHED dealing with removed groups.', \OCP\Util::DEBUG); + } + + static private function getConnector() { + if(!is_null(self::$connector)) { + return self::$connector; + } + self::$connector = new \OCA\user_ldap\lib\Connection('user_ldap'); + return self::$connector; + } + + static private function getGroupBE() { + if(!is_null(self::$groupBE)) { + return self::$groupBE; + } + self::getConnector(); + self::$groupBE = new \OCA\user_ldap\GROUP_LDAP(); + self::$groupBE->setConnector(self::$connector); + + return self::$groupBE; + } + + static private function getKnownGroups() { + if(is_array(self::$groupsFromDB)) { + return self::$groupsFromDB; + } + $query = \OCP\DB::prepare(' + SELECT owncloudname, owncloudusers + FROM *PREFIX*ldap_group_members + '); + $result = $query->execute()->fetchAll(); + self::$groupsFromDB = array(); + foreach($result as $dataset) { + self::$groupsFromDB[$dataset['owncloudname']] = $dataset; + } + + return self::$groupsFromDB; + } +}
\ No newline at end of file diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib_ldap.php deleted file mode 100644 index 70b4664542a..00000000000 --- a/apps/user_ldap/lib_ldap.php +++ /dev/null @@ -1,765 +0,0 @@ -<?php - -/** - * ownCloud – LDAP lib - * - * @author Arthur Schiwon - * @copyright 2012 Arthur Schiwon blizzz@owncloud.com - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - */ - -define('LDAP_GROUP_MEMBER_ASSOC_ATTR','uniqueMember'); -define('LDAP_GROUP_DISPLAY_NAME_ATTR','cn'); - -//needed to unbind, because we use OC_LDAP only statically -class OC_LDAP_DESTRUCTOR { - public function __destruct() { - OC_LDAP::destruct(); - } -} - -class OC_LDAP { - static protected $ldapConnectionRes = false; - static protected $configured = false; - - //cached settings - static protected $ldapHost; - static protected $ldapPort; - static protected $ldapBase; - static protected $ldapBaseUsers; - static protected $ldapBaseGroups; - static protected $ldapAgentName; - static protected $ldapAgentPassword; - static protected $ldapTLS; - static protected $ldapNoCase; - static protected $ldapIgnoreNamingRules; - // user and group settings, that are needed in both backends - static protected $ldapUserDisplayName; - static protected $ldapUserFilter; - static protected $ldapGroupDisplayName; - static protected $ldapLoginFilter; - - static protected $__d; - - /** - * @brief initializes the LDAP backend - * @param $force read the config settings no matter what - * - * initializes the LDAP backend - */ - static public function init($force = false) { - if(is_null(self::$__d)) { - self::$__d = new OC_LDAP_DESTRUCTOR(); - } - self::readConfiguration($force); - self::establishConnection(); - } - - static public function destruct() { - @ldap_unbind(self::$ldapConnectionRes); - } - - /** - * @brief returns a read-only configuration value - * @param $key the name of the configuration value - * @returns the value on success, otherwise null - * - * returns a read-only configuration values - * - * we cannot work with getters, because it is a static class - */ - static public function conf($key) { - if(!self::$configured) { - self::init(); - } - - $availableProperties = array( - 'ldapUserDisplayName', - 'ldapGroupDisplayName', - 'ldapLoginFilter' - ); - - if(in_array($key, $availableProperties)) { - return self::$$key; - } - - return null; - } - - /** - * gives back the database table for the query - */ - static private function getMapTable($isUser) { - if($isUser) { - return '*PREFIX*ldap_user_mapping'; - } else { - return '*PREFIX*ldap_group_mapping'; - } - } - - /** - * @brief returns the LDAP DN for the given internal ownCloud name of the group - * @param $name the ownCloud name in question - * @returns string with the LDAP DN on success, otherwise false - * - * returns the LDAP DN for the given internal ownCloud name of the group - */ - static public function groupname2dn($name) { - return self::ocname2dn($name, false); - } - - /** - * @brief returns the LDAP DN for the given internal ownCloud name of the user - * @param $name the ownCloud name in question - * @returns string with the LDAP DN on success, otherwise false - * - * returns the LDAP DN for the given internal ownCloud name of the user - */ - static public function username2dn($name) { - $dn = self::ocname2dn($name, true); - if($dn) { - return $dn; - } else { - //fallback: user is not mapped - self::init(); - $filter = self::combineFilterWithAnd(array( - self::$ldapUserFilter, - self::$ldapUserDisplayName . '=' . $name, - )); - $result = self::searchUsers($filter, 'dn'); - if(isset($result[0]['dn'])) { - self::mapUser($result[0], $name); - return $result[0]; - } - } - - return false; - } - - static private function ocname2dn($name, $isUser) { - $table = self::getMapTable($isUser); - - $query = OCP\DB::prepare(' - SELECT `ldap_dn` - FROM `'.$table.'` - WHERE `owncloud_name` = ? - '); - - $record = $query->execute(array($name))->fetchOne(); - return $record; - } - - /** - * @brief returns the internal ownCloud name for the given LDAP DN of the group - * @param $dn the dn of the group object - * @param $ldapname optional, the display name of the object - * @returns string with with the name to use in ownCloud, false on DN outside of search DN - * - * returns the internal ownCloud name for the given LDAP DN of the group, false on DN outside of search DN or failure - */ - static public function dn2groupname($dn, $ldapname = null) { - if(strripos($dn, self::$ldapBaseGroups) !== (strlen($dn)-strlen(self::$ldapBaseGroups))) { - return false; - } - return self::dn2ocname($dn, $ldapname, false); - } - - /** - * @brief returns the internal ownCloud name for the given LDAP DN of the user - * @param $dn the dn of the user object - * @param $ldapname optional, the display name of the object - * @returns string with with the name to use in ownCloud - * - * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN or failure - */ - static public function dn2username($dn, $ldapname = null) { - if(strripos($dn, self::$ldapBaseUsers) !== (strlen($dn)-strlen(self::$ldapBaseUsers))) { - return false; - } - return self::dn2ocname($dn, $ldapname, true); - } - - static public function dn2ocname($dn, $ldapname = null, $isUser = true) { - $dn = self::sanitizeDN($dn); - $table = self::getMapTable($isUser); - if($isUser) { - $nameAttribute = self::conf('ldapUserDisplayName'); - } else { - $nameAttribute = self::conf('ldapGroupDisplayName'); - } - - $query = OCP\DB::prepare(' - SELECT `owncloud_name` - FROM `'.$table.'` - WHERE `ldap_dn` = ? - '); - - $component = $query->execute(array($dn))->fetchOne(); - if($component) { - return $component; - } - - if(is_null($ldapname)) { - $ldapname = self::readAttribute($dn, $nameAttribute); - //we do not accept empty usernames - if(!isset($ldapname[0]) && empty($ldapname[0])) { - OCP\Util::writeLog('user_ldap', 'No or empty name for '.$dn.'.', OCP\Util::INFO); - return false; - } - $ldapname = $ldapname[0]; - } - $ldapname = self::sanitizeUsername($ldapname); - - //a new user/group! Then let's try to add it. We're shooting into the blue with the user/group name, assuming that in most cases there will not be a conflict. Otherwise an error will occur and we will continue with our second shot. - if(self::mapComponent($dn, $ldapname, $isUser)) { - return $ldapname; - } - - //doh! There is a conflict. We need to distinguish between users/groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this object is located. - $oc_name = self::alternateOwnCloudName($ldapname, $dn); - if(self::mapComponent($dn, $oc_name, $isUser)) { - return $oc_name; - } - - //if everything else did not help.. - OCP\Util::writeLog('user_ldap', 'Could not create unique ownCloud name for '.$dn.'.', OCP\Util::INFO); - } - - /** - * @brief gives back the user names as they are used ownClod internally - * @param $ldapGroups an array with the ldap Users result in style of array ( array ('dn' => foo, 'uid' => bar), ... ) - * @returns an array with the user names to use in ownCloud - * - * gives back the user names as they are used ownClod internally - */ - static public function ownCloudUserNames($ldapUsers) { - return self::ldap2ownCloudNames($ldapUsers, true); - } - - /** - * @brief gives back the group names as they are used ownClod internally - * @param $ldapGroups an array with the ldap Groups result in style of array ( array ('dn' => foo, 'cn' => bar), ... ) - * @returns an array with the group names to use in ownCloud - * - * gives back the group names as they are used ownClod internally - */ - static public function ownCloudGroupNames($ldapGroups) { - return self::ldap2ownCloudNames($ldapGroups, false); - } - - static private function ldap2ownCloudNames($ldapObjects, $isUsers) { - if($isUsers) { - $knownObjects = self::mappedUsers(); - $nameAttribute = self::conf('ldapUserDisplayName'); - } else { - $knownObjects = self::mappedGroups(); - $nameAttribute = self::conf('ldapGroupDisplayName'); - } - $ownCloudNames = array(); - - foreach($ldapObjects as $ldapObject) { - $key = self::recursiveArraySearch($knownObjects, $ldapObject['dn']); - - //everything is fine when we know the group - if($key !== false) { - $ownCloudNames[] = $knownObjects[$key]['owncloud_name']; - continue; - } - - //we do not take empty usernames - if(!isset($ldapObject[$nameAttribute]) || empty($ldapObject[$nameAttribute])) { - OCP\Util::writeLog('user_ldap', 'No or empty name for '.$ldapObject['dn'].', skipping.', OCP\Util::INFO); - continue; - } - - //a new group! Then let's try to add it. We're shooting into the blue with the group name, assuming that in most cases there will not be a conflict. But first make sure, that the display name contains only allowed characters. - $ocname = self::sanitizeUsername($ldapObject[$nameAttribute]); - if(self::mapComponent($ldapObject['dn'], $ocname, $isUsers)) { - $ownCloudNames[] = $ocname; - continue; - } - - //doh! There is a conflict. We need to distinguish between groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this entry is located. - $ocname = self::alternateOwnCloudName($ocname, $ldapObject['dn']); - if(self::mapComponent($ldapObject['dn'], $ocname, $isUsers)) { - $ownCloudNames[] = $ocname; - continue; - } - - //if everything else did not help.. - OCP\Util::writeLog('user_ldap', 'Could not create unique ownCloud name for '.$ldapObject['dn'].', skipping.', OCP\Util::INFO); - } - return $ownCloudNames; - } - - /** - * @brief creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object - * @param $name the display name of the object - * @param $dn the dn of the object - * @returns string with with the name to use in ownCloud - * - * creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object - */ - static private function alternateOwnCloudName($name, $dn) { - $ufn = ldap_dn2ufn($dn); - $name = $name . '@' . trim(substr_replace($ufn, '', 0, strpos($ufn, ','))); - $name = self::sanitizeUsername($name); - return $name; - } - - /** - * @brief retrieves all known groups from the mappings table - * @returns array with the results - * - * retrieves all known groups from the mappings table - */ - static private function mappedGroups() { - return self::mappedComponents(false); - } - - /** - * @brief retrieves all known users from the mappings table - * @returns array with the results - * - * retrieves all known users from the mappings table - */ - static private function mappedUsers() { - return self::mappedComponents(true); - } - - static private function mappedComponents($isUsers) { - $table = self::getMapTable($isUsers); - - $query = OCP\DB::prepare(' - SELECT `ldap_dn`, `owncloud_name` - FROM `'. $table .'`' - ); - - return $query->execute()->fetchAll(); - } - - /** - * @brief inserts a new group into the mappings table - * @param $dn the record in question - * @param $ocname the name to use in ownCloud - * @returns true on success, false otherwise - * - * inserts a new group into the mappings table - */ - static private function mapGroup($dn, $ocname) { - return self::mapComponent($dn, $ocname, false); - } - - /** - * @brief inserts a new user into the mappings table - * @param $dn the record in question - * @param $ocname the name to use in ownCloud - * @returns true on success, false otherwise - * - * inserts a new user into the mappings table - */ - static private function mapUser($dn, $ocname) { - return self::mapComponent($dn, $ocname, true); - } - - /** - * @brief inserts a new user or group into the mappings table - * @param $dn the record in question - * @param $ocname the name to use in ownCloud - * @param $isUser is it a user or a group? - * @returns true on success, false otherwise - * - * inserts a new user or group into the mappings table - */ - static private function mapComponent($dn, $ocname, $isUser = true) { - $table = self::getMapTable($isUser); - $dn = self::sanitizeDN($dn); - - $sqlAdjustment = ''; - $dbtype = OCP\Config::getSystemValue('dbtype'); - if($dbtype == 'mysql') { - $sqlAdjustment = 'FROM `dual`'; - } - - $insert = OCP\DB::prepare(' - INSERT INTO `'.$table.'` (`ldap_dn`, `owncloud_name`) - SELECT ?,? - '.$sqlAdjustment.' - WHERE NOT EXISTS ( - SELECT 1 - FROM `'.$table.'` - WHERE `ldap_dn` = ? - OR `owncloud_name` = ? ) - '); - - $res = $insert->execute(array($dn, $ocname, $dn, $ocname)); - - if(OCP\DB::isError($res)) { - return false; - } - - $insRows = $res->numRows(); - - if($insRows == 0) { - return false; - } - - return true; - } - - static public function fetchListOfUsers($filter, $attr) { - return self::fetchList(OC_LDAP::searchUsers($filter, $attr), (count($attr) > 1)); - } - - static public function fetchListOfGroups($filter, $attr) { - return self::fetchList(OC_LDAP::searchGroups($filter, $attr), (count($attr) > 1)); - } - - static private function fetchList($list, $manyAttributes) { - if(is_array($list)) { - if($manyAttributes) { - return $list; - } else { - return array_unique($list, SORT_LOCALE_STRING); - } - } - - //error cause actually, maybe throw an exception in future. - return array(); - } - - /** - * @brief reads a given attribute for an LDAP record identified by a DN - * @param $dn the record in question - * @param $attr the attribute that shall be retrieved - * @returns the values in an array on success, false otherwise - * - * Reads an attribute from an LDAP entry - */ - static public function readAttribute($dn, $attr) { - $cr = self::getConnectionResource(); - if(!is_resource($cr)) { - //LDAP not available - return false; - } - $rr = ldap_read($cr, $dn, 'objectClass=*', array($attr)); - $er = ldap_first_entry($cr, $rr); - //LDAP attributes are not case sensitive - $result = array_change_key_case(ldap_get_attributes($cr, $er)); - $attr = strtolower($attr); - - if(isset($result[$attr]) && $result[$attr]['count'] > 0){ - $values = array(); - for($i=0;$i<$result[$attr]['count'];$i++) { - $values[] = self::resemblesDN($attr) ? self::sanitizeDN($result[$attr][$i]) : $result[$attr][$i]; - } - return $values; - } - return false; - } - - /** - * @brief executes an LDAP search, optimized for Users - * @param $filter the LDAP filter for the search - * @param $attr optional, when a certain attribute shall be filtered out - * @returns array with the search result - * - * Executes an LDAP search - */ - static public function searchUsers($filter, $attr = null) { - self::init(); - return self::search($filter, self::$ldapBaseUsers, $attr); - } - - /** - * @brief executes an LDAP search, optimized for Groups - * @param $filter the LDAP filter for the search - * @param $attr optional, when a certain attribute shall be filtered out - * @returns array with the search result - * - * Executes an LDAP search - */ - static public function searchGroups($filter, $attr = null) { - self::init(); - return self::search($filter, self::$ldapBaseGroups, $attr); - } - - /** - * @brief executes an LDAP search - * @param $filter the LDAP filter for the search - * @param $base the LDAP subtree that shall be searched - * @param $attr optional, when a certain attribute shall be filtered out - * @returns array with the search result - * - * Executes an LDAP search - */ - static private function search($filter, $base, $attr = null) { - if(!is_null($attr) && !is_array($attr)) { - $attr = array(strtolower($attr)); - } - $cr = self::getConnectionResource(); - if(!is_resource($cr)) { - //LDAP not available - return array(); - } - $sr = @ldap_search(self::getConnectionResource(), $base, $filter, $attr); - $findings = @ldap_get_entries(self::getConnectionResource(), $sr ); - // if we're here, probably no connection ressource is returned. - // to make ownCloud behave nicely, we simply give back an empty array. - if(is_null($findings)) { - return array(); - } - - if(!is_null($attr)) { - $selection = array(); - $multiarray = false; - if(count($attr) > 1) { - $multiarray = true; - $i = 0; - } - foreach($findings as $item) { - if(!is_array($item)) { - continue; - } - $item = array_change_key_case($item); - - if($multiarray) { - foreach($attr as $key) { - $key = strtolower($key); - if(isset($item[$key])) { - if($key != 'dn'){ - $selection[$i][$key] = self::resemblesDN($key) ? self::sanitizeDN($item[$key][0]) : $item[$key][0]; - } else { - $selection[$i][$key] = self::sanitizeDN($item[$key]); - } - } - - } - $i++; - } else { - //tribute to case insensitivity - $key = strtolower($attr[0]); - - if(isset($item[$key])) { - if(self::resemblesDN($key)) { - $selection[] = self::sanitizeDN($item[$key]); - } else { - $selection[] = $item[$key]; - } - } - } - - } - return $selection; - } - - return $findings; - } - - static private function resemblesDN($attr) { - $resemblingAttributes = array( - 'dn', - 'uniquemember', - 'member' - ); - return in_array($attr, $resemblingAttributes); - } - - static private function sanitizeDN($dn) { - //OID sometimes gives back DNs with whitespace after the comma a la "uid=foo, cn=bar, dn=..." We need to tackle this! - $dn = preg_replace('/([^\\\]),(\s+)/','\1,',$dn); - - //make comparisons and everything work - $dn = strtolower($dn); - - return $dn; - } - - static private function sanitizeUsername($name) { - if(self::$ldapIgnoreNamingRules) { - return $name; - } - - //REPLACEMENTS - $name = str_replace(' ', '_', $name); - - //every remaining unallowed characters will be removed - $name = preg_replace('/[^a-zA-Z0-9_.@-]/', '', $name); - - return $name; - } - - /** - * @brief combines the input filters with AND - * @param $filters array, the filters to connect - * @returns the combined filter - * - * Combines Filter arguments with AND - */ - static public function combineFilterWithAnd($filters) { - return self::combineFilter($filters,'&'); - } - - /** - * @brief combines the input filters with AND - * @param $filters array, the filters to connect - * @returns the combined filter - * - * Combines Filter arguments with AND - */ - static public function combineFilterWithOr($filters) { - return self::combineFilter($filters,'|'); - } - - /** - * @brief combines the input filters with given operator - * @param $filters array, the filters to connect - * @param $operator either & or | - * @returns the combined filter - * - * Combines Filter arguments with AND - */ - static private function combineFilter($filters, $operator) { - $combinedFilter = '('.$operator; - foreach($filters as $filter) { - if($filter[0] != '(') { - $filter = '('.$filter.')'; - } - $combinedFilter.=$filter; - } - $combinedFilter.=')'; - return $combinedFilter; - } - - /** - * Returns the LDAP handler - */ - static private function getConnectionResource() { - if(!self::$ldapConnectionRes) { - self::init(); - } - if(is_null(self::$ldapConnectionRes)) { - OCP\Util::writeLog('ldap', 'Connection could not be established', OCP\Util::INFO); - } - return self::$ldapConnectionRes; - } - - /** - * Caches the general LDAP configuration. - */ - static private function readConfiguration($force = false) { - if(!self::$configured || $force) { - self::$ldapHost = OCP\Config::getAppValue('user_ldap', 'ldap_host', ''); - self::$ldapPort = OCP\Config::getAppValue('user_ldap', 'ldap_port', 389); - self::$ldapAgentName = OCP\Config::getAppValue('user_ldap', 'ldap_dn',''); - self::$ldapAgentPassword = base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password','')); - self::$ldapBase = self::sanitizeDN(OCP\Config::getAppValue('user_ldap', 'ldap_base', '')); - self::$ldapBaseUsers = self::sanitizeDN(OCP\Config::getAppValue('user_ldap', 'ldap_base_users',self::$ldapBase)); - self::$ldapBaseGroups = self::sanitizeDN(OCP\Config::getAppValue('user_ldap', 'ldap_base_groups', self::$ldapBase)); - self::$ldapTLS = OCP\Config::getAppValue('user_ldap', 'ldap_tls',0); - self::$ldapNoCase = OCP\Config::getAppValue('user_ldap', 'ldap_nocase', 0); - self::$ldapUserDisplayName = strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_display_name', 'uid')); - self::$ldapUserFilter = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter','objectClass=person'); - self::$ldapLoginFilter = OCP\Config::getAppValue('user_ldap', 'ldap_login_filter', '(uid=%uid)'); - self::$ldapGroupDisplayName = strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR)); - self::$ldapIgnoreNamingRules = OCP\Config::getSystemValue('ldapIgnoreNamingRules', false); - - if(empty(self::$ldapBaseUsers)) { - OCP\Util::writeLog('ldap', 'Base for Users is empty, using Base DN', OCP\Util::INFO); - self::$ldapBaseUsers = self::$ldapBase; - } - if(empty(self::$ldapBaseGroups)) { - OCP\Util::writeLog('ldap', 'Base for Groups is empty, using Base DN', OCP\Util::INFO); - self::$ldapBaseGroups = self::$ldapBase; - } - - if( - !empty(self::$ldapHost) - && !empty(self::$ldapPort) - && ( - (!empty(self::$ldapAgentName) && !empty(self::$ldapAgentPassword)) - || ( empty(self::$ldapAgentName) && empty(self::$ldapAgentPassword)) - ) - && !empty(self::$ldapBase) - && !empty(self::$ldapUserDisplayName) - ) - { - self::$configured = true; - } - } - } - - /** - * Connects and Binds to LDAP - */ - static private function establishConnection() { - static $phpLDAPinstalled = true; - if(!$phpLDAPinstalled) { - return false; - } - if(!self::$configured) { - OCP\Util::writeLog('ldap', 'Configuration is invalid, cannot connect', OCP\Util::INFO); - return false; - } - if(!self::$ldapConnectionRes) { - //check if php-ldap is installed - if(!function_exists('ldap_connect')) { - $phpLDAPinstalled = false; - OCP\Util::writeLog('user_ldap', 'function ldap_connect is not available. Make sure that the PHP ldap module is installed.', OCP\Util::ERROR); - - return false; - } - self::$ldapConnectionRes = ldap_connect(self::$ldapHost, self::$ldapPort); - if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) { - if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) { - if(self::$ldapTLS) { - ldap_start_tls(self::$ldapConnectionRes); - } - } - } - - $ldapLogin = @ldap_bind(self::$ldapConnectionRes, self::$ldapAgentName, self::$ldapAgentPassword ); - if(!$ldapLogin) { - OCP\Util::writeLog('ldap', 'Bind failed: ' . ldap_errno(self::$ldapConnectionRes) . ': ' . ldap_error(self::$ldapConnectionRes), OCP\Util::ERROR); - return false; - } - } - } - - static public function areCredentialsValid($name, $password) { - return @ldap_bind(self::getConnectionResource(), $name, $password); - } - - /** - * taken from http://www.php.net/manual/en/function.array-search.php#97645 - * TODO: move somewhere, where its better placed since it is not LDAP specific. OC_Helper maybe? - */ - static public function recursiveArraySearch($haystack, $needle, $index = null) { - $aIt = new RecursiveArrayIterator($haystack); - $it = new RecursiveIteratorIterator($aIt); - - while($it->valid()) { - if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) { - return $aIt->key(); - } - - $it->next(); - } - - return false; - } - - } diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php index 0c29e70b5ab..39aa3296265 100644 --- a/apps/user_ldap/settings.php +++ b/apps/user_ldap/settings.php @@ -20,34 +20,43 @@ * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ -$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_agent_password', 'ldap_base', 'ldap_base_users', 'ldap_base_groups', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_group_filter', 'ldap_display_name', 'ldap_group_display_name', 'ldap_tls', 'ldap_nocase', 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr', 'ldap_group_member_assoc_attribute'); +$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_agent_password', 'ldap_base', 'ldap_base_users', 'ldap_base_groups', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_group_filter', 'ldap_display_name', 'ldap_group_display_name', 'ldap_tls', 'ldap_turn_off_cert_check', 'ldap_nocase', 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr', 'ldap_group_member_assoc_attribute', 'ldap_cache_ttl'); OCP\Util::addscript('user_ldap', 'settings'); +OCP\Util::addstyle('user_ldap', 'settings'); if ($_POST) { foreach($params as $param){ if(isset($_POST[$param])){ if('ldap_agent_password' == $param) { OCP\Config::setAppValue('user_ldap', $param, base64_encode($_POST[$param])); + } elseif('ldap_cache_ttl' == $param) { + if(OCP\Config::getAppValue('user_ldap', $param,'') != $_POST[$param]) { + $ldap = new \OCA\user_ldap\lib\Connection('user_ldap'); + $ldap->clearCache(); + OCP\Config::setAppValue('user_ldap', $param, $_POST[$param]); + } } else { OCP\Config::setAppValue('user_ldap', $param, $_POST[$param]); } } elseif('ldap_tls' == $param) { // unchecked checkboxes are not included in the post paramters - OCP\Config::setAppValue('user_ldap', $param, 0); + OCP\Config::setAppValue('user_ldap', $param, 0); } elseif('ldap_nocase' == $param) { OCP\Config::setAppValue('user_ldap', $param, 0); } - + elseif('ldap_turn_off_cert_check' == $param) { + OCP\Config::setAppValue('user_ldap', $param, 0); + } } } // fill template $tmpl = new OCP\Template( 'user_ldap', 'settings'); foreach($params as $param){ - $value = htmlentities(OCP\Config::getAppValue('user_ldap', $param,'')); + $value = OCP\Config::getAppValue('user_ldap', $param,''); $tmpl->assign($param, $value); } @@ -57,5 +66,6 @@ $tmpl->assign( 'ldap_display_name', OCP\Config::getAppValue('user_ldap', 'ldap_d $tmpl->assign( 'ldap_group_display_name', OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', 'cn')); $tmpl->assign( 'ldap_group_member_assoc_attribute', OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember')); $tmpl->assign( 'ldap_agent_password', base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password'))); +$tmpl->assign( 'ldap_cache_ttl', OCP\Config::getAppValue('user_ldap', 'ldap_cache_ttl', '600')); return $tmpl->fetchPage(); diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index 31f453b5a5a..861c9ba6052 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -5,29 +5,30 @@ <li><a href="#ldapSettings-2">Advanced</a></li> </ul> <fieldset id="ldapSettings-1"> - <p><label for="ldap_host"><?php echo $l->t('Host');?><input type="text" id="ldap_host" name="ldap_host" value="<?php echo $_['ldap_host']; ?>"></label> <label for="ldap_base"><?php echo $l->t('Base');?></label><input type="text" id="ldap_base" name="ldap_base" value="<?php echo $_['ldap_base']; ?>" /></p> - <p><label for="ldap_dn"><?php echo $l->t('Name');?></label><input type="text" id="ldap_dn" name="ldap_dn" value="<?php echo $_['ldap_dn']; ?>" /> - <label for="ldap_agent_password"><?php echo $l->t('Password');?></label><input type="password" id="ldap_agent_password" name="ldap_agent_password" value="<?php echo $_['ldap_agent_password']; ?>" /> - <small><?php echo $l->t('Leave both empty for anonymous bind for search, then bind with users credentials.');?></small></p> - <p><label for="ldap_login_filter"><?php echo $l->t('User Login Filter');?></label><input type="text" id="ldap_login_filter" name="ldap_login_filter" value="<?php echo $_['ldap_login_filter']; ?>" /><small><?php echo $l->t('use %%uid placeholder, e.g. uid=%%uid');?></small></p> - <p><label for="ldap_userlist_filter"><?php echo $l->t('User List Filter');?></label><input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" value="<?php echo $_['ldap_userlist_filter']; ?>" /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=person".');?></small></p> - <p><label for="ldap_group_filter"><?php echo $l->t('Group Filter');?></label><input type="text" id="ldap_group_filter" name="ldap_group_filter" value="<?php echo $_['ldap_group_filter']; ?>" /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=posixGroup".');?></small></p> + <p><label for="ldap_host"><?php echo $l->t('Host');?></label><input type="text" id="ldap_host" name="ldap_host" value="<?php echo $_['ldap_host']; ?>" title="<?php echo $l->t('You can omit the protocol, except you require SSL. Then start with ldaps://');?>"></p> + <p><label for="ldap_base"><?php echo $l->t('Base DN');?></label><input type="text" id="ldap_base" name="ldap_base" value="<?php echo $_['ldap_base']; ?>" title="<?php echo $l->t('You can specify Base DN for users and groups in the Advanced tab');?>" /></p> + <p><label for="ldap_dn"><?php echo $l->t('User DN');?></label><input type="text" id="ldap_dn" name="ldap_dn" value="<?php echo $_['ldap_dn']; ?>" title="<?php echo $l->t('The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty.');?>" /></p> + <p><label for="ldap_agent_password"><?php echo $l->t('Password');?></label><input type="password" id="ldap_agent_password" name="ldap_agent_password" value="<?php echo $_['ldap_agent_password']; ?>" title="<?php echo $l->t('For anonymous access, leave DN and Password empty.');?>" /></p> + <p><label for="ldap_login_filter"><?php echo $l->t('User Login Filter');?></label><input type="text" id="ldap_login_filter" name="ldap_login_filter" value="<?php echo $_['ldap_login_filter']; ?>" title="<?php echo $l->t('Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action.');?>" /><br /><small><?php echo $l->t('use %%uid placeholder, e.g. "uid=%%uid"');?></small></p> + <p><label for="ldap_userlist_filter"><?php echo $l->t('User List Filter');?></label><input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" value="<?php echo $_['ldap_userlist_filter']; ?>" title="<?php echo $l->t('Defines the filter to apply, when retrieving users.');?>" /><br /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=person".');?></small></p> + <p><label for="ldap_group_filter"><?php echo $l->t('Group Filter');?></label><input type="text" id="ldap_group_filter" name="ldap_group_filter" value="<?php echo $_['ldap_group_filter']; ?>" title="<?php echo $l->t('Defines the filter to apply, when retrieving groups.');?>" /><br /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=posixGroup".');?></small></p> </fieldset> <fieldset id="ldapSettings-2"> <p><label for="ldap_port"><?php echo $l->t('Port');?></label><input type="text" id="ldap_port" name="ldap_port" value="<?php echo $_['ldap_port']; ?>" /></p> <p><label for="ldap_base_users"><?php echo $l->t('Base User Tree');?></label><input type="text" id="ldap_base_users" name="ldap_base_users" value="<?php echo $_['ldap_base_users']; ?>" /></p> <p><label for="ldap_base_groups"><?php echo $l->t('Base Group Tree');?></label><input type="text" id="ldap_base_groups" name="ldap_base_groups" value="<?php echo $_['ldap_base_groups']; ?>" /></p> <p><label for="ldap_group_member_assoc_attribute"><?php echo $l->t('Group-Member association');?></label><select id="ldap_group_member_assoc_attribute" name="ldap_group_member_assoc_attribute"><option value="uniqueMember"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] == 'uniqueMember')) echo ' selected'; ?>>uniqueMember</option><option value="memberUid"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] == 'memberUid')) echo ' selected'; ?>>memberUid</option><option value="member"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] == 'member')) echo ' selected'; ?>>member (AD)</option></select></p> - <p><input type="checkbox" id="ldap_tls" name="ldap_tls" value="1"<?php if ($_['ldap_tls']) echo ' checked'; ?>><label for="ldap_tls"><?php echo $l->t('Use TLS');?></label></p> - <p><input type="checkbox" id="ldap_nocase" name="ldap_nocase" value="1"<?php if (isset($_['ldap_nocase']) && ($_['ldap_nocase'])) echo ' checked'; ?>><label for="ldap_nocase"><?php echo $l->t('Case insensitve LDAP server (Windows)');?></label></p> - <p><label for="ldap_display_name"><?php echo $l->t('Display Name Field');?></label><input type="text" id="ldap_display_name" name="ldap_display_name" value="<?php echo $_['ldap_display_name']; ?>" /> - <small><?php echo $l->t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?></small></p> - <p><label for="ldap_group_display_name"><?php echo $l->t('Group Display Name Field');?></label><input type="text" id="ldap_group_display_name" name="ldap_group_display_name" value="<?php echo $_['ldap_group_display_name']; ?>" /></p> - <p><label for="ldap_quota_attr">Quota Attribute</label><input type="text" id="ldap_quota_attr" name="ldap_quota_attr" value="<?php echo $_['ldap_quota_attr']; ?>" /> - <label for="ldap_quota_def">Quota Default</label><input type="text" id="ldap_quota_def" name="ldap_quota_def" value="<?php if (isset($_['ldap_quota_def'])) echo $_['ldap_quota_def']; ?>" />bytes</p> - <p><label for="ldap_email_attr">Email Attribute</label><input type="text" id="ldap_email_attr" name="ldap_email_attr" value="<?php echo $_['ldap_email_attr']; ?>" /></p> + <p><label for="ldap_tls"><?php echo $l->t('Use TLS');?></label><input type="checkbox" id="ldap_tls" name="ldap_tls" value="1"<?php if ($_['ldap_tls']) echo ' checked'; ?> title="<?php echo $l->t('Do not use it for SSL connections, it will fail.');?>" /></p> + <p><label for="ldap_nocase"><?php echo $l->t('Case insensitve LDAP server (Windows)');?></label> <input type="checkbox" id="ldap_nocase" name="ldap_nocase" value="1"<?php if (isset($_['ldap_nocase']) && ($_['ldap_nocase'])) echo ' checked'; ?>></p> + <p><label for="ldap_turn_off_cert_check"><?php echo $l->t('Turn off SSL certificate validation.');?></label><input type="checkbox" id="ldap_turn_off_cert_check" name="ldap_turn_off_cert_check" title="<?php echo $l->t('If connection only works with this option, import the LDAP server\'s SSL certificate in your ownCloud server.');?>" value="1"<?php if ($_['ldap_turn_off_cert_check']) echo ' checked'; ?>><br/><small><?php echo $l->t('Not recommended, use for testing only.');?></small></p> + <p><label for="ldap_display_name"><?php echo $l->t('User Display Name Field');?></label><input type="text" id="ldap_display_name" name="ldap_display_name" value="<?php echo $_['ldap_display_name']; ?>" title="<?php echo $l->t('The LDAP attribute to use to generate the user`s ownCloud name.');?>" /></p> + <p><label for="ldap_group_display_name"><?php echo $l->t('Group Display Name Field');?></label><input type="text" id="ldap_group_display_name" name="ldap_group_display_name" value="<?php echo $_['ldap_group_display_name']; ?>" title="<?php echo $l->t('The LDAP attribute to use to generate the groups`s ownCloud name.');?>" /></p> + <p><label for="ldap_quota_attr">Quota Field</label><input type="text" id="ldap_quota_attr" name="ldap_quota_attr" value="<?php echo $_['ldap_quota_attr']; ?>" /> + <label for="ldap_quota_def">Quota Default</label><input type="text" id="ldap_quota_def" name="ldap_quota_def" value="<?php if (isset($_['ldap_quota_def'])) echo $_['ldap_quota_def']; ?>" title="<?php echo $l->t('in bytes');?>" /></p> + <p><label for="ldap_email_attr">Email Field</label><input type="text" id="ldap_email_attr" name="ldap_email_attr" value="<?php echo $_['ldap_email_attr']; ?>" /></p> + <p><label for="ldap_cache_ttl">Cache Time-To-Live</label><input type="text" id="ldap_cache_ttl" name="ldap_cache_ttl" value="<?php echo $_['ldap_cache_ttl']; ?>" title="<?php echo $l->t('in seconds. A change empties the cache.');?>" /></p> </fieldset> - <input type="submit" value="Save" /> <a href="http://owncloud.org/support/ldap-backend/" target="_blank"><img src="<?php echo OCP\Util::imagePath('','actions/info.png'); ?>" style="height:1.75ex" /> <?php echo $l->t('Help');?></a> + <input type="submit" value="Save" /> <button id="ldap_action_test_connection" name="ldap_action_test_connection">Test Configuration</button> <a href="http://owncloud.org/support/ldap-backend/" target="_blank"><img src="<?php echo OCP\Util::imagePath('','actions/info.png'); ?>" style="height:1.75ex" /> <?php echo $l->t('Help');?></a> </div> </form> diff --git a/apps/user_ldap/tests/group_ldap.php b/apps/user_ldap/tests/group_ldap.php index 2be6b46fb23..106459580fa 100644 --- a/apps/user_ldap/tests/group_ldap.php +++ b/apps/user_ldap/tests/group_ldap.php @@ -26,8 +26,8 @@ class Test_Group_Ldap extends UnitTestCase { } function testSingleBackend(){ - OC_Group::useBackend(new OC_GROUP_LDAP()); - $group_ldap = new OC_GROUP_LDAP(); + OC_Group::useBackend(new OCA\user_ldap\GROUP_LDAP()); + $group_ldap = new OCA\user_ldap\GROUP_LDAP(); $this->assertIsA(OC_Group::getGroups(),gettype(array())); $this->assertIsA($group_ldap->getGroups(),gettype(array())); diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index da99e167fd1..a97df7b4fd1 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -23,53 +23,36 @@ * */ -class OC_USER_LDAP extends OC_User_Backend { +namespace OCA\user_ldap; - // cached settings - protected $ldapUserFilter; - protected $ldapQuotaAttribute; - protected $ldapQuotaDefault; - protected $ldapEmailAttribute; - - // will be retrieved from LDAP server - protected $ldap_dc = false; - - // cache getUsers() - protected $_users = null; - - public function __construct() { - $this->ldapUserFilter = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter', '(objectClass=posixAccount)'); - $this->ldapQuotaAttribute = OCP\Config::getAppValue('user_ldap', 'ldap_quota_attr', ''); - $this->ldapQuotaDefault = OCP\Config::getAppValue('user_ldap', 'ldap_quota_def', ''); - $this->ldapEmailAttribute = OCP\Config::getAppValue('user_ldap', 'ldap_email_attr', ''); - } +class USER_LDAP extends lib\Access implements \OCP\UserInterface { private function updateQuota($dn) { $quota = null; - if(!empty($this->ldapQuotaDefault)) { - $quota = $this->ldapQuotaDefault; + if(!empty($this->connection->ldapQuotaDefault)) { + $quota = $this->connection->ldapQuotaDefault; } - if(!empty($this->ldapQuotaAttribute)) { - $aQuota = OC_LDAP::readAttribute($dn, $this->ldapQuotaAttribute); + if(!empty($this->connection->ldapQuotaAttribute)) { + $aQuota = $this->readAttribute($dn, $this->connection->ldapQuotaAttribute); if($aQuota && (count($aQuota) > 0)) { $quota = $aQuota[0]; } } if(!is_null($quota)) { - OCP\Config::setUserValue(OC_LDAP::dn2username($dn), 'files', 'quota', OCP\Util::computerFileSize($quota)); + \OCP\Config::setUserValue($this->dn2username($dn), 'files', 'quota', \OCP\Util::computerFileSize($quota)); } } private function updateEmail($dn) { $email = null; - if(!empty($this->ldapEmailAttribute)) { - $aEmail = OC_LDAP::readAttribute($dn, $this->ldapEmailAttribute); + if(!empty($this->connection->ldapEmailAttribute)) { + $aEmail = $this->readAttribute($dn, $this->connection->ldapEmailAttribute); if($aEmail && (count($aEmail) > 0)) { $email = $aEmail[0]; } - if(!is_null($email)){ - OCP\Config::setUserValue(OC_LDAP::dn2username($dn), 'settings', 'email', $email); + if(!is_null($email)) { + \OCP\Config::setUserValue($this->dn2username($dn), 'settings', 'email', $email); } } } @@ -84,26 +67,27 @@ class OC_USER_LDAP extends OC_User_Backend { */ public function checkPassword($uid, $password){ //find out dn of the user name - $filter = str_replace('%uid', $uid, OC_LDAP::conf('ldapLoginFilter')); - $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn'); + $filter = \OCP\Util::mb_str_replace('%uid', $uid, $this->connection->ldapLoginFilter, 'UTF-8'); + $ldap_users = $this->fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { return false; } $dn = $ldap_users[0]; //are the credentials OK? - if(!OC_LDAP::areCredentialsValid($dn, $password)) { + if(!$this->areCredentialsValid($dn, $password)) { return false; } //do we have a username for him/her? - $ocname = OC_LDAP::dn2username($dn); + $ocname = $this->dn2username($dn); if($ocname){ //update some settings, if necessary $this->updateQuota($dn); $this->updateEmail($dn); + //give back the display name return $ocname; } @@ -116,12 +100,25 @@ class OC_USER_LDAP extends OC_User_Backend { * * Get a list of all users. */ - public function getUsers(){ - if(is_null($this->_users)) { - $ldap_users = OC_LDAP::fetchListOfUsers($this->ldapUserFilter, array(OC_LDAP::conf('ldapUserDisplayName'), 'dn')); - $this->_users = OC_LDAP::ownCloudUserNames($ldap_users); + public function getUsers($search = '', $limit = 10, $offset = 0){ + $ldap_users = $this->connection->getFromCache('getUsers'); + if(is_null($ldap_users)) { + $ldap_users = $this->fetchListOfUsers($this->connection->ldapUserFilter, array($this->connection->ldapUserDisplayName, 'dn')); + $ldap_users = $this->ownCloudUserNames($ldap_users); + $this->connection->writeToCache('getUsers', $ldap_users); + } + $this->userSearch = $search; + if(!empty($this->userSearch)) { + $ldap_users = array_filter($ldap_users, array($this, 'userMatchesFilter')); } - return $this->_users; + if($limit = -1) { + $limit = null; + } + return array_slice($ldap_users, $offset, $limit); + } + + public function userMatchesFilter($user) { + return (strripos($user, $this->userSearch) !== false); } /** @@ -130,19 +127,49 @@ class OC_USER_LDAP extends OC_User_Backend { * @return boolean */ public function userExists($uid){ + if($this->connection->isCached('userExists'.$uid)) { + return $this->connection->getFromCache('userExists'.$uid); + } + //getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking. - $dn = OC_LDAP::username2dn($uid); + $dn = $this->username2dn($uid); if(!$dn) { + $this->connection->writeToCache('userExists'.$uid, false); return false; } - //if user really still exists, we will be able to read his cn - $cn = OC_LDAP::readAttribute($dn, 'cn'); - if(!$cn || empty($cn)) { + //if user really still exists, we will be able to read his objectclass + $objcs = $this->readAttribute($dn, 'objectclass'); + if(!$objcs || empty($objcs)) { + $this->connection->writeToCache('userExists'.$uid, false); return false; } + $this->connection->writeToCache('userExists'.$uid, true); return true; } + /** + * @brief delete a user + * @param $uid The username of the user to delete + * @returns true/false + * + * Deletes a user + */ + public function deleteUser($uid) { + return false; + } + + /** + * @brief Check if backend implements actions + * @param $actions bitwise-or'ed actions + * @returns boolean + * + * Returns the supported actions as int to be + * compared with OC_USER_BACKEND_CREATE_USER etc. + */ + public function implementsActions($actions) { + return (bool)(OC_USER_BACKEND_CHECK_PASSWORD & $actions); + } + }
\ No newline at end of file |