activeldap3 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/CHANGES +691 -0
- data/COPYING +340 -0
- data/LICENSE +58 -0
- data/README +154 -0
- data/Rakefile +121 -0
- data/TODO +32 -0
- data/activeldap3.gemspec +18 -0
- data/benchmark/bench-al.rb +263 -0
- data/benchmark/config.yaml.sample +5 -0
- data/examples/al-admin/README +182 -0
- data/examples/al-admin/Rakefile +16 -0
- data/examples/al-admin/app/controllers/account_controller.rb +60 -0
- data/examples/al-admin/app/controllers/application_controller.rb +46 -0
- data/examples/al-admin/app/controllers/attributes_controller.rb +17 -0
- data/examples/al-admin/app/controllers/directory_controller.rb +49 -0
- data/examples/al-admin/app/controllers/object_classes_controller.rb +17 -0
- data/examples/al-admin/app/controllers/syntaxes_controller.rb +17 -0
- data/examples/al-admin/app/controllers/users_controller.rb +66 -0
- data/examples/al-admin/app/controllers/welcome_controller.rb +12 -0
- data/examples/al-admin/app/helpers/account_helper.rb +2 -0
- data/examples/al-admin/app/helpers/application_helper.rb +46 -0
- data/examples/al-admin/app/helpers/attributes_helper.rb +15 -0
- data/examples/al-admin/app/helpers/directory_helper.rb +7 -0
- data/examples/al-admin/app/helpers/object_classes_helper.rb +10 -0
- data/examples/al-admin/app/helpers/syntaxes_helper.rb +10 -0
- data/examples/al-admin/app/helpers/url_helper.rb +17 -0
- data/examples/al-admin/app/helpers/users_helper.rb +17 -0
- data/examples/al-admin/app/helpers/welcome_helper.rb +2 -0
- data/examples/al-admin/app/models/entry.rb +23 -0
- data/examples/al-admin/app/models/ldap_user.rb +58 -0
- data/examples/al-admin/app/models/user.rb +91 -0
- data/examples/al-admin/app/views/_entry/_attributes_information.html.erb +29 -0
- data/examples/al-admin/app/views/_entry/_entry.html.erb +15 -0
- data/examples/al-admin/app/views/_schema/_aliases.html.erb +7 -0
- data/examples/al-admin/app/views/_switcher/_after.html.erb +2 -0
- data/examples/al-admin/app/views/_switcher/_before.html.erb +5 -0
- data/examples/al-admin/app/views/account/login.html.erb +26 -0
- data/examples/al-admin/app/views/account/sign_up.html.erb +29 -0
- data/examples/al-admin/app/views/attributes/_attributes.html.erb +19 -0
- data/examples/al-admin/app/views/attributes/_detail.html.erb +29 -0
- data/examples/al-admin/app/views/attributes/index.html.erb +3 -0
- data/examples/al-admin/app/views/attributes/show.html.erb +31 -0
- data/examples/al-admin/app/views/directory/_tree.html.erb +10 -0
- data/examples/al-admin/app/views/directory/_tree_view_js.html.erb +25 -0
- data/examples/al-admin/app/views/directory/index.html.erb +13 -0
- data/examples/al-admin/app/views/directory/populate.html.erb +2 -0
- data/examples/al-admin/app/views/layouts/_footer.html.erb +11 -0
- data/examples/al-admin/app/views/layouts/_header_menu.html.erb +10 -0
- data/examples/al-admin/app/views/layouts/_main_menu.html.erb +18 -0
- data/examples/al-admin/app/views/layouts/application.html.erb +57 -0
- data/examples/al-admin/app/views/object_classes/_attributes.html.erb +28 -0
- data/examples/al-admin/app/views/object_classes/_object_classes.html.erb +19 -0
- data/examples/al-admin/app/views/object_classes/index.html.erb +3 -0
- data/examples/al-admin/app/views/object_classes/show.html.erb +39 -0
- data/examples/al-admin/app/views/syntaxes/_detail.html.erb +14 -0
- data/examples/al-admin/app/views/syntaxes/_syntaxes.html.erb +19 -0
- data/examples/al-admin/app/views/syntaxes/index.html.erb +3 -0
- data/examples/al-admin/app/views/syntaxes/show.html.erb +22 -0
- data/examples/al-admin/app/views/users/_attributes_update_form.html.erb +42 -0
- data/examples/al-admin/app/views/users/_form.html.erb +13 -0
- data/examples/al-admin/app/views/users/_object_classes_update_form.html.erb +46 -0
- data/examples/al-admin/app/views/users/_password_change_form.html.erb +20 -0
- data/examples/al-admin/app/views/users/edit.html.erb +15 -0
- data/examples/al-admin/app/views/users/index.html.erb +10 -0
- data/examples/al-admin/app/views/users/show.html.erb +11 -0
- data/examples/al-admin/app/views/welcome/index.html.erb +13 -0
- data/examples/al-admin/config.ru +7 -0
- data/examples/al-admin/config/boot.rb +110 -0
- data/examples/al-admin/config/database.yml.example +19 -0
- data/examples/al-admin/config/environment.rb +73 -0
- data/examples/al-admin/config/environments/development.rb +17 -0
- data/examples/al-admin/config/environments/production.rb +24 -0
- data/examples/al-admin/config/environments/test.rb +22 -0
- data/examples/al-admin/config/initializers/exception_notifier.rb +2 -0
- data/examples/al-admin/config/initializers/fast_gettext.rb +3 -0
- data/examples/al-admin/config/initializers/inflections.rb +10 -0
- data/examples/al-admin/config/initializers/mime_types.rb +5 -0
- data/examples/al-admin/config/initializers/session_store.rb +23 -0
- data/examples/al-admin/config/ldap.yml.example +21 -0
- data/examples/al-admin/config/routes.rb +58 -0
- data/examples/al-admin/db/migrate/001_create_users.rb +16 -0
- data/examples/al-admin/doc/README_FOR_APP +2 -0
- data/examples/al-admin/lib/authenticated_system.rb +124 -0
- data/examples/al-admin/lib/authenticated_test_helper.rb +113 -0
- data/examples/al-admin/lib/ldap_test_helper.rb +38 -0
- data/examples/al-admin/lib/tasks/testing.rake +10 -0
- data/examples/al-admin/po/en/al-admin.po +343 -0
- data/examples/al-admin/po/ja/al-admin.po +343 -0
- data/examples/al-admin/po/nl/al-admin.po +380 -0
- data/examples/al-admin/public/.htaccess +40 -0
- data/examples/al-admin/public/404.html +30 -0
- data/examples/al-admin/public/500.html +30 -0
- data/examples/al-admin/public/dispatch.cgi +10 -0
- data/examples/al-admin/public/dispatch.fcgi +24 -0
- data/examples/al-admin/public/dispatch.rb +10 -0
- data/examples/al-admin/public/favicon.ico +0 -0
- data/examples/al-admin/public/images/active-ldap.svg +6351 -0
- data/examples/al-admin/public/images/al-admin.png +0 -0
- data/examples/al-admin/public/images/al-admin.svg +6371 -0
- data/examples/al-admin/public/images/header-background.png +0 -0
- data/examples/al-admin/public/images/header-background.svg +99 -0
- data/examples/al-admin/public/images/rails.png +0 -0
- data/examples/al-admin/public/images/spinelz/accordion_tab_left_active.gif +0 -0
- data/examples/al-admin/public/images/spinelz/accordion_tab_left_inactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/accordion_tab_middle_active.gif +0 -0
- data/examples/al-admin/public/images/spinelz/accordion_tab_middle_inactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/accordion_tab_right_active.gif +0 -0
- data/examples/al-admin/public/images/spinelz/accordion_tab_right_inactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_back.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_bottom_left.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_bottom_middle.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_bottom_right.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_left_down_arrow.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_left_up_arrow.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_middle_left.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_middle_right.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_right_down_arrow.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_right_up_arrow.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_top_left.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_top_middle.gif +0 -0
- data/examples/al-admin/public/images/spinelz/balloon_top_right.gif +0 -0
- data/examples/al-admin/public/images/spinelz/barchart_h.gif +0 -0
- data/examples/al-admin/public/images/spinelz/barchart_v.gif +0 -0
- data/examples/al-admin/public/images/spinelz/button.gif +0 -0
- data/examples/al-admin/public/images/spinelz/calendar_default_handler.gif +0 -0
- data/examples/al-admin/public/images/spinelz/calendar_delete.gif +0 -0
- data/examples/al-admin/public/images/spinelz/calendar_next.gif +0 -0
- data/examples/al-admin/public/images/spinelz/calendar_next_second.gif +0 -0
- data/examples/al-admin/public/images/spinelz/calendar_pre.gif +0 -0
- data/examples/al-admin/public/images/spinelz/calendar_pre_second.gif +0 -0
- data/examples/al-admin/public/images/spinelz/calendar_private_icon.gif +0 -0
- data/examples/al-admin/public/images/spinelz/calendar_schedule.gif +0 -0
- data/examples/al-admin/public/images/spinelz/calender_back.gif +0 -0
- data/examples/al-admin/public/images/spinelz/calender_back_second.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker2_back.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker2_back_second.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker2_next.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker2_next_second.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker2_pre.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker2_pre_second.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker_back.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker_back_second.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker_next.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker_next_second.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker_pre.gif +0 -0
- data/examples/al-admin/public/images/spinelz/datepicker_pre_second.gif +0 -0
- data/examples/al-admin/public/images/spinelz/grid_down.gif +0 -0
- data/examples/al-admin/public/images/spinelz/grid_state.gif +0 -0
- data/examples/al-admin/public/images/spinelz/grid_up.gif +0 -0
- data/examples/al-admin/public/images/spinelz/icon_day.gif +0 -0
- data/examples/al-admin/public/images/spinelz/icon_month.gif +0 -0
- data/examples/al-admin/public/images/spinelz/icon_week.gif +0 -0
- data/examples/al-admin/public/images/spinelz/menubar_back.gif +0 -0
- data/examples/al-admin/public/images/spinelz/menubar_subcontents_back.gif +0 -0
- data/examples/al-admin/public/images/spinelz/navPanel_tab_left_active.gif +0 -0
- data/examples/al-admin/public/images/spinelz/navPanel_tab_left_inactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/navPanel_tab_middle_active.gif +0 -0
- data/examples/al-admin/public/images/spinelz/navPanel_tab_middle_inactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/navPanel_tab_right_active.gif +0 -0
- data/examples/al-admin/public/images/spinelz/navPanel_tab_right_inactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/select_date.gif +0 -0
- data/examples/al-admin/public/images/spinelz/selectabletable_selected.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_about.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_menu.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_sample.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_tabBottomActive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_tabBottomInactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleActive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleActive2.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleInactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleInactive2.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_tabTopActive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_tabTopInactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sideBarBox_tabbar.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sortableTable_down.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sortableTable_normal.gif +0 -0
- data/examples/al-admin/public/images/spinelz/sortableTable_up.gif +0 -0
- data/examples/al-admin/public/images/spinelz/switcher_close.gif +0 -0
- data/examples/al-admin/public/images/spinelz/switcher_open.gif +0 -0
- data/examples/al-admin/public/images/spinelz/tabBox_close.gif +0 -0
- data/examples/al-admin/public/images/spinelz/tabBox_tabLeftActive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/tabBox_tabLeftInactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/tabBox_tabMiddleActive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/tabBox_tabMiddleInactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/tabBox_tabRightActive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/tabBox_tabRightInactive.gif +0 -0
- data/examples/al-admin/public/images/spinelz/tab_bar.gif +0 -0
- data/examples/al-admin/public/images/spinelz/table_back.gif +0 -0
- data/examples/al-admin/public/images/spinelz/timepicker_clock.gif +0 -0
- data/examples/al-admin/public/images/spinelz/toolbar_close.gif +0 -0
- data/examples/al-admin/public/images/spinelz/toolbar_left.gif +0 -0
- data/examples/al-admin/public/images/spinelz/toolbar_max.gif +0 -0
- data/examples/al-admin/public/images/spinelz/toolbar_middle.gif +0 -0
- data/examples/al-admin/public/images/spinelz/toolbar_min.gif +0 -0
- data/examples/al-admin/public/images/spinelz/toolbar_next.gif +0 -0
- data/examples/al-admin/public/images/spinelz/toolbar_right.gif +0 -0
- data/examples/al-admin/public/images/spinelz/treeview_dir.gif +0 -0
- data/examples/al-admin/public/images/spinelz/treeview_file.gif +0 -0
- data/examples/al-admin/public/images/spinelz/treeview_group.gif +0 -0
- data/examples/al-admin/public/images/spinelz/treeview_group_special.gif +0 -0
- data/examples/al-admin/public/images/spinelz/treeview_state.gif +0 -0
- data/examples/al-admin/public/images/spinelz/treeview_user.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_bottom_left.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_bottom_middle.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_bottom_right.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_close.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_max.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_middle_left.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_middle_right.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_min.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_top_left.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_top_middle.gif +0 -0
- data/examples/al-admin/public/images/spinelz/window_top_right.gif +0 -0
- data/examples/al-admin/public/javascripts/application.js +2 -0
- data/examples/al-admin/public/javascripts/controls.js +963 -0
- data/examples/al-admin/public/javascripts/dragdrop.js +973 -0
- data/examples/al-admin/public/javascripts/effects.js +1128 -0
- data/examples/al-admin/public/javascripts/prototype.js +4320 -0
- data/examples/al-admin/public/javascripts/spinelz/accordion.js +185 -0
- data/examples/al-admin/public/javascripts/spinelz/ajaxHistory.js +157 -0
- data/examples/al-admin/public/javascripts/spinelz/balloon.js +287 -0
- data/examples/al-admin/public/javascripts/spinelz/barchart.js +524 -0
- data/examples/al-admin/public/javascripts/spinelz/calendar.js +3012 -0
- data/examples/al-admin/public/javascripts/spinelz/colorpicker.js +128 -0
- data/examples/al-admin/public/javascripts/spinelz/datepicker.js +438 -0
- data/examples/al-admin/public/javascripts/spinelz/grid.js +1391 -0
- data/examples/al-admin/public/javascripts/spinelz/grid_resizeEx.js +100 -0
- data/examples/al-admin/public/javascripts/spinelz/grid_sortabletableEx.js +129 -0
- data/examples/al-admin/public/javascripts/spinelz/inplaceEditorEx.js +148 -0
- data/examples/al-admin/public/javascripts/spinelz/menubar.js +232 -0
- data/examples/al-admin/public/javascripts/spinelz/navPanel.js +170 -0
- data/examples/al-admin/public/javascripts/spinelz/selectableTable.js +433 -0
- data/examples/al-admin/public/javascripts/spinelz/sideBarBox.js +282 -0
- data/examples/al-admin/public/javascripts/spinelz/sideBarBox_effects.js +83 -0
- data/examples/al-admin/public/javascripts/spinelz/sortableTable.js +270 -0
- data/examples/al-admin/public/javascripts/spinelz/switcher.js +78 -0
- data/examples/al-admin/public/javascripts/spinelz/tabBox.js +469 -0
- data/examples/al-admin/public/javascripts/spinelz/timepicker.js +384 -0
- data/examples/al-admin/public/javascripts/spinelz/toolbar.js +152 -0
- data/examples/al-admin/public/javascripts/spinelz/treeview.js +703 -0
- data/examples/al-admin/public/javascripts/spinelz/window.js +641 -0
- data/examples/al-admin/public/javascripts/spinelz/window_resizeEx.js +130 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/builder.js +131 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/controls.js +835 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/dragdrop.js +944 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/effects.js +1090 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/json.js +139 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/prototype.js +2515 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/resize.js +215 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/scriptaculous.js +51 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/slider.js +278 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/spinelz_util.js +1266 -0
- data/examples/al-admin/public/javascripts/spinelz_lib/unittest.js +564 -0
- data/examples/al-admin/public/robots.txt +1 -0
- data/examples/al-admin/public/stylesheets/account.css +41 -0
- data/examples/al-admin/public/stylesheets/attributes.css +1 -0
- data/examples/al-admin/public/stylesheets/base.css +104 -0
- data/examples/al-admin/public/stylesheets/detail.css +36 -0
- data/examples/al-admin/public/stylesheets/directory.css +22 -0
- data/examples/al-admin/public/stylesheets/object-classes.css +6 -0
- data/examples/al-admin/public/stylesheets/rails.css +35 -0
- data/examples/al-admin/public/stylesheets/spinelz/accordion.css +59 -0
- data/examples/al-admin/public/stylesheets/spinelz/balloon.css +151 -0
- data/examples/al-admin/public/stylesheets/spinelz/calendar.css +564 -0
- data/examples/al-admin/public/stylesheets/spinelz/datepicker.css +175 -0
- data/examples/al-admin/public/stylesheets/spinelz/grid.css +137 -0
- data/examples/al-admin/public/stylesheets/spinelz/menubar.css +78 -0
- data/examples/al-admin/public/stylesheets/spinelz/modal.css +22 -0
- data/examples/al-admin/public/stylesheets/spinelz/navPanel.css +58 -0
- data/examples/al-admin/public/stylesheets/spinelz/selectableTable.css +28 -0
- data/examples/al-admin/public/stylesheets/spinelz/sideBarBox.css +82 -0
- data/examples/al-admin/public/stylesheets/spinelz/sortableTable.css +51 -0
- data/examples/al-admin/public/stylesheets/spinelz/switcher.css +23 -0
- data/examples/al-admin/public/stylesheets/spinelz/tabBox.css +94 -0
- data/examples/al-admin/public/stylesheets/spinelz/timepicker.css +508 -0
- data/examples/al-admin/public/stylesheets/spinelz/toolbar.css +82 -0
- data/examples/al-admin/public/stylesheets/spinelz/treeview.css +121 -0
- data/examples/al-admin/public/stylesheets/spinelz/window.css +140 -0
- data/examples/al-admin/public/stylesheets/structure.css +81 -0
- data/examples/al-admin/public/stylesheets/syntaxes.css +1 -0
- data/examples/al-admin/public/stylesheets/users.css +13 -0
- data/examples/al-admin/public/stylesheets/welcome.css +0 -0
- data/examples/al-admin/script/about +3 -0
- data/examples/al-admin/script/console +3 -0
- data/examples/al-admin/script/dbconsole +3 -0
- data/examples/al-admin/script/destroy +3 -0
- data/examples/al-admin/script/generate +3 -0
- data/examples/al-admin/script/performance/benchmarker +3 -0
- data/examples/al-admin/script/performance/profiler +3 -0
- data/examples/al-admin/script/performance/request +3 -0
- data/examples/al-admin/script/plugin +3 -0
- data/examples/al-admin/script/process/inspector +3 -0
- data/examples/al-admin/script/process/reaper +3 -0
- data/examples/al-admin/script/process/spawner +3 -0
- data/examples/al-admin/script/runner +3 -0
- data/examples/al-admin/script/server +3 -0
- data/examples/al-admin/test/fixtures/users.yml +9 -0
- data/examples/al-admin/test/functional/account_controller_test.rb +12 -0
- data/examples/al-admin/test/functional/attributes_controller_test.rb +8 -0
- data/examples/al-admin/test/functional/directory_controller_test.rb +8 -0
- data/examples/al-admin/test/functional/object_classes_controller_test.rb +8 -0
- data/examples/al-admin/test/functional/syntaxes_controller_test.rb +8 -0
- data/examples/al-admin/test/functional/users_controller_test.rb +8 -0
- data/examples/al-admin/test/functional/welcome_controller_test.rb +8 -0
- data/examples/al-admin/test/integration/sign_up_test.rb +44 -0
- data/examples/al-admin/test/run-test.sh +3 -0
- data/examples/al-admin/test/test_helper.rb +52 -0
- data/examples/al-admin/test/unit/user_test.rb +12 -0
- data/examples/al-admin/vendor/plugins/exception_notification/README +111 -0
- data/examples/al-admin/vendor/plugins/exception_notification/init.rb +1 -0
- data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifiable.rb +99 -0
- data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifier.rb +66 -0
- data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifier_helper.rb +78 -0
- data/examples/al-admin/vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb +61 -0
- data/examples/al-admin/vendor/plugins/exception_notification/test/test_helper.rb +7 -0
- data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml +1 -0
- data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml +7 -0
- data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml +16 -0
- data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml +4 -0
- data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml +2 -0
- data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml +3 -0
- data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml +6 -0
- data/examples/config.yaml.example +5 -0
- data/examples/example.der +0 -0
- data/examples/example.jpg +0 -0
- data/examples/groupadd +41 -0
- data/examples/groupdel +35 -0
- data/examples/groupls +49 -0
- data/examples/groupmod +42 -0
- data/examples/lpasswd +55 -0
- data/examples/objects/group.rb +13 -0
- data/examples/objects/ou.rb +4 -0
- data/examples/objects/user.rb +20 -0
- data/examples/ouadd +38 -0
- data/examples/useradd +45 -0
- data/examples/useradd-binary +53 -0
- data/examples/userdel +34 -0
- data/examples/userls +50 -0
- data/examples/usermod +42 -0
- data/examples/usermod-binary-add +50 -0
- data/examples/usermod-binary-add-time +54 -0
- data/examples/usermod-binary-del +48 -0
- data/examples/usermod-lang-add +43 -0
- data/lib/active_ldap.rb +105 -0
- data/lib/active_ldap/action_controller/ldap_benchmarking.rb +55 -0
- data/lib/active_ldap/acts/tree.rb +75 -0
- data/lib/active_ldap/adapter/base.rb +705 -0
- data/lib/active_ldap/adapter/jndi.rb +184 -0
- data/lib/active_ldap/adapter/jndi_connection.rb +185 -0
- data/lib/active_ldap/adapter/ldap.rb +290 -0
- data/lib/active_ldap/adapter/ldap_ext.rb +105 -0
- data/lib/active_ldap/adapter/net_ldap.rb +309 -0
- data/lib/active_ldap/adapter/net_ldap_ext.rb +23 -0
- data/lib/active_ldap/association/belongs_to.rb +47 -0
- data/lib/active_ldap/association/belongs_to_many.rb +58 -0
- data/lib/active_ldap/association/children.rb +21 -0
- data/lib/active_ldap/association/collection.rb +105 -0
- data/lib/active_ldap/association/has_many.rb +31 -0
- data/lib/active_ldap/association/has_many_utils.rb +44 -0
- data/lib/active_ldap/association/has_many_wrap.rb +62 -0
- data/lib/active_ldap/association/proxy.rb +107 -0
- data/lib/active_ldap/associations.rb +202 -0
- data/lib/active_ldap/attributes.rb +184 -0
- data/lib/active_ldap/base.rb +1594 -0
- data/lib/active_ldap/callbacks.rb +52 -0
- data/lib/active_ldap/command.rb +49 -0
- data/lib/active_ldap/compatible.rb +44 -0
- data/lib/active_ldap/configuration.rb +147 -0
- data/lib/active_ldap/connection.rb +294 -0
- data/lib/active_ldap/distinguished_name.rb +291 -0
- data/lib/active_ldap/entry_attribute.rb +78 -0
- data/lib/active_ldap/escape.rb +12 -0
- data/lib/active_ldap/get_text.rb +9 -0
- data/lib/active_ldap/get_text/parser.rb +161 -0
- data/lib/active_ldap/get_text_fallback.rb +60 -0
- data/lib/active_ldap/get_text_support.rb +20 -0
- data/lib/active_ldap/helper.rb +92 -0
- data/lib/active_ldap/human_readable.rb +132 -0
- data/lib/active_ldap/ldap_error.rb +74 -0
- data/lib/active_ldap/ldif.rb +930 -0
- data/lib/active_ldap/object_class.rb +95 -0
- data/lib/active_ldap/operations.rb +610 -0
- data/lib/active_ldap/populate.rb +53 -0
- data/lib/active_ldap/railtie.rb +31 -0
- data/lib/active_ldap/schema.rb +699 -0
- data/lib/active_ldap/schema/syntaxes.rb +417 -0
- data/lib/active_ldap/timeout.rb +75 -0
- data/lib/active_ldap/timeout_stub.rb +17 -0
- data/lib/active_ldap/user_password.rb +92 -0
- data/lib/active_ldap/validations.rb +229 -0
- data/lib/active_ldap/xml.rb +122 -0
- data/po/en/active-ldap.po +4029 -0
- data/po/ja/active-ldap.po +4060 -0
- data/rails_generators/model_active_ldap/USAGE +17 -0
- data/rails_generators/model_active_ldap/model_active_ldap_generator.rb +69 -0
- data/rails_generators/model_active_ldap/templates/model_active_ldap.rb +3 -0
- data/rails_generators/model_active_ldap/templates/unit_test.rb +8 -0
- data/rails_generators/scaffold_active_ldap/scaffold_active_ldap_generator.rb +7 -0
- data/rails_generators/scaffold_active_ldap/templates/ldap.yml +18 -0
- data/test/al-test-utils.rb +439 -0
- data/test/command.rb +112 -0
- data/test/config.yaml.sample +6 -0
- data/test/fixtures/lower_case_object_class_schema.rb +802 -0
- data/test/run-test.rb +44 -0
- data/test/test_acts_as_tree.rb +60 -0
- data/test/test_adapter.rb +121 -0
- data/test/test_associations.rb +664 -0
- data/test/test_attributes.rb +117 -0
- data/test/test_base.rb +1177 -0
- data/test/test_base_per_instance.rb +61 -0
- data/test/test_bind.rb +62 -0
- data/test/test_callback.rb +37 -0
- data/test/test_configuration.rb +40 -0
- data/test/test_connection.rb +82 -0
- data/test/test_connection_per_class.rb +112 -0
- data/test/test_connection_per_dn.rb +112 -0
- data/test/test_dn.rb +172 -0
- data/test/test_find.rb +176 -0
- data/test/test_groupadd.rb +50 -0
- data/test/test_groupdel.rb +46 -0
- data/test/test_groupls.rb +107 -0
- data/test/test_groupmod.rb +51 -0
- data/test/test_ldif.rb +1891 -0
- data/test/test_load.rb +133 -0
- data/test/test_lpasswd.rb +75 -0
- data/test/test_object_class.rb +74 -0
- data/test/test_reflection.rb +182 -0
- data/test/test_schema.rb +559 -0
- data/test/test_syntax.rb +383 -0
- data/test/test_user.rb +217 -0
- data/test/test_user_password.rb +101 -0
- data/test/test_useradd-binary.rb +62 -0
- data/test/test_useradd.rb +57 -0
- data/test/test_userdel.rb +48 -0
- data/test/test_userls.rb +91 -0
- data/test/test_usermod-binary-add-time.rb +65 -0
- data/test/test_usermod-binary-add.rb +64 -0
- data/test/test_usermod-binary-del.rb +66 -0
- data/test/test_usermod-lang-add.rb +60 -0
- data/test/test_usermod.rb +58 -0
- data/test/test_validation.rb +274 -0
- metadata +502 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
4
|
+
$LOAD_PATH << File.join(base, "lib")
|
5
|
+
$LOAD_PATH << File.join(base, "examples")
|
6
|
+
|
7
|
+
require 'active_ldap'
|
8
|
+
require 'objects/user'
|
9
|
+
require 'objects/group'
|
10
|
+
|
11
|
+
argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
|
12
|
+
opts.banner += " USER_NAME CN UID"
|
13
|
+
end
|
14
|
+
|
15
|
+
if argv.size == 3
|
16
|
+
name, cn, uid = argv
|
17
|
+
else
|
18
|
+
$stderr.puts opts
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
pwb = Proc.new do |user|
|
23
|
+
ActiveLdap::Command.read_password("[#{user}] Password: ")
|
24
|
+
end
|
25
|
+
|
26
|
+
ActiveLdap::Base.setup_connection(:password_block => pwb,
|
27
|
+
:allow_anonymous => false)
|
28
|
+
|
29
|
+
unless User.exists?(name)
|
30
|
+
$stderr.puts("User #{name} doesn't exist.")
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
user = User.find(name)
|
35
|
+
user.cn = cn
|
36
|
+
user.uid_number = uid
|
37
|
+
user.gid_number = uid
|
38
|
+
|
39
|
+
if user.classes.include?('strongAuthenticationUser')
|
40
|
+
user.user_certificate = nil
|
41
|
+
user.remove_class('strongAuthenticationUser')
|
42
|
+
end
|
43
|
+
|
44
|
+
unless user.save
|
45
|
+
puts "failed"
|
46
|
+
puts user.errors.full_messages
|
47
|
+
exit 1
|
48
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
4
|
+
$LOAD_PATH << File.join(base, "lib")
|
5
|
+
$LOAD_PATH << File.join(base, "examples")
|
6
|
+
|
7
|
+
require 'active_ldap'
|
8
|
+
require 'objects/user'
|
9
|
+
require 'objects/group'
|
10
|
+
|
11
|
+
argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
|
12
|
+
opts.banner += " USER_NAME CN UID"
|
13
|
+
end
|
14
|
+
|
15
|
+
if argv.size == 3
|
16
|
+
name, cn, uid = argv
|
17
|
+
else
|
18
|
+
$stderr.puts opts
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
pwb = Proc.new do |user|
|
23
|
+
ActiveLdap::Command.read_password("[#{user}] Password: ")
|
24
|
+
end
|
25
|
+
|
26
|
+
ActiveLdap::Base.setup_connection(:password_block => pwb,
|
27
|
+
:allow_anonymous => false)
|
28
|
+
|
29
|
+
unless User.exists?(name)
|
30
|
+
$stderr.puts("User #{name} doesn't exist.")
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
user = User.find(name)
|
35
|
+
user.cn = [cn, {'lang-en-us' => cn}]
|
36
|
+
user.uid_number = uid
|
37
|
+
user.gid_number = uid
|
38
|
+
|
39
|
+
unless user.save
|
40
|
+
puts "failed"
|
41
|
+
puts user.errors.full_messages
|
42
|
+
exit 1
|
43
|
+
end
|
data/lib/active_ldap.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require_gem_if_need = Proc.new do |library_name, gem_name, *gem_args|
|
2
|
+
gem_name ||= library_name
|
3
|
+
begin
|
4
|
+
if !gem_args.empty? and Object.const_defined?(:Gem)
|
5
|
+
gem gem_name, *gem_args
|
6
|
+
end
|
7
|
+
require library_name
|
8
|
+
rescue LoadError
|
9
|
+
require 'rubygems'
|
10
|
+
gem gem_name, *gem_args
|
11
|
+
require library_name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require_gem_if_need.call("active_support", "activesupport", ">= 3.0.0")
|
16
|
+
|
17
|
+
if ActiveSupport
|
18
|
+
require 'active_support/dependencies'
|
19
|
+
require 'active_support/all'
|
20
|
+
end
|
21
|
+
|
22
|
+
if ActiveSupport.const_defined?(:Dependencies)
|
23
|
+
dependencies = ActiveSupport::Dependencies
|
24
|
+
else
|
25
|
+
dependencies = Dependencies
|
26
|
+
end
|
27
|
+
|
28
|
+
if dependencies.respond_to?(:load_paths)
|
29
|
+
dependencies.load_paths << File.expand_path(File.dirname(__FILE__))
|
30
|
+
end
|
31
|
+
|
32
|
+
module ActiveLdap
|
33
|
+
VERSION = "1.2.3"
|
34
|
+
end
|
35
|
+
|
36
|
+
if RUBY_PLATFORM.match('linux')
|
37
|
+
require 'active_ldap/timeout'
|
38
|
+
else
|
39
|
+
require 'active_ldap/timeout_stub'
|
40
|
+
end
|
41
|
+
|
42
|
+
require_gem_if_need.call("active_record", "activerecord", ">= 3.0.0")
|
43
|
+
begin
|
44
|
+
require_gem_if_need.call("locale", nil, "= 2.0.5")
|
45
|
+
require_gem_if_need.call("fast_gettext", nil, "= 0.5.8")
|
46
|
+
rescue LoadError
|
47
|
+
end
|
48
|
+
require 'active_ldap/get_text'
|
49
|
+
|
50
|
+
require 'active_ldap/compatible'
|
51
|
+
|
52
|
+
require 'active_ldap/base'
|
53
|
+
|
54
|
+
require 'active_ldap/distinguished_name'
|
55
|
+
require 'active_ldap/ldif'
|
56
|
+
require 'active_ldap/xml'
|
57
|
+
|
58
|
+
require 'active_ldap/associations'
|
59
|
+
require 'active_ldap/attributes'
|
60
|
+
require 'active_ldap/configuration'
|
61
|
+
require 'active_ldap/connection'
|
62
|
+
require 'active_ldap/operations'
|
63
|
+
require 'active_ldap/object_class'
|
64
|
+
require 'active_ldap/human_readable'
|
65
|
+
|
66
|
+
require 'active_ldap/acts/tree'
|
67
|
+
|
68
|
+
require 'active_ldap/populate'
|
69
|
+
require 'active_ldap/escape'
|
70
|
+
require 'active_ldap/user_password'
|
71
|
+
require 'active_ldap/helper'
|
72
|
+
|
73
|
+
require 'active_ldap/validations'
|
74
|
+
require 'active_ldap/callbacks'
|
75
|
+
|
76
|
+
require 'active_ldap/command'
|
77
|
+
|
78
|
+
|
79
|
+
ActiveLdap::Base.class_eval do
|
80
|
+
include ActiveLdap::Associations
|
81
|
+
include ActiveLdap::Attributes
|
82
|
+
include ActiveLdap::Configuration
|
83
|
+
include ActiveLdap::Connection
|
84
|
+
include ActiveLdap::Operations
|
85
|
+
include ActiveLdap::ObjectClass
|
86
|
+
include ActiveLdap::HumanReadable
|
87
|
+
|
88
|
+
include ActiveLdap::Acts::Tree
|
89
|
+
|
90
|
+
include ActiveLdap::Validations
|
91
|
+
include ActiveLdap::Callbacks
|
92
|
+
end
|
93
|
+
|
94
|
+
unless defined?(ACTIVE_LDAP_CONNECTION_ADAPTERS)
|
95
|
+
ACTIVE_LDAP_CONNECTION_ADAPTERS = %w(ldap net_ldap jndi)
|
96
|
+
end
|
97
|
+
|
98
|
+
ACTIVE_LDAP_CONNECTION_ADAPTERS.each do |adapter|
|
99
|
+
require "active_ldap/adapter/#{adapter}"
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
if defined?(Rails)
|
104
|
+
require 'active_ldap/railtie'
|
105
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module ActiveLdap
|
2
|
+
module ActionController
|
3
|
+
module LdapBenchmarking
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
alias_method_chain :render_with_benchmark, :active_ldap
|
7
|
+
if private_method_defined?(:view_runtime)
|
8
|
+
alias_method_chain :view_runtime, :active_ldap
|
9
|
+
else
|
10
|
+
alias_method_chain :rendering_runtime, :active_ldap
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
def render_with_benchmark_with_active_ldap(*args, &block)
|
17
|
+
if logger
|
18
|
+
ldap_runtime_before_render = ActiveLdap::Base.reset_runtime
|
19
|
+
end
|
20
|
+
result = render_with_benchmark_without_active_ldap(*args, &block)
|
21
|
+
if logger
|
22
|
+
@ldap_runtime_before_render = ldap_runtime_before_render
|
23
|
+
@ldap_runtime_after_render = ActiveLdap::Base.reset_runtime
|
24
|
+
if defined?(@rendering_runtime)
|
25
|
+
@rendering_runtime -= @ldap_runtime_after_render
|
26
|
+
else
|
27
|
+
@view_runtime -= @ldap_runtime_after_render
|
28
|
+
end
|
29
|
+
end
|
30
|
+
result
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def rendering_runtime_with_active_ldap(runtime)
|
35
|
+
result = rendering_runtime_without_active_ldap(runtime)
|
36
|
+
ldap_runtime = ActiveLdap::Base.reset_runtime
|
37
|
+
ldap_runtime += @ldap_runtime_before_render || 0
|
38
|
+
ldap_runtime += @ldap_runtime_after_render || 0
|
39
|
+
ldap_percentage = ldap_runtime * 100 / runtime
|
40
|
+
result + (" | LDAP: %.5f (%d%%)" % [ldap_runtime, ldap_percentage])
|
41
|
+
end
|
42
|
+
|
43
|
+
def view_runtime_with_active_ldap
|
44
|
+
result = view_runtime_without_active_ldap
|
45
|
+
ldap_runtime = ActiveLdap::Base.reset_runtime
|
46
|
+
@ldap_runtime_before_render ||= 0
|
47
|
+
@ldap_runtime_after_render ||= 0
|
48
|
+
ldap_runtime += @ldap_runtime_before_render
|
49
|
+
ldap_runtime += @ldap_runtime_after_render
|
50
|
+
result + (", LDAP: %.0f" % (ldap_runtime * 1000))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module ActiveLdap
|
2
|
+
module Acts
|
3
|
+
module Tree
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
extend(ClassMethods)
|
7
|
+
association_accessor(:children) do |target|
|
8
|
+
Association::Children.new(target, {})
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def root(options={})
|
15
|
+
find(:first, options.merge(:scope => :base))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns list of ancestors, starting from parent until root.
|
20
|
+
#
|
21
|
+
# subchild1.ancestors # => [child1, root]
|
22
|
+
def ancestors
|
23
|
+
node, nodes = self, []
|
24
|
+
nodes << node = node.parent while node.parent
|
25
|
+
nodes
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the root node of the tree.
|
29
|
+
def root
|
30
|
+
node = self
|
31
|
+
node = node.parent while node.parent
|
32
|
+
node
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns all siblings of the current node.
|
36
|
+
#
|
37
|
+
# subchild1.siblings # => [subchild2]
|
38
|
+
def siblings
|
39
|
+
self_and_siblings - [self]
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns all siblings and a reference to the current node.
|
43
|
+
#
|
44
|
+
# subchild1.self_and_siblings # => [subchild1, subchild2]
|
45
|
+
def self_and_siblings
|
46
|
+
parent ? parent.children : [self]
|
47
|
+
end
|
48
|
+
|
49
|
+
def parent
|
50
|
+
if base == self.class.base
|
51
|
+
nil
|
52
|
+
else
|
53
|
+
find(:first, :base => base, :scope => :base)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def parent=(entry)
|
58
|
+
if entry.is_a?(String) or entry.is_a?(DN)
|
59
|
+
base = entry
|
60
|
+
elsif entry.respond_to?(:dn)
|
61
|
+
base = entry.dn
|
62
|
+
if entry.respond_to?(:clear_association_cache)
|
63
|
+
entry.clear_association_cache
|
64
|
+
end
|
65
|
+
else
|
66
|
+
message = _("parent must be an entry or parent DN: %s") % entry.inspect
|
67
|
+
raise ArgumentError, message
|
68
|
+
end
|
69
|
+
destroy unless new_entry?
|
70
|
+
self.dn = "#{dn_attribute}=#{id},#{base}"
|
71
|
+
save
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,705 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
|
3
|
+
require 'active_ldap/schema'
|
4
|
+
require 'active_ldap/entry_attribute'
|
5
|
+
require 'active_ldap/ldap_error'
|
6
|
+
|
7
|
+
module ActiveLdap
|
8
|
+
module Adapter
|
9
|
+
class Base
|
10
|
+
include GetTextSupport
|
11
|
+
|
12
|
+
VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :timeout,
|
13
|
+
:retry_on_timeout, :retry_limit,
|
14
|
+
:retry_wait, :bind_dn, :password,
|
15
|
+
:password_block, :try_sasl,
|
16
|
+
:sasl_mechanisms, :sasl_quiet,
|
17
|
+
:allow_anonymous, :store_password,
|
18
|
+
:scope, :sasl_options]
|
19
|
+
|
20
|
+
@@row_even = true
|
21
|
+
|
22
|
+
attr_reader :runtime
|
23
|
+
def initialize(configuration={})
|
24
|
+
@runtime = 0
|
25
|
+
@connection = nil
|
26
|
+
@disconnected = false
|
27
|
+
@bound = false
|
28
|
+
@bind_tried = false
|
29
|
+
@entry_attributes = {}
|
30
|
+
@configuration = configuration.dup
|
31
|
+
@logger = @configuration.delete(:logger)
|
32
|
+
@configuration.assert_valid_keys(VALID_ADAPTER_CONFIGURATION_KEYS)
|
33
|
+
VALID_ADAPTER_CONFIGURATION_KEYS.each do |name|
|
34
|
+
instance_variable_set("@#{name}", configuration[name])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def reset_runtime
|
39
|
+
runtime, @runtime = @runtime, 0
|
40
|
+
runtime
|
41
|
+
end
|
42
|
+
|
43
|
+
def connect(options={})
|
44
|
+
host = options[:host] || @host
|
45
|
+
method = options[:method] || @method || :plain
|
46
|
+
port = options[:port] || @port || ensure_port(method)
|
47
|
+
method = ensure_method(method)
|
48
|
+
@disconnected = false
|
49
|
+
@bound = false
|
50
|
+
@bind_tried = false
|
51
|
+
@connection, @uri, @with_start_tls = yield(host, port, method)
|
52
|
+
prepare_connection(options)
|
53
|
+
bind(options)
|
54
|
+
end
|
55
|
+
|
56
|
+
def disconnect!(options={})
|
57
|
+
unbind(options)
|
58
|
+
@connection = @uri = @with_start_tls = nil
|
59
|
+
@disconnected = true
|
60
|
+
end
|
61
|
+
|
62
|
+
def rebind(options={})
|
63
|
+
unbind(options) if bound?
|
64
|
+
connect(options)
|
65
|
+
end
|
66
|
+
|
67
|
+
def bind(options={})
|
68
|
+
@bind_tried = true
|
69
|
+
|
70
|
+
bind_dn = ensure_dn_string(options[:bind_dn] || @bind_dn)
|
71
|
+
try_sasl = options.has_key?(:try_sasl) ? options[:try_sasl] : @try_sasl
|
72
|
+
if options.has_key?(:allow_anonymous)
|
73
|
+
allow_anonymous = options[:allow_anonymous]
|
74
|
+
else
|
75
|
+
allow_anonymous = @allow_anonymous
|
76
|
+
end
|
77
|
+
options = options.merge(:allow_anonymous => allow_anonymous)
|
78
|
+
|
79
|
+
# Rough bind loop:
|
80
|
+
# Attempt 1: SASL if available
|
81
|
+
# Attempt 2: SIMPLE with credentials if password block
|
82
|
+
# Attempt 3: SIMPLE ANONYMOUS if 1 and 2 fail (or pwblock returns '')
|
83
|
+
if try_sasl and sasl_bind(bind_dn, options)
|
84
|
+
@logger.info {_('Bound to %s by SASL as %s') % [target, bind_dn]}
|
85
|
+
elsif simple_bind(bind_dn, options)
|
86
|
+
@logger.info {_('Bound to %s by simple as %s') % [target, bind_dn]}
|
87
|
+
elsif allow_anonymous and bind_as_anonymous(options)
|
88
|
+
@logger.info {_('Bound to %s as anonymous') % target}
|
89
|
+
else
|
90
|
+
message = yield if block_given?
|
91
|
+
message ||= _('All authentication methods for %s exhausted.') % target
|
92
|
+
raise AuthenticationError, message
|
93
|
+
end
|
94
|
+
|
95
|
+
@bound = true
|
96
|
+
@bound
|
97
|
+
end
|
98
|
+
|
99
|
+
def unbind(options={})
|
100
|
+
yield if @connection and (@bind_tried or bound?)
|
101
|
+
@bind_tried = @bound = false
|
102
|
+
end
|
103
|
+
|
104
|
+
def bind_as_anonymous(options={})
|
105
|
+
yield
|
106
|
+
end
|
107
|
+
|
108
|
+
def connecting?
|
109
|
+
!@connection.nil? and !@disconnected
|
110
|
+
end
|
111
|
+
|
112
|
+
def bound?
|
113
|
+
connecting? and @bound
|
114
|
+
end
|
115
|
+
|
116
|
+
def schema(options={})
|
117
|
+
@schema ||= operation(options) do
|
118
|
+
base = options[:base]
|
119
|
+
attrs = options[:attributes]
|
120
|
+
|
121
|
+
attrs ||= [
|
122
|
+
'objectClasses',
|
123
|
+
'attributeTypes',
|
124
|
+
'matchingRules',
|
125
|
+
'matchingRuleUse',
|
126
|
+
'dITStructureRules',
|
127
|
+
'dITContentRules',
|
128
|
+
'nameForms',
|
129
|
+
'ldapSyntaxes',
|
130
|
+
#'extendedAttributeInfo', # if we need RANGE-LOWER/UPPER.
|
131
|
+
]
|
132
|
+
base ||= root_dse_values('subschemaSubentry', options)[0]
|
133
|
+
base ||= 'cn=schema'
|
134
|
+
schema = nil
|
135
|
+
search(:base => base,
|
136
|
+
:scope => :base,
|
137
|
+
:filter => '(objectClass=subschema)',
|
138
|
+
:attributes => attrs,
|
139
|
+
:limit => 1) do |dn, attributes|
|
140
|
+
schema = Schema.new(attributes)
|
141
|
+
end
|
142
|
+
schema || Schema.new([])
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def naming_contexts
|
147
|
+
root_dse_values('namingContexts')
|
148
|
+
end
|
149
|
+
|
150
|
+
def entry_attribute(object_classes)
|
151
|
+
@entry_attributes[object_classes.uniq.sort] ||=
|
152
|
+
EntryAttribute.new(schema, object_classes)
|
153
|
+
end
|
154
|
+
|
155
|
+
def search(options={})
|
156
|
+
filter = parse_filter(options[:filter]) || 'objectClass=*'
|
157
|
+
attrs = options[:attributes] || []
|
158
|
+
scope = ensure_scope(options[:scope] || @scope)
|
159
|
+
base = options[:base]
|
160
|
+
limit = options[:limit] || 0
|
161
|
+
limit = nil if limit <= 0
|
162
|
+
|
163
|
+
attrs = attrs.to_a # just in case
|
164
|
+
base = ensure_dn_string(base)
|
165
|
+
begin
|
166
|
+
operation(options) do
|
167
|
+
yield(base, scope, filter, attrs, limit)
|
168
|
+
end
|
169
|
+
rescue LdapError::NoSuchObject, LdapError::InvalidDnSyntax
|
170
|
+
# Do nothing on failure
|
171
|
+
@logger.info do
|
172
|
+
args = [$!.class, $!.message, filter, attrs.inspect]
|
173
|
+
_("Ignore error %s(%s): filter %s: attributes: %s") % args
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def delete(targets, options={})
|
179
|
+
targets = [targets] unless targets.is_a?(Array)
|
180
|
+
return if targets.empty?
|
181
|
+
begin
|
182
|
+
operation(options) do
|
183
|
+
targets.each do |target|
|
184
|
+
target = ensure_dn_string(target)
|
185
|
+
begin
|
186
|
+
yield(target)
|
187
|
+
rescue LdapError::UnwillingToPerform, LdapError::InsufficientAccess
|
188
|
+
raise OperationNotPermitted, _("%s: %s") % [$!.message, target]
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
rescue LdapError::NoSuchObject
|
193
|
+
raise EntryNotFound, _("No such entry: %s") % target
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def add(dn, entries, options={})
|
198
|
+
dn = ensure_dn_string(dn)
|
199
|
+
begin
|
200
|
+
operation(options) do
|
201
|
+
yield(dn, entries)
|
202
|
+
end
|
203
|
+
rescue LdapError::NoSuchObject
|
204
|
+
raise EntryNotFound, _("No such entry: %s") % dn
|
205
|
+
rescue LdapError::InvalidDnSyntax
|
206
|
+
raise DistinguishedNameInvalid.new(dn)
|
207
|
+
rescue LdapError::AlreadyExists
|
208
|
+
raise EntryAlreadyExist, _("%s: %s") % [$!.message, dn]
|
209
|
+
rescue LdapError::StrongAuthRequired
|
210
|
+
raise StrongAuthenticationRequired, _("%s: %s") % [$!.message, dn]
|
211
|
+
rescue LdapError::ObjectClassViolation
|
212
|
+
raise RequiredAttributeMissed, _("%s: %s") % [$!.message, dn]
|
213
|
+
rescue LdapError::UnwillingToPerform
|
214
|
+
raise OperationNotPermitted, _("%s: %s") % [$!.message, dn]
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def modify(dn, entries, options={})
|
219
|
+
dn = ensure_dn_string(dn)
|
220
|
+
begin
|
221
|
+
operation(options) do
|
222
|
+
begin
|
223
|
+
yield(dn, entries)
|
224
|
+
rescue LdapError::UnwillingToPerform, LdapError::InsufficientAccess
|
225
|
+
raise OperationNotPermitted, _("%s: %s") % [$!.message, target]
|
226
|
+
end
|
227
|
+
end
|
228
|
+
rescue LdapError::UndefinedType
|
229
|
+
raise
|
230
|
+
rescue LdapError::ObjectClassViolation
|
231
|
+
raise RequiredAttributeMissed, _("%s: %s") % [$!.message, dn]
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={})
|
236
|
+
dn = ensure_dn_string(dn)
|
237
|
+
operation(options) do
|
238
|
+
yield(dn, new_rdn, delete_old_rdn, new_superior)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def log_info(name, runtime_in_seconds, info=nil)
|
243
|
+
return unless @logger
|
244
|
+
return unless @logger.debug?
|
245
|
+
message = "LDAP: #{name} (#{'%.1f' % (runtime_in_seconds * 1000)}ms)"
|
246
|
+
@logger.debug(format_log_entry(message, info))
|
247
|
+
end
|
248
|
+
|
249
|
+
private
|
250
|
+
def ensure_port(method)
|
251
|
+
if method == :ssl
|
252
|
+
URI::LDAPS::DEFAULT_PORT
|
253
|
+
else
|
254
|
+
URI::LDAP::DEFAULT_PORT
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def prepare_connection(options)
|
259
|
+
end
|
260
|
+
|
261
|
+
def operation(options)
|
262
|
+
retried = false
|
263
|
+
options = options.dup
|
264
|
+
options[:try_reconnect] = true unless options.has_key?(:try_reconnect)
|
265
|
+
try_reconnect = false
|
266
|
+
begin
|
267
|
+
reconnect_if_need(options)
|
268
|
+
try_reconnect = options[:try_reconnect]
|
269
|
+
with_timeout(try_reconnect, options) do
|
270
|
+
yield
|
271
|
+
end
|
272
|
+
rescue ConnectionError
|
273
|
+
if try_reconnect and !retried
|
274
|
+
retried = true
|
275
|
+
@disconnected = true
|
276
|
+
retry
|
277
|
+
else
|
278
|
+
raise
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def need_credential_sasl_mechanism?(mechanism)
|
284
|
+
not %(GSSAPI EXTERNAL ANONYMOUS).include?(mechanism)
|
285
|
+
end
|
286
|
+
|
287
|
+
def password(bind_dn, options={})
|
288
|
+
passwd = options[:password] || @password
|
289
|
+
return passwd if passwd
|
290
|
+
|
291
|
+
password_block = options[:password_block] || @password_block
|
292
|
+
# TODO: Give a warning to reconnect users with password clearing
|
293
|
+
# Get the passphrase for the first time, or anew if we aren't storing
|
294
|
+
if password_block.respond_to?(:call)
|
295
|
+
passwd = password_block.call(bind_dn)
|
296
|
+
else
|
297
|
+
@logger.error {_('password_block not nil or Proc object. Ignoring.')}
|
298
|
+
return nil
|
299
|
+
end
|
300
|
+
|
301
|
+
# Store the password for quick reference later
|
302
|
+
if options.has_key?(:store_password)
|
303
|
+
store_password = options[:store_password]
|
304
|
+
else
|
305
|
+
store_password = @store_password
|
306
|
+
end
|
307
|
+
@password = store_password ? passwd : nil
|
308
|
+
|
309
|
+
passwd
|
310
|
+
end
|
311
|
+
|
312
|
+
def with_timeout(try_reconnect=true, options={}, &block)
|
313
|
+
n_retries = 0
|
314
|
+
retry_limit = options[:retry_limit] || @retry_limit
|
315
|
+
begin
|
316
|
+
do_in_timeout(@timeout, &block)
|
317
|
+
rescue Timeout::Error => e
|
318
|
+
@logger.error {_('Requested action timed out.')}
|
319
|
+
if @retry_on_timeout and retry_limit < 0 and n_retries <= retry_limit
|
320
|
+
if connecting?
|
321
|
+
retry
|
322
|
+
elsif try_reconnect
|
323
|
+
retry if with_timeout(false, options) {reconnect(options)}
|
324
|
+
end
|
325
|
+
end
|
326
|
+
@logger.error {e.message}
|
327
|
+
raise TimeoutError, e.message
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
def do_in_timeout(timeout, &block)
|
332
|
+
Timeout.alarm(timeout, &block)
|
333
|
+
end
|
334
|
+
|
335
|
+
def sasl_bind(bind_dn, options={})
|
336
|
+
# Get all SASL mechanisms
|
337
|
+
mechanisms = operation(options) do
|
338
|
+
root_dse_values("supportedSASLMechanisms")
|
339
|
+
end
|
340
|
+
|
341
|
+
if options.has_key?(:sasl_quiet)
|
342
|
+
sasl_quiet = options[:sasl_quiet]
|
343
|
+
else
|
344
|
+
sasl_quiet = @sasl_quiet
|
345
|
+
end
|
346
|
+
|
347
|
+
sasl_mechanisms = options[:sasl_mechanisms] || @sasl_mechanisms
|
348
|
+
sasl_mechanisms.each do |mechanism|
|
349
|
+
next unless mechanisms.include?(mechanism)
|
350
|
+
return true if yield(bind_dn, mechanism, sasl_quiet)
|
351
|
+
end
|
352
|
+
false
|
353
|
+
end
|
354
|
+
|
355
|
+
def simple_bind(bind_dn, options={})
|
356
|
+
return false unless bind_dn
|
357
|
+
|
358
|
+
passwd = password(bind_dn, options)
|
359
|
+
return false unless passwd
|
360
|
+
|
361
|
+
if passwd.empty?
|
362
|
+
if options[:allow_anonymous]
|
363
|
+
@logger.info {_("Skip simple bind with empty password.")}
|
364
|
+
return false
|
365
|
+
else
|
366
|
+
raise AuthenticationError,
|
367
|
+
_("Can't use empty password for simple bind.")
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
begin
|
372
|
+
yield(bind_dn, passwd)
|
373
|
+
rescue LdapError::InvalidDnSyntax
|
374
|
+
raise DistinguishedNameInvalid.new(bind_dn)
|
375
|
+
rescue LdapError::InvalidCredentials
|
376
|
+
false
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def parse_filter(filter, operator=nil)
|
381
|
+
return nil if filter.nil?
|
382
|
+
if !filter.is_a?(String) and !filter.respond_to?(:collect)
|
383
|
+
filter = filter.to_s
|
384
|
+
end
|
385
|
+
|
386
|
+
case filter
|
387
|
+
when String
|
388
|
+
parse_filter_string(filter)
|
389
|
+
when Hash
|
390
|
+
components = filter.sort_by {|k, v| k.to_s}.collect do |key, value|
|
391
|
+
construct_component(key, value, operator)
|
392
|
+
end
|
393
|
+
construct_filter(components, operator)
|
394
|
+
else
|
395
|
+
operator, components = normalize_array_filter(filter, operator)
|
396
|
+
components = construct_components(components, operator)
|
397
|
+
construct_filter(components, operator)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
def parse_filter_string(filter)
|
402
|
+
if /\A\s*\z/.match(filter)
|
403
|
+
nil
|
404
|
+
else
|
405
|
+
if filter[0, 1] == "("
|
406
|
+
filter
|
407
|
+
else
|
408
|
+
"(#{filter})"
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
def normalize_array_filter(filter, operator=nil)
|
414
|
+
filter_operator, *components = filter
|
415
|
+
if filter_logical_operator?(filter_operator)
|
416
|
+
operator = filter_operator
|
417
|
+
else
|
418
|
+
components.unshift(filter_operator)
|
419
|
+
components = [components] unless filter_operator.is_a?(Array)
|
420
|
+
end
|
421
|
+
[operator, components]
|
422
|
+
end
|
423
|
+
|
424
|
+
def extract_filter_value_options(value)
|
425
|
+
options = {}
|
426
|
+
if value.is_a?(Array)
|
427
|
+
case value[0]
|
428
|
+
when Hash
|
429
|
+
options = value[0]
|
430
|
+
value = value[1]
|
431
|
+
when "=", "~=", "<=", ">="
|
432
|
+
options[:operator] = value[0]
|
433
|
+
if value.size > 2
|
434
|
+
value = value[1..-1]
|
435
|
+
else
|
436
|
+
value = value[1]
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
[value, options]
|
441
|
+
end
|
442
|
+
|
443
|
+
def construct_components(components, operator)
|
444
|
+
components.collect do |component|
|
445
|
+
if component.is_a?(Array)
|
446
|
+
if filter_logical_operator?(component[0])
|
447
|
+
parse_filter(component)
|
448
|
+
elsif component.size == 2
|
449
|
+
key, value = component
|
450
|
+
if value.is_a?(Hash)
|
451
|
+
parse_filter(value, key)
|
452
|
+
else
|
453
|
+
construct_component(key, value, operator)
|
454
|
+
end
|
455
|
+
else
|
456
|
+
construct_component(component[0], component[1..-1], operator)
|
457
|
+
end
|
458
|
+
elsif component.is_a?(Symbol)
|
459
|
+
assert_filter_logical_operator(component)
|
460
|
+
nil
|
461
|
+
else
|
462
|
+
parse_filter(component, operator)
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
def construct_component(key, value, operator=nil)
|
468
|
+
value, options = extract_filter_value_options(value)
|
469
|
+
comparison_operator = options[:operator] || "="
|
470
|
+
if collection?(value)
|
471
|
+
return nil if value.empty?
|
472
|
+
operator, value = normalize_array_filter(value, operator)
|
473
|
+
values = []
|
474
|
+
value.each do |val|
|
475
|
+
if collection?(val)
|
476
|
+
values.concat(val.collect {|v| [key, comparison_operator, v]})
|
477
|
+
else
|
478
|
+
values << [key, comparison_operator, val]
|
479
|
+
end
|
480
|
+
end
|
481
|
+
values[0] = values[0][1] if filter_logical_operator?(values[0][1])
|
482
|
+
parse_filter(values, operator)
|
483
|
+
else
|
484
|
+
[
|
485
|
+
"(",
|
486
|
+
escape_filter_key(key),
|
487
|
+
comparison_operator,
|
488
|
+
escape_filter_value(value, options),
|
489
|
+
")"
|
490
|
+
].join
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
def escape_filter_key(key)
|
495
|
+
escape_filter_value(key.to_s)
|
496
|
+
end
|
497
|
+
|
498
|
+
def escape_filter_value(value, options={})
|
499
|
+
case value
|
500
|
+
when Numeric, DN
|
501
|
+
value = value.to_s
|
502
|
+
when Time
|
503
|
+
value = Schema::GeneralizedTime.new.normalize_value(value)
|
504
|
+
end
|
505
|
+
value.gsub(/(?:[:()\\\0]|\*\*?)/) do |s|
|
506
|
+
if s == "*"
|
507
|
+
s
|
508
|
+
else
|
509
|
+
s = "*" if s == "**"
|
510
|
+
if s.respond_to?(:getbyte)
|
511
|
+
"\\%02X" % s.getbyte(0)
|
512
|
+
else
|
513
|
+
"\\%02X" % s[0]
|
514
|
+
end
|
515
|
+
end
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
def construct_filter(components, operator=nil)
|
520
|
+
operator = normalize_filter_logical_operator(operator)
|
521
|
+
components = components.compact
|
522
|
+
case components.size
|
523
|
+
when 0
|
524
|
+
nil
|
525
|
+
when 1
|
526
|
+
filter = components[0]
|
527
|
+
filter = "(!#{filter})" if operator == :not
|
528
|
+
filter
|
529
|
+
else
|
530
|
+
"(#{operator == :and ? '&' : '|'}#{components.join})"
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
def collection?(object)
|
535
|
+
!object.is_a?(String) and object.respond_to?(:each)
|
536
|
+
end
|
537
|
+
|
538
|
+
LOGICAL_OPERATORS = [:and, :or, :not, :&, :|]
|
539
|
+
def filter_logical_operator?(operator)
|
540
|
+
LOGICAL_OPERATORS.include?(operator)
|
541
|
+
end
|
542
|
+
|
543
|
+
def normalize_filter_logical_operator(operator)
|
544
|
+
assert_filter_logical_operator(operator)
|
545
|
+
case (operator || :and)
|
546
|
+
when :and, :&
|
547
|
+
:and
|
548
|
+
when :or, :|
|
549
|
+
:or
|
550
|
+
else
|
551
|
+
:not
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
def assert_filter_logical_operator(operator)
|
556
|
+
return if operator.nil?
|
557
|
+
unless filter_logical_operator?(operator)
|
558
|
+
raise ArgumentError,
|
559
|
+
_("invalid logical operator: %s: available operators: %s") %
|
560
|
+
[operator.inspect, LOGICAL_OPERATORS.inspect]
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
# Attempts to reconnect up to the number of times allowed
|
565
|
+
# If forced, try once then fail with ConnectionError if not connected.
|
566
|
+
def reconnect(options={})
|
567
|
+
options = options.dup
|
568
|
+
force = options[:force]
|
569
|
+
retry_limit = options[:retry_limit] || @retry_limit
|
570
|
+
retry_wait = options[:retry_wait] || @retry_wait
|
571
|
+
options[:reconnect_attempts] ||= 0
|
572
|
+
|
573
|
+
loop do
|
574
|
+
@logger.debug {_('Attempting to reconnect')}
|
575
|
+
disconnect!
|
576
|
+
|
577
|
+
# Reset the attempts if this was forced.
|
578
|
+
options[:reconnect_attempts] = 0 if force
|
579
|
+
options[:reconnect_attempts] += 1 if retry_limit >= 0
|
580
|
+
begin
|
581
|
+
connect(options)
|
582
|
+
break
|
583
|
+
rescue AuthenticationError
|
584
|
+
raise
|
585
|
+
rescue => detail
|
586
|
+
@logger.error do
|
587
|
+
_("Reconnect to server failed: %s\n" \
|
588
|
+
"Reconnect to server failed backtrace:\n" \
|
589
|
+
"%s") % [detail.exception, detail.backtrace.join("\n")]
|
590
|
+
end
|
591
|
+
# Do not loop if forced
|
592
|
+
raise ConnectionError, detail.message if force
|
593
|
+
end
|
594
|
+
|
595
|
+
unless can_reconnect?(options)
|
596
|
+
raise ConnectionError,
|
597
|
+
_('Giving up trying to reconnect to LDAP server.')
|
598
|
+
end
|
599
|
+
|
600
|
+
# Sleep before looping
|
601
|
+
sleep retry_wait
|
602
|
+
end
|
603
|
+
|
604
|
+
true
|
605
|
+
end
|
606
|
+
|
607
|
+
def reconnect_if_need(options={})
|
608
|
+
return if connecting?
|
609
|
+
with_timeout(false, options) do
|
610
|
+
reconnect(options)
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
# Determine if we have exceed the retry limit or not.
|
615
|
+
# True is reconnecting is allowed - False if not.
|
616
|
+
def can_reconnect?(options={})
|
617
|
+
retry_limit = options[:retry_limit] || @retry_limit
|
618
|
+
reconnect_attempts = options[:reconnect_attempts] || 0
|
619
|
+
|
620
|
+
retry_limit < 0 or reconnect_attempts <= retry_limit
|
621
|
+
end
|
622
|
+
|
623
|
+
def root_dse_values(key, options={})
|
624
|
+
dse = root_dse([key], options)
|
625
|
+
return [] if dse.nil?
|
626
|
+
normalized_key = key.downcase
|
627
|
+
dse.each do |_key, _value|
|
628
|
+
return _value if _key.downcase == normalized_key
|
629
|
+
end
|
630
|
+
[]
|
631
|
+
end
|
632
|
+
|
633
|
+
def root_dse(attrs, options={})
|
634
|
+
found_attributes = nil
|
635
|
+
search(:base => "",
|
636
|
+
:scope => :base,
|
637
|
+
:attributes => attrs,
|
638
|
+
:limit => 1) do |dn, attributes|
|
639
|
+
found_attributes = attributes
|
640
|
+
end
|
641
|
+
found_attributes
|
642
|
+
end
|
643
|
+
|
644
|
+
def construct_uri(host, port, ssl)
|
645
|
+
protocol = ssl ? "ldaps" : "ldap"
|
646
|
+
URI.parse("#{protocol}://#{host}:#{port}").to_s
|
647
|
+
end
|
648
|
+
|
649
|
+
def target
|
650
|
+
return nil if @uri.nil?
|
651
|
+
if @with_start_tls
|
652
|
+
"#{@uri}(StartTLS)"
|
653
|
+
else
|
654
|
+
@uri
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
def log(name, info=nil)
|
659
|
+
if block_given?
|
660
|
+
result = nil
|
661
|
+
seconds = Benchmark.realtime {result = yield}
|
662
|
+
@runtime += seconds
|
663
|
+
log_info(name, seconds, info)
|
664
|
+
result
|
665
|
+
else
|
666
|
+
log_info(name, 0, info)
|
667
|
+
nil
|
668
|
+
end
|
669
|
+
rescue Exception
|
670
|
+
log_info("#{name}: FAILED", 0,
|
671
|
+
(info || {}).merge(:error => $!.class.name,
|
672
|
+
:error_message => $!.message))
|
673
|
+
raise
|
674
|
+
end
|
675
|
+
|
676
|
+
def format_log_entry(message, info=nil)
|
677
|
+
if ActiveLdap::Base.colorize_logging
|
678
|
+
if @@row_even
|
679
|
+
message_color, dump_color = "4;36;1", "0;1"
|
680
|
+
else
|
681
|
+
@@row_even = true
|
682
|
+
message_color, dump_color = "4;35;1", "0"
|
683
|
+
end
|
684
|
+
@@row_even = !@@row_even
|
685
|
+
|
686
|
+
log_entry = " \e[#{message_color}m#{message}\e[0m"
|
687
|
+
log_entry << ": \e[#{dump_color}m#{info.inspect}\e[0m" if info
|
688
|
+
log_entry
|
689
|
+
else
|
690
|
+
log_entry = message
|
691
|
+
log_entry += ": #{info.inspect}" if info
|
692
|
+
log_entry
|
693
|
+
end
|
694
|
+
end
|
695
|
+
|
696
|
+
def ensure_dn_string(dn)
|
697
|
+
if dn.is_a?(DN)
|
698
|
+
dn.to_s
|
699
|
+
else
|
700
|
+
dn
|
701
|
+
end
|
702
|
+
end
|
703
|
+
end
|
704
|
+
end
|
705
|
+
end
|