summaryrefslogtreecommitdiffstats
path: root/apps/user_ldap
diff options
context:
space:
mode:
authorJörn Friedrich Dreyer <jfd@butonic.de>2012-08-25 00:05:07 +0200
committerJörn Friedrich Dreyer <jfd@butonic.de>2012-08-25 00:05:07 +0200
commitc8255a170c2d7449b4e7728edd2237eea71dca80 (patch)
treee5a3854ec472be9700064bc7b689b8adf7c7f692 /apps/user_ldap
parent0c0ae928dcd483211a92303eb2b202453d02a86e (diff)
parent46d6fd15e4cc02d45079ffc688be0684e61f1434 (diff)
downloadnextcloud-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')
-rw-r--r--apps/user_ldap/ajax/testConfiguration.php39
-rw-r--r--apps/user_ldap/appinfo/app.php16
-rw-r--r--apps/user_ldap/appinfo/database.xml49
-rw-r--r--apps/user_ldap/appinfo/update.php57
-rw-r--r--apps/user_ldap/appinfo/version2
-rw-r--r--apps/user_ldap/css/settings.css10
-rw-r--r--apps/user_ldap/group_ldap.php170
-rw-r--r--apps/user_ldap/js/settings.js21
-rw-r--r--apps/user_ldap/l10n/.gitkeep0
-rw-r--r--apps/user_ldap/l10n/ca.php36
-rw-r--r--apps/user_ldap/l10n/cs_CZ.php36
-rw-r--r--apps/user_ldap/l10n/da.php9
-rw-r--r--apps/user_ldap/l10n/de.php36
-rw-r--r--apps/user_ldap/l10n/el.php6
-rw-r--r--apps/user_ldap/l10n/eo.php32
-rw-r--r--apps/user_ldap/l10n/es.php7
-rw-r--r--apps/user_ldap/l10n/fi_FI.php31
-rw-r--r--apps/user_ldap/l10n/fr.php32
-rw-r--r--apps/user_ldap/l10n/it.php36
-rw-r--r--apps/user_ldap/l10n/ja_JP.php36
-rw-r--r--apps/user_ldap/l10n/lt_LT.php9
-rw-r--r--apps/user_ldap/l10n/pl.php36
-rw-r--r--apps/user_ldap/l10n/ro.php36
-rw-r--r--apps/user_ldap/l10n/sl.php36
-rw-r--r--apps/user_ldap/l10n/sv.php36
-rw-r--r--apps/user_ldap/l10n/th_TH.php36
-rw-r--r--apps/user_ldap/lib/access.php676
-rw-r--r--apps/user_ldap/lib/connection.php358
-rw-r--r--apps/user_ldap/lib/jobs.php157
-rw-r--r--apps/user_ldap/lib_ldap.php765
-rw-r--r--apps/user_ldap/settings.php18
-rw-r--r--apps/user_ldap/templates/settings.php33
-rw-r--r--apps/user_ldap/tests/group_ldap.php4
-rw-r--r--apps/user_ldap/user_ldap.php109
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